@dickpy/dsh-imagegen 1.5.1 → 1.5.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.md +13 -9
- package/docs/images/ecommerce-mode.png +0 -0
- package/docs/images/gallery-workspace.png +0 -0
- package/docs/images/image-generation-studio-three-column.png +0 -0
- package/docs/images/imagegen-overview.png +0 -0
- package/docs/images/plugin-settings.png +0 -0
- package/docs/images/prompt-template-library.png +0 -0
- package/lib/client.js +1304 -447
- package/lib/client.js.map +1 -1
- package/lib/index.js +632 -76
- package/package.json +1 -1
- package/src/client/ImageGenPanel.tsx +15 -9
- package/src/client/InspirationGallery.tsx +106 -0
- package/src/client/SettingsCard.tsx +9 -3
- package/src/client/TemplateLibrary.tsx +159 -48
- package/src/client/api.ts +41 -8
- package/src/client/helpers.ts +71 -33
- package/src/client/index.ts +59 -7
- package/src/client/inspiration.module.css +148 -0
- package/src/client/locales.ts +417 -8
- package/src/client/templates.module.css +95 -0
- package/src/client/use-language.ts +14 -0
- package/src/engine.ts +148 -0
- package/src/index.ts +23 -3
- package/src/model-catalog.ts +10 -1
- package/src/presets.ts +15 -0
- package/src/protocol.ts +81 -7
- package/src/routes.ts +124 -10
- package/src/template-favorites.ts +108 -0
- package/src/templates/canghe-cases.json +11126 -0
- package/src/templates-store.ts +179 -68
- package/docs/images/image-generation-studio-single.png +0 -0
- package/docs/images/image-generation-studio.png +0 -0
- package/docs/images/poster-features-16x9.png +0 -0
package/lib/client.js
CHANGED
|
@@ -76,16 +76,43 @@ window.__ModuleLoader__.load({
|
|
|
76
76
|
image: "/api/dsh-imagegen/gallery/image"
|
|
77
77
|
};
|
|
78
78
|
/**
|
|
79
|
-
* Same-origin route family for the
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
79
|
+
* Same-origin route family for the prompt-template libraries. The library is
|
|
80
|
+
* multi-source: every request names a source id from {@link TEMPLATE_SOURCES},
|
|
81
|
+
* each source keeps an independent snapshot/image cache host-side, and
|
|
82
|
+
* reference images are proxied through the source-scoped `image` prefix route
|
|
83
|
+
* (`…/image/<sourceId>/<file>`) and cached on disk so repeated views never hit
|
|
84
|
+
* the network again.
|
|
83
85
|
*/
|
|
84
86
|
const TEMPLATES_API = {
|
|
85
87
|
list: "/api/dsh-imagegen/templates/list",
|
|
86
88
|
refresh: "/api/dsh-imagegen/templates/refresh",
|
|
89
|
+
sample: "/api/dsh-imagegen/templates/sample",
|
|
87
90
|
image: "/api/dsh-imagegen/templates/image"
|
|
88
91
|
};
|
|
92
|
+
/** Same-origin route family for the user's saved (favorited) templates. */
|
|
93
|
+
const TEMPLATE_FAVORITES_API = {
|
|
94
|
+
list: "/api/dsh-imagegen/templates/favorites/list",
|
|
95
|
+
add: "/api/dsh-imagegen/templates/favorites/add",
|
|
96
|
+
remove: "/api/dsh-imagegen/templates/favorites/remove"
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* The template-library source registry. Each entry is fully independent (own
|
|
100
|
+
* upstream JSON, own image pool, own refresh state) and renders as its own
|
|
101
|
+
* tab; adding a source later means appending an entry here plus a host-side
|
|
102
|
+
* fetch definition in templates-store.ts and an optional bundled snapshot.
|
|
103
|
+
*/
|
|
104
|
+
const TEMPLATE_SOURCES = [{
|
|
105
|
+
id: "vibeui",
|
|
106
|
+
label: "精选案例库",
|
|
107
|
+
homepage: "https://vibeui.top/",
|
|
108
|
+
description: "awesome-gpt-image-2 精选提示词案例(vibeui.top 镜像)"
|
|
109
|
+
}, {
|
|
110
|
+
id: "canghe",
|
|
111
|
+
label: "沧河案例库",
|
|
112
|
+
homepage: "https://gpt-image2.canghe.ai/",
|
|
113
|
+
description: "GPT-Image2 Prompt Gallery(gpt-image2.canghe.ai,定期更新)"
|
|
114
|
+
}];
|
|
115
|
+
TEMPLATE_SOURCES[0].id;
|
|
89
116
|
//#endregion
|
|
90
117
|
//#region src/client/api.ts
|
|
91
118
|
/**
|
|
@@ -245,10 +272,15 @@ window.__ModuleLoader__.load({
|
|
|
245
272
|
})
|
|
246
273
|
}))).entries;
|
|
247
274
|
}
|
|
248
|
-
/** Fetch
|
|
249
|
-
async templatesList() {
|
|
250
|
-
const body = await readEnvelope(await fetch(TEMPLATES_API.list, {
|
|
275
|
+
/** Fetch one template source's list (bundled snapshot or refreshed copy). */
|
|
276
|
+
async templatesList(sourceId) {
|
|
277
|
+
const body = await readEnvelope(await fetch(TEMPLATES_API.list, {
|
|
278
|
+
method: "POST",
|
|
279
|
+
headers: { "content-type": "application/json" },
|
|
280
|
+
body: JSON.stringify({ source: sourceId })
|
|
281
|
+
}));
|
|
251
282
|
return {
|
|
283
|
+
sourceId: body.sourceId,
|
|
252
284
|
cases: body.cases,
|
|
253
285
|
total: body.total,
|
|
254
286
|
origin: body.origin,
|
|
@@ -256,14 +288,50 @@ window.__ModuleLoader__.load({
|
|
|
256
288
|
fetchedAt: body.fetchedAt
|
|
257
289
|
};
|
|
258
290
|
}
|
|
259
|
-
/** Re-download
|
|
260
|
-
async templatesRefresh() {
|
|
261
|
-
const body = await readEnvelope(await fetch(TEMPLATES_API.refresh, {
|
|
291
|
+
/** Re-download one template source's list from its upstream mirror (host-side). */
|
|
292
|
+
async templatesRefresh(sourceId) {
|
|
293
|
+
const body = await readEnvelope(await fetch(TEMPLATES_API.refresh, {
|
|
294
|
+
method: "POST",
|
|
295
|
+
headers: { "content-type": "application/json" },
|
|
296
|
+
body: JSON.stringify({ source: sourceId })
|
|
297
|
+
}));
|
|
262
298
|
return {
|
|
299
|
+
sourceId: body.sourceId,
|
|
263
300
|
total: body.total,
|
|
264
301
|
fetchedAt: body.fetchedAt
|
|
265
302
|
};
|
|
266
303
|
}
|
|
304
|
+
/** Draw random cases across every source (studio inspiration wall). */
|
|
305
|
+
async templatesSample(count) {
|
|
306
|
+
return (await readEnvelope(await fetch(TEMPLATES_API.sample, {
|
|
307
|
+
method: "POST",
|
|
308
|
+
headers: { "content-type": "application/json" },
|
|
309
|
+
body: JSON.stringify({ count })
|
|
310
|
+
}))).samples;
|
|
311
|
+
}
|
|
312
|
+
/** List the host-persisted template favorites. */
|
|
313
|
+
async favoritesList() {
|
|
314
|
+
return (await readEnvelope(await fetch(TEMPLATE_FAVORITES_API.list, { method: "POST" }))).favorites;
|
|
315
|
+
}
|
|
316
|
+
/** Star one template (the host keeps a full case snapshot). */
|
|
317
|
+
async favoritesAdd(sourceId, item) {
|
|
318
|
+
return (await readEnvelope(await fetch(TEMPLATE_FAVORITES_API.add, {
|
|
319
|
+
method: "POST",
|
|
320
|
+
headers: { "content-type": "application/json" },
|
|
321
|
+
body: JSON.stringify({
|
|
322
|
+
source: sourceId,
|
|
323
|
+
case: item
|
|
324
|
+
})
|
|
325
|
+
}))).favorites;
|
|
326
|
+
}
|
|
327
|
+
/** Unstar one template by its favorites key. */
|
|
328
|
+
async favoritesRemove(key) {
|
|
329
|
+
return (await readEnvelope(await fetch(TEMPLATE_FAVORITES_API.remove, {
|
|
330
|
+
method: "POST",
|
|
331
|
+
headers: { "content-type": "application/json" },
|
|
332
|
+
body: JSON.stringify({ key })
|
|
333
|
+
}))).favorites;
|
|
334
|
+
}
|
|
267
335
|
};
|
|
268
336
|
//#endregion
|
|
269
337
|
//#region src/client/controller.ts
|
|
@@ -589,6 +657,7 @@ window.__ModuleLoader__.load({
|
|
|
589
657
|
"settings.invalidNumber": "请输入有效数字",
|
|
590
658
|
"templates.open": "模板库",
|
|
591
659
|
"templates.title": "提示词模板库",
|
|
660
|
+
"templates.sources": "模板库来源",
|
|
592
661
|
"templates.meta": "共 {count} 个模板 · {origin}",
|
|
593
662
|
"templates.origin.bundled": "内置快照",
|
|
594
663
|
"templates.origin.refreshed": "在线刷新",
|
|
@@ -599,21 +668,32 @@ window.__ModuleLoader__.load({
|
|
|
599
668
|
"templates.use": "使用此提示词",
|
|
600
669
|
"templates.copy": "复制提示词",
|
|
601
670
|
"templates.copied": "已复制",
|
|
602
|
-
"templates.refresh": "
|
|
671
|
+
"templates.refresh": "刷新本库",
|
|
603
672
|
"templates.refreshing": "刷新中…",
|
|
604
673
|
"templates.refreshed": "已刷新,共 {count} 个模板",
|
|
605
674
|
"templates.refreshFailed": "刷新失败:{error}",
|
|
675
|
+
"templates.favorites": "收藏",
|
|
676
|
+
"templates.favoritesHint": "只看已收藏的模板",
|
|
677
|
+
"templates.favoritesEmpty": "还没有收藏,点击模板卡片右上角的星标即可收藏",
|
|
678
|
+
"templates.favoriteAdd": "收藏此模板",
|
|
679
|
+
"templates.favoriteRemove": "取消收藏",
|
|
680
|
+
"templates.favorite": "收藏",
|
|
681
|
+
"templates.unfavorite": "已收藏",
|
|
606
682
|
"templates.cacheAll": "缓存全部图片",
|
|
607
|
-
"templates.cacheAllHint": "
|
|
683
|
+
"templates.cacheAllHint": "通过本机代理把当前模板库的全部参考图缓存到本地磁盘,之后离线也能浏览",
|
|
608
684
|
"templates.caching": "缓存中 {done}/{total}…",
|
|
609
685
|
"templates.cached": "图片已全部缓存",
|
|
610
686
|
"templates.empty": "没有匹配的模板",
|
|
611
687
|
"templates.loading": "正在加载模板库…",
|
|
612
688
|
"templates.loadFailed": "模板库加载失败:{error}",
|
|
613
689
|
"templates.retry": "重试",
|
|
614
|
-
"templates.attribution": "
|
|
615
|
-
"templates.source": "来源:
|
|
690
|
+
"templates.attribution": "模板与图片来自各来源站点,作者链接见模板详情",
|
|
691
|
+
"templates.source": "来源:{label}",
|
|
616
692
|
"templates.featured": "精选",
|
|
693
|
+
"inspiration.title": "灵感案例",
|
|
694
|
+
"inspiration.shuffle": "随机",
|
|
695
|
+
"inspiration.shuffling": "换一批…",
|
|
696
|
+
"inspiration.useHint": "点击使用该提示词",
|
|
617
697
|
"channels.title": "渠道",
|
|
618
698
|
"channels.hint": "填写各渠道的 API 地址与密钥即可使用对应模型",
|
|
619
699
|
"channels.empty": "尚无渠道,点击下方按钮添加",
|
|
@@ -950,6 +1030,7 @@ window.__ModuleLoader__.load({
|
|
|
950
1030
|
"settings.invalidNumber": "Enter a valid number",
|
|
951
1031
|
"templates.open": "Templates",
|
|
952
1032
|
"templates.title": "Prompt Template Library",
|
|
1033
|
+
"templates.sources": "Template sources",
|
|
953
1034
|
"templates.meta": "{count} templates · {origin}",
|
|
954
1035
|
"templates.origin.bundled": "bundled snapshot",
|
|
955
1036
|
"templates.origin.refreshed": "refreshed online",
|
|
@@ -960,21 +1041,32 @@ window.__ModuleLoader__.load({
|
|
|
960
1041
|
"templates.use": "Use this prompt",
|
|
961
1042
|
"templates.copy": "Copy prompt",
|
|
962
1043
|
"templates.copied": "Copied",
|
|
963
|
-
"templates.refresh": "Refresh library",
|
|
1044
|
+
"templates.refresh": "Refresh this library",
|
|
964
1045
|
"templates.refreshing": "Refreshing…",
|
|
965
1046
|
"templates.refreshed": "Refreshed — {count} templates",
|
|
966
1047
|
"templates.refreshFailed": "Refresh failed: {error}",
|
|
1048
|
+
"templates.favorites": "Favorites",
|
|
1049
|
+
"templates.favoritesHint": "Show favorited templates only",
|
|
1050
|
+
"templates.favoritesEmpty": "No favorites yet — tap the star in a card's top-right corner to save one",
|
|
1051
|
+
"templates.favoriteAdd": "Favorite this template",
|
|
1052
|
+
"templates.favoriteRemove": "Remove from favorites",
|
|
1053
|
+
"templates.favorite": "Favorite",
|
|
1054
|
+
"templates.unfavorite": "Favorited",
|
|
967
1055
|
"templates.cacheAll": "Cache all images",
|
|
968
|
-
"templates.cacheAllHint": "Mirror every reference image to local disk through the host proxy, for offline browsing",
|
|
1056
|
+
"templates.cacheAllHint": "Mirror every reference image of the current library to local disk through the host proxy, for offline browsing",
|
|
969
1057
|
"templates.caching": "Caching {done}/{total}…",
|
|
970
1058
|
"templates.cached": "All images cached",
|
|
971
1059
|
"templates.empty": "No matching templates",
|
|
972
1060
|
"templates.loading": "Loading the template library…",
|
|
973
1061
|
"templates.loadFailed": "Failed to load the library: {error}",
|
|
974
1062
|
"templates.retry": "Retry",
|
|
975
|
-
"templates.attribution": "Templates and images come from
|
|
976
|
-
"templates.source": "Source:
|
|
1063
|
+
"templates.attribution": "Templates and images come from each source site; author links are on each template",
|
|
1064
|
+
"templates.source": "Source: {label}",
|
|
977
1065
|
"templates.featured": "Featured",
|
|
1066
|
+
"inspiration.title": "Inspiration",
|
|
1067
|
+
"inspiration.shuffle": "Shuffle",
|
|
1068
|
+
"inspiration.shuffling": "Shuffling…",
|
|
1069
|
+
"inspiration.useHint": "Click to use this prompt",
|
|
978
1070
|
"channels.title": "Channels",
|
|
979
1071
|
"channels.hint": "Fill in each channel's API URL and key to use its models",
|
|
980
1072
|
"channels.empty": "No channels yet — add one below",
|
|
@@ -1025,16 +1117,425 @@ window.__ModuleLoader__.load({
|
|
|
1025
1117
|
"channels.presetCustomHint": "Configure the API URL, key, and model catalog yourself",
|
|
1026
1118
|
"channels.presetLoadFailed": "Failed to load providers: {error}"
|
|
1027
1119
|
};
|
|
1120
|
+
/** Russian mirror of every key (полный словарь интерфейса). */
|
|
1121
|
+
const ru = {
|
|
1122
|
+
"entry.label": "ИИ-генерация",
|
|
1123
|
+
"entry.tooltip": "Панель ИИ-генерации изображений (gpt-image-2 / glm-image / grok-imagine-image / nanobanana / seedream)",
|
|
1124
|
+
"entry.newSession": "Новая сессия",
|
|
1125
|
+
"entry.newSessionTooltip": "Создать новую сессию DSH",
|
|
1126
|
+
"entry.image": "Генерация",
|
|
1127
|
+
"panel.title": "ИИ-генерация изображений",
|
|
1128
|
+
"panel.githubTip": "Понравился плагин или есть идеи? Поставьте звезду или откройте issue на GitHub!",
|
|
1129
|
+
"conversation.add": "В диалог",
|
|
1130
|
+
"conversation.adding": "Добавляем…",
|
|
1131
|
+
"conversation.added": "Изображение добавлено в текущий диалог",
|
|
1132
|
+
"conversation.addHint": "После добавления можно править через /edit_image; команда использует модель плагина",
|
|
1133
|
+
"conversation.noSession": "Сначала откройте сессию, затем добавьте изображение",
|
|
1134
|
+
"conversation.unavailable": "Текущая сессия недоступна",
|
|
1135
|
+
"conversation.busy": "Диалог отправляет сообщение, попробуйте позже",
|
|
1136
|
+
"mode.text": "Из текста",
|
|
1137
|
+
"mode.edit": "Из изображения",
|
|
1138
|
+
"workspace.label": "Режим работы",
|
|
1139
|
+
"workspace.normal": "Генерация",
|
|
1140
|
+
"workspace.ecommerce": "E-commerce",
|
|
1141
|
+
"chat.expand": "Показать диалог",
|
|
1142
|
+
"chat.collapse": "Скрыть диалог",
|
|
1143
|
+
"chat.toggle": "Диалог",
|
|
1144
|
+
"config.resizeHint": "Потяните, чтобы изменить ширину панели параметров",
|
|
1145
|
+
"ecommerce.generation": "Параметры генерации",
|
|
1146
|
+
"ecommerce.title": "Режим e-commerce",
|
|
1147
|
+
"ecommerce.badge": "Превью",
|
|
1148
|
+
"ecommerce.short": "E-com",
|
|
1149
|
+
"ecommerce.anchorPending": "Главное изображение готово, остальные генерируются по нему для единого стиля…",
|
|
1150
|
+
"ecommerce.anchorFailed": "Не удалось создать главное изображение, остальные приостановлены. Повторите главное (или всю группу) и продолжите.",
|
|
1151
|
+
"ecommerce.anchorNote": "Якорная генерация: сначала главное изображение, остальные создаются по нему для единого стиля",
|
|
1152
|
+
"ecommerce.noAssetWarn": "Товар не загружен: главное изображение будет создано по описанию и станет якорем; загрузите фото товара для большей точности",
|
|
1153
|
+
"ecommerce.product": "Товар",
|
|
1154
|
+
"ecommerce.productName": "Название товара (обязательно)",
|
|
1155
|
+
"ecommerce.projectName": "Название проекта (необязательно)",
|
|
1156
|
+
"ecommerce.constraints": "Преимущества и ограничения",
|
|
1157
|
+
"ecommerce.sellingPoints": "Преимущества товара, например: водостойкость / большая вместимость / компактность",
|
|
1158
|
+
"ecommerce.protectedFeatures": "Что обязательно сохранить: цвет, логотип, текст упаковки, конструкцию",
|
|
1159
|
+
"ecommerce.styleHint": "Стиль, например: премиальный / реалистичный / естественный свет",
|
|
1160
|
+
"ecommerce.setStructure": "Структура комплекта",
|
|
1161
|
+
"ecommerce.preview": "Создать превью комплекта",
|
|
1162
|
+
"ecommerce.planTitle": "Будет сгенерировано изображений: {count}",
|
|
1163
|
+
"ecommerce.planSlot": "{count} шт. · {description}",
|
|
1164
|
+
"ecommerce.confirm": "Сгенерировать весь комплект",
|
|
1165
|
+
"ecommerce.uploadRef": "Материалы товара (необязательно, до 4 шт.: товар / упаковка / детали / стиль)",
|
|
1166
|
+
"ecommerce.uploadShort": "Загрузить материалы",
|
|
1167
|
+
"ecommerce.sellingTitle": "Преимущества товара",
|
|
1168
|
+
"ecommerce.advanced": "Дополнительно (проект / площадка / ограничения)",
|
|
1169
|
+
"ecommerce.params": "Параметры",
|
|
1170
|
+
"ecommerce.platformLabel": "Площадка",
|
|
1171
|
+
"ecommerce.languageLabel": "Язык текста",
|
|
1172
|
+
"ecommerce.ratioLabel": "Пропорции",
|
|
1173
|
+
"ecommerce.categoryLabel": "Категория",
|
|
1174
|
+
"ecommerce.multiSelect": "Можно выбрать несколько",
|
|
1175
|
+
"ecommerce.countHint": "Нажмите, чтобы изменить количество (1-4)",
|
|
1176
|
+
"ecommerce.refSettings": "Настройки референсов (необязательно)",
|
|
1177
|
+
"ecommerce.styleTitle": "Стиль / дополнения",
|
|
1178
|
+
"ecommerce.protectedLabel": "Обязательно сохранить (необязательно)",
|
|
1179
|
+
"ecommerce.assetsFull": "Не более 4 материалов",
|
|
1180
|
+
"ecommerce.refSelect": "Референс для этого назначения",
|
|
1181
|
+
"ecommerce.refNone": "Без референса",
|
|
1182
|
+
"ecommerce.role.product": "Товар",
|
|
1183
|
+
"ecommerce.role.packaging": "Упаковка",
|
|
1184
|
+
"ecommerce.role.detail": "Детали/ракурс",
|
|
1185
|
+
"ecommerce.role.style": "Стиль",
|
|
1186
|
+
"ecommerce.footerReady": "Будет сгенерировано {count} изображений",
|
|
1187
|
+
"ecommerce.footerEmpty": "Выберите структуру комплекта",
|
|
1188
|
+
"ecommerce.results.title": "Результаты комплекта",
|
|
1189
|
+
"ecommerce.results.progress": "{done}/{total} готово",
|
|
1190
|
+
"ecommerce.results.failed": "{count} с ошибкой",
|
|
1191
|
+
"ecommerce.results.empty": "После запуска генерации здесь появятся статус и результат каждого изображения",
|
|
1192
|
+
"ecommerce.results.regenerate": "Сгенерировать заново",
|
|
1193
|
+
"ecommerce.results.export": "Экспорт списка",
|
|
1194
|
+
"ecommerce.results.newProduct": "Новый товар",
|
|
1195
|
+
"prompt.placeholder": "Опишите желаемое изображение, например: рыжий кот в шлеме космонавта смотрит в телескоп на Луне, акварель, мягкий свет…",
|
|
1196
|
+
"prompt.required": "Введите промпт",
|
|
1197
|
+
"prompt.count": "{count}",
|
|
1198
|
+
"prompt.enhance": "Улучш.",
|
|
1199
|
+
"prompt.enhancing": "Улучшаем…",
|
|
1200
|
+
"prompt.enhanceHint": "Развернуть краткий промпт через настроенную диалоговую модель",
|
|
1201
|
+
"prompt.configTitle": "Сначала настройте модель улучшения промптов",
|
|
1202
|
+
"prompt.configHint": "Настройки открыты. Перейдите в «Плагины → ИИ-генерация», укажите или переиспользуйте API-адрес и ключ, выберите диалоговую модель и сохраните.",
|
|
1203
|
+
"tasks.title": "Задачи генерации",
|
|
1204
|
+
"tasks.queued": "В очереди",
|
|
1205
|
+
"tasks.running": "Генерация",
|
|
1206
|
+
"tasks.completed": "Готово",
|
|
1207
|
+
"tasks.failed": "Ошибка",
|
|
1208
|
+
"tasks.cancelled": "Отменено",
|
|
1209
|
+
"tasks.cancel": "Отменить",
|
|
1210
|
+
"tasks.retry": "Повторить",
|
|
1211
|
+
"params.size": "Размер",
|
|
1212
|
+
"params.quality": "Чёткость",
|
|
1213
|
+
"params.count": "Количество",
|
|
1214
|
+
"params.detail": "Детализация",
|
|
1215
|
+
"size.auto": "Авто",
|
|
1216
|
+
"size.square": "1:1 квадрат",
|
|
1217
|
+
"size.portrait34": "3:4 верт.",
|
|
1218
|
+
"size.landscape43": "4:3 гориз.",
|
|
1219
|
+
"size.portrait916": "9:16 верт.",
|
|
1220
|
+
"size.portrait23": "2:3 верт.",
|
|
1221
|
+
"size.landscape32": "3:2 гориз.",
|
|
1222
|
+
"size.wide169": "16:9 шир.",
|
|
1223
|
+
"size.ultrawide21": "21:9 ультрашир.",
|
|
1224
|
+
"quality.auto": "Авто",
|
|
1225
|
+
"quality.1k": "1K",
|
|
1226
|
+
"quality.2k": "2K",
|
|
1227
|
+
"quality.4k": "4K",
|
|
1228
|
+
"count.one": "1 шт.",
|
|
1229
|
+
"count.two": "2 шт.",
|
|
1230
|
+
"count.three": "3 шт.",
|
|
1231
|
+
"count.four": "4 шт.",
|
|
1232
|
+
"detail.auto": "Авто",
|
|
1233
|
+
"detail.standard": "Стандарт",
|
|
1234
|
+
"detail.high": "Высокая",
|
|
1235
|
+
"detail.hint": "Сквозной параметр, поддерживают некоторые шлюзы gpt-image-2; для официального API оставьте «Авто»",
|
|
1236
|
+
"model.label": "Модель",
|
|
1237
|
+
"model.noEditModels": "В текущем режиме нет доступных моделей",
|
|
1238
|
+
"compare.enable": "Сравнение моделей",
|
|
1239
|
+
"compare.models": "Модели для сравнения",
|
|
1240
|
+
"compare.title": "Сравнение результатов моделей",
|
|
1241
|
+
"compare.fullscreen": "Полноэкранное сравнение",
|
|
1242
|
+
"compare.selectRequired": "Выберите хотя бы одну модель для сравнения",
|
|
1243
|
+
"generate": "Сгенерировать",
|
|
1244
|
+
"generating": "Генерация…",
|
|
1245
|
+
"edit.upload": "Нажмите или перетащите референс",
|
|
1246
|
+
"edit.uploadHint": "PNG / JPG / WEBP, до 10 МБ",
|
|
1247
|
+
"edit.change": "Заменить изображение",
|
|
1248
|
+
"edit.remove": "Убрать",
|
|
1249
|
+
"edit.required": "Сначала загрузите референс",
|
|
1250
|
+
"canvas.emptyTitle": "Начните творить",
|
|
1251
|
+
"canvas.emptyHint": "Введите промпт слева и нажмите «Сгенерировать» — результат появится здесь",
|
|
1252
|
+
"canvas.new": "Новая генерация",
|
|
1253
|
+
"canvas.newHint": "Начать новую генерацию и очистить просмотр",
|
|
1254
|
+
"canvas.error": "Ошибка генерации: {error}",
|
|
1255
|
+
"canvas.submitting": "Ставим в очередь…",
|
|
1256
|
+
"canvas.queued": "Задача в очереди",
|
|
1257
|
+
"canvas.queueHint": "Сейчас ожидают {count} задач",
|
|
1258
|
+
"canvas.generating": "Генерируем изображение…",
|
|
1259
|
+
"canvas.elapsed": "Прошло {seconds} с",
|
|
1260
|
+
"canvas.images": "Сгенерировано: {count}",
|
|
1261
|
+
"download": "Скачать",
|
|
1262
|
+
"revisedPrompt": "Улучшенный промпт: {prompt}",
|
|
1263
|
+
"history.title": "История",
|
|
1264
|
+
"history.empty": "Истории пока нет — созданные изображения появятся здесь",
|
|
1265
|
+
"history.clear": "Очистить",
|
|
1266
|
+
"history.clearConfirm": "Очистить всю историю? Действие необратимо.",
|
|
1267
|
+
"history.restore": "Восстановить",
|
|
1268
|
+
"history.delete": "Удалить",
|
|
1269
|
+
"history.images": "шт.",
|
|
1270
|
+
"history.viewing": "История · {time}",
|
|
1271
|
+
"history.search": "Поиск по промптам и моделям…",
|
|
1272
|
+
"history.model": "Фильтр по модели",
|
|
1273
|
+
"history.ratio": "Фильтр по пропорциям",
|
|
1274
|
+
"history.allModels": "Все модели",
|
|
1275
|
+
"history.allRatios": "Все пропорции",
|
|
1276
|
+
"gallery.title": "Галерея",
|
|
1277
|
+
"gallery.categories": "Категории",
|
|
1278
|
+
"gallery.all": "Все работы",
|
|
1279
|
+
"gallery.gpt": "gpt-image-2",
|
|
1280
|
+
"gallery.grok": "grok-imagine-image",
|
|
1281
|
+
"gallery.ratio": "Пропорции",
|
|
1282
|
+
"gallery.tags": "Метки",
|
|
1283
|
+
"gallery.filterHint": "Фильтр галереи по режиму, модели и пропорциям",
|
|
1284
|
+
"gallery.count": "· всего {count}",
|
|
1285
|
+
"gallery.viewMode": "Вид",
|
|
1286
|
+
"gallery.masonry": "Плитка",
|
|
1287
|
+
"gallery.grid": "Сетка",
|
|
1288
|
+
"gallery.sort": "Сортировка",
|
|
1289
|
+
"gallery.newest": "Сначала новые",
|
|
1290
|
+
"gallery.oldest": "Сначала старые",
|
|
1291
|
+
"gallery.untitled": "Без названия",
|
|
1292
|
+
"gallery.search": "Поиск по работам и моделям…",
|
|
1293
|
+
"gallery.tagsPlaceholder": "Метки через запятую",
|
|
1294
|
+
"gallery.tagsApply": "Добавить метки",
|
|
1295
|
+
"gallery.editTags": "Править метки",
|
|
1296
|
+
"gallery.tagsEditShort": "Правка",
|
|
1297
|
+
"gallery.tagsSave": "Сохранить",
|
|
1298
|
+
"gallery.tagsCancel": "Отмена",
|
|
1299
|
+
"gallery.selected": "Выбрано: {count}",
|
|
1300
|
+
"gallery.selectionDone": "Завершить выбор",
|
|
1301
|
+
"gallery.selectionClear": "Снять выбор",
|
|
1302
|
+
"gallery.downloadSelected": "Скачать выбранные",
|
|
1303
|
+
"gallery.exportJson": "Экспорт JSON",
|
|
1304
|
+
"gallery.select": "Выбрать работы",
|
|
1305
|
+
"gallery.add": "В галерею",
|
|
1306
|
+
"gallery.added": "Добавлено в галерею",
|
|
1307
|
+
"gallery.already": "Уже в галерее",
|
|
1308
|
+
"gallery.delete": "Убрать из галереи",
|
|
1309
|
+
"gallery.clear": "Очистить галерею",
|
|
1310
|
+
"gallery.clearConfirm": "Очистить всю галерею? Действие необратимо.",
|
|
1311
|
+
"gallery.empty": "Галерея пуста — добавьте понравившиеся изображения",
|
|
1312
|
+
"gallery.viewing": "Галерея · {time}",
|
|
1313
|
+
"preview.title": "Просмотр изображения",
|
|
1314
|
+
"preview.open": "Открыть просмотр",
|
|
1315
|
+
"preview.close": "Закрыть",
|
|
1316
|
+
"preview.prev": "Назад",
|
|
1317
|
+
"preview.next": "Вперёд",
|
|
1318
|
+
"preview.index": "{index} / {total}",
|
|
1319
|
+
"preview.zoomControls": "Управление масштабом",
|
|
1320
|
+
"preview.zoomIn": "Увеличить",
|
|
1321
|
+
"preview.zoomOut": "Уменьшить",
|
|
1322
|
+
"preview.zoomReset": "Сбросить масштаб",
|
|
1323
|
+
"preview.zoomLevel": "{percent}%",
|
|
1324
|
+
"preview.copyPrompt": "Копировать промпт",
|
|
1325
|
+
"preview.copied": "Скопировано",
|
|
1326
|
+
"preview.addToEdit": "В режим img2img",
|
|
1327
|
+
"config.missing": "API не настроен: откройте «Настройки → Плагины → Настраиваемые» и заполните api_url и api_key для ИИ-генерации.",
|
|
1328
|
+
"config.generationTitle": "Сначала настройте API генерации",
|
|
1329
|
+
"config.generationHint": "Открыты «Настройки → Плагины → ИИ-генерация». Укажите адрес и ключ API генерации, сохраните — и можно творить.",
|
|
1330
|
+
"config.enhancementTitle": "Сначала настройте модель улучшения промптов",
|
|
1331
|
+
"config.enhancementHint": "Открыты «Настройки → Плагины → ИИ-генерация». Укажите или переиспользуйте адрес и ключ диалогового API, выберите модель и сохраните.",
|
|
1332
|
+
"config.disabledTitle": "Плагин ИИ-генерации отключён",
|
|
1333
|
+
"config.disabledHint": "Открыты «Настройки → Плагины → ИИ-генерация». Включите плагин — и генерация заработает.",
|
|
1334
|
+
"config.configured": "Подключено: {url}",
|
|
1335
|
+
"config.disabled": "Плагин отключён — включите его в настройках.",
|
|
1336
|
+
"connection.connected": "Подключено",
|
|
1337
|
+
"connection.disconnected": "Нет подключения",
|
|
1338
|
+
"panel.collapseConfig": "Свернуть параметры",
|
|
1339
|
+
"panel.expandConfig": "Развернуть параметры",
|
|
1340
|
+
"update.available": "Доступна новая версия: {version}",
|
|
1341
|
+
"update.install": "Обновить онлайн",
|
|
1342
|
+
"update.installing": "Обновляем…",
|
|
1343
|
+
"update.success": "Обновлено до {version}, перезапустите DSH",
|
|
1344
|
+
"update.failed": "Не удалось обновить, попробуйте ещё раз",
|
|
1345
|
+
"update.release": "Открыть релиз",
|
|
1346
|
+
"settings.title": "ИИ-генерация (dsh-imagegen)",
|
|
1347
|
+
"settings.description": "Адрес и ключ API генерации изображений",
|
|
1348
|
+
"settings.currentVersion": "Текущая версия",
|
|
1349
|
+
"settings.apiUrl": "Адрес API (api_url)",
|
|
1350
|
+
"settings.apiUrlHint": "База OpenAI-совместимого API, например https://api.openai.com/v1; /images/generations и /images/edits дописываются автоматически",
|
|
1351
|
+
"settings.apiKey": "Ключ API (api_key)",
|
|
1352
|
+
"settings.apiKeyHint": "Bearer-ключ хранится открыто в локальном документе настроек; интерфейс показывает лишь факт его наличия",
|
|
1353
|
+
"settings.apiKeySet": "Ключ сохранён; введите новый, чтобы заменить, или нажмите «Очистить»",
|
|
1354
|
+
"settings.apiKeyClear": "Очистить",
|
|
1355
|
+
"settings.imageModelsTitle": "Модели генерации",
|
|
1356
|
+
"settings.imageModelsHint": "После сохранения адреса и ключа будут найдены кандидаты; выбирайте только те, что реально умеют генерировать изображения.",
|
|
1357
|
+
"settings.imageModels": "Разрешённые модели генерации",
|
|
1358
|
+
"settings.imageModelsManualHint": "По одной модели в строке; можно заполнить вручную, если API не отдаёт /models. Панель и агент используют только этот список.",
|
|
1359
|
+
"settings.imageModelsFetch": "Найти модели",
|
|
1360
|
+
"settings.imageModelsLoading": "Ищем…",
|
|
1361
|
+
"settings.imageModelsCandidates": "Найденные кандидаты (отметьте и сохраните)",
|
|
1362
|
+
"settings.addModel": "+ Добавить вручную",
|
|
1363
|
+
"settings.cancelAddModel": "Скрыть добавление",
|
|
1364
|
+
"settings.addModelPlaceholder": "Имя модели, например qwen-image",
|
|
1365
|
+
"settings.addModelConfirm": "Добавить",
|
|
1366
|
+
"settings.removeModel": "Удалить модель",
|
|
1367
|
+
"settings.optional": "необязательно",
|
|
1368
|
+
"settings.moreOptions": "Дополнительно",
|
|
1369
|
+
"settings.promptEnhanceTitle": "Модель улучшения промптов",
|
|
1370
|
+
"settings.promptEnhanceHint": "Разворачивает краткое описание в полноценный промпт; пустые адрес и ключ наследуют настройки генерации.",
|
|
1371
|
+
"settings.promptApiUrl": "Адрес диалогового API (необязательно)",
|
|
1372
|
+
"settings.promptApiUrlHint": "OpenAI-совместимая база; если пусто — используется адрес API генерации.",
|
|
1373
|
+
"settings.promptApiKey": "Ключ диалогового API (необязательно)",
|
|
1374
|
+
"settings.promptApiKeyHint": "Если пусто — используется ключ API генерации.",
|
|
1375
|
+
"settings.promptModel": "Диалоговая модель",
|
|
1376
|
+
"settings.promptModelHint": "Выберите или впишите модель с поддержкой /chat/completions.",
|
|
1377
|
+
"settings.promptModelDetectionHint": "По умолчанию используется API генерации; после поиска просто выберите модель.",
|
|
1378
|
+
"settings.promptModelsFetch": "Получить модели",
|
|
1379
|
+
"settings.promptModelsLoading": "Получаем…",
|
|
1380
|
+
"settings.promptModelsSelect": "Выберите модель",
|
|
1381
|
+
"settings.promptModelsCandidates": "Найденные диалоговые модели",
|
|
1382
|
+
"settings.addPromptModelPlaceholder": "Имя диалоговой модели, например gpt-4.1-mini",
|
|
1383
|
+
"settings.promptApiAdvanced": "Отдельный диалоговый API (необязательно)",
|
|
1384
|
+
"settings.announceToAgent": "Оповещать агентов о плагине",
|
|
1385
|
+
"settings.announceToAgentHint": "Включено — возможности плагина добавляются в системный промпт каждого агента",
|
|
1386
|
+
"settings.allowAgentImageGeneration": "Разрешить агентам генерацию",
|
|
1387
|
+
"settings.allowAgentImageGenerationHint": "Включено по умолчанию. Выключено — агенты не могут создавать, смотреть или отменять задачи; боковая панель работает.",
|
|
1388
|
+
"settings.enabled": "Включить плагин",
|
|
1389
|
+
"settings.enabledHint": "Выключено — панель генерации недоступна (карточка настроек работает всегда)",
|
|
1390
|
+
"settings.save": "Сохранить",
|
|
1391
|
+
"settings.saving": "Сохраняем…",
|
|
1392
|
+
"settings.discard": "Отменить правки",
|
|
1393
|
+
"settings.unsaved": "Есть несохранённые правки",
|
|
1394
|
+
"settings.saveFailed": "Не удалось сохранить, попробуйте ещё раз",
|
|
1395
|
+
"settings.readOnly": "Документ настроек сейчас только для чтения, сохранить нельзя.",
|
|
1396
|
+
"settings.notExposed": "Пространство настроек недоступно: этот деплой не предоставляет сервис настроек плагина.",
|
|
1397
|
+
"settings.expand": "Развернуть",
|
|
1398
|
+
"settings.collapse": "Свернуть",
|
|
1399
|
+
"settings.inherit": "Наследовать",
|
|
1400
|
+
"settings.on": "Вкл",
|
|
1401
|
+
"settings.off": "Выкл",
|
|
1402
|
+
"settings.overridden": "Переопределено",
|
|
1403
|
+
"settings.reset": "Сбросить",
|
|
1404
|
+
"settings.invalidNumber": "Введите корректное число",
|
|
1405
|
+
"templates.open": "Шаблоны",
|
|
1406
|
+
"templates.title": "Библиотека промпт-шаблонов",
|
|
1407
|
+
"templates.sources": "Источники шаблонов",
|
|
1408
|
+
"templates.meta": "Всего шаблонов: {count} · {origin}",
|
|
1409
|
+
"templates.origin.bundled": "встроенный снимок",
|
|
1410
|
+
"templates.origin.refreshed": "обновлено онлайн",
|
|
1411
|
+
"templates.search": "Поиск по названиям и промптам…",
|
|
1412
|
+
"templates.all": "Все",
|
|
1413
|
+
"templates.close": "Закрыть",
|
|
1414
|
+
"templates.back": "К списку",
|
|
1415
|
+
"templates.use": "Использовать промпт",
|
|
1416
|
+
"templates.copy": "Копировать промпт",
|
|
1417
|
+
"templates.copied": "Скопировано",
|
|
1418
|
+
"templates.refresh": "Обновить библиотеку",
|
|
1419
|
+
"templates.refreshing": "Обновляем…",
|
|
1420
|
+
"templates.refreshed": "Обновлено, шаблонов: {count}",
|
|
1421
|
+
"templates.refreshFailed": "Ошибка обновления: {error}",
|
|
1422
|
+
"templates.favorites": "Избранное",
|
|
1423
|
+
"templates.favoritesHint": "Показать только избранные шаблоны",
|
|
1424
|
+
"templates.favoritesEmpty": "Пока пусто — нажмите звёздочку в углу карточки, чтобы сохранить шаблон",
|
|
1425
|
+
"templates.favoriteAdd": "Добавить в избранное",
|
|
1426
|
+
"templates.favoriteRemove": "Убрать из избранного",
|
|
1427
|
+
"templates.favorite": "В избранное",
|
|
1428
|
+
"templates.unfavorite": "В избранном",
|
|
1429
|
+
"templates.cacheAll": "Кэшировать все картинки",
|
|
1430
|
+
"templates.cacheAllHint": "Через локальный прокси сохранит все референсы этой библиотеки на диск — дальше доступно офлайн",
|
|
1431
|
+
"templates.caching": "Кэшируем {done}/{total}…",
|
|
1432
|
+
"templates.cached": "Все картинки закэшированы",
|
|
1433
|
+
"templates.empty": "Нет подходящих шаблонов",
|
|
1434
|
+
"templates.loading": "Загружаем библиотеку…",
|
|
1435
|
+
"templates.loadFailed": "Не удалось загрузить библиотеку: {error}",
|
|
1436
|
+
"templates.retry": "Повторить",
|
|
1437
|
+
"templates.attribution": "Шаблоны и изображения принадлежат сайтам-источникам; ссылки на авторов — в карточках",
|
|
1438
|
+
"templates.source": "Источник: {label}",
|
|
1439
|
+
"templates.featured": "Выбор редакции",
|
|
1440
|
+
"inspiration.title": "Вдохновение",
|
|
1441
|
+
"inspiration.shuffle": "Другие",
|
|
1442
|
+
"inspiration.shuffling": "Подбираем…",
|
|
1443
|
+
"inspiration.useHint": "Нажмите, чтобы использовать промпт",
|
|
1444
|
+
"channels.title": "Каналы",
|
|
1445
|
+
"channels.hint": "Укажите адрес и ключ API каждого канала — и модели станут доступны",
|
|
1446
|
+
"channels.empty": "Каналов пока нет — добавьте кнопкой ниже",
|
|
1447
|
+
"channels.addProvider": "Добавить провайдера",
|
|
1448
|
+
"channels.addCustom": "Добавить свой канал",
|
|
1449
|
+
"channels.untitled": "Канал без названия",
|
|
1450
|
+
"channels.keySet": "Ключ задан",
|
|
1451
|
+
"channels.keyMissing": "Ключ не задан",
|
|
1452
|
+
"channels.modelCount": "Моделей: {n}",
|
|
1453
|
+
"channels.noModels": "Модели не настроены",
|
|
1454
|
+
"channels.defaultLabel": "По умолчанию",
|
|
1455
|
+
"channels.statusReady": "Готов",
|
|
1456
|
+
"channels.statusIncomplete": "Настройка не завершена",
|
|
1457
|
+
"channels.edit": "Править",
|
|
1458
|
+
"channels.delete": "Удалить",
|
|
1459
|
+
"channels.deleteConfirmTitle": "Удалить канал «{name}»? Ключ канала будет удалён; история и галерея сохранятся.",
|
|
1460
|
+
"channels.confirm": "Удалить",
|
|
1461
|
+
"channels.cancel": "Отмена",
|
|
1462
|
+
"channels.editorTitle": "Канал",
|
|
1463
|
+
"channels.editorSaveNote": "Изменения вступят в силу после «Сохранить» внизу карточки",
|
|
1464
|
+
"channels.displayName": "Название",
|
|
1465
|
+
"channels.apiUrl": "Адрес API",
|
|
1466
|
+
"channels.apiKey": "Ключ API",
|
|
1467
|
+
"channels.keyReplaceHint": "Задан — введите новый, чтобы заменить",
|
|
1468
|
+
"channels.keyMissingHint": "Введите ключ",
|
|
1469
|
+
"channels.keyClear": "Очистить ключ",
|
|
1470
|
+
"channels.modelCatalogTitle": "Каталог моделей",
|
|
1471
|
+
"channels.noModelsHint": "Моделей пока нет: нажмите «Найти» для списка кандидатов или добавьте вручную; псевдоним по умолчанию равен id модели и его можно менять.",
|
|
1472
|
+
"channels.detect": "Найти снова",
|
|
1473
|
+
"channels.detecting": "Ищем…",
|
|
1474
|
+
"channels.detectSuccess": "Связь есть ✓ · кандидатов: {n}",
|
|
1475
|
+
"channels.detectFailed": "Ошибка поиска: {error}",
|
|
1476
|
+
"channels.detectOk": "API отвечает",
|
|
1477
|
+
"channels.modelAliasLabel": "Псевдоним (отображается)",
|
|
1478
|
+
"channels.modelIdLabel": "id модели у провайдера",
|
|
1479
|
+
"channels.generated": "Сгенерировано: {n}",
|
|
1480
|
+
"channels.unknownProtocol": "Протокол неизвестен — пробуем универсальный OpenAI",
|
|
1481
|
+
"channels.removeModel": "Удалить модель",
|
|
1482
|
+
"channels.manualAddPlaceholder": "id модели, например qwen-image",
|
|
1483
|
+
"channels.addModelConfirm": "Добавить",
|
|
1484
|
+
"channels.copyFrom": "Скопировать из канала…",
|
|
1485
|
+
"channels.copyApply": "Копировать",
|
|
1486
|
+
"channels.candidatesTitle": "Кандидаты (нажмите, чтобы добавить)",
|
|
1487
|
+
"channels.deleteThisChannel": "Удалить этот канал",
|
|
1488
|
+
"channels.setDefault": "Сделать каналом по умолчанию",
|
|
1489
|
+
"channels.presetPickerTitle": "Добавить провайдера",
|
|
1490
|
+
"channels.presetPickerHint": "Выберите встроенного провайдера — останется ввести только ключ API",
|
|
1491
|
+
"channels.presetCustomHint": "Свой адрес, ключ и каталог моделей",
|
|
1492
|
+
"channels.presetLoadFailed": "Не удалось загрузить провайдеров: {error}"
|
|
1493
|
+
};
|
|
1028
1494
|
//#endregion
|
|
1029
1495
|
//#region src/client/helpers.ts
|
|
1030
1496
|
/**
|
|
1031
|
-
* Shared panel helpers: the active-dictionary pick
|
|
1032
|
-
*
|
|
1497
|
+
* Shared panel helpers: the active-dictionary pick bound to the dsh-imagegen
|
|
1498
|
+
* interpolator, the plugin locale that follows the DSH interface language
|
|
1499
|
+
* (bridged in client/index.ts from ctx.locale — the plugin ships zh / en / ru
|
|
1500
|
+
* and registers itself as a DSH language pack for Русский), plus a small
|
|
1033
1501
|
* error-message extractor. All copy stays in the locale dictionaries.
|
|
1034
1502
|
*/
|
|
1035
|
-
|
|
1503
|
+
const DICTIONARIES = {
|
|
1504
|
+
zh,
|
|
1505
|
+
en,
|
|
1506
|
+
ru
|
|
1507
|
+
};
|
|
1508
|
+
/** The active DSH locale mapped onto our dictionary (module-level, one value per app). */
|
|
1509
|
+
let activeLocale = "zh";
|
|
1510
|
+
/** Bumped on every locale change; useSyncExternalStore version. */
|
|
1511
|
+
let languageVersion = 0;
|
|
1512
|
+
const languageListeners = /* @__PURE__ */ new Set();
|
|
1513
|
+
/**
|
|
1514
|
+
* Adopt the DSH interface language. Unknown ids (future language packs)
|
|
1515
|
+
* resolve to English — the same per-key fallback convention the host locale
|
|
1516
|
+
* chain uses.
|
|
1517
|
+
*/
|
|
1518
|
+
function applyHostLocale(id) {
|
|
1519
|
+
const next = id === "zh" || id === "ru" ? id : "en";
|
|
1520
|
+
if (next === activeLocale) return;
|
|
1521
|
+
activeLocale = next;
|
|
1522
|
+
languageVersion += 1;
|
|
1523
|
+
for (const listener of [...languageListeners]) listener();
|
|
1524
|
+
}
|
|
1525
|
+
/** Monotonic version of the active locale (external-store snapshot). */
|
|
1526
|
+
function getImageGenLanguageVersion() {
|
|
1527
|
+
return languageVersion;
|
|
1528
|
+
}
|
|
1529
|
+
/** Observe locale changes; returns the unsubscriber. */
|
|
1530
|
+
function subscribeImageGenLanguage(listener) {
|
|
1531
|
+
languageListeners.add(listener);
|
|
1532
|
+
return () => {
|
|
1533
|
+
languageListeners.delete(listener);
|
|
1534
|
+
};
|
|
1535
|
+
}
|
|
1536
|
+
/** Active dictionary for the current DSH language. */
|
|
1036
1537
|
function dictionary() {
|
|
1037
|
-
return
|
|
1538
|
+
return DICTIONARIES[activeLocale];
|
|
1038
1539
|
}
|
|
1039
1540
|
/** Translate a key with optional {name} template params (current language). */
|
|
1040
1541
|
function tt(key, values) {
|
|
@@ -1051,73 +1552,84 @@ window.__ModuleLoader__.load({
|
|
|
1051
1552
|
}
|
|
1052
1553
|
//#endregion
|
|
1053
1554
|
//#region \0dsh-css:E:\dsh-plugin\src\client\templates.module.css.mjs
|
|
1054
|
-
const css$
|
|
1055
|
-
const tagId$
|
|
1056
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$
|
|
1555
|
+
const css$4 = ".o0mAxG_overlay,.o0mAxG_overlay *,.o0mAxG_overlay :before,.o0mAxG_overlay :after{box-sizing:border-box}.o0mAxG_overlay{z-index:130;background:var(--dsw-alias-bg-mask-1);color:var(--dsw-alias-label-primary);font-family:var(--dsw-font-family);justify-content:center;align-items:center;padding:28px;display:flex;position:fixed;inset:0}.o0mAxG_shell{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);border-radius:14px;flex-direction:column;width:min(1180px,100%);height:100%;max-height:100%;display:flex;overflow:hidden;box-shadow:0 18px 60px #00000047}.o0mAxG_header{flex:none;justify-content:space-between;align-items:center;gap:12px;padding:14px 18px 10px;display:flex}.o0mAxG_heading{align-items:baseline;gap:10px;min-width:0;display:flex}.o0mAxG_title{margin:0;font-size:15px;font-weight:650}.o0mAxG_meta{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-size:12px}.o0mAxG_headerActions{flex:none;align-items:center;gap:8px;display:inline-flex}.o0mAxG_close{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:8px;justify-content:center;align-items:center;display:inline-flex}.o0mAxG_close:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.o0mAxG_sourceTabs{border-bottom:1px solid var(--dsw-alias-border-l1);flex:none;align-items:center;gap:6px;padding:0 18px 10px;display:flex}.o0mAxG_sourceTab{height:30px;color:var(--dsw-alias-label-secondary);cursor:pointer;white-space:nowrap;background:0 0;border:1px solid #0000;border-bottom:none;border-radius:9px 9px 0 0;align-items:center;gap:6px;padding:0 14px;font-family:inherit;font-size:13px;font-weight:600;display:inline-flex}.o0mAxG_sourceTab:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}.o0mAxG_sourceTab[data-active]{border-color:var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-brand-primary);border-radius:9px}.o0mAxG_sourceTabCount{background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-tertiary);border-radius:999px;padding:0 6px;font-size:11px;font-weight:500}.o0mAxG_sourceTab[data-active] .o0mAxG_sourceTabCount{color:var(--dsw-alias-label-secondary)}.o0mAxG_toolbar{flex-direction:column;flex:none;gap:10px;padding:0 18px 12px;display:flex}.o0mAxG_search{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);width:100%;height:34px;color:var(--dsw-alias-label-primary);border-radius:9px;outline:none;padding:0 12px;font-family:inherit;font-size:13px}.o0mAxG_search:focus{border-color:var(--dsw-alias-brand-primary)}.o0mAxG_search::placeholder{color:var(--dsw-alias-label-dimmed)}.o0mAxG_categoryRow{flex-wrap:wrap;gap:6px;max-height:64px;display:flex;overflow-y:auto}.o0mAxG_categoryPill{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);height:26px;color:var(--dsw-alias-label-secondary);cursor:pointer;white-space:nowrap;border-radius:999px;padding:0 11px;font-family:inherit;font-size:12px}.o0mAxG_categoryPill:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}.o0mAxG_categoryPill[data-active]{border-color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-brand-primary);color:var(--dsw-alias-bg-base)}.o0mAxG_notice{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);border-radius:9px;flex:none;margin:0 18px 10px;padding:8px 12px;font-size:12px}.o0mAxG_body{flex:1;min-height:0;padding:2px 18px 14px;overflow-y:auto}.o0mAxG_state{height:100%;min-height:220px;color:var(--dsw-alias-label-tertiary);flex-direction:column;justify-content:center;align-items:center;gap:12px;font-size:13px;display:flex}.o0mAxG_spinner{border:2px solid var(--dsw-alias-border-l2);border-top-color:var(--dsw-alias-brand-primary);border-radius:50%;width:26px;height:26px;animation:.9s linear infinite o0mAxG_dsh-imagegen-templates-spin}@keyframes o0mAxG_dsh-imagegen-templates-spin{to{transform:rotate(360deg)}}.o0mAxG_grid{grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:12px;display:grid}.o0mAxG_card{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);cursor:pointer;text-align:left;color:var(--dsw-alias-label-primary);border-radius:11px;flex-direction:column;gap:0;padding:0;font-family:inherit;transition:border-color .15s,transform .15s;display:flex;overflow:hidden}.o0mAxG_card:hover{border-color:var(--dsw-alias-brand-primary);transform:translateY(-1px)}.o0mAxG_thumbWrap{aspect-ratio:1;background:var(--dsw-alias-bg-layer-2);width:100%;display:block;position:relative}.o0mAxG_thumb{object-fit:cover;width:100%;height:100%;display:block}.o0mAxG_thumbPlaceholder{width:100%;height:100%;color:var(--dsw-alias-label-dimmed);justify-content:center;align-items:center;display:flex}.o0mAxG_featuredBadge{background:var(--dsw-alias-brand-primary);color:var(--dsw-alias-bg-base);border-radius:999px;padding:2px 8px;font-size:11px;font-weight:600;position:absolute;top:8px;left:8px}.o0mAxG_favStar{color:#ffffffd9;cursor:pointer;opacity:0;background:#00000059;border:none;border-radius:8px;justify-content:center;align-items:center;width:26px;height:26px;padding:0;transition:opacity .15s;display:inline-flex;position:absolute;top:6px;right:6px}.o0mAxG_card:hover .o0mAxG_favStar,.o0mAxG_favStar:focus-visible,.o0mAxG_favStar[data-active]{opacity:1}.o0mAxG_favStar:hover{color:#fff;background:#0000008c}.o0mAxG_favStar[data-active]{color:#ffb020}@media (hover:none){.o0mAxG_favStar{opacity:1}}.o0mAxG_cardBody{flex-direction:column;gap:4px;min-width:0;padding:9px 11px 10px;display:flex}.o0mAxG_cardTitle{-webkit-line-clamp:2;-webkit-box-orient:vertical;font-size:12.5px;font-weight:600;line-height:1.35;display:-webkit-box;overflow:hidden}.o0mAxG_cardMeta{min-width:0;color:var(--dsw-alias-label-tertiary);align-items:center;gap:6px;font-size:11px;display:flex}.o0mAxG_cardCategory{background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 7px}.o0mAxG_cardSource{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.o0mAxG_footer{border-top:1px solid var(--dsw-alias-border-l1);flex:none;justify-content:space-between;align-items:center;gap:10px;padding:9px 18px;display:flex}.o0mAxG_attribution{color:var(--dsw-alias-label-dimmed);min-width:0;font-size:11.5px}.o0mAxG_sourceLink{color:var(--dsw-alias-brand-primary);white-space:nowrap;flex:none;font-size:11.5px;font-weight:600;text-decoration:none}.o0mAxG_sourceLink:hover{text-decoration:underline}.o0mAxG_detailOverlay{background:var(--dsw-alias-bg-mask-1);justify-content:center;align-items:center;padding:34px;display:flex;position:absolute;inset:0}.o0mAxG_detail{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);border-radius:14px;grid-template-rows:minmax(0,1fr);grid-template-columns:minmax(0,5fr) minmax(0,4fr);gap:0;width:min(980px,100%);max-height:100%;display:grid;overflow:hidden;box-shadow:0 18px 60px #00000052}.o0mAxG_detailMedia{background:var(--dsw-alias-bg-layer-2);justify-content:center;align-items:center;min-height:0;display:flex;overflow:hidden}.o0mAxG_detailImage{object-fit:contain;width:100%;height:100%;display:block}.o0mAxG_detailInfo{flex-direction:column;gap:10px;min-height:0;padding:18px;display:flex;overflow-y:auto}.o0mAxG_detailTitle{margin:0;font-size:15px;font-weight:650;line-height:1.4}.o0mAxG_detailMeta{color:var(--dsw-alias-label-tertiary);flex-wrap:wrap;align-items:center;gap:8px;font-size:12px;display:flex}.o0mAxG_detailLink{color:var(--dsw-alias-brand-primary);text-overflow:ellipsis;white-space:nowrap;text-decoration:none;overflow:hidden}.o0mAxG_detailLink:hover{text-decoration:underline}.o0mAxG_detailPrompt{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);min-height:0;color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;user-select:text;border-radius:10px;flex:1;margin:0;padding:12px;font-family:inherit;font-size:12.5px;line-height:1.6;overflow-y:auto}.o0mAxG_detailActions{background:var(--dsw-alias-bg-base);border-top:1px solid var(--dsw-alias-border-l1);flex:none;gap:8px;margin:0 -18px -18px;padding:12px 18px;display:flex;position:sticky;bottom:0}@media (width<=760px){.o0mAxG_detail{grid-template-rows:minmax(0,3fr) minmax(0,4fr);grid-template-columns:1fr}}";
|
|
1556
|
+
const tagId$4 = "@dickpy/dsh-imagegen/templates.module.css";
|
|
1557
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]") === null) {
|
|
1057
1558
|
const tag = document.createElement("style");
|
|
1058
1559
|
tag.dataset.plugin = "@dickpy/dsh-imagegen";
|
|
1059
|
-
tag.dataset.pluginCss = tagId$
|
|
1060
|
-
tag.textContent = css$
|
|
1560
|
+
tag.dataset.pluginCss = tagId$4;
|
|
1561
|
+
tag.textContent = css$4;
|
|
1061
1562
|
document.head.appendChild(tag);
|
|
1062
1563
|
}
|
|
1063
1564
|
var templates_module_css_default = {
|
|
1064
|
-
"
|
|
1065
|
-
"headerActions": "o0mAxG_headerActions",
|
|
1066
|
-
"state": "o0mAxG_state",
|
|
1067
|
-
"detailLink": "o0mAxG_detailLink",
|
|
1068
|
-
"toolbar": "o0mAxG_toolbar",
|
|
1069
|
-
"card": "o0mAxG_card",
|
|
1070
|
-
"cardCategory": "o0mAxG_cardCategory",
|
|
1071
|
-
"categoryPill": "o0mAxG_categoryPill",
|
|
1072
|
-
"thumbPlaceholder": "o0mAxG_thumbPlaceholder",
|
|
1565
|
+
"detailActions": "o0mAxG_detailActions",
|
|
1073
1566
|
"spinner": "o0mAxG_spinner",
|
|
1074
1567
|
"thumbWrap": "o0mAxG_thumbWrap",
|
|
1075
|
-
"
|
|
1076
|
-
"featuredBadge": "o0mAxG_featuredBadge",
|
|
1077
|
-
"footer": "o0mAxG_footer",
|
|
1568
|
+
"cardCategory": "o0mAxG_cardCategory",
|
|
1078
1569
|
"search": "o0mAxG_search",
|
|
1079
|
-
"
|
|
1080
|
-
"cardSource": "o0mAxG_cardSource",
|
|
1570
|
+
"favStar": "o0mAxG_favStar",
|
|
1081
1571
|
"detailOverlay": "o0mAxG_detailOverlay",
|
|
1082
|
-
"
|
|
1083
|
-
"
|
|
1084
|
-
"detailActions": "o0mAxG_detailActions",
|
|
1085
|
-
"body": "o0mAxG_body",
|
|
1086
|
-
"attribution": "o0mAxG_attribution",
|
|
1087
|
-
"cardMeta": "o0mAxG_cardMeta",
|
|
1088
|
-
"heading": "o0mAxG_heading",
|
|
1089
|
-
"thumb": "o0mAxG_thumb",
|
|
1572
|
+
"close": "o0mAxG_close",
|
|
1573
|
+
"featuredBadge": "o0mAxG_featuredBadge",
|
|
1090
1574
|
"detailPrompt": "o0mAxG_detailPrompt",
|
|
1091
|
-
"
|
|
1092
|
-
"
|
|
1575
|
+
"cardMeta": "o0mAxG_cardMeta",
|
|
1576
|
+
"detailMeta": "o0mAxG_detailMeta",
|
|
1577
|
+
"card": "o0mAxG_card",
|
|
1578
|
+
"dsh-imagegen-templates-spin": "o0mAxG_dsh-imagegen-templates-spin",
|
|
1579
|
+
"toolbar": "o0mAxG_toolbar",
|
|
1580
|
+
"categoryRow": "o0mAxG_categoryRow",
|
|
1581
|
+
"categoryPill": "o0mAxG_categoryPill",
|
|
1093
1582
|
"overlay": "o0mAxG_overlay",
|
|
1094
|
-
"header": "o0mAxG_header",
|
|
1095
1583
|
"meta": "o0mAxG_meta",
|
|
1096
|
-
"
|
|
1584
|
+
"detailMedia": "o0mAxG_detailMedia",
|
|
1585
|
+
"body": "o0mAxG_body",
|
|
1586
|
+
"detailImage": "o0mAxG_detailImage",
|
|
1587
|
+
"header": "o0mAxG_header",
|
|
1588
|
+
"detailLink": "o0mAxG_detailLink",
|
|
1589
|
+
"heading": "o0mAxG_heading",
|
|
1590
|
+
"headerActions": "o0mAxG_headerActions",
|
|
1591
|
+
"sourceTabs": "o0mAxG_sourceTabs",
|
|
1592
|
+
"sourceTab": "o0mAxG_sourceTab",
|
|
1593
|
+
"state": "o0mAxG_state",
|
|
1594
|
+
"shell": "o0mAxG_shell",
|
|
1595
|
+
"thumb": "o0mAxG_thumb",
|
|
1596
|
+
"detailInfo": "o0mAxG_detailInfo",
|
|
1097
1597
|
"cardTitle": "o0mAxG_cardTitle",
|
|
1598
|
+
"sourceTabCount": "o0mAxG_sourceTabCount",
|
|
1599
|
+
"grid": "o0mAxG_grid",
|
|
1600
|
+
"thumbPlaceholder": "o0mAxG_thumbPlaceholder",
|
|
1601
|
+
"sourceLink": "o0mAxG_sourceLink",
|
|
1098
1602
|
"notice": "o0mAxG_notice",
|
|
1099
|
-
"
|
|
1100
|
-
"
|
|
1101
|
-
"dsh-imagegen-templates-spin": "o0mAxG_dsh-imagegen-templates-spin",
|
|
1102
|
-
"detailMedia": "o0mAxG_detailMedia",
|
|
1603
|
+
"cardBody": "o0mAxG_cardBody",
|
|
1604
|
+
"attribution": "o0mAxG_attribution",
|
|
1103
1605
|
"detail": "o0mAxG_detail",
|
|
1104
|
-
"
|
|
1606
|
+
"detailTitle": "o0mAxG_detailTitle",
|
|
1607
|
+
"title": "o0mAxG_title",
|
|
1608
|
+
"cardSource": "o0mAxG_cardSource",
|
|
1609
|
+
"footer": "o0mAxG_footer"
|
|
1105
1610
|
};
|
|
1106
1611
|
//#endregion
|
|
1107
1612
|
//#region src/client/TemplateLibrary.tsx
|
|
1108
1613
|
/**
|
|
1109
|
-
* Prompt-template library overlay: a searchable, category-
|
|
1110
|
-
*
|
|
1111
|
-
*
|
|
1112
|
-
*
|
|
1113
|
-
*
|
|
1114
|
-
*
|
|
1614
|
+
* Prompt-template library overlay: a multi-source, searchable, category-
|
|
1615
|
+
* filtered gallery. Each registered source (TEMPLATE_SOURCES) renders as its
|
|
1616
|
+
* own tab with an independent list, refresh state, and image pool; case lists
|
|
1617
|
+
* are served by the host (bundled snapshot, optionally refreshed online or
|
|
1618
|
+
* auto-synced in the background) and reference images load lazily through the
|
|
1619
|
+
* host's caching proxy, so browsing progressively mirrors the gallery onto the
|
|
1620
|
+
* local disk. Templates can be starred; favorites persist host-side as full
|
|
1621
|
+
* case snapshots and are reachable through the ★ filter pill per tab. Picking
|
|
1622
|
+
* a template hands its prompt back to the studio form.
|
|
1115
1623
|
*/
|
|
1116
1624
|
/** Concurrent image downloads while caching the whole gallery offline. */
|
|
1117
1625
|
const CACHE_ALL_CONCURRENCY = 4;
|
|
1626
|
+
/** Stable favorites key of one case within a source. */
|
|
1627
|
+
function favoriteKeyOf(sourceId, item) {
|
|
1628
|
+
return `${sourceId}:${item.id}`;
|
|
1629
|
+
}
|
|
1118
1630
|
/** Same-origin URL of one case's reference image (host caching proxy). */
|
|
1119
|
-
function imageUrlOf(item) {
|
|
1120
|
-
return `${TEMPLATES_API.image}/${encodeURIComponent(item.image)}`;
|
|
1631
|
+
function imageUrlOf$1(sourceId, item) {
|
|
1632
|
+
return `${TEMPLATES_API.image}/${encodeURIComponent(sourceId)}/${encodeURIComponent(item.image)}`;
|
|
1121
1633
|
}
|
|
1122
1634
|
/** A card thumbnail that falls back to a placeholder when the proxy 404s. */
|
|
1123
1635
|
function TemplateThumb(props) {
|
|
@@ -1153,7 +1665,7 @@ window.__ModuleLoader__.load({
|
|
|
1153
1665
|
});
|
|
1154
1666
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
1155
1667
|
className: templates_module_css_default.thumb,
|
|
1156
|
-
src: imageUrlOf(props.item),
|
|
1668
|
+
src: imageUrlOf$1(props.sourceId, props.item),
|
|
1157
1669
|
alt: props.item.title,
|
|
1158
1670
|
loading: "lazy",
|
|
1159
1671
|
onError: () => {
|
|
@@ -1161,13 +1673,50 @@ window.__ModuleLoader__.load({
|
|
|
1161
1673
|
}
|
|
1162
1674
|
});
|
|
1163
1675
|
}
|
|
1676
|
+
/** Card-corner star toggle; the click must not open the detail view. Rendered
|
|
1677
|
+
* as a span (a button cannot nest inside the card button). */
|
|
1678
|
+
function FavoriteStar(props) {
|
|
1679
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1680
|
+
role: "button",
|
|
1681
|
+
tabIndex: 0,
|
|
1682
|
+
className: templates_module_css_default.favStar,
|
|
1683
|
+
"data-active": props.active ? "" : void 0,
|
|
1684
|
+
"aria-label": props.title,
|
|
1685
|
+
title: props.title,
|
|
1686
|
+
onClick: (event) => {
|
|
1687
|
+
event.stopPropagation();
|
|
1688
|
+
props.onToggle();
|
|
1689
|
+
},
|
|
1690
|
+
onKeyDown: (event) => {
|
|
1691
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
1692
|
+
event.stopPropagation();
|
|
1693
|
+
event.preventDefault();
|
|
1694
|
+
props.onToggle();
|
|
1695
|
+
},
|
|
1696
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
1697
|
+
viewBox: "0 0 24 24",
|
|
1698
|
+
width: "15",
|
|
1699
|
+
height: "15",
|
|
1700
|
+
fill: props.active ? "currentColor" : "none",
|
|
1701
|
+
stroke: "currentColor",
|
|
1702
|
+
strokeWidth: "1.6",
|
|
1703
|
+
strokeLinecap: "round",
|
|
1704
|
+
strokeLinejoin: "round",
|
|
1705
|
+
"aria-hidden": "true",
|
|
1706
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M12 3.6l2.6 5.3 5.8.8-4.2 4.1 1 5.8-5.2-2.7-5.2 2.7 1-5.8L3.6 9.7l5.8-.8z" })
|
|
1707
|
+
})
|
|
1708
|
+
});
|
|
1709
|
+
}
|
|
1164
1710
|
/** The template-library modal. Rendered through a portal above the studio. */
|
|
1165
1711
|
function TemplateLibrary(props) {
|
|
1166
1712
|
const { api, onUse, onClose } = props;
|
|
1167
|
-
const [
|
|
1168
|
-
const [
|
|
1713
|
+
const [activeSource, setActiveSource] = (0, react.useState)(TEMPLATE_SOURCES[0].id);
|
|
1714
|
+
const [lists, setLists] = (0, react.useState)({});
|
|
1715
|
+
const [loadErrors, setLoadErrors] = (0, react.useState)({});
|
|
1716
|
+
const [favorites, setFavorites] = (0, react.useState)([]);
|
|
1169
1717
|
const [query, setQuery] = (0, react.useState)("");
|
|
1170
1718
|
const [category, setCategory] = (0, react.useState)("");
|
|
1719
|
+
const [favoritesOnly, setFavoritesOnly] = (0, react.useState)(false);
|
|
1171
1720
|
const [selected, setSelected] = (0, react.useState)(null);
|
|
1172
1721
|
const [copied, setCopied] = (0, react.useState)(false);
|
|
1173
1722
|
const [refreshing, setRefreshing] = (0, react.useState)(false);
|
|
@@ -1178,20 +1727,42 @@ window.__ModuleLoader__.load({
|
|
|
1178
1727
|
total: 0
|
|
1179
1728
|
});
|
|
1180
1729
|
const searchRef = (0, react.useRef)(null);
|
|
1181
|
-
const
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1730
|
+
const list = lists[activeSource];
|
|
1731
|
+
const loadError = loadErrors[activeSource] || null;
|
|
1732
|
+
/** Fetch one source's list into the per-source cache. */
|
|
1733
|
+
const loadSource = (sourceId) => {
|
|
1734
|
+
api.templatesList(sourceId).then((result) => {
|
|
1735
|
+
setLists((current) => ({
|
|
1736
|
+
...current,
|
|
1737
|
+
[sourceId]: result
|
|
1738
|
+
}));
|
|
1739
|
+
setLoadErrors((current) => ({
|
|
1740
|
+
...current,
|
|
1741
|
+
[sourceId]: ""
|
|
1742
|
+
}));
|
|
1185
1743
|
}).catch((caught) => {
|
|
1186
|
-
|
|
1744
|
+
setLoadErrors((current) => ({
|
|
1745
|
+
...current,
|
|
1746
|
+
[sourceId]: errorMessage(caught)
|
|
1747
|
+
}));
|
|
1187
1748
|
});
|
|
1188
1749
|
};
|
|
1189
1750
|
(0, react.useEffect)(() => {
|
|
1190
|
-
|
|
1751
|
+
loadSource(TEMPLATE_SOURCES[0].id);
|
|
1752
|
+
api.favoritesList().then(setFavorites).catch(() => {});
|
|
1191
1753
|
searchRef.current?.focus();
|
|
1192
1754
|
}, []);
|
|
1755
|
+
const switchSource = (sourceId) => {
|
|
1756
|
+
if (sourceId === activeSource) return;
|
|
1757
|
+
setActiveSource(sourceId);
|
|
1758
|
+
setCategory("");
|
|
1759
|
+
setFavoritesOnly(false);
|
|
1760
|
+
setSelected(null);
|
|
1761
|
+
setNotice(null);
|
|
1762
|
+
if (lists[sourceId] === void 0) loadSource(sourceId);
|
|
1763
|
+
};
|
|
1193
1764
|
const categories = (0, react.useMemo)(() => {
|
|
1194
|
-
if (list ===
|
|
1765
|
+
if (list === void 0) return [];
|
|
1195
1766
|
const counts = /* @__PURE__ */ new Map();
|
|
1196
1767
|
for (const item of list.cases) {
|
|
1197
1768
|
const entry = counts.get(item.category) ?? {
|
|
@@ -1207,16 +1778,21 @@ window.__ModuleLoader__.load({
|
|
|
1207
1778
|
count: value.count
|
|
1208
1779
|
}));
|
|
1209
1780
|
}, [list]);
|
|
1781
|
+
/** Favorites of the active source, as standalone case snapshots. */
|
|
1782
|
+
const activeFavorites = (0, react.useMemo)(() => favorites.filter((entry) => entry.sourceId === activeSource).map((entry) => entry.case), [favorites, activeSource]);
|
|
1783
|
+
const favKeys = (0, react.useMemo)(() => new Set(favorites.map((entry) => entry.key)), [favorites]);
|
|
1210
1784
|
const filtered = (0, react.useMemo)(() => {
|
|
1211
|
-
|
|
1785
|
+
const pool = favoritesOnly ? activeFavorites : list?.cases ?? [];
|
|
1212
1786
|
const needle = query.trim().toLowerCase();
|
|
1213
|
-
return
|
|
1787
|
+
return pool.filter((item) => {
|
|
1214
1788
|
if (category !== "" && item.category !== category) return false;
|
|
1215
1789
|
if (needle === "") return true;
|
|
1216
1790
|
return item.title.toLowerCase().includes(needle) || item.prompt.toLowerCase().includes(needle) || item.sourceLabel.toLowerCase().includes(needle);
|
|
1217
1791
|
});
|
|
1218
1792
|
}, [
|
|
1219
1793
|
list,
|
|
1794
|
+
activeFavorites,
|
|
1795
|
+
favoritesOnly,
|
|
1220
1796
|
query,
|
|
1221
1797
|
category
|
|
1222
1798
|
]);
|
|
@@ -1235,10 +1811,12 @@ window.__ModuleLoader__.load({
|
|
|
1235
1811
|
setRefreshing(true);
|
|
1236
1812
|
setNotice(null);
|
|
1237
1813
|
try {
|
|
1238
|
-
const result = await api.templatesRefresh();
|
|
1239
|
-
const reloaded = await api.templatesList();
|
|
1240
|
-
|
|
1241
|
-
|
|
1814
|
+
const result = await api.templatesRefresh(activeSource);
|
|
1815
|
+
const reloaded = await api.templatesList(activeSource);
|
|
1816
|
+
setLists((current) => ({
|
|
1817
|
+
...current,
|
|
1818
|
+
[activeSource]: reloaded
|
|
1819
|
+
}));
|
|
1242
1820
|
setNotice(tt("templates.refreshed", { count: result.total }));
|
|
1243
1821
|
} catch (caught) {
|
|
1244
1822
|
setNotice(tt("templates.refreshFailed", { error: errorMessage(caught) }));
|
|
@@ -1246,9 +1824,14 @@ window.__ModuleLoader__.load({
|
|
|
1246
1824
|
setRefreshing(false);
|
|
1247
1825
|
}
|
|
1248
1826
|
};
|
|
1249
|
-
/**
|
|
1827
|
+
/** Star / unstar one template of the active source. */
|
|
1828
|
+
const toggleFavorite = (item) => {
|
|
1829
|
+
const key = favoriteKeyOf(activeSource, item);
|
|
1830
|
+
(favKeys.has(key) ? api.favoritesRemove(key) : api.favoritesAdd(activeSource, item)).then(setFavorites).catch(() => {});
|
|
1831
|
+
};
|
|
1832
|
+
/** Mirror every reference image of the active source through the host cache. */
|
|
1250
1833
|
const cacheAllImages = async () => {
|
|
1251
|
-
if (cacheAll.running || list ===
|
|
1834
|
+
if (cacheAll.running || list === void 0) return;
|
|
1252
1835
|
const files = [...new Set(list.cases.map((item) => item.image).filter((name) => name !== ""))];
|
|
1253
1836
|
setCacheAll({
|
|
1254
1837
|
running: true,
|
|
@@ -1261,7 +1844,7 @@ window.__ModuleLoader__.load({
|
|
|
1261
1844
|
const file = files[index];
|
|
1262
1845
|
index += 1;
|
|
1263
1846
|
try {
|
|
1264
|
-
await fetch(`${TEMPLATES_API.image}/${encodeURIComponent(file)}`);
|
|
1847
|
+
await fetch(`${TEMPLATES_API.image}/${encodeURIComponent(activeSource)}/${encodeURIComponent(file)}`);
|
|
1265
1848
|
} catch {}
|
|
1266
1849
|
setCacheAll((current) => ({
|
|
1267
1850
|
...current,
|
|
@@ -1298,7 +1881,8 @@ window.__ModuleLoader__.load({
|
|
|
1298
1881
|
setCopied(false);
|
|
1299
1882
|
}
|
|
1300
1883
|
};
|
|
1301
|
-
const originLabel = list ===
|
|
1884
|
+
const originLabel = list === void 0 ? "" : tt(list.origin === "refreshed" ? "templates.origin.refreshed" : "templates.origin.bundled");
|
|
1885
|
+
const activeMeta = TEMPLATE_SOURCES.find((source) => source.id === activeSource);
|
|
1302
1886
|
return (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1303
1887
|
className: templates_module_css_default.overlay,
|
|
1304
1888
|
role: "dialog",
|
|
@@ -1318,7 +1902,7 @@ window.__ModuleLoader__.load({
|
|
|
1318
1902
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
1319
1903
|
className: templates_module_css_default.title,
|
|
1320
1904
|
children: tt("templates.title")
|
|
1321
|
-
}), list !==
|
|
1905
|
+
}), list !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1322
1906
|
className: templates_module_css_default.meta,
|
|
1323
1907
|
children: tt("templates.meta", {
|
|
1324
1908
|
count: list.total,
|
|
@@ -1340,7 +1924,7 @@ window.__ModuleLoader__.load({
|
|
|
1340
1924
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1341
1925
|
variant: "outline",
|
|
1342
1926
|
size: "sm",
|
|
1343
|
-
disabled: list ===
|
|
1927
|
+
disabled: list === void 0 || cacheAll.running,
|
|
1344
1928
|
title: tt("templates.cacheAllHint"),
|
|
1345
1929
|
onClick: () => {
|
|
1346
1930
|
cacheAllImages();
|
|
@@ -1371,6 +1955,26 @@ window.__ModuleLoader__.load({
|
|
|
1371
1955
|
]
|
|
1372
1956
|
})]
|
|
1373
1957
|
}),
|
|
1958
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1959
|
+
className: templates_module_css_default.sourceTabs,
|
|
1960
|
+
role: "tablist",
|
|
1961
|
+
"aria-label": tt("templates.sources"),
|
|
1962
|
+
children: TEMPLATE_SOURCES.map((source) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1963
|
+
type: "button",
|
|
1964
|
+
role: "tab",
|
|
1965
|
+
"aria-selected": source.id === activeSource,
|
|
1966
|
+
className: templates_module_css_default.sourceTab,
|
|
1967
|
+
"data-active": source.id === activeSource ? "" : void 0,
|
|
1968
|
+
title: source.description,
|
|
1969
|
+
onClick: () => {
|
|
1970
|
+
switchSource(source.id);
|
|
1971
|
+
},
|
|
1972
|
+
children: [source.label, lists[source.id] !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1973
|
+
className: templates_module_css_default.sourceTabCount,
|
|
1974
|
+
children: lists[source.id].total
|
|
1975
|
+
}) : null]
|
|
1976
|
+
}, source.id))
|
|
1977
|
+
}),
|
|
1374
1978
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1375
1979
|
className: templates_module_css_default.toolbar,
|
|
1376
1980
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
@@ -1384,27 +1988,46 @@ window.__ModuleLoader__.load({
|
|
|
1384
1988
|
}
|
|
1385
1989
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1386
1990
|
className: templates_module_css_default.categoryRow,
|
|
1387
|
-
children: [
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
},
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1991
|
+
children: [
|
|
1992
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1993
|
+
type: "button",
|
|
1994
|
+
className: templates_module_css_default.categoryPill,
|
|
1995
|
+
"data-active": favoritesOnly ? "" : void 0,
|
|
1996
|
+
title: tt("templates.favoritesHint"),
|
|
1997
|
+
onClick: () => {
|
|
1998
|
+
setFavoritesOnly((value) => !value);
|
|
1999
|
+
},
|
|
2000
|
+
children: [
|
|
2001
|
+
"★ ",
|
|
2002
|
+
tt("templates.favorites"),
|
|
2003
|
+
activeFavorites.length > 0 ? ` ${activeFavorites.length}` : ""
|
|
2004
|
+
]
|
|
2005
|
+
}),
|
|
2006
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
2007
|
+
type: "button",
|
|
2008
|
+
className: templates_module_css_default.categoryPill,
|
|
2009
|
+
"data-active": !favoritesOnly && category === "" ? "" : void 0,
|
|
2010
|
+
onClick: () => {
|
|
2011
|
+
setFavoritesOnly(false);
|
|
2012
|
+
setCategory("");
|
|
2013
|
+
},
|
|
2014
|
+
children: [tt("templates.all"), list !== void 0 ? ` ${list.total}` : ""]
|
|
2015
|
+
}),
|
|
2016
|
+
categories.map((entry) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
2017
|
+
type: "button",
|
|
2018
|
+
className: templates_module_css_default.categoryPill,
|
|
2019
|
+
"data-active": !favoritesOnly && category === entry.key ? "" : void 0,
|
|
2020
|
+
onClick: () => {
|
|
2021
|
+
setFavoritesOnly(false);
|
|
2022
|
+
setCategory(entry.key);
|
|
2023
|
+
},
|
|
2024
|
+
children: [
|
|
2025
|
+
entry.label,
|
|
2026
|
+
" ",
|
|
2027
|
+
entry.count
|
|
2028
|
+
]
|
|
2029
|
+
}, entry.key))
|
|
2030
|
+
]
|
|
1408
2031
|
})]
|
|
1409
2032
|
}),
|
|
1410
2033
|
notice !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -1415,7 +2038,7 @@ window.__ModuleLoader__.load({
|
|
|
1415
2038
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1416
2039
|
className: templates_module_css_default.body,
|
|
1417
2040
|
children: [
|
|
1418
|
-
list ===
|
|
2041
|
+
list === void 0 && loadError === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1419
2042
|
className: templates_module_css_default.state,
|
|
1420
2043
|
role: "status",
|
|
1421
2044
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: templates_module_css_default.spinner }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tt("templates.loading") })]
|
|
@@ -1427,18 +2050,20 @@ window.__ModuleLoader__.load({
|
|
|
1427
2050
|
variant: "outline",
|
|
1428
2051
|
size: "sm",
|
|
1429
2052
|
onClick: () => {
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
2053
|
+
setLoadErrors((current) => ({
|
|
2054
|
+
...current,
|
|
2055
|
+
[activeSource]: ""
|
|
2056
|
+
}));
|
|
2057
|
+
loadSource(activeSource);
|
|
1433
2058
|
},
|
|
1434
2059
|
children: tt("templates.retry")
|
|
1435
2060
|
})]
|
|
1436
2061
|
}) : null,
|
|
1437
|
-
list !==
|
|
2062
|
+
loadError === null && (list !== void 0 || favoritesOnly) && filtered.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1438
2063
|
className: templates_module_css_default.state,
|
|
1439
|
-
children: tt("templates.empty")
|
|
2064
|
+
children: favoritesOnly && activeFavorites.length === 0 ? tt("templates.favoritesEmpty") : tt("templates.empty")
|
|
1440
2065
|
}) : null,
|
|
1441
|
-
|
|
2066
|
+
filtered.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1442
2067
|
className: templates_module_css_default.grid,
|
|
1443
2068
|
children: filtered.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1444
2069
|
type: "button",
|
|
@@ -1449,10 +2074,23 @@ window.__ModuleLoader__.load({
|
|
|
1449
2074
|
},
|
|
1450
2075
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1451
2076
|
className: templates_module_css_default.thumbWrap,
|
|
1452
|
-
children: [
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
2077
|
+
children: [
|
|
2078
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TemplateThumb, {
|
|
2079
|
+
sourceId: activeSource,
|
|
2080
|
+
item
|
|
2081
|
+
}),
|
|
2082
|
+
item.featured ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2083
|
+
className: templates_module_css_default.featuredBadge,
|
|
2084
|
+
children: tt("templates.featured")
|
|
2085
|
+
}) : null,
|
|
2086
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(FavoriteStar, {
|
|
2087
|
+
active: favKeys.has(favoriteKeyOf(activeSource, item)),
|
|
2088
|
+
title: favKeys.has(favoriteKeyOf(activeSource, item)) ? tt("templates.favoriteRemove") : tt("templates.favoriteAdd"),
|
|
2089
|
+
onToggle: () => {
|
|
2090
|
+
toggleFavorite(item);
|
|
2091
|
+
}
|
|
2092
|
+
})
|
|
2093
|
+
]
|
|
1456
2094
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1457
2095
|
className: templates_module_css_default.cardBody,
|
|
1458
2096
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
@@ -1469,7 +2107,7 @@ window.__ModuleLoader__.load({
|
|
|
1469
2107
|
}) : null]
|
|
1470
2108
|
})]
|
|
1471
2109
|
})]
|
|
1472
|
-
}, item.id))
|
|
2110
|
+
}, `${activeSource}:${item.id}`))
|
|
1473
2111
|
}) : null
|
|
1474
2112
|
]
|
|
1475
2113
|
}),
|
|
@@ -1480,10 +2118,10 @@ window.__ModuleLoader__.load({
|
|
|
1480
2118
|
children: tt("templates.attribution")
|
|
1481
2119
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
1482
2120
|
className: templates_module_css_default.sourceLink,
|
|
1483
|
-
href:
|
|
2121
|
+
href: activeMeta.homepage,
|
|
1484
2122
|
target: "_blank",
|
|
1485
2123
|
rel: "noreferrer",
|
|
1486
|
-
children: tt("templates.source")
|
|
2124
|
+
children: tt("templates.source", { label: activeMeta.label })
|
|
1487
2125
|
})]
|
|
1488
2126
|
})
|
|
1489
2127
|
]
|
|
@@ -1501,7 +2139,7 @@ window.__ModuleLoader__.load({
|
|
|
1501
2139
|
className: templates_module_css_default.detailMedia,
|
|
1502
2140
|
children: selected.image !== "" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
1503
2141
|
className: templates_module_css_default.detailImage,
|
|
1504
|
-
src: imageUrlOf(selected),
|
|
2142
|
+
src: imageUrlOf$1(activeSource, selected),
|
|
1505
2143
|
alt: selected.title
|
|
1506
2144
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1507
2145
|
className: templates_module_css_default.thumbPlaceholder,
|
|
@@ -1560,6 +2198,14 @@ window.__ModuleLoader__.load({
|
|
|
1560
2198
|
},
|
|
1561
2199
|
children: copied ? tt("templates.copied") : tt("templates.copy")
|
|
1562
2200
|
}),
|
|
2201
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2202
|
+
variant: "outline",
|
|
2203
|
+
size: "md",
|
|
2204
|
+
onClick: () => {
|
|
2205
|
+
toggleFavorite(selected);
|
|
2206
|
+
},
|
|
2207
|
+
children: favKeys.has(favoriteKeyOf(activeSource, selected)) ? tt("templates.unfavorite") : tt("templates.favorite")
|
|
2208
|
+
}),
|
|
1563
2209
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1564
2210
|
variant: "outline",
|
|
1565
2211
|
size: "md",
|
|
@@ -1577,6 +2223,188 @@ window.__ModuleLoader__.load({
|
|
|
1577
2223
|
}), document.body);
|
|
1578
2224
|
}
|
|
1579
2225
|
//#endregion
|
|
2226
|
+
//#region \0dsh-css:E:\dsh-plugin\src\client\inspiration.module.css.mjs
|
|
2227
|
+
const css$3 = ".IgRnJG_wrap{width:min(880px,100%);font-family:var(--dsw-font-family);flex-direction:column;align-items:center;gap:16px;margin:auto;padding:24px;display:flex}.IgRnJG_title{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:650}.IgRnJG_emptyIcon{color:var(--dsw-alias-label-dimmed);display:inline-flex}.IgRnJG_emptyTitle{color:var(--dsw-alias-label-primary);margin-top:-6px;font-size:15px;font-weight:650}.IgRnJG_emptyHint{color:var(--dsw-alias-label-tertiary);font-size:12.5px}.IgRnJG_grid{grid-template-columns:repeat(4,1fr);gap:12px;width:100%;display:grid}@media (width<=900px){.IgRnJG_grid{grid-template-columns:repeat(3,1fr)}}@media (width<=560px){.IgRnJG_grid{grid-template-columns:repeat(2,1fr)}}.IgRnJG_tile{aspect-ratio:1;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);cursor:pointer;border-radius:12px;width:100%;padding:0;transition:transform .15s,border-color .15s,box-shadow .15s;display:block;position:relative;overflow:hidden}.IgRnJG_tile:hover{border-color:var(--dsw-alias-brand-primary);transform:translateY(-2px);box-shadow:0 6px 18px #0000001f}.IgRnJG_thumbWrap{display:block;position:absolute;inset:0}.IgRnJG_thumb{object-fit:cover;width:100%;height:100%;display:block}.IgRnJG_thumbFallback{background:var(--dsw-alias-bg-layer-2);width:100%;height:100%;color:var(--dsw-alias-label-tertiary);text-align:center;justify-content:center;align-items:center;padding:6px;font-size:11px;line-height:1.4;display:flex;overflow:hidden}.IgRnJG_thumbTitle{text-overflow:ellipsis;white-space:nowrap;color:#fff;text-align:center;opacity:0;pointer-events:none;background:linear-gradient(#0000,#0000008c);padding:14px 8px 6px;font-size:10.5px;transition:opacity .15s;position:absolute;inset:auto 0 0;overflow:hidden}.IgRnJG_tile:hover .IgRnJG_thumbTitle{opacity:1}.IgRnJG_spinner{border:2px solid var(--dsw-alias-border-l2);border-top-color:var(--dsw-alias-brand-primary);border-radius:50%;width:20px;height:20px;animation:.9s linear infinite IgRnJG_dsh-imagegen-inspiration-spin}@keyframes IgRnJG_dsh-imagegen-inspiration-spin{to{transform:rotate(360deg)}}@media (hover:none){.IgRnJG_thumbTitle{opacity:1}}";
|
|
2228
|
+
const tagId$3 = "@dickpy/dsh-imagegen/inspiration.module.css";
|
|
2229
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
|
|
2230
|
+
const tag = document.createElement("style");
|
|
2231
|
+
tag.dataset.plugin = "@dickpy/dsh-imagegen";
|
|
2232
|
+
tag.dataset.pluginCss = tagId$3;
|
|
2233
|
+
tag.textContent = css$3;
|
|
2234
|
+
document.head.appendChild(tag);
|
|
2235
|
+
}
|
|
2236
|
+
var inspiration_module_css_default = {
|
|
2237
|
+
"emptyIcon": "IgRnJG_emptyIcon",
|
|
2238
|
+
"wrap": "IgRnJG_wrap",
|
|
2239
|
+
"spinner": "IgRnJG_spinner",
|
|
2240
|
+
"thumbWrap": "IgRnJG_thumbWrap",
|
|
2241
|
+
"grid": "IgRnJG_grid",
|
|
2242
|
+
"thumb": "IgRnJG_thumb",
|
|
2243
|
+
"title": "IgRnJG_title",
|
|
2244
|
+
"emptyTitle": "IgRnJG_emptyTitle",
|
|
2245
|
+
"emptyHint": "IgRnJG_emptyHint",
|
|
2246
|
+
"tile": "IgRnJG_tile",
|
|
2247
|
+
"thumbFallback": "IgRnJG_thumbFallback",
|
|
2248
|
+
"thumbTitle": "IgRnJG_thumbTitle",
|
|
2249
|
+
"dsh-imagegen-inspiration-spin": "IgRnJG_dsh-imagegen-inspiration-spin"
|
|
2250
|
+
};
|
|
2251
|
+
//#endregion
|
|
2252
|
+
//#region src/client/InspirationGallery.tsx
|
|
2253
|
+
/**
|
|
2254
|
+
* Inspiration wall for the studio's empty canvas: a small grid of random
|
|
2255
|
+
* template cases sampled host-side across every library source. Clicking a
|
|
2256
|
+
* card hands its prompt to the form; the 随机 button re-rolls the pick. On
|
|
2257
|
+
* failure the wall collapses to nothing (the panel falls back to the plain
|
|
2258
|
+
* empty-state hint).
|
|
2259
|
+
*/
|
|
2260
|
+
/** Card count per deal — a 4×3 wall that uses the canvas's spare width. */
|
|
2261
|
+
const SAMPLE_COUNT = 12;
|
|
2262
|
+
/** Same-origin proxy URL of one sampled case's reference image. */
|
|
2263
|
+
function imageUrlOf(sample) {
|
|
2264
|
+
return `${TEMPLATES_API.image}/${encodeURIComponent(sample.sourceId)}/${encodeURIComponent(sample.case.image)}`;
|
|
2265
|
+
}
|
|
2266
|
+
/** One thumbnail that degrades to a text tile when the image 404s. */
|
|
2267
|
+
function SampleThumb(props) {
|
|
2268
|
+
const [failed, setFailed] = (0, react.useState)(false);
|
|
2269
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2270
|
+
className: inspiration_module_css_default.thumbWrap,
|
|
2271
|
+
children: [props.sample.case.image !== "" && !failed ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
2272
|
+
className: inspiration_module_css_default.thumb,
|
|
2273
|
+
src: imageUrlOf(props.sample),
|
|
2274
|
+
alt: props.sample.case.title,
|
|
2275
|
+
loading: "lazy",
|
|
2276
|
+
onError: () => {
|
|
2277
|
+
setFailed(true);
|
|
2278
|
+
}
|
|
2279
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2280
|
+
className: inspiration_module_css_default.thumbFallback,
|
|
2281
|
+
"aria-hidden": "true",
|
|
2282
|
+
children: props.sample.case.title
|
|
2283
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2284
|
+
className: inspiration_module_css_default.thumbTitle,
|
|
2285
|
+
children: props.sample.case.title
|
|
2286
|
+
})]
|
|
2287
|
+
});
|
|
2288
|
+
}
|
|
2289
|
+
/** The random-case wall shown while the canvas has no results. */
|
|
2290
|
+
function InspirationGallery(props) {
|
|
2291
|
+
const { api, onUse } = props;
|
|
2292
|
+
const [samples, setSamples] = (0, react.useState)(null);
|
|
2293
|
+
const [loading, setLoading] = (0, react.useState)(false);
|
|
2294
|
+
const deal = () => {
|
|
2295
|
+
if (loading) return;
|
|
2296
|
+
setLoading(true);
|
|
2297
|
+
api.templatesSample(SAMPLE_COUNT).then(setSamples).catch(() => {
|
|
2298
|
+
setSamples((current) => current ?? []);
|
|
2299
|
+
}).finally(() => {
|
|
2300
|
+
setLoading(false);
|
|
2301
|
+
});
|
|
2302
|
+
};
|
|
2303
|
+
(0, react.useEffect)(() => {
|
|
2304
|
+
deal();
|
|
2305
|
+
}, []);
|
|
2306
|
+
if (samples !== null && samples.length === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2307
|
+
className: inspiration_module_css_default.wrap,
|
|
2308
|
+
"aria-label": tt("inspiration.title"),
|
|
2309
|
+
children: [
|
|
2310
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2311
|
+
className: inspiration_module_css_default.emptyIcon,
|
|
2312
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
2313
|
+
viewBox: "0 0 24 24",
|
|
2314
|
+
width: "34",
|
|
2315
|
+
height: "34",
|
|
2316
|
+
fill: "none",
|
|
2317
|
+
stroke: "currentColor",
|
|
2318
|
+
strokeWidth: "1.2",
|
|
2319
|
+
strokeLinecap: "round",
|
|
2320
|
+
strokeLinejoin: "round",
|
|
2321
|
+
"aria-hidden": "true",
|
|
2322
|
+
children: [
|
|
2323
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
|
|
2324
|
+
x: "3",
|
|
2325
|
+
y: "3",
|
|
2326
|
+
width: "18",
|
|
2327
|
+
height: "18",
|
|
2328
|
+
rx: "3"
|
|
2329
|
+
}),
|
|
2330
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
|
|
2331
|
+
cx: "8.5",
|
|
2332
|
+
cy: "8.5",
|
|
2333
|
+
r: "1.5"
|
|
2334
|
+
}),
|
|
2335
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M21 15l-5-5L5 21" })
|
|
2336
|
+
]
|
|
2337
|
+
})
|
|
2338
|
+
}),
|
|
2339
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2340
|
+
className: inspiration_module_css_default.emptyTitle,
|
|
2341
|
+
children: tt("canvas.emptyTitle")
|
|
2342
|
+
}),
|
|
2343
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2344
|
+
className: inspiration_module_css_default.emptyHint,
|
|
2345
|
+
children: tt("canvas.emptyHint")
|
|
2346
|
+
})
|
|
2347
|
+
]
|
|
2348
|
+
});
|
|
2349
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2350
|
+
className: inspiration_module_css_default.wrap,
|
|
2351
|
+
"aria-label": tt("inspiration.title"),
|
|
2352
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2353
|
+
className: inspiration_module_css_default.title,
|
|
2354
|
+
children: tt("inspiration.title")
|
|
2355
|
+
}), samples === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2356
|
+
className: inspiration_module_css_default.spinner,
|
|
2357
|
+
"aria-hidden": "true"
|
|
2358
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2359
|
+
className: inspiration_module_css_default.grid,
|
|
2360
|
+
children: samples.map((sample) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2361
|
+
type: "button",
|
|
2362
|
+
className: inspiration_module_css_default.tile,
|
|
2363
|
+
title: tt("inspiration.useHint"),
|
|
2364
|
+
onClick: () => {
|
|
2365
|
+
onUse(sample.case.prompt);
|
|
2366
|
+
},
|
|
2367
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SampleThumb, { sample })
|
|
2368
|
+
}, `${sample.sourceId}:${sample.case.id}`))
|
|
2369
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2370
|
+
variant: "outline",
|
|
2371
|
+
size: "sm",
|
|
2372
|
+
disabled: loading,
|
|
2373
|
+
onClick: deal,
|
|
2374
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
2375
|
+
viewBox: "0 0 24 24",
|
|
2376
|
+
width: "14",
|
|
2377
|
+
height: "14",
|
|
2378
|
+
fill: "none",
|
|
2379
|
+
stroke: "currentColor",
|
|
2380
|
+
strokeWidth: "1.8",
|
|
2381
|
+
strokeLinecap: "round",
|
|
2382
|
+
strokeLinejoin: "round",
|
|
2383
|
+
"aria-hidden": "true",
|
|
2384
|
+
children: [
|
|
2385
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M2 18h1.4c1.3 0 2.5-.6 3.3-1.7l6.1-8.6c.8-1.1 2-1.7 3.3-1.7H22" }),
|
|
2386
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "m18 2 4 4-4 4" }),
|
|
2387
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M2 6h1.9c1.5 0 2.9.9 3.6 2.2" }),
|
|
2388
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M22 18h-5.9c-1.3 0-2.6-.7-3.3-1.8l-.5-.8" }),
|
|
2389
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "m18 14 4 4-4 4" })
|
|
2390
|
+
]
|
|
2391
|
+
}), loading ? tt("inspiration.shuffling") : tt("inspiration.shuffle")]
|
|
2392
|
+
})] })]
|
|
2393
|
+
});
|
|
2394
|
+
}
|
|
2395
|
+
//#endregion
|
|
2396
|
+
//#region src/client/use-language.ts
|
|
2397
|
+
/**
|
|
2398
|
+
* React binding for the plugin locale, which follows the DSH interface
|
|
2399
|
+
* language (bridged from ctx.locale in client/index.ts). Surfaces that render
|
|
2400
|
+
* tt() output subscribe to this tick so a DSH language switch re-renders them
|
|
2401
|
+
* immediately.
|
|
2402
|
+
*/
|
|
2403
|
+
/** Re-render the calling component whenever the DSH language changes. */
|
|
2404
|
+
function useImageGenLanguageTick() {
|
|
2405
|
+
return (0, react.useSyncExternalStore)(subscribeImageGenLanguage, getImageGenLanguageVersion);
|
|
2406
|
+
}
|
|
2407
|
+
//#endregion
|
|
1580
2408
|
//#region src/client/settings-scope.ts
|
|
1581
2409
|
/**
|
|
1582
2410
|
* Browser-side settings scope for the dsh-imagegen namespace, served by the
|
|
@@ -1889,6 +2717,14 @@ window.__ModuleLoader__.load({
|
|
|
1889
2717
|
supportsEdit: false,
|
|
1890
2718
|
supportsAspectRatio: false,
|
|
1891
2719
|
qualityTiers: ["HD"]
|
|
2720
|
+
},
|
|
2721
|
+
qwen: {
|
|
2722
|
+
label: "qwen-image",
|
|
2723
|
+
labelZh: "千问图像",
|
|
2724
|
+
known: true,
|
|
2725
|
+
supportsEdit: true,
|
|
2726
|
+
supportsAspectRatio: true,
|
|
2727
|
+
qualityTiers: ["auto"]
|
|
1892
2728
|
}
|
|
1893
2729
|
};
|
|
1894
2730
|
/** Official Gemini image ids served by Nano Banana gateways. */
|
|
@@ -1927,6 +2763,10 @@ window.__ModuleLoader__.load({
|
|
|
1927
2763
|
family: "zhipu",
|
|
1928
2764
|
...ENTRIES.zhipu
|
|
1929
2765
|
};
|
|
2766
|
+
if (/^qwen-image(?:[-_.]|$)/i.test(id)) return {
|
|
2767
|
+
family: "qwen",
|
|
2768
|
+
...ENTRIES.qwen
|
|
2769
|
+
};
|
|
1930
2770
|
return {
|
|
1931
2771
|
family: "unknown",
|
|
1932
2772
|
label: "unknown",
|
|
@@ -1953,226 +2793,226 @@ window.__ModuleLoader__.load({
|
|
|
1953
2793
|
document.head.appendChild(tag);
|
|
1954
2794
|
}
|
|
1955
2795
|
var panel_module_css_default = {
|
|
2796
|
+
"galleryRatio": "Yvqh9W_galleryRatio",
|
|
2797
|
+
"lightboxMeta": "Yvqh9W_lightboxMeta",
|
|
2798
|
+
"ecommerceAsset": "Yvqh9W_ecommerceAsset",
|
|
2799
|
+
"configGuideBody": "Yvqh9W_configGuideBody",
|
|
2800
|
+
"enhanceButton": "Yvqh9W_enhanceButton",
|
|
2801
|
+
"imageCaption": "Yvqh9W_imageCaption",
|
|
2802
|
+
"ecommercePlanNote": "Yvqh9W_ecommercePlanNote",
|
|
2803
|
+
"zoomHint": "Yvqh9W_zoomHint",
|
|
2804
|
+
"historyTitle": "Yvqh9W_historyTitle",
|
|
2805
|
+
"comparisonImageButton": "Yvqh9W_comparisonImageButton",
|
|
2806
|
+
"topNavDivider": "Yvqh9W_topNavDivider",
|
|
2807
|
+
"modelWrap": "Yvqh9W_modelWrap",
|
|
1956
2808
|
"galleryAdd": "Yvqh9W_galleryAdd",
|
|
1957
|
-
"
|
|
1958
|
-
"
|
|
1959
|
-
"
|
|
1960
|
-
"
|
|
1961
|
-
"
|
|
1962
|
-
"
|
|
1963
|
-
"
|
|
1964
|
-
"
|
|
1965
|
-
"galleryCardInfo": "Yvqh9W_galleryCardInfo",
|
|
1966
|
-
"studio": "Yvqh9W_studio",
|
|
1967
|
-
"ecommerceFooterHint": "Yvqh9W_ecommerceFooterHint",
|
|
1968
|
-
"download": "Yvqh9W_download",
|
|
2809
|
+
"historyHeaderActions": "Yvqh9W_historyHeaderActions",
|
|
2810
|
+
"historyFilters": "Yvqh9W_historyFilters",
|
|
2811
|
+
"configGuide": "Yvqh9W_configGuide",
|
|
2812
|
+
"previewBadge": "Yvqh9W_previewBadge",
|
|
2813
|
+
"updateBanner": "Yvqh9W_updateBanner",
|
|
2814
|
+
"ecommerceAssetAdd": "Yvqh9W_ecommerceAssetAdd",
|
|
2815
|
+
"panelHeaderActions": "Yvqh9W_panelHeaderActions",
|
|
2816
|
+
"modelLabel": "Yvqh9W_modelLabel",
|
|
1969
2817
|
"galleryFilterHeading": "Yvqh9W_galleryFilterHeading",
|
|
1970
|
-
"dshImageGenSpin": "Yvqh9W_dshImageGenSpin",
|
|
1971
|
-
"galleryRatioList": "Yvqh9W_galleryRatioList",
|
|
1972
|
-
"configHeader": "Yvqh9W_configHeader",
|
|
1973
|
-
"configGuideBody": "Yvqh9W_configGuideBody",
|
|
1974
|
-
"view": "Yvqh9W_view",
|
|
1975
|
-
"historyPrompt": "Yvqh9W_historyPrompt",
|
|
1976
|
-
"ecommerceGroups": "Yvqh9W_ecommerceGroups",
|
|
1977
|
-
"galleryTags": "Yvqh9W_galleryTags",
|
|
1978
|
-
"modelMenuList": "Yvqh9W_modelMenuList",
|
|
1979
|
-
"topNav": "Yvqh9W_topNav",
|
|
1980
|
-
"galleryWorkspace": "Yvqh9W_galleryWorkspace",
|
|
1981
2818
|
"gallerySelectMode": "Yvqh9W_gallerySelectMode",
|
|
1982
|
-
"
|
|
1983
|
-
"ecommerceSlotCard": "Yvqh9W_ecommerceSlotCard",
|
|
1984
|
-
"configScroll": "Yvqh9W_configScroll",
|
|
1985
|
-
"galleryTagInput": "Yvqh9W_galleryTagInput",
|
|
1986
|
-
"ecommercePlanBack": "Yvqh9W_ecommercePlanBack",
|
|
1987
|
-
"modelMenu": "Yvqh9W_modelMenu",
|
|
1988
|
-
"ecommerceTaskCard": "Yvqh9W_ecommerceTaskCard",
|
|
1989
|
-
"chatResizer": "Yvqh9W_chatResizer",
|
|
1990
|
-
"canvasMeta": "Yvqh9W_canvasMeta",
|
|
1991
|
-
"card": "Yvqh9W_card",
|
|
1992
|
-
"ecommerceAdvancedToggle": "Yvqh9W_ecommerceAdvancedToggle",
|
|
1993
|
-
"optionPill": "Yvqh9W_optionPill",
|
|
1994
|
-
"lightbox": "Yvqh9W_lightbox",
|
|
1995
|
-
"galleryFilter": "Yvqh9W_galleryFilter",
|
|
1996
|
-
"spinner": "Yvqh9W_spinner",
|
|
2819
|
+
"gallerySort": "Yvqh9W_gallerySort",
|
|
1997
2820
|
"historyMeta": "Yvqh9W_historyMeta",
|
|
1998
|
-
"
|
|
1999
|
-
"
|
|
2000
|
-
"
|
|
2001
|
-
"
|
|
2002
|
-
"
|
|
2003
|
-
"galleryHeading": "Yvqh9W_galleryHeading",
|
|
2004
|
-
"galleryAvatar": "Yvqh9W_galleryAvatar",
|
|
2005
|
-
"taskStatus": "Yvqh9W_taskStatus",
|
|
2006
|
-
"taskTrayToggle": "Yvqh9W_taskTrayToggle",
|
|
2007
|
-
"taskRows": "Yvqh9W_taskRows",
|
|
2008
|
-
"panelHeaderActions": "Yvqh9W_panelHeaderActions",
|
|
2009
|
-
"sessionTabLabel": "Yvqh9W_sessionTabLabel",
|
|
2010
|
-
"ecommerceFooterBody": "Yvqh9W_ecommerceFooterBody",
|
|
2821
|
+
"grid": "Yvqh9W_grid",
|
|
2822
|
+
"download": "Yvqh9W_download",
|
|
2823
|
+
"galleryTagEditor": "Yvqh9W_galleryTagEditor",
|
|
2824
|
+
"ecommerceField": "Yvqh9W_ecommerceField",
|
|
2825
|
+
"canvas": "Yvqh9W_canvas",
|
|
2011
2826
|
"panelHeading": "Yvqh9W_panelHeading",
|
|
2012
|
-
"
|
|
2013
|
-
"
|
|
2014
|
-
"
|
|
2015
|
-
"
|
|
2827
|
+
"taskRow": "Yvqh9W_taskRow",
|
|
2828
|
+
"historyList": "Yvqh9W_historyList",
|
|
2829
|
+
"historySearch": "Yvqh9W_historySearch",
|
|
2830
|
+
"ecommerceAdvancedBody": "Yvqh9W_ecommerceAdvancedBody",
|
|
2831
|
+
"galleryToolbarActions": "Yvqh9W_galleryToolbarActions",
|
|
2832
|
+
"galleryBulkButton": "Yvqh9W_galleryBulkButton",
|
|
2833
|
+
"galleryFilter": "Yvqh9W_galleryFilter",
|
|
2834
|
+
"connectionStatus": "Yvqh9W_connectionStatus",
|
|
2835
|
+
"panel": "Yvqh9W_panel",
|
|
2836
|
+
"reference": "Yvqh9W_reference",
|
|
2837
|
+
"galleryToast": "Yvqh9W_galleryToast",
|
|
2838
|
+
"comparisonFullscreenGrid": "Yvqh9W_comparisonFullscreenGrid",
|
|
2839
|
+
"modelMenuItem": "Yvqh9W_modelMenuItem",
|
|
2840
|
+
"panelTitle": "Yvqh9W_panelTitle",
|
|
2841
|
+
"githubLink": "Yvqh9W_githubLink",
|
|
2842
|
+
"galleryTagInput": "Yvqh9W_galleryTagInput",
|
|
2843
|
+
"topNavItem": "Yvqh9W_topNavItem",
|
|
2844
|
+
"optionGrid": "Yvqh9W_optionGrid",
|
|
2845
|
+
"lightboxDownload": "Yvqh9W_lightboxDownload",
|
|
2846
|
+
"configResizer": "Yvqh9W_configResizer",
|
|
2016
2847
|
"ecommerceResultBadge": "Yvqh9W_ecommerceResultBadge",
|
|
2017
|
-
"
|
|
2018
|
-
"
|
|
2019
|
-
"
|
|
2020
|
-
"
|
|
2021
|
-
"
|
|
2848
|
+
"configHeader": "Yvqh9W_configHeader",
|
|
2849
|
+
"gallerySearch": "Yvqh9W_gallerySearch",
|
|
2850
|
+
"ecommerceSlotCard": "Yvqh9W_ecommerceSlotCard",
|
|
2851
|
+
"ecommerceSlotCount": "Yvqh9W_ecommerceSlotCount",
|
|
2852
|
+
"uploadBox": "Yvqh9W_uploadBox",
|
|
2853
|
+
"lightboxZoomLevel": "Yvqh9W_lightboxZoomLevel",
|
|
2854
|
+
"optionPill": "Yvqh9W_optionPill",
|
|
2855
|
+
"lightboxStage": "Yvqh9W_lightboxStage",
|
|
2856
|
+
"galleryFilterCount": "Yvqh9W_galleryFilterCount",
|
|
2857
|
+
"imageCard": "Yvqh9W_imageCard",
|
|
2858
|
+
"galleryCardActions": "Yvqh9W_galleryCardActions",
|
|
2859
|
+
"galleryRatioList": "Yvqh9W_galleryRatioList",
|
|
2860
|
+
"connectionDot": "Yvqh9W_connectionDot",
|
|
2861
|
+
"ecommerceSectionHint": "Yvqh9W_ecommerceSectionHint",
|
|
2862
|
+
"comparisonFullscreen": "Yvqh9W_comparisonFullscreen",
|
|
2863
|
+
"galleryRemove": "Yvqh9W_galleryRemove",
|
|
2864
|
+
"ecommerceRefRow": "Yvqh9W_ecommerceRefRow",
|
|
2865
|
+
"gallerySelectionBar": "Yvqh9W_gallerySelectionBar",
|
|
2866
|
+
"galleryWorkspace": "Yvqh9W_galleryWorkspace",
|
|
2867
|
+
"galleryImage": "Yvqh9W_galleryImage",
|
|
2868
|
+
"historyEmpty": "Yvqh9W_historyEmpty",
|
|
2869
|
+
"galleryTagEdit": "Yvqh9W_galleryTagEdit",
|
|
2022
2870
|
"taskTrayChevron": "Yvqh9W_taskTrayChevron",
|
|
2023
|
-
"lightboxCaptionRow": "Yvqh9W_lightboxCaptionRow",
|
|
2024
|
-
"lightboxCaption": "Yvqh9W_lightboxCaption",
|
|
2025
2871
|
"taskTrayClose": "Yvqh9W_taskTrayClose",
|
|
2026
|
-
"
|
|
2027
|
-
"
|
|
2028
|
-
"
|
|
2029
|
-
"
|
|
2030
|
-
"
|
|
2031
|
-
"
|
|
2032
|
-
"
|
|
2872
|
+
"historyThumb": "Yvqh9W_historyThumb",
|
|
2873
|
+
"ecommerceAdvancedToggle": "Yvqh9W_ecommerceAdvancedToggle",
|
|
2874
|
+
"galleryHeading": "Yvqh9W_galleryHeading",
|
|
2875
|
+
"galleryCard": "Yvqh9W_galleryCard",
|
|
2876
|
+
"uploadHint": "Yvqh9W_uploadHint",
|
|
2877
|
+
"promptCount": "Yvqh9W_promptCount",
|
|
2878
|
+
"modelSelect": "Yvqh9W_modelSelect",
|
|
2879
|
+
"lightboxIndex": "Yvqh9W_lightboxIndex",
|
|
2880
|
+
"ecommerceStructureGrid": "Yvqh9W_ecommerceStructureGrid",
|
|
2881
|
+
"lightbox": "Yvqh9W_lightbox",
|
|
2882
|
+
"comparisonGrid": "Yvqh9W_comparisonGrid",
|
|
2883
|
+
"entryIcon": "Yvqh9W_entryIcon",
|
|
2884
|
+
"paramGroup": "Yvqh9W_paramGroup",
|
|
2033
2885
|
"historyHeader": "Yvqh9W_historyHeader",
|
|
2034
|
-
"
|
|
2035
|
-
"
|
|
2036
|
-
"generateInner": "Yvqh9W_generateInner",
|
|
2037
|
-
"dshImageGenToastIn": "Yvqh9W_dshImageGenToastIn",
|
|
2038
|
-
"galleryTagFilterList": "Yvqh9W_galleryTagFilterList",
|
|
2039
|
-
"generateButton": "Yvqh9W_generateButton",
|
|
2040
|
-
"imageCaption": "Yvqh9W_imageCaption",
|
|
2041
|
-
"ecommerceAdvancedBody": "Yvqh9W_ecommerceAdvancedBody",
|
|
2042
|
-
"ecommerceWorkspace": "Yvqh9W_ecommerceWorkspace",
|
|
2043
|
-
"ecommerceTaskActions": "Yvqh9W_ecommerceTaskActions",
|
|
2886
|
+
"gallerySelectionClear": "Yvqh9W_gallerySelectionClear",
|
|
2887
|
+
"galleryCardAction": "Yvqh9W_galleryCardAction",
|
|
2044
2888
|
"gallerySelect": "Yvqh9W_gallerySelect",
|
|
2045
|
-
"
|
|
2046
|
-
"
|
|
2889
|
+
"updateText": "Yvqh9W_updateText",
|
|
2890
|
+
"lightboxCaption": "Yvqh9W_lightboxCaption",
|
|
2891
|
+
"ecommercePrimaryAction": "Yvqh9W_ecommercePrimaryAction",
|
|
2892
|
+
"canvasEmptyIcon": "Yvqh9W_canvasEmptyIcon",
|
|
2893
|
+
"panelHeader": "Yvqh9W_panelHeader",
|
|
2894
|
+
"historyPrompt": "Yvqh9W_historyPrompt",
|
|
2895
|
+
"generateInner": "Yvqh9W_generateInner",
|
|
2896
|
+
"lightboxTools": "Yvqh9W_lightboxTools",
|
|
2897
|
+
"compareModelChoices": "Yvqh9W_compareModelChoices",
|
|
2898
|
+
"configScroll": "Yvqh9W_configScroll",
|
|
2047
2899
|
"historyClear": "Yvqh9W_historyClear",
|
|
2048
|
-
"
|
|
2049
|
-
"
|
|
2900
|
+
"configToggle": "Yvqh9W_configToggle",
|
|
2901
|
+
"historyInfo": "Yvqh9W_historyInfo",
|
|
2050
2902
|
"referenceActions": "Yvqh9W_referenceActions",
|
|
2051
|
-
"gallerySort": "Yvqh9W_gallerySort",
|
|
2052
|
-
"compareToggle": "Yvqh9W_compareToggle",
|
|
2053
|
-
"sidebarHistoryHost": "Yvqh9W_sidebarHistoryHost",
|
|
2054
|
-
"ecommercePlanList": "Yvqh9W_ecommercePlanList",
|
|
2055
|
-
"ecommercePrimaryAction": "Yvqh9W_ecommercePrimaryAction",
|
|
2056
|
-
"updateActions": "Yvqh9W_updateActions",
|
|
2057
|
-
"configGuide": "Yvqh9W_configGuide",
|
|
2058
|
-
"galleryFilterCount": "Yvqh9W_galleryFilterCount",
|
|
2059
|
-
"ecommerceField": "Yvqh9W_ecommerceField",
|
|
2060
|
-
"lightboxFigure": "Yvqh9W_lightboxFigure",
|
|
2061
|
-
"gallerySelectionClear": "Yvqh9W_gallerySelectionClear",
|
|
2062
|
-
"modeRow": "Yvqh9W_modeRow",
|
|
2063
|
-
"galleryCardFooter": "Yvqh9W_galleryCardFooter",
|
|
2064
|
-
"topNavDivider": "Yvqh9W_topNavDivider",
|
|
2065
|
-
"comparisonFullscreen": "Yvqh9W_comparisonFullscreen",
|
|
2066
|
-
"galleryRatio": "Yvqh9W_galleryRatio",
|
|
2067
|
-
"ecommercePlanMini": "Yvqh9W_ecommercePlanMini",
|
|
2068
|
-
"ecommerceResults": "Yvqh9W_ecommerceResults",
|
|
2069
|
-
"paramLabel": "Yvqh9W_paramLabel",
|
|
2070
|
-
"lightboxMeta": "Yvqh9W_lightboxMeta",
|
|
2071
|
-
"comparisonImageButton": "Yvqh9W_comparisonImageButton",
|
|
2072
|
-
"taskPrompt": "Yvqh9W_taskPrompt",
|
|
2073
|
-
"gallerySearch": "Yvqh9W_gallerySearch",
|
|
2074
|
-
"ecommerceActionChip": "Yvqh9W_ecommerceActionChip",
|
|
2075
|
-
"historyFilters": "Yvqh9W_historyFilters",
|
|
2076
|
-
"canvasBody": "Yvqh9W_canvasBody",
|
|
2077
2903
|
"lightboxNav": "Yvqh9W_lightboxNav",
|
|
2078
|
-
"
|
|
2079
|
-
"
|
|
2080
|
-
"
|
|
2081
|
-
"
|
|
2904
|
+
"galleryFilterNote": "Yvqh9W_galleryFilterNote",
|
|
2905
|
+
"comparisonBoard": "Yvqh9W_comparisonBoard",
|
|
2906
|
+
"galleryTagFilter": "Yvqh9W_galleryTagFilter",
|
|
2907
|
+
"historyMain": "Yvqh9W_historyMain",
|
|
2908
|
+
"galleryCount": "Yvqh9W_galleryCount",
|
|
2909
|
+
"lightboxActions": "Yvqh9W_lightboxActions",
|
|
2082
2910
|
"ecommerceParamGrid": "Yvqh9W_ecommerceParamGrid",
|
|
2083
|
-
"
|
|
2084
|
-
"
|
|
2085
|
-
"connectionDot": "Yvqh9W_connectionDot",
|
|
2086
|
-
"lightboxImage": "Yvqh9W_lightboxImage",
|
|
2087
|
-
"galleryClear": "Yvqh9W_galleryClear",
|
|
2088
|
-
"updateRelease": "Yvqh9W_updateRelease",
|
|
2089
|
-
"historyItem": "Yvqh9W_historyItem",
|
|
2090
|
-
"uploadIcon": "Yvqh9W_uploadIcon",
|
|
2091
|
-
"modelWrap": "Yvqh9W_modelWrap",
|
|
2092
|
-
"galleryToast": "Yvqh9W_galleryToast",
|
|
2093
|
-
"grid": "Yvqh9W_grid",
|
|
2094
|
-
"lightboxStage": "Yvqh9W_lightboxStage",
|
|
2095
|
-
"galleryImageButton": "Yvqh9W_galleryImageButton",
|
|
2096
|
-
"galleryRemove": "Yvqh9W_galleryRemove",
|
|
2911
|
+
"ecommercePlanBack": "Yvqh9W_ecommercePlanBack",
|
|
2912
|
+
"canvasBody": "Yvqh9W_canvasBody",
|
|
2097
2913
|
"galleryBadge": "Yvqh9W_galleryBadge",
|
|
2098
|
-
"
|
|
2099
|
-
"modePill": "Yvqh9W_modePill",
|
|
2100
|
-
"historySearch": "Yvqh9W_historySearch",
|
|
2101
|
-
"compareModelChoices": "Yvqh9W_compareModelChoices",
|
|
2102
|
-
"topNavItem": "Yvqh9W_topNavItem",
|
|
2103
|
-
"sessionTabIcon": "Yvqh9W_sessionTabIcon",
|
|
2104
|
-
"ecommercePlanNote": "Yvqh9W_ecommercePlanNote",
|
|
2105
|
-
"galleryCardAction": "Yvqh9W_galleryCardAction",
|
|
2106
|
-
"prompt": "Yvqh9W_prompt",
|
|
2107
|
-
"ecommerceSection": "Yvqh9W_ecommerceSection",
|
|
2108
|
-
"historyMain": "Yvqh9W_historyMain",
|
|
2109
|
-
"optionGrid": "Yvqh9W_optionGrid",
|
|
2110
|
-
"conversationToast": "Yvqh9W_conversationToast",
|
|
2111
|
-
"galleryCard": "Yvqh9W_galleryCard",
|
|
2112
|
-
"conversationAdd": "Yvqh9W_conversationAdd",
|
|
2113
|
-
"ecommerceSectionHint": "Yvqh9W_ecommerceSectionHint",
|
|
2114
|
-
"entryLabel": "Yvqh9W_entryLabel",
|
|
2115
|
-
"taskTrayCount": "Yvqh9W_taskTrayCount",
|
|
2116
|
-
"connectionStatus": "Yvqh9W_connectionStatus",
|
|
2117
|
-
"historyThumb": "Yvqh9W_historyThumb",
|
|
2118
|
-
"ecommerceRefRow": "Yvqh9W_ecommerceRefRow",
|
|
2119
|
-
"lightboxTool": "Yvqh9W_lightboxTool",
|
|
2120
|
-
"galleryToolbarActions": "Yvqh9W_galleryToolbarActions",
|
|
2121
|
-
"comparisonGrid": "Yvqh9W_comparisonGrid",
|
|
2122
|
-
"hiddenFile": "Yvqh9W_hiddenFile",
|
|
2914
|
+
"card": "Yvqh9W_card",
|
|
2123
2915
|
"canvasState": "Yvqh9W_canvasState",
|
|
2124
|
-
"
|
|
2125
|
-
"ecommerceTaskState": "Yvqh9W_ecommerceTaskState",
|
|
2126
|
-
"canvasStateTitle": "Yvqh9W_canvasStateTitle",
|
|
2127
|
-
"canvasStateHint": "Yvqh9W_canvasStateHint",
|
|
2128
|
-
"githubLink": "Yvqh9W_githubLink",
|
|
2129
|
-
"lightboxTools": "Yvqh9W_lightboxTools",
|
|
2130
|
-
"galleryTagFilter": "Yvqh9W_galleryTagFilter",
|
|
2131
|
-
"galleryFilterNote": "Yvqh9W_galleryFilterNote",
|
|
2132
|
-
"galleryImage": "Yvqh9W_galleryImage",
|
|
2133
|
-
"taskTrayHeader": "Yvqh9W_taskTrayHeader",
|
|
2134
|
-
"galleryCount": "Yvqh9W_galleryCount",
|
|
2135
|
-
"galleryCardActions": "Yvqh9W_galleryCardActions",
|
|
2916
|
+
"galleryFilterDivider": "Yvqh9W_galleryFilterDivider",
|
|
2136
2917
|
"historyActions": "Yvqh9W_historyActions",
|
|
2137
|
-
"
|
|
2138
|
-
"
|
|
2139
|
-
"
|
|
2140
|
-
"lightboxActions": "Yvqh9W_lightboxActions",
|
|
2918
|
+
"view": "Yvqh9W_view",
|
|
2919
|
+
"galleryImageButton": "Yvqh9W_galleryImageButton",
|
|
2920
|
+
"sessionTab": "Yvqh9W_sessionTab",
|
|
2141
2921
|
"history": "Yvqh9W_history",
|
|
2142
|
-
"
|
|
2143
|
-
"
|
|
2144
|
-
"
|
|
2145
|
-
"
|
|
2146
|
-
"
|
|
2147
|
-
"
|
|
2148
|
-
"
|
|
2149
|
-
"
|
|
2150
|
-
"
|
|
2922
|
+
"sessionTabIcon": "Yvqh9W_sessionTabIcon",
|
|
2923
|
+
"ecommerceFooterHint": "Yvqh9W_ecommerceFooterHint",
|
|
2924
|
+
"modeRow": "Yvqh9W_modeRow",
|
|
2925
|
+
"lightboxCopy": "Yvqh9W_lightboxCopy",
|
|
2926
|
+
"entryLabel": "Yvqh9W_entryLabel",
|
|
2927
|
+
"ecommercePlanWarn": "Yvqh9W_ecommercePlanWarn",
|
|
2928
|
+
"promptFooter": "Yvqh9W_promptFooter",
|
|
2929
|
+
"ecommerceResults": "Yvqh9W_ecommerceResults",
|
|
2930
|
+
"ecommerceResultsHeader": "Yvqh9W_ecommerceResultsHeader",
|
|
2931
|
+
"historyThumbPlaceholder": "Yvqh9W_historyThumbPlaceholder",
|
|
2932
|
+
"ecommercePlanMini": "Yvqh9W_ecommercePlanMini",
|
|
2933
|
+
"referenceImage": "Yvqh9W_referenceImage",
|
|
2151
2934
|
"templatesButton": "Yvqh9W_templatesButton",
|
|
2935
|
+
"uploadIcon": "Yvqh9W_uploadIcon",
|
|
2936
|
+
"ecommerceGroup": "Yvqh9W_ecommerceGroup",
|
|
2937
|
+
"modelMenu": "Yvqh9W_modelMenu",
|
|
2938
|
+
"canvasMeta": "Yvqh9W_canvasMeta",
|
|
2939
|
+
"bigSpinner": "Yvqh9W_bigSpinner",
|
|
2940
|
+
"image": "Yvqh9W_image",
|
|
2941
|
+
"dshImageGenSpin": "Yvqh9W_dshImageGenSpin",
|
|
2942
|
+
"sessionTabLabel": "Yvqh9W_sessionTabLabel",
|
|
2943
|
+
"chatToggle": "Yvqh9W_chatToggle",
|
|
2944
|
+
"modePill": "Yvqh9W_modePill",
|
|
2945
|
+
"lightboxScaleFrame": "Yvqh9W_lightboxScaleFrame",
|
|
2946
|
+
"lightboxCaptionRow": "Yvqh9W_lightboxCaptionRow",
|
|
2947
|
+
"galleryMasonry": "Yvqh9W_galleryMasonry",
|
|
2948
|
+
"ecommerceWorkspace": "Yvqh9W_ecommerceWorkspace",
|
|
2949
|
+
"ecommerceTaskActions": "Yvqh9W_ecommerceTaskActions",
|
|
2950
|
+
"lightboxImage": "Yvqh9W_lightboxImage",
|
|
2951
|
+
"ecommerceGroups": "Yvqh9W_ecommerceGroups",
|
|
2952
|
+
"ecommerceActionChip": "Yvqh9W_ecommerceActionChip",
|
|
2953
|
+
"ecommerceAdvancedChevron": "Yvqh9W_ecommerceAdvancedChevron",
|
|
2954
|
+
"sidebarHistoryHost": "Yvqh9W_sidebarHistoryHost",
|
|
2955
|
+
"taskRows": "Yvqh9W_taskRows",
|
|
2956
|
+
"taskTray": "Yvqh9W_taskTray",
|
|
2957
|
+
"ecommerceResultsActions": "Yvqh9W_ecommerceResultsActions",
|
|
2958
|
+
"paramLabel": "Yvqh9W_paramLabel",
|
|
2959
|
+
"galleryFilters": "Yvqh9W_galleryFilters",
|
|
2960
|
+
"chatResizer": "Yvqh9W_chatResizer",
|
|
2961
|
+
"galleryClear": "Yvqh9W_galleryClear",
|
|
2962
|
+
"config": "Yvqh9W_config",
|
|
2963
|
+
"taskTrayHeader": "Yvqh9W_taskTrayHeader",
|
|
2964
|
+
"ecommerceFieldLabel": "Yvqh9W_ecommerceFieldLabel",
|
|
2965
|
+
"historyNew": "Yvqh9W_historyNew",
|
|
2966
|
+
"ecommerceGroupGrid": "Yvqh9W_ecommerceGroupGrid",
|
|
2967
|
+
"modelMenuList": "Yvqh9W_modelMenuList",
|
|
2968
|
+
"ecommercePlanList": "Yvqh9W_ecommercePlanList",
|
|
2969
|
+
"generateButton": "Yvqh9W_generateButton",
|
|
2970
|
+
"canvasStateHint": "Yvqh9W_canvasStateHint",
|
|
2971
|
+
"lightboxTool": "Yvqh9W_lightboxTool",
|
|
2972
|
+
"ecommerceFooterBody": "Yvqh9W_ecommerceFooterBody",
|
|
2973
|
+
"footer": "Yvqh9W_footer",
|
|
2974
|
+
"conversationToast": "Yvqh9W_conversationToast",
|
|
2975
|
+
"galleryViewToggle": "Yvqh9W_galleryViewToggle",
|
|
2976
|
+
"compareToggle": "Yvqh9W_compareToggle",
|
|
2152
2977
|
"paramHint": "Yvqh9W_paramHint",
|
|
2153
|
-
"
|
|
2154
|
-
"
|
|
2155
|
-
"
|
|
2156
|
-
"canvasEmptyIcon": "Yvqh9W_canvasEmptyIcon",
|
|
2157
|
-
"lightboxZoomLevel": "Yvqh9W_lightboxZoomLevel",
|
|
2158
|
-
"comparisonFullscreenGrid": "Yvqh9W_comparisonFullscreenGrid",
|
|
2159
|
-
"gallerySelectionBar": "Yvqh9W_gallerySelectionBar",
|
|
2160
|
-
"canvas": "Yvqh9W_canvas",
|
|
2161
|
-
"galleryMasonry": "Yvqh9W_galleryMasonry",
|
|
2162
|
-
"taskRow": "Yvqh9W_taskRow",
|
|
2163
|
-
"image": "Yvqh9W_image",
|
|
2164
|
-
"uploadBox": "Yvqh9W_uploadBox",
|
|
2165
|
-
"panelHeader": "Yvqh9W_panelHeader",
|
|
2166
|
-
"panelTitle": "Yvqh9W_panelTitle",
|
|
2978
|
+
"galleryTagFilterList": "Yvqh9W_galleryTagFilterList",
|
|
2979
|
+
"lightboxFigure": "Yvqh9W_lightboxFigure",
|
|
2980
|
+
"galleryCardFooter": "Yvqh9W_galleryCardFooter",
|
|
2167
2981
|
"historyAction": "Yvqh9W_historyAction",
|
|
2168
|
-
"
|
|
2169
|
-
"
|
|
2982
|
+
"galleryAvatar": "Yvqh9W_galleryAvatar",
|
|
2983
|
+
"galleryTags": "Yvqh9W_galleryTags",
|
|
2984
|
+
"sessionTabs": "Yvqh9W_sessionTabs",
|
|
2985
|
+
"lightboxClose": "Yvqh9W_lightboxClose",
|
|
2986
|
+
"ecommerceResultsEmpty": "Yvqh9W_ecommerceResultsEmpty",
|
|
2987
|
+
"ecommerceTaskCard": "Yvqh9W_ecommerceTaskCard",
|
|
2988
|
+
"topNav": "Yvqh9W_topNav",
|
|
2989
|
+
"optionRow": "Yvqh9W_optionRow",
|
|
2990
|
+
"updateActions": "Yvqh9W_updateActions",
|
|
2991
|
+
"studio": "Yvqh9W_studio",
|
|
2992
|
+
"updateRelease": "Yvqh9W_updateRelease",
|
|
2170
2993
|
"generation": "Yvqh9W_generation",
|
|
2171
|
-
"
|
|
2172
|
-
"
|
|
2173
|
-
"
|
|
2174
|
-
"
|
|
2175
|
-
"
|
|
2994
|
+
"canvasStateTitle": "Yvqh9W_canvasStateTitle",
|
|
2995
|
+
"taskTrayToggle": "Yvqh9W_taskTrayToggle",
|
|
2996
|
+
"ecommerceTaskState": "Yvqh9W_ecommerceTaskState",
|
|
2997
|
+
"ecommerceUploadHero": "Yvqh9W_ecommerceUploadHero",
|
|
2998
|
+
"compareControl": "Yvqh9W_compareControl",
|
|
2999
|
+
"galleryCardInfo": "Yvqh9W_galleryCardInfo",
|
|
3000
|
+
"taskTrayCount": "Yvqh9W_taskTrayCount",
|
|
3001
|
+
"taskPrompt": "Yvqh9W_taskPrompt",
|
|
3002
|
+
"prompt": "Yvqh9W_prompt",
|
|
3003
|
+
"conversationAdd": "Yvqh9W_conversationAdd",
|
|
3004
|
+
"spinner": "Yvqh9W_spinner",
|
|
3005
|
+
"hiddenFile": "Yvqh9W_hiddenFile",
|
|
3006
|
+
"ecommerceSection": "Yvqh9W_ecommerceSection",
|
|
3007
|
+
"taskStatus": "Yvqh9W_taskStatus",
|
|
3008
|
+
"lightboxEdit": "Yvqh9W_lightboxEdit",
|
|
3009
|
+
"canvasHistoryTag": "Yvqh9W_canvasHistoryTag",
|
|
3010
|
+
"ecommerceAssets": "Yvqh9W_ecommerceAssets",
|
|
3011
|
+
"historyItem": "Yvqh9W_historyItem",
|
|
3012
|
+
"entry": "Yvqh9W_entry",
|
|
3013
|
+
"galleryToolbar": "Yvqh9W_galleryToolbar",
|
|
3014
|
+
"canvasError": "Yvqh9W_canvasError",
|
|
3015
|
+
"dshImageGenToastIn": "Yvqh9W_dshImageGenToastIn"
|
|
2176
3016
|
};
|
|
2177
3017
|
//#endregion
|
|
2178
3018
|
//#region src/client/ImageGenPanel.tsx
|
|
@@ -2606,6 +3446,7 @@ window.__ModuleLoader__.load({
|
|
|
2606
3446
|
function ImageGenPanel(props) {
|
|
2607
3447
|
const { api, scope, sessions, conversation } = props;
|
|
2608
3448
|
const config = useConfig(scope);
|
|
3449
|
+
useImageGenLanguageTick();
|
|
2609
3450
|
const enabled = config?.enabled ?? true;
|
|
2610
3451
|
const modelOptions = imageModelOptions(config);
|
|
2611
3452
|
const imageModels = (config?.channels ?? []).length > 0 ? modelOptions.models : normalizeImageModels(config?.imageModels);
|
|
@@ -5312,47 +6153,12 @@ window.__ModuleLoader__.load({
|
|
|
5312
6153
|
role: "alert",
|
|
5313
6154
|
children: tt("canvas.error", { error })
|
|
5314
6155
|
}) : null,
|
|
5315
|
-
!generating && !error && images.length === 0 && workspace !== "ecommerce" ? /* @__PURE__ */ (0, react_jsx_runtime.
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
viewBox: "0 0 24 24",
|
|
5322
|
-
width: "34",
|
|
5323
|
-
height: "34",
|
|
5324
|
-
fill: "none",
|
|
5325
|
-
stroke: "currentColor",
|
|
5326
|
-
strokeWidth: "1.2",
|
|
5327
|
-
strokeLinecap: "round",
|
|
5328
|
-
strokeLinejoin: "round",
|
|
5329
|
-
"aria-hidden": "true",
|
|
5330
|
-
children: [
|
|
5331
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
|
|
5332
|
-
x: "3",
|
|
5333
|
-
y: "3",
|
|
5334
|
-
width: "18",
|
|
5335
|
-
height: "18",
|
|
5336
|
-
rx: "3"
|
|
5337
|
-
}),
|
|
5338
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
|
|
5339
|
-
cx: "8.5",
|
|
5340
|
-
cy: "8.5",
|
|
5341
|
-
r: "1.5"
|
|
5342
|
-
}),
|
|
5343
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M21 15l-5-5L5 21" })
|
|
5344
|
-
]
|
|
5345
|
-
})
|
|
5346
|
-
}),
|
|
5347
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5348
|
-
className: panel_module_css_default.canvasStateTitle,
|
|
5349
|
-
children: tt("canvas.emptyTitle")
|
|
5350
|
-
}),
|
|
5351
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5352
|
-
className: panel_module_css_default.canvasStateHint,
|
|
5353
|
-
children: tt("canvas.emptyHint")
|
|
5354
|
-
})
|
|
5355
|
-
]
|
|
6156
|
+
!generating && !error && images.length === 0 && workspace !== "ecommerce" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InspirationGallery, {
|
|
6157
|
+
api,
|
|
6158
|
+
onUse: (text) => {
|
|
6159
|
+
setPrompt(text);
|
|
6160
|
+
setError(null);
|
|
6161
|
+
}
|
|
5356
6162
|
}) : null,
|
|
5357
6163
|
!generating && images.length > 0 && workspace !== "ecommerce" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5358
6164
|
className: panel_module_css_default.canvasBody,
|
|
@@ -6653,97 +7459,97 @@ window.__ModuleLoader__.load({
|
|
|
6653
7459
|
document.head.appendChild(tag);
|
|
6654
7460
|
}
|
|
6655
7461
|
var settings_card_module_css_default = {
|
|
7462
|
+
"channelAction": "i1cc5G_channelAction",
|
|
7463
|
+
"channelHost": "i1cc5G_channelHost",
|
|
7464
|
+
"presetMeta": "i1cc5G_presetMeta",
|
|
7465
|
+
"disclosure": "i1cc5G_disclosure",
|
|
7466
|
+
"modelFetchRow": "i1cc5G_modelFetchRow",
|
|
7467
|
+
"sectionHint": "i1cc5G_sectionHint",
|
|
7468
|
+
"footer": "i1cc5G_footer",
|
|
7469
|
+
"presetRow": "i1cc5G_presetRow",
|
|
7470
|
+
"editorSectionHeader": "i1cc5G_editorSectionHeader",
|
|
7471
|
+
"modelArrow": "i1cc5G_modelArrow",
|
|
7472
|
+
"inlineDisclosure": "i1cc5G_inlineDisclosure",
|
|
7473
|
+
"presetInlineHeader": "i1cc5G_presetInlineHeader",
|
|
7474
|
+
"reset": "i1cc5G_reset",
|
|
7475
|
+
"channelDanger": "i1cc5G_channelDanger",
|
|
7476
|
+
"modelSection": "i1cc5G_modelSection",
|
|
7477
|
+
"channelMeta": "i1cc5G_channelMeta",
|
|
7478
|
+
"editorBackdrop": "i1cc5G_editorBackdrop",
|
|
7479
|
+
"modelRowBadges": "i1cc5G_modelRowBadges",
|
|
7480
|
+
"modelRow": "i1cc5G_modelRow",
|
|
7481
|
+
"chevron": "i1cc5G_chevron",
|
|
7482
|
+
"body": "i1cc5G_body",
|
|
7483
|
+
"versionRow": "i1cc5G_versionRow",
|
|
7484
|
+
"sectionTitle": "i1cc5G_sectionTitle",
|
|
7485
|
+
"inputInvalid": "i1cc5G_inputInvalid",
|
|
6656
7486
|
"textareaInvalid": "i1cc5G_textareaInvalid",
|
|
6657
|
-
"
|
|
6658
|
-
"
|
|
7487
|
+
"failed": "i1cc5G_failed",
|
|
7488
|
+
"modelChip": "i1cc5G_modelChip",
|
|
7489
|
+
"select": "i1cc5G_select",
|
|
6659
7490
|
"channelName": "i1cc5G_channelName",
|
|
6660
7491
|
"channelAdd": "i1cc5G_channelAdd",
|
|
6661
|
-
"
|
|
6662
|
-
"
|
|
6663
|
-
"
|
|
6664
|
-
"
|
|
6665
|
-
"
|
|
6666
|
-
"
|
|
6667
|
-
"inputInvalid": "i1cc5G_inputInvalid",
|
|
6668
|
-
"channelDotWarn": "i1cc5G_channelDotWarn",
|
|
7492
|
+
"spacer": "i1cc5G_spacer",
|
|
7493
|
+
"card": "i1cc5G_card",
|
|
7494
|
+
"channelEmpty": "i1cc5G_channelEmpty",
|
|
7495
|
+
"modelRows": "i1cc5G_modelRows",
|
|
7496
|
+
"presetList": "i1cc5G_presetList",
|
|
7497
|
+
"editorField": "i1cc5G_editorField",
|
|
6669
7498
|
"presetName": "i1cc5G_presetName",
|
|
6670
|
-
"presetHint": "i1cc5G_presetHint",
|
|
6671
|
-
"modelRow": "i1cc5G_modelRow",
|
|
6672
|
-
"select": "i1cc5G_select",
|
|
6673
|
-
"input": "i1cc5G_input",
|
|
6674
7499
|
"badges": "i1cc5G_badges",
|
|
6675
|
-
"
|
|
7500
|
+
"notExposed": "i1cc5G_notExposed",
|
|
7501
|
+
"sectionHeader": "i1cc5G_sectionHeader",
|
|
7502
|
+
"modelChoices": "i1cc5G_modelChoices",
|
|
7503
|
+
"modelCandidateLabel": "i1cc5G_modelCandidateLabel",
|
|
7504
|
+
"discard": "i1cc5G_discard",
|
|
7505
|
+
"textarea": "i1cc5G_textarea",
|
|
7506
|
+
"versionLabel": "i1cc5G_versionLabel",
|
|
7507
|
+
"header": "i1cc5G_header",
|
|
7508
|
+
"editorFooter": "i1cc5G_editorFooter",
|
|
7509
|
+
"deleteConfirmText": "i1cc5G_deleteConfirmText",
|
|
7510
|
+
"label": "i1cc5G_label",
|
|
7511
|
+
"input": "i1cc5G_input",
|
|
7512
|
+
"modelSummary": "i1cc5G_modelSummary",
|
|
7513
|
+
"channelAddRow": "i1cc5G_channelAddRow",
|
|
7514
|
+
"modelFetch": "i1cc5G_modelFetch",
|
|
6676
7515
|
"editorTools": "i1cc5G_editorTools",
|
|
6677
|
-
"channelMeta": "i1cc5G_channelMeta",
|
|
6678
7516
|
"modelRowRemove": "i1cc5G_modelRowRemove",
|
|
6679
|
-
"
|
|
6680
|
-
"
|
|
6681
|
-
"
|
|
6682
|
-
"sectionHeader": "i1cc5G_sectionHeader",
|
|
6683
|
-
"editorField": "i1cc5G_editorField",
|
|
6684
|
-
"editorSectionHeader": "i1cc5G_editorSectionHeader",
|
|
7517
|
+
"head": "i1cc5G_head",
|
|
7518
|
+
"hint": "i1cc5G_hint",
|
|
7519
|
+
"detectOk": "i1cc5G_detectOk",
|
|
6685
7520
|
"editorHeader": "i1cc5G_editorHeader",
|
|
7521
|
+
"chevronOpen": "i1cc5G_chevronOpen",
|
|
7522
|
+
"channelSection": "i1cc5G_channelSection",
|
|
7523
|
+
"invalid": "i1cc5G_invalid",
|
|
7524
|
+
"channelBadge": "i1cc5G_channelBadge",
|
|
6686
7525
|
"editorClose": "i1cc5G_editorClose",
|
|
6687
|
-
"modelFetchRow": "i1cc5G_modelFetchRow",
|
|
6688
|
-
"failed": "i1cc5G_failed",
|
|
6689
|
-
"editorDivider": "i1cc5G_editorDivider",
|
|
6690
|
-
"discard": "i1cc5G_discard",
|
|
6691
|
-
"name": "i1cc5G_name",
|
|
6692
|
-
"channelAddRow": "i1cc5G_channelAddRow",
|
|
6693
|
-
"editorBackdrop": "i1cc5G_editorBackdrop",
|
|
6694
|
-
"channelDotReady": "i1cc5G_channelDotReady",
|
|
6695
7526
|
"headText": "i1cc5G_headText",
|
|
6696
|
-
"
|
|
7527
|
+
"channelList": "i1cc5G_channelList",
|
|
7528
|
+
"pending": "i1cc5G_pending",
|
|
7529
|
+
"channelDotWarn": "i1cc5G_channelDotWarn",
|
|
7530
|
+
"manualModelRow": "i1cc5G_manualModelRow",
|
|
7531
|
+
"presetHint": "i1cc5G_presetHint",
|
|
7532
|
+
"channelMain": "i1cc5G_channelMain",
|
|
6697
7533
|
"editorPanel": "i1cc5G_editorPanel",
|
|
6698
|
-
"presetList": "i1cc5G_presetList",
|
|
6699
|
-
"modelCandidate": "i1cc5G_modelCandidate",
|
|
6700
|
-
"optionalContent": "i1cc5G_optionalContent",
|
|
6701
|
-
"modelRows": "i1cc5G_modelRows",
|
|
6702
|
-
"modelRowInputs": "i1cc5G_modelRowInputs",
|
|
6703
7534
|
"addModel": "i1cc5G_addModel",
|
|
6704
|
-
"
|
|
6705
|
-
"
|
|
6706
|
-
"
|
|
6707
|
-
"
|
|
6708
|
-
"
|
|
7535
|
+
"channelControls": "i1cc5G_channelControls",
|
|
7536
|
+
"versionValue": "i1cc5G_versionValue",
|
|
7537
|
+
"badge": "i1cc5G_badge",
|
|
7538
|
+
"channelDotReady": "i1cc5G_channelDotReady",
|
|
7539
|
+
"editorDivider": "i1cc5G_editorDivider",
|
|
7540
|
+
"modelBadge": "i1cc5G_modelBadge",
|
|
7541
|
+
"save": "i1cc5G_save",
|
|
7542
|
+
"description": "i1cc5G_description",
|
|
6709
7543
|
"field": "i1cc5G_field",
|
|
6710
|
-
"
|
|
6711
|
-
"versionLabel": "i1cc5G_versionLabel",
|
|
6712
|
-
"body": "i1cc5G_body",
|
|
6713
|
-
"manualModelRow": "i1cc5G_manualModelRow",
|
|
6714
|
-
"pending": "i1cc5G_pending",
|
|
6715
|
-
"notExposed": "i1cc5G_notExposed",
|
|
6716
|
-
"modelCandidateList": "i1cc5G_modelCandidateList",
|
|
6717
|
-
"modelArrow": "i1cc5G_modelArrow",
|
|
6718
|
-
"chevron": "i1cc5G_chevron",
|
|
6719
|
-
"modelChoices": "i1cc5G_modelChoices",
|
|
6720
|
-
"head": "i1cc5G_head",
|
|
6721
|
-
"inlineDisclosure": "i1cc5G_inlineDisclosure",
|
|
6722
|
-
"disclosure": "i1cc5G_disclosure",
|
|
7544
|
+
"name": "i1cc5G_name",
|
|
6723
7545
|
"channelRow": "i1cc5G_channelRow",
|
|
6724
|
-
"
|
|
6725
|
-
"description": "i1cc5G_description",
|
|
6726
|
-
"modelFetch": "i1cc5G_modelFetch",
|
|
6727
|
-
"channelMain": "i1cc5G_channelMain",
|
|
6728
|
-
"header": "i1cc5G_header",
|
|
6729
|
-
"modelSummary": "i1cc5G_modelSummary",
|
|
6730
|
-
"versionRow": "i1cc5G_versionRow",
|
|
6731
|
-
"channelAction": "i1cc5G_channelAction",
|
|
7546
|
+
"optionalContent": "i1cc5G_optionalContent",
|
|
6732
7547
|
"sectionDivider": "i1cc5G_sectionDivider",
|
|
6733
|
-
"
|
|
6734
|
-
"presetInlineHeader": "i1cc5G_presetInlineHeader",
|
|
7548
|
+
"modelRowInputs": "i1cc5G_modelRowInputs",
|
|
6735
7549
|
"presetInline": "i1cc5G_presetInline",
|
|
6736
|
-
"
|
|
6737
|
-
"
|
|
6738
|
-
"
|
|
6739
|
-
"spacer": "i1cc5G_spacer",
|
|
6740
|
-
"editorFooter": "i1cc5G_editorFooter",
|
|
6741
|
-
"reset": "i1cc5G_reset",
|
|
6742
|
-
"channelEmpty": "i1cc5G_channelEmpty",
|
|
6743
|
-
"invalid": "i1cc5G_invalid",
|
|
6744
|
-
"modelSection": "i1cc5G_modelSection",
|
|
6745
|
-
"footer": "i1cc5G_footer",
|
|
6746
|
-
"sectionHint": "i1cc5G_sectionHint"
|
|
7550
|
+
"modelCandidateList": "i1cc5G_modelCandidateList",
|
|
7551
|
+
"readOnly": "i1cc5G_readOnly",
|
|
7552
|
+
"modelCandidate": "i1cc5G_modelCandidate"
|
|
6747
7553
|
};
|
|
6748
7554
|
//#endregion
|
|
6749
7555
|
//#region src/client/SettingsCard.tsx
|
|
@@ -6814,7 +7620,8 @@ window.__ModuleLoader__.load({
|
|
|
6814
7620
|
* @returns the card, or nothing while the namespace is still loading.
|
|
6815
7621
|
*/
|
|
6816
7622
|
function ImageGenSettingsCard(props) {
|
|
6817
|
-
const
|
|
7623
|
+
const t = tt;
|
|
7624
|
+
useImageGenLanguageTick();
|
|
6818
7625
|
const state = props.useImageGenSettingsCard((snapshot) => snapshot);
|
|
6819
7626
|
const [open, setOpen] = (0, react.useState)(false);
|
|
6820
7627
|
const [promptModels, setPromptModels] = (0, react.useState)([]);
|
|
@@ -7316,10 +8123,10 @@ window.__ModuleLoader__.load({
|
|
|
7316
8123
|
...fieldProps,
|
|
7317
8124
|
...state.allowAgentImageGeneration,
|
|
7318
8125
|
onEdit: (text) => {
|
|
7319
|
-
props.edit("
|
|
8126
|
+
props.edit("enabled", text);
|
|
7320
8127
|
},
|
|
7321
8128
|
onReset: () => {
|
|
7322
|
-
props.resetField("
|
|
8129
|
+
props.resetField("enabled");
|
|
7323
8130
|
}
|
|
7324
8131
|
})
|
|
7325
8132
|
]
|
|
@@ -8006,16 +8813,16 @@ window.__ModuleLoader__.load({
|
|
|
8006
8813
|
document.head.appendChild(tag);
|
|
8007
8814
|
}
|
|
8008
8815
|
var image_toolview_module_css_default = {
|
|
8009
|
-
"imageLink": "_3eGrYG_imageLink",
|
|
8010
|
-
"error": "_3eGrYG_error",
|
|
8011
8816
|
"root": "_3eGrYG_root",
|
|
8012
|
-
"
|
|
8817
|
+
"status": "_3eGrYG_status",
|
|
8818
|
+
"error": "_3eGrYG_error",
|
|
8013
8819
|
"images": "_3eGrYG_images",
|
|
8014
|
-
"
|
|
8820
|
+
"imageLink": "_3eGrYG_imageLink",
|
|
8821
|
+
"message": "_3eGrYG_message",
|
|
8015
8822
|
"image": "_3eGrYG_image",
|
|
8016
|
-
"
|
|
8823
|
+
"header": "_3eGrYG_header",
|
|
8017
8824
|
"icon": "_3eGrYG_icon",
|
|
8018
|
-
"
|
|
8825
|
+
"loading": "_3eGrYG_loading"
|
|
8019
8826
|
};
|
|
8020
8827
|
//#endregion
|
|
8021
8828
|
//#region src/client/image-toolview.tsx
|
|
@@ -8206,6 +9013,34 @@ window.__ModuleLoader__.load({
|
|
|
8206
9013
|
zh,
|
|
8207
9014
|
en
|
|
8208
9015
|
}), "dsh-imagegen: dictionaries");
|
|
9016
|
+
ctx.effect(() => {
|
|
9017
|
+
try {
|
|
9018
|
+
return ctx.locale.register(NS, "ru", ru);
|
|
9019
|
+
} catch (error) {
|
|
9020
|
+
console.warn("[dsh-imagegen] ru dictionary not registered:", error);
|
|
9021
|
+
return () => {};
|
|
9022
|
+
}
|
|
9023
|
+
}, "dsh-imagegen: ru dictionary");
|
|
9024
|
+
ctx.effect(() => {
|
|
9025
|
+
try {
|
|
9026
|
+
if (ctx.locale.getLocale().locales.some((locale) => locale.id === "ru")) return () => {};
|
|
9027
|
+
return ctx.locale.addLanguage({
|
|
9028
|
+
id: "ru",
|
|
9029
|
+
label: "Русский",
|
|
9030
|
+
fallback: "en"
|
|
9031
|
+
});
|
|
9032
|
+
} catch (error) {
|
|
9033
|
+
console.warn("[dsh-imagegen] ru language not added to the catalog:", error);
|
|
9034
|
+
return () => {};
|
|
9035
|
+
}
|
|
9036
|
+
}, "dsh-imagegen: ru language pack");
|
|
9037
|
+
ctx.effect(() => {
|
|
9038
|
+
const applyLocale = () => {
|
|
9039
|
+
applyHostLocale(ctx.locale.getLocale().active);
|
|
9040
|
+
};
|
|
9041
|
+
applyLocale();
|
|
9042
|
+
return ctx.locale.subscribe(applyLocale);
|
|
9043
|
+
}, "dsh-imagegen: follow host locale");
|
|
8209
9044
|
registerImageToolviews(ctx);
|
|
8210
9045
|
const scope = bindImageGenScope(ctx.get("connection")?.isLoopback === true ? (input, init) => fetch(input, init) : () => {
|
|
8211
9046
|
throw new Error("settings bridge is loopback-only");
|
|
@@ -8239,6 +9074,28 @@ window.__ModuleLoader__.load({
|
|
|
8239
9074
|
sessions,
|
|
8240
9075
|
conversation
|
|
8241
9076
|
}));
|
|
9077
|
+
disposers.push(ctx.locale.subscribe(() => {
|
|
9078
|
+
const root = document.querySelector("[data-dsh-imagegen-sidebar-root]");
|
|
9079
|
+
if (root === null) return;
|
|
9080
|
+
const labels = [[
|
|
9081
|
+
"new-session",
|
|
9082
|
+
tt("entry.newSession"),
|
|
9083
|
+
tt("entry.newSessionTooltip")
|
|
9084
|
+
], [
|
|
9085
|
+
"image",
|
|
9086
|
+
tt("entry.image"),
|
|
9087
|
+
tt("entry.tooltip")
|
|
9088
|
+
]];
|
|
9089
|
+
for (const [tab, label, tooltip] of labels) {
|
|
9090
|
+
const button = root.querySelector(`[data-dsh-imagegen-tab="${tab}"]`);
|
|
9091
|
+
if (button === null) continue;
|
|
9092
|
+
button.setAttribute("aria-label", label);
|
|
9093
|
+
button.setAttribute("title", tooltip);
|
|
9094
|
+
const labelSpan = button.querySelector("span:nth-child(2)");
|
|
9095
|
+
if (labelSpan !== null) labelSpan.textContent = label;
|
|
9096
|
+
}
|
|
9097
|
+
root.querySelector("[role=\"tablist\"][data-dsh-imagegen-session-tabs]")?.setAttribute("aria-label", tt("entry.tooltip"));
|
|
9098
|
+
}));
|
|
8242
9099
|
} catch (error) {
|
|
8243
9100
|
console.warn("[dsh-imagegen] mount failed:", error);
|
|
8244
9101
|
}
|