dsh-codex-subscription 2.5.6 → 2.5.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +8 -2
- package/README.md +8 -2
- package/lib/client.js +639 -203
- package/lib/index.js +42 -11
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
**Use your ChatGPT / Codex subscription directly in DeepSeek Harness**
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Sign in with ChatGPT Plus / Pro to use GPT-6 and other Codex models, quota, web search, and image generation inside DSH. No OpenAI API key or Codex CLI.
|
|
12
12
|
|
|
13
13
|
[](https://github.com/WSL043/dsh-codex-subscription/actions/workflows/ci.yml)
|
|
14
14
|
[](https://www.npmjs.com/package/dsh-codex-subscription)
|
|
@@ -106,7 +106,7 @@ This plugin supports the latest DeepSeek Harness release recorded in its package
|
|
|
106
106
|
2. Paste this package name, with its version, into the **Package name or address** field:
|
|
107
107
|
|
|
108
108
|
```text
|
|
109
|
-
dsh-codex-subscription@2.5.
|
|
109
|
+
dsh-codex-subscription@2.5.8
|
|
110
110
|
```
|
|
111
111
|
|
|
112
112
|
3. Click **Install** and wait for completion. Follow the page instructions; save your work before restarting if requested.
|
|
@@ -139,6 +139,12 @@ dsh --profile headless "Reply with only the word: ok"
|
|
|
139
139
|
|
|
140
140
|
## Inside the plugin
|
|
141
141
|
|
|
142
|
+
<details>
|
|
143
|
+
<summary><b>Interface demo (animation, click to expand)</b>: models, prompts, images, annotation, sketch board, quota and resets</summary>
|
|
144
|
+
<br>
|
|
145
|
+
<p align="center"><img src="docs/assets/readme-demo-en.webp" width="1100" alt="Demo: sign in with ChatGPT, pick a subscription model, ask, generate an image, view and annotate it, continue on the sketch board, and check quota and resets"></p>
|
|
146
|
+
</details>
|
|
147
|
+
|
|
142
148
|
### Everyday controls, right in the composer
|
|
143
149
|
|
|
144
150
|
Choose a model, adjust reasoning, switch speed tiers, and check remaining quota without opening settings for every request.
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
**把 ChatGPT / Codex 订阅直接接入 DeepSeek Harness**
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
用 ChatGPT Plus / Pro 订阅登录,即可在 DSH 中使用 GPT-6 等 Codex 模型、查额度、联网搜索和生图。无需 OpenAI API Key,也不依赖 Codex CLI。
|
|
12
12
|
|
|
13
13
|
[](https://github.com/WSL043/dsh-codex-subscription/actions/workflows/ci.yml)
|
|
14
14
|
[](https://www.npmjs.com/package/dsh-codex-subscription)
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
2. 在 **包名或地址** 输入框中粘贴下面的包名(已带版本号):
|
|
107
107
|
|
|
108
108
|
```text
|
|
109
|
-
dsh-codex-subscription@2.5.
|
|
109
|
+
dsh-codex-subscription@2.5.8
|
|
110
110
|
```
|
|
111
111
|
|
|
112
112
|
3. 点击 **安装**,等待安装完成;按页面提示操作,需要重启时先保存工作。
|
|
@@ -139,6 +139,12 @@ dsh --profile headless "只回复:ok"
|
|
|
139
139
|
|
|
140
140
|
## 界面一览
|
|
141
141
|
|
|
142
|
+
<details>
|
|
143
|
+
<summary><b>界面演示(动图,点击展开)</b>:选模型、提问、出图、标注、草图、额度与重置</summary>
|
|
144
|
+
<br>
|
|
145
|
+
<p align="center"><img src="docs/assets/readme-demo.webp" width="1100" alt="演示:登录 ChatGPT 选订阅模型、提问、用订阅出图、查看与标注、进入草图、查看额度与重置"></p>
|
|
146
|
+
</details>
|
|
147
|
+
|
|
142
148
|
### 日常操作,留在输入框
|
|
143
149
|
|
|
144
150
|
选模型、调推理档位、切换速度档位,同时查看剩余额度。无需为每次请求打开设置。
|
package/lib/client.js
CHANGED
|
@@ -587,6 +587,88 @@ window.__ModuleLoader__.load({
|
|
|
587
587
|
].join("\n");
|
|
588
588
|
}
|
|
589
589
|
//#endregion
|
|
590
|
+
//#region src/image-official-tools.js
|
|
591
|
+
const IMAGE_ASPECT_RATIOS = Object.freeze([
|
|
592
|
+
["square", "1:1"],
|
|
593
|
+
["portrait", "3:4"],
|
|
594
|
+
["story", "9:16"],
|
|
595
|
+
["landscape", "4:3"],
|
|
596
|
+
["widescreen", "16:9"]
|
|
597
|
+
]);
|
|
598
|
+
/**
|
|
599
|
+
* Build viewer actions for one image.
|
|
600
|
+
* @param {{ src: string, name: string, t: (key: string) => string,
|
|
601
|
+
* attachForEdit: (src: string, name: string, draft: string, annotations?: unknown[], referenceName?: string, sourceInDraft?: boolean, extraFiles?: File[]) => Promise<unknown>,
|
|
602
|
+
* sourceInDraft?: boolean }} options
|
|
603
|
+
*/
|
|
604
|
+
function officialImageTools({ src, name, t, attachForEdit, sourceInDraft = false }) {
|
|
605
|
+
const send = (draft, extraFiles = []) => attachForEdit(src, name, draft, [], void 0, sourceInDraft, extraFiles);
|
|
606
|
+
const base = {
|
|
607
|
+
pendingLabel: t("imageEditPreparing"),
|
|
608
|
+
errorLabel: t("imageEditFailed"),
|
|
609
|
+
closeOnSuccess: true
|
|
610
|
+
};
|
|
611
|
+
return [
|
|
612
|
+
{
|
|
613
|
+
...base,
|
|
614
|
+
id: "remove-background",
|
|
615
|
+
kind: "tool",
|
|
616
|
+
label: t("imageRemoveBackground"),
|
|
617
|
+
onInvoke: () => send(t("imageRemoveBackgroundPrompt"))
|
|
618
|
+
},
|
|
619
|
+
{
|
|
620
|
+
...base,
|
|
621
|
+
id: "erase",
|
|
622
|
+
kind: "mask",
|
|
623
|
+
label: t("imageErase"),
|
|
624
|
+
onInvoke: async ({ mask }) => {
|
|
625
|
+
if (!(mask instanceof Blob)) throw new Error("Mark the area to erase first");
|
|
626
|
+
const maskName = `${String(name).replace(/\.[a-z0-9]+$/iu, "")}-erase-mask.png`;
|
|
627
|
+
return send(t("imageErasePrompt"), [new File([mask], maskName, { type: "image/png" })]);
|
|
628
|
+
}
|
|
629
|
+
},
|
|
630
|
+
{
|
|
631
|
+
...base,
|
|
632
|
+
id: "resize",
|
|
633
|
+
kind: "choice",
|
|
634
|
+
label: t("imageResize"),
|
|
635
|
+
options: IMAGE_ASPECT_RATIOS.map(([id, ratio]) => ({
|
|
636
|
+
value: ratio,
|
|
637
|
+
label: `${t(`imageRatio_${id}`)} ${ratio}`
|
|
638
|
+
})),
|
|
639
|
+
onInvoke: ({ option }) => send(t("imageResizePrompt").replaceAll("{aspectRatio}", option))
|
|
640
|
+
}
|
|
641
|
+
];
|
|
642
|
+
}
|
|
643
|
+
/** Draw relative erase strokes in one color onto a canvas of the given size. */
|
|
644
|
+
function paintEraseStrokes(context, strokes, width, height, color) {
|
|
645
|
+
context.strokeStyle = color;
|
|
646
|
+
context.fillStyle = color;
|
|
647
|
+
context.lineCap = "round";
|
|
648
|
+
context.lineJoin = "round";
|
|
649
|
+
const scale = Math.min(width, height);
|
|
650
|
+
for (const stroke of strokes) {
|
|
651
|
+
const points = stroke.points;
|
|
652
|
+
if (points.length === 0) continue;
|
|
653
|
+
context.lineWidth = stroke.size * scale;
|
|
654
|
+
context.beginPath();
|
|
655
|
+
if (points.length === 1) {
|
|
656
|
+
context.arc(points[0].x * width, points[0].y * height, stroke.size * scale / 2, 0, Math.PI * 2);
|
|
657
|
+
context.fill();
|
|
658
|
+
continue;
|
|
659
|
+
}
|
|
660
|
+
context.moveTo(points[0].x * width, points[0].y * height);
|
|
661
|
+
for (const point of points.slice(1)) context.lineTo(point.x * width, point.y * height);
|
|
662
|
+
context.stroke();
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
/** Codex's erase mask: the marked area white on black, at the image's own resolution. */
|
|
666
|
+
function paintEraseMask(context, strokes, width, height) {
|
|
667
|
+
context.fillStyle = "#000";
|
|
668
|
+
context.fillRect(0, 0, width, height);
|
|
669
|
+
paintEraseStrokes(context, strokes, width, height, "#fff");
|
|
670
|
+
}
|
|
671
|
+
//#endregion
|
|
590
672
|
//#region src/client-image-previews.jsx
|
|
591
673
|
function openPreview(props, item, opener, sourceInDraft = false) {
|
|
592
674
|
const { service, preference, t, attachForEdit } = props;
|
|
@@ -595,25 +677,35 @@ window.__ModuleLoader__.load({
|
|
|
595
677
|
service.open({
|
|
596
678
|
items: [{
|
|
597
679
|
...item,
|
|
598
|
-
actions: settings.imageEditing ? [
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
annotations,
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
680
|
+
actions: settings.imageEditing ? [
|
|
681
|
+
{
|
|
682
|
+
id: "edit",
|
|
683
|
+
label: t("imageEdit"),
|
|
684
|
+
pendingLabel: t("imageEditPreparing"),
|
|
685
|
+
errorLabel: t("imageEditFailed"),
|
|
686
|
+
closeOnSuccess: true,
|
|
687
|
+
onInvoke: ({ annotations }) => attachForEdit(item.src, item.name, buildImageEditDraft({
|
|
688
|
+
annotations,
|
|
689
|
+
translate: t,
|
|
690
|
+
sourceName: item.name,
|
|
691
|
+
referenceName
|
|
692
|
+
}), annotations, referenceName, sourceInDraft)
|
|
693
|
+
},
|
|
694
|
+
...officialImageTools({
|
|
695
|
+
src: item.src,
|
|
696
|
+
name: item.name,
|
|
697
|
+
t,
|
|
698
|
+
attachForEdit,
|
|
699
|
+
sourceInDraft
|
|
700
|
+
}),
|
|
701
|
+
...settings.imageSketch && props.openSketchImage ? [{
|
|
702
|
+
id: "sketch",
|
|
703
|
+
label: t("imageToSketch"),
|
|
704
|
+
pendingLabel: t("imageEditPreparing"),
|
|
705
|
+
errorLabel: t("imageEditFailed"),
|
|
706
|
+
onInvoke: () => props.openSketchImage(item.src, item.name)
|
|
707
|
+
}] : []
|
|
708
|
+
] : []
|
|
617
709
|
}],
|
|
618
710
|
opener,
|
|
619
711
|
source: sourceInDraft ? "codex-draft" : "codex-message",
|
|
@@ -804,7 +896,27 @@ window.__ModuleLoader__.load({
|
|
|
804
896
|
d: "M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99"
|
|
805
897
|
}));
|
|
806
898
|
}
|
|
807
|
-
const ForwardRef$
|
|
899
|
+
const ForwardRef$6 = /*#__PURE__*/ react.forwardRef(ArrowPathIcon);
|
|
900
|
+
//#endregion
|
|
901
|
+
//#region node_modules/.pnpm/@heroicons+react@2.2.0_react@18.3.1/node_modules/@heroicons/react/24/outline/esm/ArrowsPointingOutIcon.js
|
|
902
|
+
function ArrowsPointingOutIcon({ title, titleId, ...props }, svgRef) {
|
|
903
|
+
return /*#__PURE__*/ react.createElement("svg", Object.assign({
|
|
904
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
905
|
+
fill: "none",
|
|
906
|
+
viewBox: "0 0 24 24",
|
|
907
|
+
strokeWidth: 1.5,
|
|
908
|
+
stroke: "currentColor",
|
|
909
|
+
"aria-hidden": "true",
|
|
910
|
+
"data-slot": "icon",
|
|
911
|
+
ref: svgRef,
|
|
912
|
+
"aria-labelledby": titleId
|
|
913
|
+
}, props), title ? /*#__PURE__*/ react.createElement("title", { id: titleId }, title) : null, /*#__PURE__*/ react.createElement("path", {
|
|
914
|
+
strokeLinecap: "round",
|
|
915
|
+
strokeLinejoin: "round",
|
|
916
|
+
d: "M3.75 3.75v4.5m0-4.5h4.5m-4.5 0L9 9M3.75 20.25v-4.5m0 4.5h4.5m-4.5 0L9 15M20.25 3.75h-4.5m4.5 0v4.5m0-4.5L15 9m5.25 11.25h-4.5m4.5 0v-4.5m0 4.5L15 15"
|
|
917
|
+
}));
|
|
918
|
+
}
|
|
919
|
+
const ForwardRef$5 = /*#__PURE__*/ react.forwardRef(ArrowsPointingOutIcon);
|
|
808
920
|
//#endregion
|
|
809
921
|
//#region node_modules/.pnpm/@heroicons+react@2.2.0_react@18.3.1/node_modules/@heroicons/react/24/outline/esm/ExclamationCircleIcon.js
|
|
810
922
|
function ExclamationCircleIcon({ title, titleId, ...props }, svgRef) {
|
|
@@ -824,7 +936,27 @@ window.__ModuleLoader__.load({
|
|
|
824
936
|
d: "M12 9v3.75m9-.75a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 3.75h.008v.008H12v-.008Z"
|
|
825
937
|
}));
|
|
826
938
|
}
|
|
827
|
-
const ForwardRef$
|
|
939
|
+
const ForwardRef$4 = /*#__PURE__*/ react.forwardRef(ExclamationCircleIcon);
|
|
940
|
+
//#endregion
|
|
941
|
+
//#region node_modules/.pnpm/@heroicons+react@2.2.0_react@18.3.1/node_modules/@heroicons/react/24/outline/esm/PaintBrushIcon.js
|
|
942
|
+
function PaintBrushIcon({ title, titleId, ...props }, svgRef) {
|
|
943
|
+
return /*#__PURE__*/ react.createElement("svg", Object.assign({
|
|
944
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
945
|
+
fill: "none",
|
|
946
|
+
viewBox: "0 0 24 24",
|
|
947
|
+
strokeWidth: 1.5,
|
|
948
|
+
stroke: "currentColor",
|
|
949
|
+
"aria-hidden": "true",
|
|
950
|
+
"data-slot": "icon",
|
|
951
|
+
ref: svgRef,
|
|
952
|
+
"aria-labelledby": titleId
|
|
953
|
+
}, props), title ? /*#__PURE__*/ react.createElement("title", { id: titleId }, title) : null, /*#__PURE__*/ react.createElement("path", {
|
|
954
|
+
strokeLinecap: "round",
|
|
955
|
+
strokeLinejoin: "round",
|
|
956
|
+
d: "M9.53 16.122a3 3 0 0 0-5.78 1.128 2.25 2.25 0 0 1-2.4 2.245 4.5 4.5 0 0 0 8.4-2.245c0-.399-.078-.78-.22-1.128Zm0 0a15.998 15.998 0 0 0 3.388-1.62m-5.043-.025a15.994 15.994 0 0 1 1.622-3.395m3.42 3.42a15.995 15.995 0 0 0 4.764-4.648l3.876-5.814a1.151 1.151 0 0 0-1.597-1.597L14.146 6.32a15.996 15.996 0 0 0-4.649 4.763m3.42 3.42a6.776 6.776 0 0 0-3.42-3.42"
|
|
957
|
+
}));
|
|
958
|
+
}
|
|
959
|
+
const ForwardRef$3 = /*#__PURE__*/ react.forwardRef(PaintBrushIcon);
|
|
828
960
|
//#endregion
|
|
829
961
|
//#region node_modules/.pnpm/@heroicons+react@2.2.0_react@18.3.1/node_modules/@heroicons/react/24/outline/esm/PhotoIcon.js
|
|
830
962
|
function PhotoIcon({ title, titleId, ...props }, svgRef) {
|
|
@@ -844,7 +976,27 @@ window.__ModuleLoader__.load({
|
|
|
844
976
|
d: "m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z"
|
|
845
977
|
}));
|
|
846
978
|
}
|
|
847
|
-
const ForwardRef$
|
|
979
|
+
const ForwardRef$2 = /*#__PURE__*/ react.forwardRef(PhotoIcon);
|
|
980
|
+
//#endregion
|
|
981
|
+
//#region node_modules/.pnpm/@heroicons+react@2.2.0_react@18.3.1/node_modules/@heroicons/react/24/outline/esm/ScissorsIcon.js
|
|
982
|
+
function ScissorsIcon({ title, titleId, ...props }, svgRef) {
|
|
983
|
+
return /*#__PURE__*/ react.createElement("svg", Object.assign({
|
|
984
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
985
|
+
fill: "none",
|
|
986
|
+
viewBox: "0 0 24 24",
|
|
987
|
+
strokeWidth: 1.5,
|
|
988
|
+
stroke: "currentColor",
|
|
989
|
+
"aria-hidden": "true",
|
|
990
|
+
"data-slot": "icon",
|
|
991
|
+
ref: svgRef,
|
|
992
|
+
"aria-labelledby": titleId
|
|
993
|
+
}, props), title ? /*#__PURE__*/ react.createElement("title", { id: titleId }, title) : null, /*#__PURE__*/ react.createElement("path", {
|
|
994
|
+
strokeLinecap: "round",
|
|
995
|
+
strokeLinejoin: "round",
|
|
996
|
+
d: "m7.848 8.25 1.536.887M7.848 8.25a3 3 0 1 1-5.196-3 3 3 0 0 1 5.196 3Zm1.536.887a2.165 2.165 0 0 1 1.083 1.839c.005.351.054.695.14 1.024M9.384 9.137l2.077 1.199M7.848 15.75l1.536-.887m-1.536.887a3 3 0 1 1-5.196 3 3 3 0 0 1 5.196-3Zm1.536-.887a2.165 2.165 0 0 0 1.083-1.838c.005-.352.054-.695.14-1.025m-1.223 2.863 2.077-1.199m0-3.328a4.323 4.323 0 0 1 2.068-1.379l5.325-1.628a4.5 4.5 0 0 1 2.48-.044l.803.215-7.794 4.5m-2.882-1.664A4.33 4.33 0 0 0 10.607 12m3.736 0 7.794 4.5-.802.215a4.5 4.5 0 0 1-2.48-.043l-5.326-1.629a4.324 4.324 0 0 1-2.068-1.379M14.343 12l-2.882 1.664"
|
|
997
|
+
}));
|
|
998
|
+
}
|
|
999
|
+
const ForwardRef$1 = /*#__PURE__*/ react.forwardRef(ScissorsIcon);
|
|
848
1000
|
const ORIGINAL_IMAGE_ID_PATTERN = /^img_[0-9a-f]{32}$/u;
|
|
849
1001
|
const positiveInteger = (value) => Number.isSafeInteger(value) && value > 0;
|
|
850
1002
|
function decodeOriginalImageRef(value) {
|
|
@@ -1032,32 +1184,41 @@ window.__ModuleLoader__.load({
|
|
|
1032
1184
|
errorLabel: t("imageDownloadFailed"),
|
|
1033
1185
|
onInvoke: downloadOriginal
|
|
1034
1186
|
},
|
|
1035
|
-
actions: !features.imageEditing ? [] : [
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1187
|
+
actions: !features.imageEditing ? [] : [
|
|
1188
|
+
{
|
|
1189
|
+
id: "continue-editing",
|
|
1190
|
+
label: t("imageEdit"),
|
|
1191
|
+
pendingLabel: t("imageEditPreparing"),
|
|
1192
|
+
errorLabel: t("imageEditFailed"),
|
|
1193
|
+
closeOnSuccess: true,
|
|
1194
|
+
onInvoke: ({ annotations = [] }) => {
|
|
1195
|
+
const imageKey = String(attachment.attachmentId ?? "image").replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1196
|
+
const sourceName = annotations.length === 0 ? downloadName : `codex-edit-${imageKey}-source.png`;
|
|
1197
|
+
const referenceName = `codex-edit-${imageKey}-annotations.png`;
|
|
1198
|
+
return attachForEdit(src, sourceName, buildImageEditDraft({
|
|
1199
|
+
annotations,
|
|
1200
|
+
translate: t,
|
|
1201
|
+
width: attachment.width,
|
|
1202
|
+
height: attachment.height,
|
|
1203
|
+
sourceName,
|
|
1204
|
+
referenceName
|
|
1205
|
+
}), annotations, referenceName);
|
|
1206
|
+
}
|
|
1207
|
+
},
|
|
1208
|
+
...officialImageTools({
|
|
1209
|
+
src,
|
|
1210
|
+
name: downloadName,
|
|
1211
|
+
t,
|
|
1212
|
+
attachForEdit
|
|
1213
|
+
}),
|
|
1214
|
+
...features.imageSketch && openSketchImage ? [{
|
|
1215
|
+
id: "sketch",
|
|
1216
|
+
label: t("imageToSketch"),
|
|
1217
|
+
pendingLabel: t("imageEditPreparing"),
|
|
1218
|
+
errorLabel: t("imageEditFailed"),
|
|
1219
|
+
onInvoke: () => openSketchImage(src, downloadName)
|
|
1220
|
+
}] : []
|
|
1221
|
+
]
|
|
1061
1222
|
}],
|
|
1062
1223
|
opener: triggerRef.current,
|
|
1063
1224
|
source: "codex-generated",
|
|
@@ -1107,7 +1268,7 @@ window.__ModuleLoader__.load({
|
|
|
1107
1268
|
showOutput ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1108
1269
|
className: "codexImageToolRow",
|
|
1109
1270
|
children: [
|
|
1110
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(!settled ? ForwardRef$
|
|
1271
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(!settled ? ForwardRef$6 : failed ? ForwardRef$4 : ForwardRef$2, {
|
|
1111
1272
|
className: "codexImageToolIcon",
|
|
1112
1273
|
"aria-hidden": "true"
|
|
1113
1274
|
}),
|
|
@@ -5525,6 +5686,21 @@ window.__ModuleLoader__.load({
|
|
|
5525
5686
|
sketchEditableFile: "可编辑草稿",
|
|
5526
5687
|
sketchFormatHint: "PNG 为合并图片;可编辑草稿保留原生笔画,可重新导入(32 MB 内)。",
|
|
5527
5688
|
imageToSketch: "进入草图",
|
|
5689
|
+
imageRemoveBackground: "移除背景",
|
|
5690
|
+
imageRemoveBackgroundPrompt: "移除此图像的背景。保持所有前景主体不变且完整,边缘干净平滑。将背景设为透明。",
|
|
5691
|
+
imageErase: "擦除",
|
|
5692
|
+
imageEraseHint: "在要移除的内容上涂抹",
|
|
5693
|
+
imageErasePrompt: "从第一张图像中移除第二张图像中标记的区域",
|
|
5694
|
+
imageBrushSize: "画笔大小",
|
|
5695
|
+
imageUndo: "撤销",
|
|
5696
|
+
imageSend: "发送",
|
|
5697
|
+
imageResize: "调整大小",
|
|
5698
|
+
imageResizePrompt: "将宽高比设为 {aspectRatio}",
|
|
5699
|
+
imageRatio_square: "正方形",
|
|
5700
|
+
imageRatio_portrait: "竖向",
|
|
5701
|
+
imageRatio_story: "故事版式",
|
|
5702
|
+
imageRatio_landscape: "横向",
|
|
5703
|
+
imageRatio_widescreen: "宽屏",
|
|
5528
5704
|
sketchPictures: "图片",
|
|
5529
5705
|
sketchPictureAdd: "添加",
|
|
5530
5706
|
sketchPictureSelect: "选择图片",
|
|
@@ -5781,15 +5957,18 @@ window.__ModuleLoader__.load({
|
|
|
5781
5957
|
unlimited: "不限额",
|
|
5782
5958
|
monthlyCreditLimit: "Credits 月度消费上限",
|
|
5783
5959
|
resetCredits: "额度重置",
|
|
5960
|
+
resetCreditsHint: "使用重置可恢复短周期额度、每周额度,或两者同时恢复。",
|
|
5961
|
+
resetAvailableTab: "可用",
|
|
5962
|
+
resetFull: "完全重置",
|
|
5784
5963
|
resetCreditsAvailable: "额度重置(可用 {count} 次)",
|
|
5785
5964
|
resetCreditDefaultName: "额度重置",
|
|
5786
|
-
resetUse: "
|
|
5965
|
+
resetUse: "使用重置",
|
|
5787
5966
|
resetPreparing: "准备中…",
|
|
5788
5967
|
resetConfirmTitle: "确认使用额度重置",
|
|
5789
5968
|
resetWarning: "执行后会消耗 1 次,且无法撤销。",
|
|
5790
5969
|
resetEarlyWarning: "当前额度未用尽,服务可能不执行重置。",
|
|
5791
5970
|
resetAcknowledge: "我知道这次操作可能立即消耗 1 次重置",
|
|
5792
|
-
resetCreditExpires: "
|
|
5971
|
+
resetCreditExpires: "有效期至:{value}",
|
|
5793
5972
|
resetCreditExpiryUnknown: "到期时间未提供",
|
|
5794
5973
|
resetCreditExpiryLoading: "正在读取到期时间…",
|
|
5795
5974
|
resetCreditExpiryFailed: "无法读取到期时间",
|
|
@@ -6094,6 +6273,21 @@ window.__ModuleLoader__.load({
|
|
|
6094
6273
|
sketchEditableFile: "Editable draft",
|
|
6095
6274
|
sketchFormatHint: "PNG is flattened; editable drafts retain native strokes and can be imported again (up to 32 MB).",
|
|
6096
6275
|
imageToSketch: "Open in sketch",
|
|
6276
|
+
imageRemoveBackground: "Remove background",
|
|
6277
|
+
imageRemoveBackgroundPrompt: "Remove the background from this image. Keep all foreground subjects unchanged and fully intact, with clean, smooth edges. Make the background transparent.",
|
|
6278
|
+
imageErase: "Erase",
|
|
6279
|
+
imageEraseHint: "Brush over what you want to remove",
|
|
6280
|
+
imageErasePrompt: "Remove the area marked in the second image from the first image",
|
|
6281
|
+
imageBrushSize: "Brush size",
|
|
6282
|
+
imageUndo: "Undo",
|
|
6283
|
+
imageSend: "Send",
|
|
6284
|
+
imageResize: "Resize",
|
|
6285
|
+
imageResizePrompt: "Make the aspect ratio {aspectRatio}",
|
|
6286
|
+
imageRatio_square: "Square",
|
|
6287
|
+
imageRatio_portrait: "Portrait",
|
|
6288
|
+
imageRatio_story: "Story",
|
|
6289
|
+
imageRatio_landscape: "Landscape",
|
|
6290
|
+
imageRatio_widescreen: "Widescreen",
|
|
6097
6291
|
sketchPictures: "Images",
|
|
6098
6292
|
sketchPictureAdd: "Add",
|
|
6099
6293
|
sketchPictureSelect: "Select image",
|
|
@@ -6350,15 +6544,18 @@ window.__ModuleLoader__.load({
|
|
|
6350
6544
|
unlimited: "Unlimited",
|
|
6351
6545
|
monthlyCreditLimit: "Monthly Credits spending cap",
|
|
6352
6546
|
resetCredits: "Quota resets",
|
|
6547
|
+
resetCreditsHint: "A reset restores your short-window limit, weekly limit, or both.",
|
|
6548
|
+
resetAvailableTab: "Available",
|
|
6549
|
+
resetFull: "Full reset",
|
|
6353
6550
|
resetCreditsAvailable: "Quota resets ({count} available)",
|
|
6354
6551
|
resetCreditDefaultName: "Quota reset",
|
|
6355
|
-
resetUse: "Use",
|
|
6552
|
+
resetUse: "Use reset",
|
|
6356
6553
|
resetPreparing: "Preparing…",
|
|
6357
6554
|
resetConfirmTitle: "Confirm quota reset",
|
|
6358
6555
|
resetWarning: "This consumes one reset and cannot be undone.",
|
|
6359
6556
|
resetEarlyWarning: "Quota remains. The service may decline the reset.",
|
|
6360
6557
|
resetAcknowledge: "I understand this may consume one reset now",
|
|
6361
|
-
resetCreditExpires: "
|
|
6558
|
+
resetCreditExpires: "Valid until {value}",
|
|
6362
6559
|
resetCreditExpiryUnknown: "Expiration time not provided",
|
|
6363
6560
|
resetCreditExpiryLoading: "Reading expiration…",
|
|
6364
6561
|
resetCreditExpiryFailed: "Could not read expiration",
|
|
@@ -6634,9 +6831,21 @@ window.__ModuleLoader__.load({
|
|
|
6634
6831
|
.codexSubscriptionCreditBalance strong{font:600 18px/24px ui-monospace,SFMono-Regular,Consolas,monospace;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
|
|
6635
6832
|
.codexSubscriptionCreditRows{display:flex;flex-direction:column;gap:6px}
|
|
6636
6833
|
.codexSubscriptionResetMeta{display:flex;min-width:0;flex-direction:column;gap:1px}
|
|
6637
|
-
.
|
|
6638
|
-
.
|
|
6639
|
-
.
|
|
6834
|
+
.codexSubscriptionResetPanel{display:flex;flex-direction:column;gap:10px;margin-top:6px}
|
|
6835
|
+
.codexSubscriptionResetHead{display:flex;flex-direction:column;gap:2px}
|
|
6836
|
+
.codexSubscriptionResetHead strong{font-size:14px;line-height:20px;font-weight:600;color:var(--dsw-alias-label-primary)}
|
|
6837
|
+
.codexSubscriptionResetHead span{font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary)}
|
|
6838
|
+
.codexSubscriptionResetBox{border:1px solid var(--dsw-alias-border-l2);border-radius:12px;padding:6px 14px 2px}
|
|
6839
|
+
.codexSubscriptionResetTabs{display:flex;gap:8px;padding:6px 0 10px;border-bottom:1px solid var(--dsw-alias-border-l2)}
|
|
6840
|
+
.codexSubscriptionResetTabs span{display:inline-flex;align-items:center;gap:6px;padding:3px 10px;border-radius:8px;background:var(--dsw-alias-bg-module-platform);font-size:12px;line-height:18px;font-weight:600;color:var(--dsw-alias-label-primary)}
|
|
6841
|
+
.codexSubscriptionResetTabs b{font-weight:400;color:var(--dsw-alias-label-secondary)}
|
|
6842
|
+
.codexSubscriptionResetBox .codexSubscriptionResetBalance{gap:0}
|
|
6843
|
+
.codexSubscriptionResetBox .codexSubscriptionResetCard{padding:12px 0;border:0;border-radius:0;background:none}
|
|
6844
|
+
.codexSubscriptionResetBox .codexSubscriptionResetCard+.codexSubscriptionResetCard{border-top:1px solid var(--dsw-alias-border-l2)}
|
|
6845
|
+
.codexSubscriptionResetBox .codexSubscriptionResetCard strong{font-size:13px;line-height:20px;font-weight:600}
|
|
6846
|
+
.codexSubscriptionResetBox .codexSubscriptionResetExpiry{font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary)}
|
|
6847
|
+
.codexSubscriptionResetBox .codexSubscriptionResetUse{min-height:28px;padding:0 12px;border:0!important;border-radius:8px;background:var(--dsw-alias-bg-module-platform);font-size:12px;font-weight:600}
|
|
6848
|
+
.codexSubscriptionResetBox>.codexSubscriptionResetBalance>.codexSubscriptionCreditNote{padding:12px 0}
|
|
6640
6849
|
.codexSubscriptionResetBalance{display:flex;flex-direction:column;gap:8px}
|
|
6641
6850
|
.codexSubscriptionResetCard{display:flex;align-items:center;justify-content:space-between;gap:10px;min-width:0;padding:9px 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:9px;background:var(--dsw-alias-bg-module-platform)}
|
|
6642
6851
|
.codexSubscriptionResetCard{flex-wrap:wrap}
|
|
@@ -6901,6 +7110,9 @@ window.__ModuleLoader__.load({
|
|
|
6901
7110
|
.dcsiv-inline-note{position:absolute;bottom:34px;box-sizing:border-box;display:grid;width:min(300px,calc(100vw - 40px));grid-template-columns:24px minmax(0,1fr) 24px;align-items:center;gap:7px;padding:7px 8px;border:1px solid rgba(255,255,255,.12);border-radius:18px;background:rgba(32,33,37,.94);box-shadow:0 14px 38px rgba(0,0,0,.38);color:#fff;pointer-events:auto;backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px)}.dcsiv-annotation[data-x=right] .dcsiv-inline-note{left:-8px}.dcsiv-annotation[data-x=left] .dcsiv-inline-note{right:-8px}.dcsiv-annotation[data-x=center] .dcsiv-inline-note{left:50%;transform:translateX(-50%)}.dcsiv-annotation[data-y=down] .dcsiv-inline-note{top:34px;bottom:auto}.dcsiv-inline-note::after{position:absolute;width:9px;height:9px;background:rgba(32,33,37,.94);content:'';transform:rotate(45deg)}.dcsiv-annotation[data-y=up] .dcsiv-inline-note::after{bottom:-5px}.dcsiv-annotation[data-y=down] .dcsiv-inline-note::after{top:-5px}.dcsiv-annotation[data-x=right] .dcsiv-inline-note::after{left:13px}.dcsiv-annotation[data-x=left] .dcsiv-inline-note::after{right:13px}.dcsiv-annotation[data-x=center] .dcsiv-inline-note::after{left:calc(50% - 4px)}.dcsiv-inline-index{display:grid;place-items:center;width:22px;height:22px;border-radius:50%;background:var(--dsw-alias-state-business-primary,#3964fe);color:#fff;font-size:10px;font-weight:700}.dcsiv-inline-note textarea{box-sizing:border-box;width:100%;min-height:24px;max-height:92px;resize:none;overflow:auto;border:0;outline:0;background:transparent;color:#fff;font:inherit;font-size:12px;line-height:18px}.dcsiv-inline-note textarea::placeholder{color:rgba(255,255,255,.44)}.dcsiv-note-remove{display:grid;place-items:center;width:24px;height:24px;padding:0;border:0;border-radius:50%;background:transparent;color:rgba(255,255,255,.68);cursor:pointer}.dcsiv-note-remove:hover{background:rgba(255,255,255,.1);color:#fff}
|
|
6902
7111
|
.dcsiv-nav{position:absolute;top:50%;z-index:4;width:42px;height:42px;padding:0;transform:translateY(-50%);background:rgba(48,49,53,.82);box-shadow:0 8px 24px rgba(0,0,0,.28);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px)}.dcsiv-prev{left:6px}.dcsiv-next{right:6px}.dcsiv-counter{position:absolute;bottom:8px;left:50%;padding:5px 10px;border-radius:999px;background:rgba(38,39,43,.86);color:rgba(255,255,255,.72);font-size:11px;transform:translateX(-50%);backdrop-filter:blur(16px)}
|
|
6903
7112
|
.dcsiv-hint{display:none}
|
|
7113
|
+
.dcsiv-mask{position:absolute;inset:0;width:100%;height:100%;border-radius:12px;cursor:crosshair;touch-action:none}
|
|
7114
|
+
.dcsiv-tool-icon{width:16px;height:16px;flex:none}.dcsiv-menu{position:fixed;z-index:12;display:flex;flex-direction:column;min-width:150px;padding:6px;border:1px solid rgba(255,255,255,.12);border-radius:12px;background:rgba(32,33,37,.97);box-shadow:0 12px 32px rgba(0,0,0,.4)}.dcsiv-menu button{height:32px;padding:0 10px;border:0;border-radius:8px;background:none;color:rgba(255,255,255,.9);font:inherit;font-size:13px;text-align:left;cursor:pointer}.dcsiv-menu button:hover,.dcsiv-menu button:focus-visible{background:rgba(255,255,255,.1)}
|
|
7115
|
+
.dcsiv-erase-bar{position:absolute;left:50%;top:22px;z-index:7;display:flex;align-items:center;gap:10px;padding:6px 8px 6px 14px;transform:translateX(-50%);border:1px solid rgba(255,255,255,.1);border-radius:999px;background:rgba(38,39,43,.92);color:rgba(255,255,255,.86);font-size:12px;white-space:nowrap}.dcsiv-erase-bar label{display:inline-flex;align-items:center;gap:6px}.dcsiv-erase-bar input{width:90px}.dcsiv-primary{background:#fff!important;color:#111!important}
|
|
6904
7116
|
.dcsiv-copy-notes{position:absolute;right:20px;bottom:22px;z-index:6;display:inline-flex;align-items:center;gap:6px;height:32px;padding:0 11px;border:1px solid rgba(255,255,255,.1);border-radius:999px;background:rgba(38,39,43,.86);color:rgba(255,255,255,.82);font:inherit;font-size:12px;cursor:pointer;backdrop-filter:blur(16px)}
|
|
6905
7117
|
.dcsiv-edit-short{display:none}
|
|
6906
7118
|
@media(max-width:760px){.dcsiv-actions{flex-wrap:wrap;justify-content:center}.dcsiv-edit-short{display:inline;white-space:normal;max-width:min(280px,calc(100vw - 80px))}.dcsiv-edit-action{height:auto;min-height:32px}.dcsiv-close-floating{top:12px;right:12px;width:40px;height:40px}.dcsiv-workspace{padding:60px 12px 68px}.dcsiv-image{max-width:calc(100vw - 24px);max-height:calc(100vh - 136px)}.dcsiv-topbar{bottom:12px;max-width:calc(100vw - 24px)}.dcsiv-button{padding:0 8px}.dcsiv-button span.dcsiv-label{display:none}.dcsiv-inline-note{width:min(260px,calc(100vw - 40px))}.dcsiv-copy-notes{display:none}}
|
|
@@ -7084,6 +7296,18 @@ window.__ModuleLoader__.load({
|
|
|
7084
7296
|
}
|
|
7085
7297
|
//#endregion
|
|
7086
7298
|
//#region src/subscription-image-viewer.jsx
|
|
7299
|
+
const TOOL_ICONS = {
|
|
7300
|
+
"remove-background": ForwardRef$1,
|
|
7301
|
+
erase: ForwardRef$3,
|
|
7302
|
+
resize: ForwardRef$5
|
|
7303
|
+
};
|
|
7304
|
+
const ToolIcon = ({ id }) => {
|
|
7305
|
+
const Icon = TOOL_ICONS[id];
|
|
7306
|
+
return Icon ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
|
|
7307
|
+
className: "dcsiv-tool-icon",
|
|
7308
|
+
"aria-hidden": "true"
|
|
7309
|
+
}) : null;
|
|
7310
|
+
};
|
|
7087
7311
|
const fill$1 = (value, variables) => Object.entries(variables).reduce((text, [key, replacement]) => text.replaceAll(`{${key}}`, String(replacement)), value);
|
|
7088
7312
|
const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
7089
7313
|
const bytesLabel = (bytes) => bytes === void 0 ? void 0 : bytes < 1024 * 1024 ? `${Math.max(.1, bytes / 1024).toLocaleString(void 0, { maximumFractionDigits: 1 })} KB` : `${(bytes / 1024 / 1024).toLocaleString(void 0, { maximumFractionDigits: 1 })} MB`;
|
|
@@ -7094,8 +7318,9 @@ window.__ModuleLoader__.load({
|
|
|
7094
7318
|
const noteText = (annotations, t) => annotations.map((annotation, index) => {
|
|
7095
7319
|
return `${fill$1(t("imageAnnotation"), { value: index + 1 })} (${Math.round(annotation.x * 100)}%, ${Math.round(annotation.y * 100)}%): ${annotation.note.trim()}`;
|
|
7096
7320
|
}).filter((line) => !line.endsWith(": ")).join("\n");
|
|
7097
|
-
function ViewerAction({ action, annotations, item, service, revision, t }) {
|
|
7321
|
+
function ViewerAction({ action, annotations, item, service, revision, t, onStartMask }) {
|
|
7098
7322
|
const [state, setState] = (0, react.useState)("idle");
|
|
7323
|
+
const [menu, setMenu] = (0, react.useState)();
|
|
7099
7324
|
const active = (0, react.useRef)(true);
|
|
7100
7325
|
(0, react.useEffect)(() => {
|
|
7101
7326
|
active.current = true;
|
|
@@ -7103,14 +7328,15 @@ window.__ModuleLoader__.load({
|
|
|
7103
7328
|
active.current = false;
|
|
7104
7329
|
};
|
|
7105
7330
|
}, []);
|
|
7106
|
-
const invoke = async () => {
|
|
7331
|
+
const invoke = async (extra = {}) => {
|
|
7107
7332
|
if (state === "pending") return;
|
|
7108
7333
|
setState("pending");
|
|
7109
7334
|
try {
|
|
7110
7335
|
await action.onInvoke({
|
|
7111
7336
|
annotations,
|
|
7112
7337
|
item,
|
|
7113
|
-
src: item.src
|
|
7338
|
+
src: item.src,
|
|
7339
|
+
...extra
|
|
7114
7340
|
});
|
|
7115
7341
|
if (!active.current || service.getSnapshot()?.revision !== revision) return;
|
|
7116
7342
|
setState("idle");
|
|
@@ -7120,6 +7346,62 @@ window.__ModuleLoader__.load({
|
|
|
7120
7346
|
}
|
|
7121
7347
|
};
|
|
7122
7348
|
const label = state === "pending" ? action.pendingLabel : state === "failed" ? action.errorLabel : action.label;
|
|
7349
|
+
if (action.kind === "mask") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
7350
|
+
type: "button",
|
|
7351
|
+
className: "dcsiv-button",
|
|
7352
|
+
onClick: () => onStartMask(action),
|
|
7353
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolIcon, { id: action.id }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7354
|
+
className: "dcsiv-label",
|
|
7355
|
+
children: action.label
|
|
7356
|
+
})]
|
|
7357
|
+
});
|
|
7358
|
+
if (action.kind === "tool") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
7359
|
+
type: "button",
|
|
7360
|
+
className: "dcsiv-button",
|
|
7361
|
+
disabled: state === "pending",
|
|
7362
|
+
onClick: () => {
|
|
7363
|
+
invoke();
|
|
7364
|
+
},
|
|
7365
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolIcon, { id: action.id }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7366
|
+
className: "dcsiv-label",
|
|
7367
|
+
children: label
|
|
7368
|
+
})]
|
|
7369
|
+
});
|
|
7370
|
+
if (action.kind === "choice") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
7371
|
+
type: "button",
|
|
7372
|
+
className: "dcsiv-button",
|
|
7373
|
+
"aria-haspopup": "menu",
|
|
7374
|
+
"aria-expanded": menu !== void 0,
|
|
7375
|
+
disabled: state === "pending",
|
|
7376
|
+
onClick: (event) => {
|
|
7377
|
+
const box = event.currentTarget.getBoundingClientRect();
|
|
7378
|
+
const host = event.currentTarget.closest(".dcsiv-root");
|
|
7379
|
+
setMenu((value) => value === void 0 && host ? {
|
|
7380
|
+
host,
|
|
7381
|
+
style: {
|
|
7382
|
+
left: box.left,
|
|
7383
|
+
bottom: window.innerHeight - box.top + 8
|
|
7384
|
+
}
|
|
7385
|
+
} : void 0);
|
|
7386
|
+
},
|
|
7387
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolIcon, { id: action.id }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7388
|
+
className: "dcsiv-label",
|
|
7389
|
+
children: label
|
|
7390
|
+
})]
|
|
7391
|
+
}), menu ? (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7392
|
+
className: "dcsiv-menu",
|
|
7393
|
+
role: "menu",
|
|
7394
|
+
style: menu.style,
|
|
7395
|
+
children: action.options.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7396
|
+
type: "button",
|
|
7397
|
+
role: "menuitem",
|
|
7398
|
+
onClick: () => {
|
|
7399
|
+
setMenu(void 0);
|
|
7400
|
+
invoke({ option: option.value });
|
|
7401
|
+
},
|
|
7402
|
+
children: option.label
|
|
7403
|
+
}, option.value))
|
|
7404
|
+
}), menu.host) : null] });
|
|
7123
7405
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
7124
7406
|
type: "button",
|
|
7125
7407
|
className: "dcsiv-button dcsiv-edit-action",
|
|
@@ -7206,6 +7488,12 @@ window.__ModuleLoader__.load({
|
|
|
7206
7488
|
const [selected, setSelected] = (0, react.useState)();
|
|
7207
7489
|
const [focusNote, setFocusNote] = (0, react.useState)();
|
|
7208
7490
|
const [copied, setCopied] = (0, react.useState)(false);
|
|
7491
|
+
const [erasing, setErasing] = (0, react.useState)();
|
|
7492
|
+
const [strokes, setStrokes] = (0, react.useState)([]);
|
|
7493
|
+
const [brush, setBrush] = (0, react.useState)(.05);
|
|
7494
|
+
const [sending, setSending] = (0, react.useState)(false);
|
|
7495
|
+
const drawingRef = (0, react.useRef)(false);
|
|
7496
|
+
const maskRef = (0, react.useRef)(null);
|
|
7209
7497
|
const rootRef = (0, react.useRef)(null);
|
|
7210
7498
|
annotationsByImageRef.current = annotationsByImage;
|
|
7211
7499
|
(0, react.useEffect)(() => {
|
|
@@ -7298,11 +7586,85 @@ window.__ModuleLoader__.load({
|
|
|
7298
7586
|
(0, react.useEffect)(() => {
|
|
7299
7587
|
setAnnotating(false);
|
|
7300
7588
|
setSelected(void 0);
|
|
7589
|
+
setErasing(void 0);
|
|
7590
|
+
setStrokes([]);
|
|
7301
7591
|
}, [
|
|
7302
7592
|
item?.id,
|
|
7303
7593
|
item?.src,
|
|
7304
7594
|
request?.revision
|
|
7305
7595
|
]);
|
|
7596
|
+
(0, react.useEffect)(() => {
|
|
7597
|
+
const canvas = maskRef.current;
|
|
7598
|
+
if (!erasing || canvas === null) return;
|
|
7599
|
+
const context = canvas.getContext("2d");
|
|
7600
|
+
context.clearRect(0, 0, canvas.width, canvas.height);
|
|
7601
|
+
paintEraseStrokes(context, strokes, canvas.width, canvas.height, "rgba(255,59,48,.5)");
|
|
7602
|
+
}, [erasing, strokes]);
|
|
7603
|
+
const strokePoint = (event) => {
|
|
7604
|
+
const bounds = maskRef.current?.getBoundingClientRect();
|
|
7605
|
+
if (bounds === void 0) return void 0;
|
|
7606
|
+
return {
|
|
7607
|
+
x: clamp((event.clientX - bounds.left) / bounds.width, 0, 1),
|
|
7608
|
+
y: clamp((event.clientY - bounds.top) / bounds.height, 0, 1)
|
|
7609
|
+
};
|
|
7610
|
+
};
|
|
7611
|
+
const maskHandlers = {
|
|
7612
|
+
onPointerDown: (event) => {
|
|
7613
|
+
const point = strokePoint(event);
|
|
7614
|
+
if (point === void 0) return;
|
|
7615
|
+
event.stopPropagation();
|
|
7616
|
+
event.currentTarget.setPointerCapture?.(event.pointerId);
|
|
7617
|
+
drawingRef.current = true;
|
|
7618
|
+
setStrokes((current) => [...current, {
|
|
7619
|
+
size: brush / transformRef.current.zoom,
|
|
7620
|
+
points: [point]
|
|
7621
|
+
}]);
|
|
7622
|
+
},
|
|
7623
|
+
onPointerMove: (event) => {
|
|
7624
|
+
if (!drawingRef.current) return;
|
|
7625
|
+
const point = strokePoint(event);
|
|
7626
|
+
if (point === void 0) return;
|
|
7627
|
+
setStrokes((current) => current.length === 0 ? current : [...current.slice(0, -1), {
|
|
7628
|
+
...current.at(-1),
|
|
7629
|
+
points: [...current.at(-1).points, point]
|
|
7630
|
+
}]);
|
|
7631
|
+
},
|
|
7632
|
+
onPointerUp: () => {
|
|
7633
|
+
drawingRef.current = false;
|
|
7634
|
+
},
|
|
7635
|
+
onPointerCancel: () => {
|
|
7636
|
+
drawingRef.current = false;
|
|
7637
|
+
}
|
|
7638
|
+
};
|
|
7639
|
+
const startMask = (action) => {
|
|
7640
|
+
resetGesture();
|
|
7641
|
+
setAnnotating(false);
|
|
7642
|
+
setStrokes([]);
|
|
7643
|
+
setErasing(action);
|
|
7644
|
+
};
|
|
7645
|
+
const sendMask = async () => {
|
|
7646
|
+
const image = imageRef.current;
|
|
7647
|
+
if (!erasing || strokes.length === 0 || image === null || sending) return;
|
|
7648
|
+
setSending(true);
|
|
7649
|
+
try {
|
|
7650
|
+
const canvas = document.createElement("canvas");
|
|
7651
|
+
canvas.width = image.naturalWidth;
|
|
7652
|
+
canvas.height = image.naturalHeight;
|
|
7653
|
+
paintEraseMask(canvas.getContext("2d"), strokes, canvas.width, canvas.height);
|
|
7654
|
+
const mask = await new Promise((resolve, reject) => canvas.toBlob((blob) => blob ? resolve(blob) : reject(/* @__PURE__ */ new Error("Mask")), "image/png"));
|
|
7655
|
+
await erasing.onInvoke({
|
|
7656
|
+
mask,
|
|
7657
|
+
item,
|
|
7658
|
+
src: item.src,
|
|
7659
|
+
annotations: []
|
|
7660
|
+
});
|
|
7661
|
+
setErasing(void 0);
|
|
7662
|
+
setStrokes([]);
|
|
7663
|
+
if (erasing.closeOnSuccess) service.close();
|
|
7664
|
+
} finally {
|
|
7665
|
+
setSending(false);
|
|
7666
|
+
}
|
|
7667
|
+
};
|
|
7306
7668
|
const addAnnotation = (event) => {
|
|
7307
7669
|
if (!annotating || event.target.closest(".dcsiv-annotation")) return;
|
|
7308
7670
|
const bounds = surfaceRef.current?.getBoundingClientRect();
|
|
@@ -7434,7 +7796,8 @@ window.__ModuleLoader__.load({
|
|
|
7434
7796
|
item,
|
|
7435
7797
|
service,
|
|
7436
7798
|
revision: request.revision,
|
|
7437
|
-
t
|
|
7799
|
+
t,
|
|
7800
|
+
onStartMask: startMask
|
|
7438
7801
|
}, `${request.revision}:${index}:${action.id}`))
|
|
7439
7802
|
]
|
|
7440
7803
|
})
|
|
@@ -7448,142 +7811,194 @@ window.__ModuleLoader__.load({
|
|
|
7448
7811
|
}),
|
|
7449
7812
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7450
7813
|
className: "dcsiv-workspace",
|
|
7451
|
-
children: [
|
|
7452
|
-
|
|
7453
|
-
|
|
7454
|
-
|
|
7455
|
-
|
|
7456
|
-
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
|
|
7461
|
-
|
|
7462
|
-
|
|
7463
|
-
|
|
7464
|
-
|
|
7465
|
-
|
|
7466
|
-
|
|
7467
|
-
|
|
7468
|
-
|
|
7469
|
-
|
|
7470
|
-
|
|
7471
|
-
|
|
7472
|
-
|
|
7473
|
-
|
|
7474
|
-
|
|
7475
|
-
|
|
7476
|
-
|
|
7477
|
-
|
|
7478
|
-
|
|
7479
|
-
|
|
7480
|
-
|
|
7481
|
-
|
|
7482
|
-
|
|
7483
|
-
|
|
7484
|
-
|
|
7485
|
-
|
|
7486
|
-
|
|
7487
|
-
|
|
7488
|
-
|
|
7489
|
-
|
|
7490
|
-
|
|
7491
|
-
|
|
7492
|
-
|
|
7493
|
-
|
|
7494
|
-
|
|
7495
|
-
|
|
7496
|
-
|
|
7497
|
-
|
|
7498
|
-
|
|
7499
|
-
|
|
7500
|
-
|
|
7501
|
-
|
|
7502
|
-
|
|
7503
|
-
|
|
7504
|
-
|
|
7505
|
-
|
|
7506
|
-
|
|
7507
|
-
|
|
7508
|
-
|
|
7509
|
-
|
|
7510
|
-
|
|
7511
|
-
|
|
7512
|
-
|
|
7513
|
-
|
|
7514
|
-
|
|
7515
|
-
|
|
7516
|
-
|
|
7517
|
-
|
|
7518
|
-
|
|
7519
|
-
|
|
7520
|
-
|
|
7521
|
-
event.
|
|
7814
|
+
children: [
|
|
7815
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("main", {
|
|
7816
|
+
ref: stageRef,
|
|
7817
|
+
className: "dcsiv-stage",
|
|
7818
|
+
"data-dragging": dragging,
|
|
7819
|
+
"data-annotating": annotating || erasing !== void 0,
|
|
7820
|
+
onClick: (event) => {
|
|
7821
|
+
if (event.target === event.currentTarget && !annotating && !erasing && transform.zoom === 1) service.close();
|
|
7822
|
+
},
|
|
7823
|
+
...!annotating && !erasing ? pointerHandlers : {},
|
|
7824
|
+
onDoubleClick: () => {
|
|
7825
|
+
if (transform.zoom === 1) actual();
|
|
7826
|
+
else fit();
|
|
7827
|
+
},
|
|
7828
|
+
children: [
|
|
7829
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7830
|
+
ref: surfaceRef,
|
|
7831
|
+
className: "dcsiv-surface",
|
|
7832
|
+
onClick: addAnnotation,
|
|
7833
|
+
style: { transform: `translate3d(${transform.x}px,${transform.y}px,0) scale(${transform.zoom})` },
|
|
7834
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
7835
|
+
ref: imageRef,
|
|
7836
|
+
className: "dcsiv-image",
|
|
7837
|
+
src: item.src,
|
|
7838
|
+
alt: item.name,
|
|
7839
|
+
draggable: "false",
|
|
7840
|
+
onLoad: () => {
|
|
7841
|
+
measure();
|
|
7842
|
+
}
|
|
7843
|
+
}, `${request.revision}:${item.id}`), erasing ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("canvas", {
|
|
7844
|
+
ref: maskRef,
|
|
7845
|
+
className: "dcsiv-mask",
|
|
7846
|
+
width: imageRef.current?.naturalWidth || 1,
|
|
7847
|
+
height: imageRef.current?.naturalHeight || 1,
|
|
7848
|
+
"aria-label": t("imageEraseHint"),
|
|
7849
|
+
...maskHandlers
|
|
7850
|
+
}) : null]
|
|
7851
|
+
}),
|
|
7852
|
+
annotations.map((annotation, position) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7853
|
+
className: "dcsiv-annotation",
|
|
7854
|
+
"data-x": annotation.x < .38 ? "right" : annotation.x > .62 ? "left" : "center",
|
|
7855
|
+
"data-y": annotation.y < .28 ? "down" : "up",
|
|
7856
|
+
style: annotationPosition(annotation),
|
|
7857
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7858
|
+
type: "button",
|
|
7859
|
+
className: "dcsiv-pin",
|
|
7860
|
+
"data-active": selected === annotation.id,
|
|
7861
|
+
"aria-label": fill$1(t("imageAnnotation"), { value: position + 1 }),
|
|
7862
|
+
onClick: (event) => {
|
|
7863
|
+
event.stopPropagation();
|
|
7864
|
+
const opening = selected !== annotation.id;
|
|
7865
|
+
setSelected(opening ? annotation.id : void 0);
|
|
7866
|
+
if (opening) setFocusNote(annotation.id);
|
|
7867
|
+
},
|
|
7868
|
+
children: position + 1
|
|
7869
|
+
}), selected === annotation.id ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7870
|
+
className: "dcsiv-inline-note",
|
|
7871
|
+
"data-note-id": annotation.id,
|
|
7872
|
+
onClick: (event) => event.stopPropagation(),
|
|
7873
|
+
children: [
|
|
7874
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7875
|
+
className: "dcsiv-inline-index",
|
|
7876
|
+
children: position + 1
|
|
7877
|
+
}),
|
|
7878
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
7879
|
+
value: annotation.note,
|
|
7880
|
+
rows: 1,
|
|
7881
|
+
"aria-label": fill$1(t("imageAnnotation"), { value: position + 1 }),
|
|
7882
|
+
placeholder: t("imageAnnotationPlaceholder"),
|
|
7883
|
+
onChange: (event) => {
|
|
7884
|
+
const note = event.target.value;
|
|
7885
|
+
setAnnotations((current) => current.map((entry) => entry.id === annotation.id ? {
|
|
7886
|
+
...entry,
|
|
7887
|
+
note
|
|
7888
|
+
} : entry));
|
|
7889
|
+
},
|
|
7890
|
+
onKeyDown: (event) => {
|
|
7891
|
+
if (event.key === "Enter" && !event.shiftKey || event.key === "Escape") {
|
|
7892
|
+
event.preventDefault();
|
|
7893
|
+
event.stopPropagation();
|
|
7894
|
+
event.nativeEvent?.stopImmediatePropagation?.();
|
|
7895
|
+
setSelected(void 0);
|
|
7896
|
+
}
|
|
7897
|
+
}
|
|
7898
|
+
}),
|
|
7899
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7900
|
+
type: "button",
|
|
7901
|
+
className: "dcsiv-note-remove",
|
|
7902
|
+
"aria-label": t("imageRemoveAnnotation"),
|
|
7903
|
+
onClick: (event) => {
|
|
7522
7904
|
event.stopPropagation();
|
|
7523
|
-
|
|
7905
|
+
setAnnotations((current) => current.filter((entry) => entry.id !== annotation.id));
|
|
7524
7906
|
setSelected(void 0);
|
|
7525
|
-
}
|
|
7526
|
-
|
|
7527
|
-
|
|
7528
|
-
|
|
7529
|
-
|
|
7530
|
-
|
|
7531
|
-
|
|
7532
|
-
|
|
7533
|
-
|
|
7534
|
-
|
|
7535
|
-
|
|
7536
|
-
|
|
7537
|
-
|
|
7538
|
-
|
|
7539
|
-
|
|
7540
|
-
|
|
7541
|
-
|
|
7542
|
-
|
|
7907
|
+
},
|
|
7908
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconCloseOutline16, {})
|
|
7909
|
+
})
|
|
7910
|
+
]
|
|
7911
|
+
}) : null]
|
|
7912
|
+
}, annotation.id)),
|
|
7913
|
+
showCounter ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
7914
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7915
|
+
type: "button",
|
|
7916
|
+
className: "dcsiv-button dcsiv-icon-only dcsiv-nav dcsiv-prev",
|
|
7917
|
+
"aria-label": t("imagePrevious"),
|
|
7918
|
+
onClick: (event) => {
|
|
7919
|
+
event.stopPropagation();
|
|
7920
|
+
setIndex((value) => (value - 1 + request.items.length) % request.items.length);
|
|
7921
|
+
},
|
|
7922
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconChevronLeftOutline14, {})
|
|
7923
|
+
}),
|
|
7924
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7925
|
+
type: "button",
|
|
7926
|
+
className: "dcsiv-button dcsiv-icon-only dcsiv-nav dcsiv-next",
|
|
7927
|
+
"aria-label": t("imageNext"),
|
|
7928
|
+
onClick: (event) => {
|
|
7929
|
+
event.stopPropagation();
|
|
7930
|
+
setIndex((value) => (value + 1) % request.items.length);
|
|
7931
|
+
},
|
|
7932
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconChevronRightOutline14, {})
|
|
7933
|
+
}),
|
|
7934
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
7935
|
+
className: "dcsiv-counter",
|
|
7936
|
+
children: [
|
|
7937
|
+
index + 1,
|
|
7938
|
+
" / ",
|
|
7939
|
+
request.items.length
|
|
7940
|
+
]
|
|
7941
|
+
})
|
|
7942
|
+
] }) : annotating ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7943
|
+
className: "dcsiv-hint",
|
|
7944
|
+
children: t("imageAnnotateHint")
|
|
7945
|
+
}) : transform.zoom === 1 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7946
|
+
className: "dcsiv-hint",
|
|
7947
|
+
children: t("imageZoomHint")
|
|
7948
|
+
}) : null
|
|
7949
|
+
]
|
|
7950
|
+
}),
|
|
7951
|
+
erasing ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7952
|
+
className: "dcsiv-erase-bar",
|
|
7953
|
+
role: "toolbar",
|
|
7954
|
+
"aria-label": t("imageErase"),
|
|
7955
|
+
children: [
|
|
7956
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("imageEraseHint") }),
|
|
7957
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [t("imageBrushSize"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
7958
|
+
type: "range",
|
|
7959
|
+
min: "0.01",
|
|
7960
|
+
max: "0.15",
|
|
7961
|
+
step: "0.01",
|
|
7962
|
+
value: brush,
|
|
7963
|
+
onChange: (event) => setBrush(Number(event.target.value))
|
|
7964
|
+
})] }),
|
|
7543
7965
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7544
7966
|
type: "button",
|
|
7545
|
-
className: "dcsiv-button
|
|
7546
|
-
|
|
7547
|
-
onClick: (
|
|
7548
|
-
|
|
7549
|
-
setIndex((value) => (value - 1 + request.items.length) % request.items.length);
|
|
7550
|
-
},
|
|
7551
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconChevronLeftOutline14, {})
|
|
7967
|
+
className: "dcsiv-button",
|
|
7968
|
+
disabled: strokes.length === 0 || sending,
|
|
7969
|
+
onClick: () => setStrokes((current) => current.slice(0, -1)),
|
|
7970
|
+
children: t("imageUndo")
|
|
7552
7971
|
}),
|
|
7553
7972
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7554
7973
|
type: "button",
|
|
7555
|
-
className: "dcsiv-button
|
|
7556
|
-
|
|
7557
|
-
onClick: (
|
|
7558
|
-
|
|
7559
|
-
|
|
7974
|
+
className: "dcsiv-button",
|
|
7975
|
+
disabled: sending,
|
|
7976
|
+
onClick: () => {
|
|
7977
|
+
setErasing(void 0);
|
|
7978
|
+
setStrokes([]);
|
|
7560
7979
|
},
|
|
7561
|
-
children:
|
|
7980
|
+
children: t("cancel")
|
|
7562
7981
|
}),
|
|
7563
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
7564
|
-
|
|
7565
|
-
|
|
7566
|
-
|
|
7567
|
-
|
|
7568
|
-
|
|
7569
|
-
|
|
7982
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7983
|
+
type: "button",
|
|
7984
|
+
className: "dcsiv-button dcsiv-primary",
|
|
7985
|
+
disabled: strokes.length === 0 || sending,
|
|
7986
|
+
onClick: () => {
|
|
7987
|
+
sendMask();
|
|
7988
|
+
},
|
|
7989
|
+
children: sending ? t("imageEditPreparing") : t("imageSend")
|
|
7570
7990
|
})
|
|
7571
|
-
]
|
|
7572
|
-
|
|
7573
|
-
|
|
7574
|
-
|
|
7575
|
-
|
|
7576
|
-
|
|
7577
|
-
|
|
7578
|
-
|
|
7579
|
-
|
|
7580
|
-
|
|
7581
|
-
|
|
7582
|
-
onClick: () => {
|
|
7583
|
-
copyNotes();
|
|
7584
|
-
},
|
|
7585
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconCopyOutline16, {}), copied ? t("imageCopied") : t("imageCopyNotes")]
|
|
7586
|
-
}) : null]
|
|
7991
|
+
]
|
|
7992
|
+
}) : null,
|
|
7993
|
+
annotations.some((annotation) => annotation.note.trim() !== "") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
7994
|
+
type: "button",
|
|
7995
|
+
className: "dcsiv-copy-notes",
|
|
7996
|
+
onClick: () => {
|
|
7997
|
+
copyNotes();
|
|
7998
|
+
},
|
|
7999
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconCopyOutline16, {}), copied ? t("imageCopied") : t("imageCopyNotes")]
|
|
8000
|
+
}) : null
|
|
8001
|
+
]
|
|
7587
8002
|
})
|
|
7588
8003
|
]
|
|
7589
8004
|
});
|
|
@@ -7604,6 +8019,12 @@ window.__ModuleLoader__.load({
|
|
|
7604
8019
|
pendingLabel: typeof action.pendingLabel === "string" && action.pendingLabel !== "" ? action.pendingLabel : action.label,
|
|
7605
8020
|
errorLabel: typeof action.errorLabel === "string" && action.errorLabel !== "" ? action.errorLabel : action.label,
|
|
7606
8021
|
closeOnSuccess: action.closeOnSuccess === true,
|
|
8022
|
+
kind: [
|
|
8023
|
+
"tool",
|
|
8024
|
+
"mask",
|
|
8025
|
+
"choice"
|
|
8026
|
+
].includes(action.kind) ? action.kind : "edit",
|
|
8027
|
+
options: Array.isArray(action.options) ? action.options.filter((option) => typeof option?.value === "string" && typeof option?.label === "string") : [],
|
|
7607
8028
|
onInvoke: action.onInvoke
|
|
7608
8029
|
}];
|
|
7609
8030
|
}) : [];
|
|
@@ -8531,7 +8952,7 @@ window.__ModuleLoader__.load({
|
|
|
8531
8952
|
}
|
|
8532
8953
|
//#endregion
|
|
8533
8954
|
//#region src/version.js
|
|
8534
|
-
const PACKAGE_VERSION = "2.5.
|
|
8955
|
+
const PACKAGE_VERSION = "2.5.8";
|
|
8535
8956
|
//#endregion
|
|
8536
8957
|
//#region src/client-recovery.js
|
|
8537
8958
|
async function recoveryCall(rpc, endpoint, payload = {}, timeoutMs = 1e4) {
|
|
@@ -11247,7 +11668,10 @@ window.__ModuleLoader__.load({
|
|
|
11247
11668
|
children: date === void 0 ? t("resetCreditExpiryUnknown") : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("time", {
|
|
11248
11669
|
dateTime: date.toISOString(),
|
|
11249
11670
|
title: date.toLocaleString(),
|
|
11250
|
-
children: fill(t("resetCreditExpires"), { value: date.
|
|
11671
|
+
children: fill(t("resetCreditExpires"), { value: date.toLocaleDateString(void 0, {
|
|
11672
|
+
month: "long",
|
|
11673
|
+
day: "numeric"
|
|
11674
|
+
}) })
|
|
11251
11675
|
})
|
|
11252
11676
|
});
|
|
11253
11677
|
}
|
|
@@ -11349,7 +11773,7 @@ window.__ModuleLoader__.load({
|
|
|
11349
11773
|
children: [
|
|
11350
11774
|
challenge === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
11351
11775
|
className: "codexSubscriptionResetMeta",
|
|
11352
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: credit.name
|
|
11776
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: credit.name === void 0 ? t("resetCreditDefaultName") : /^full reset$/iu.test(credit.name) ? t("resetFull") : credit.name }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResetCreditExpiry, {
|
|
11353
11777
|
expiresAt: credit.expiresAt,
|
|
11354
11778
|
t
|
|
11355
11779
|
})]
|
|
@@ -11626,17 +12050,27 @@ window.__ModuleLoader__.load({
|
|
|
11626
12050
|
cloud: visibleUsage.credits.approxCloudMessages ? `${count(visibleUsage.credits.approxCloudMessages[0])}–${count(visibleUsage.credits.approxCloudMessages[1])}` : t("unavailable")
|
|
11627
12051
|
})
|
|
11628
12052
|
}) : null,
|
|
11629
|
-
visibleUsage?.resetCredits?.availableCount > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("
|
|
11630
|
-
className: "
|
|
11631
|
-
|
|
11632
|
-
|
|
11633
|
-
|
|
11634
|
-
|
|
11635
|
-
|
|
11636
|
-
|
|
11637
|
-
|
|
11638
|
-
|
|
11639
|
-
|
|
12053
|
+
visibleUsage?.resetCredits?.availableCount > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
12054
|
+
className: "codexSubscriptionResetPanel",
|
|
12055
|
+
"aria-label": t("resetCredits"),
|
|
12056
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12057
|
+
className: "codexSubscriptionResetHead",
|
|
12058
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("resetCredits") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("resetCreditsHint") })]
|
|
12059
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12060
|
+
className: "codexSubscriptionResetBox",
|
|
12061
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
12062
|
+
className: "codexSubscriptionResetTabs",
|
|
12063
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [t("resetAvailableTab"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: visibleUsage.resetCredits.availableCount })] })
|
|
12064
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResetCreditList, {
|
|
12065
|
+
rpc,
|
|
12066
|
+
t,
|
|
12067
|
+
count: visibleUsage.resetCredits.availableCount,
|
|
12068
|
+
nextExpiresAt: visibleUsage.resetCredits.nextExpiresAt,
|
|
12069
|
+
initialCredits: visibleUsage.resetCredits.credits,
|
|
12070
|
+
refreshKey: `${resetKey}:${usageRefreshGeneration}`,
|
|
12071
|
+
hasExhaustedQuota: exhausted,
|
|
12072
|
+
onConsumed: () => load(true)
|
|
12073
|
+
})]
|
|
11640
12074
|
})]
|
|
11641
12075
|
}) : null,
|
|
11642
12076
|
visibleUsage?.individualLimit ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -12130,7 +12564,8 @@ window.__ModuleLoader__.load({
|
|
|
12130
12564
|
imageViewer.close();
|
|
12131
12565
|
liveOpen("sketch", document.activeElement, new File([blob], name || "image.png", { type: blob.type || "image/png" }));
|
|
12132
12566
|
};
|
|
12133
|
-
const attachForEdit = (sessionId) => async (src, filename, draft, annotations = [], referenceName, sourceInDraft = false) => {
|
|
12567
|
+
const attachForEdit = (sessionId) => async (src, filename, draft, annotations = [], referenceName, sourceInDraft = false, extraFiles) => {
|
|
12568
|
+
const tool = Array.isArray(extraFiles);
|
|
12134
12569
|
if (!preference.getSnapshot().imageEditing) throw new Error("Image editing is disabled");
|
|
12135
12570
|
return withComposerSession(sessions, sessionId, async (actx) => {
|
|
12136
12571
|
if (conversation.input?.for === void 0) throw new Error("This DSH version does not provide the image composer bridge");
|
|
@@ -12142,14 +12577,15 @@ window.__ModuleLoader__.load({
|
|
|
12142
12577
|
const reference = await createAnnotatedImageReference(blob, annotations);
|
|
12143
12578
|
files.push(new File([reference], referenceName, { type: "image/png" }));
|
|
12144
12579
|
}
|
|
12580
|
+
if (tool) files.push(...extraFiles);
|
|
12145
12581
|
lifetime.signal.throwIfAborted();
|
|
12146
12582
|
const input = conversation.input.for(actx);
|
|
12147
12583
|
if (!preference.getSnapshot().imageEditing) throw new Error("Image editing is disabled");
|
|
12148
12584
|
if (files.length) attachImageFiles(conversation, input, files, sessionId);
|
|
12149
12585
|
openComposerSession(sessions, ctx.get("uiWorkspace"), sessionId);
|
|
12150
|
-
if (sourceInDraft && !annotations.length) return;
|
|
12586
|
+
if (sourceInDraft && !annotations.length && !tool) return;
|
|
12151
12587
|
if (!input.state.getSnapshot().draft.trim()) input.setDraft(draft);
|
|
12152
|
-
else if (annotations.length) if (!input.state.getSnapshot().occurrences?.length) appendImagePrompt(input, draft);
|
|
12588
|
+
else if (annotations.length || tool) if (!input.state.getSnapshot().occurrences?.length) appendImagePrompt(input, draft);
|
|
12153
12589
|
else input.notify("info", draft);
|
|
12154
12590
|
});
|
|
12155
12591
|
};
|
package/lib/index.js
CHANGED
|
@@ -2049,7 +2049,7 @@ function inheritedOriginalImageRef(session, assetId) {
|
|
|
2049
2049
|
}
|
|
2050
2050
|
//#endregion
|
|
2051
2051
|
//#region src/version.js
|
|
2052
|
-
const PACKAGE_VERSION = "2.5.
|
|
2052
|
+
const PACKAGE_VERSION = "2.5.8";
|
|
2053
2053
|
const USER_AGENT = `dsh-codex-subscription/${PACKAGE_VERSION}`;
|
|
2054
2054
|
//#endregion
|
|
2055
2055
|
//#region src/codex-images.js
|
|
@@ -3590,6 +3590,8 @@ function withInputImageDetail(payload, detail) {
|
|
|
3590
3590
|
}
|
|
3591
3591
|
const DSH_REVIEW_POLICY_PREFIX = "REVIEW_POLICY\nYou are the final authorization reviewer";
|
|
3592
3592
|
const REVIEW_MODEL_SESSION = "session";
|
|
3593
|
+
const REVIEW_RETRIES = 2;
|
|
3594
|
+
const TRANSIENT_REVIEW_FAILURE = /stream ended (?:before|without)|\b(?:network|connection|socket)\b|\bECONN[A-Z]+\b|other side closed|premature close|\bterminated\b|WebSocket closed (?:1006|1011|1012|1013)/iu;
|
|
3593
3595
|
function systemText(context) {
|
|
3594
3596
|
if (typeof context?.systemPrompt === "string") return context.systemPrompt;
|
|
3595
3597
|
const first = Array.isArray(context?.messages) ? context.messages[0] : void 0;
|
|
@@ -3683,7 +3685,8 @@ function openaiCodexSubscriptionProvider({ resolveSpeedMode = () => void 0, reso
|
|
|
3683
3685
|
const review = {
|
|
3684
3686
|
requests: 0,
|
|
3685
3687
|
routed: 0,
|
|
3686
|
-
sessionModel: 0
|
|
3688
|
+
sessionModel: 0,
|
|
3689
|
+
retries: 0
|
|
3687
3690
|
};
|
|
3688
3691
|
const reviewRoute = (model, context) => {
|
|
3689
3692
|
if (resolveReviewModel() !== "official" || !isDshAutoReview(context)) return void 0;
|
|
@@ -3710,6 +3713,34 @@ function openaiCodexSubscriptionProvider({ resolveSpeedMode = () => void 0, reso
|
|
|
3710
3713
|
}
|
|
3711
3714
|
};
|
|
3712
3715
|
};
|
|
3716
|
+
const reviewIterable = (create) => {
|
|
3717
|
+
let replay;
|
|
3718
|
+
const run = async function* () {
|
|
3719
|
+
for (let attempt = 0;; attempt += 1) {
|
|
3720
|
+
const events = [];
|
|
3721
|
+
let failure;
|
|
3722
|
+
let thrown;
|
|
3723
|
+
try {
|
|
3724
|
+
for await (const event of create()) {
|
|
3725
|
+
events.push(event);
|
|
3726
|
+
if (event?.type === "error") failure = event.error?.errorMessage;
|
|
3727
|
+
}
|
|
3728
|
+
} catch (error) {
|
|
3729
|
+
thrown = error;
|
|
3730
|
+
failure = error?.message;
|
|
3731
|
+
}
|
|
3732
|
+
if (failure !== void 0 && attempt < REVIEW_RETRIES && TRANSIENT_REVIEW_FAILURE.test(failure)) {
|
|
3733
|
+
review.retries += 1;
|
|
3734
|
+
continue;
|
|
3735
|
+
}
|
|
3736
|
+
if (thrown !== void 0 && events.length === 0) throw thrown;
|
|
3737
|
+
yield* events;
|
|
3738
|
+
if (thrown !== void 0) throw thrown;
|
|
3739
|
+
return;
|
|
3740
|
+
}
|
|
3741
|
+
};
|
|
3742
|
+
return { [Symbol.asyncIterator]: () => replay ??= run() };
|
|
3743
|
+
};
|
|
3713
3744
|
const networkIterable = (factory, options, direct = false) => {
|
|
3714
3745
|
let iterator;
|
|
3715
3746
|
let prepared;
|
|
@@ -3739,6 +3770,11 @@ function openaiCodexSubscriptionProvider({ resolveSpeedMode = () => void 0, reso
|
|
|
3739
3770
|
throw: (error) => iterator ? step("throw", error) : Promise.reject(error)
|
|
3740
3771
|
};
|
|
3741
3772
|
};
|
|
3773
|
+
const routed = (method, model, context, options) => {
|
|
3774
|
+
const route = reviewRoute(model, context);
|
|
3775
|
+
const create = () => route === void 0 ? networkIterable((prepared) => provider[method](model, context, prepared), withPreferences(model, options)) : networkIterable((prepared) => provider[method](model, context, prepared), withReview(route, options), true);
|
|
3776
|
+
return isDshAutoReview(context) ? reviewIterable(create) : create();
|
|
3777
|
+
};
|
|
3742
3778
|
return Object.freeze({
|
|
3743
3779
|
...provider,
|
|
3744
3780
|
auth: Object.freeze({
|
|
@@ -3746,14 +3782,8 @@ function openaiCodexSubscriptionProvider({ resolveSpeedMode = () => void 0, reso
|
|
|
3746
3782
|
apiKey: requestToken
|
|
3747
3783
|
}),
|
|
3748
3784
|
getModels,
|
|
3749
|
-
stream: (model, context, options) =>
|
|
3750
|
-
|
|
3751
|
-
return route === void 0 ? networkIterable((prepared) => provider.stream(model, context, prepared), withPreferences(model, options)) : networkIterable((prepared) => provider.stream(model, context, prepared), withReview(route, options), true);
|
|
3752
|
-
},
|
|
3753
|
-
streamSimple: (model, context, options) => {
|
|
3754
|
-
const route = reviewRoute(model, context);
|
|
3755
|
-
return route === void 0 ? networkIterable((prepared) => provider.streamSimple(model, context, prepared), withPreferences(model, options)) : networkIterable((prepared) => provider.streamSimple(model, context, prepared), withReview(route, options), true);
|
|
3756
|
-
},
|
|
3785
|
+
stream: (model, context, options) => routed("stream", model, context, options),
|
|
3786
|
+
streamSimple: (model, context, options) => routed("streamSimple", model, context, options),
|
|
3757
3787
|
reviewCounters: () => ({ ...review })
|
|
3758
3788
|
});
|
|
3759
3789
|
}
|
|
@@ -4759,7 +4789,8 @@ async function createSubscriptionDiagnostics({ auth, preferences, login = { phas
|
|
|
4759
4789
|
() => typeof review?.reviewCounters === "function" ? safeCounters({ snapshot: () => review.reviewCounters() }, [
|
|
4760
4790
|
"requests",
|
|
4761
4791
|
"routed",
|
|
4762
|
-
"sessionModel"
|
|
4792
|
+
"sessionModel",
|
|
4793
|
+
"retries"
|
|
4763
4794
|
]) : void 0
|
|
4764
4795
|
],
|
|
4765
4796
|
[
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-codex-subscription",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.8",
|
|
4
4
|
"description": "Use ChatGPT and Codex subscriptions in DeepSeek Harness with OAuth, quota, safe resets, web search, images, and Fast mode",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|