dsh-image-viewer 0.1.2-beta.1 → 0.1.2

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/AGENTS.md CHANGED
@@ -12,8 +12,10 @@ Use this guide only when the user asks to install, update, verify, or remove `ds
12
12
 
13
13
  ## Install or update
14
14
 
15
+ In **Plugins → Add plugin**, enter `dsh-image-viewer@0.1.2` in the package field (not the whole command). Follow the activation action shown by DSH. The terminal alternative is:
16
+
15
17
  ```sh
16
- dsh plugin --profile web add ./dsh-image-viewer-0.1.0.tgz
18
+ dsh plugin --profile web add dsh-image-viewer@0.1.2
17
19
  ```
18
20
 
19
21
  DSH-Portable exposes the same standard `dsh plugin` command. Do not use a private executable path in public instructions.
package/README.en.md CHANGED
@@ -45,20 +45,37 @@ DSH keeps working when the plugin is absent or cannot recognize a newer image su
45
45
 
46
46
  ## Install
47
47
 
48
- Install the stable release from npm:
48
+ ### Official plugin page (recommended)
49
+
50
+ 1. Open **Plugins → Add plugin** in DSH.
51
+ 2. Paste this line into **Package name or address**, then select Install:
52
+
53
+ ```text
54
+ dsh-image-viewer@0.1.2
55
+ ```
56
+
57
+ 3. Follow the result shown on the page. Refresh or restart only when requested. If installation fails, read its error before retrying.
58
+
59
+ **This version supports DSH 0.1.6-alpha.2 and 0.1.7-alpha.1.** Do not paste a complete `dsh plugin ...` command into the package field or treat the repository's `main` branch as a qualified release package.
60
+
61
+ ### Terminal installation (optional)
62
+
63
+ Run in the DSH or Portable terminal:
49
64
 
50
65
  ```sh
51
- dsh plugin --profile web add dsh-image-viewer@0.1.0
66
+ dsh plugin --profile web add dsh-image-viewer@0.1.2
52
67
  ```
53
68
 
54
- Restart DSH manually after saving active work. The plugin never needs access to provider credentials or image-generation accounts.
69
+ If DSH is running, save your work and restart after this terminal operation to load the change. For older cores, choose the plugin version verified in its release notes.
55
70
 
56
71
  ## Update
57
72
 
58
- Run the same version-pinned `dsh plugin ... add` command for the version you want to install.
73
+ Use the installed plugin’s update action on the official **Plugins** page. If it is unavailable, use **Add plugin** with the published target `package@version`. Refresh or restart only when requested. The version-pinned terminal command above is an alternative.
59
74
 
60
75
  ## Uninstall
61
76
 
77
+ Uninstall this plugin from the official **Plugins** page, or use the terminal:
78
+
62
79
  ```sh
63
80
  dsh plugin --profile web remove dsh-image-viewer
64
81
  ```
package/README.md CHANGED
@@ -20,7 +20,7 @@
20
20
 
21
21
  </div>
22
22
 
23
- > 正式版 0.1.0 已发布到 npm。遇到无法识别的新图片结构时会保留 DSH 原生行为,不会猜测接管。
23
+ > 请按下方说明选择与内核匹配的已发布版本。旧发布记录不代表支持所有后续 Alpha。
24
24
 
25
25
  稳定版与当前 Alpha 都在隔离环境验收真实附件的多图切换、缩放、拖动、下载、区域备注及关闭后焦点恢复。发布前必须通过;定时工作流每六小时检查官方新版本,失败保留浏览器和启动记录,不自动宣称兼容或发布。
26
26
 
@@ -44,20 +44,37 @@
44
44
 
45
45
  ## 安装
46
46
 
47
- 从 npm 安装正式版:
47
+ ### 在官方插件页面安装(推荐)
48
+
49
+ 1. 打开 DSH 的 **插件 → 添加插件**。
50
+ 2. 在“包名或地址”中粘贴下面这一行,再点击安装:
51
+
52
+ ```text
53
+ dsh-image-viewer@0.1.2
54
+ ```
55
+
56
+ 3. 查看安装结果;仅在页面要求时刷新或重启。安装失败时留在插件页查看错误,不必重复安装。
57
+
58
+ **此版本兼容 DSH 0.1.6-alpha.2 和 0.1.7-alpha.1。** 不要把整条 `dsh plugin ...` 命令粘贴进包名框,也不要把仓库的 `main` 分支当作已验证发布包。
59
+
60
+ ### 终端安装(可选)
61
+
62
+ 在 DSH 或 Portable 的终端中执行:
48
63
 
49
64
  ```sh
50
- dsh plugin --profile web add dsh-image-viewer@0.1.0
65
+ dsh plugin --profile web add dsh-image-viewer@0.1.2
51
66
  ```
52
67
 
53
- 保存正在进行的工作后手动重启 DSH。本插件不需要供应商凭据或图片生成账户权限。
68
+ 如果 DSH 正在运行,命令完成后保存工作并重新启动,以加载终端改动。旧内核请选择对应发布说明中已验证的插件版本。
54
69
 
55
70
  ## 更新
56
71
 
57
- 使用目标版本对应的固定 `dsh plugin ... add` 命令更新。
72
+ 在官方 **插件** 页面使用已安装插件的更新操作;没有更新按钮时,在“添加插件”中填写已发布的目标 `包名@版本`。仅按页面提示刷新或重启。也可使用上面的终端命令安装目标版本。
58
73
 
59
74
  ## 卸载
60
75
 
76
+ 在官方 **插件** 页面找到本插件并选择卸载,或使用终端:
77
+
61
78
  ```sh
62
79
  dsh plugin --profile web remove dsh-image-viewer
63
80
  ```
@@ -72,7 +89,7 @@ dsh plugin --profile web remove dsh-image-viewer
72
89
 
73
90
  ## 隐私
74
91
 
75
- 插件只读取 DSH 已经渲染的图片 URL,不调用模型或读取供应商凭据。下一版的标注操作会通过 DSH 的附件与输入框接口加入当前草稿,由用户决定是否发送。当前页面内重新打开同一张图片时,区域备注仍会保留;这不等于已发送或永久保存会话。
92
+ 插件只读取 DSH 已经渲染的图片 URL,不调用模型或读取供应商凭据。支持标注回填的版本通过 DSH 的附件与输入框接口加入当前草稿,由用户决定是否发送。当前页面内重新打开同一张图片时,区域备注仍会保留;这不等于已发送或永久保存会话。
76
93
 
77
94
  ## 反馈
78
95
 
@@ -0,0 +1,18 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64">
2
+ <defs>
3
+ <linearGradient id="frame" x1="8" y1="9" x2="46" y2="51" gradientUnits="userSpaceOnUse">
4
+ <stop stop-color="#b6a0fc"/><stop offset="1" stop-color="#7561de"/>
5
+ </linearGradient>
6
+ <linearGradient id="mountain" x1="10" y1="30" x2="46" y2="50" gradientUnits="userSpaceOnUse">
7
+ <stop stop-color="#dee0ff"/><stop offset="1" stop-color="#a6b5f8"/>
8
+ </linearGradient>
9
+ <linearGradient id="pen" x1="36" y1="50" x2="54" y2="30" gradientUnits="userSpaceOnUse">
10
+ <stop stop-color="#32b7d7"/><stop offset="1" stop-color="#7de5e9"/>
11
+ </linearGradient>
12
+ </defs>
13
+ <rect x="7" y="9" width="44" height="42" rx="8" fill="url(#frame)"/>
14
+ <circle cx="20" cy="22" r="4.5" fill="#f1eaff"/>
15
+ <path d="m7 40 12-10a3 3 0 0 1 4 0l8 7 7-6a3 3 0 0 1 4 0l9 8v4a8 8 0 0 1-8 8H15a8 8 0 0 1-8-8Z" fill="url(#mountain)"/>
16
+ <path d="m35 44 16-16a3 3 0 0 1 4 0l4 4a3 3 0 0 1 0 4L43 52l-11 3Z" fill="url(#pen)"/>
17
+ <path d="m35 44 8 8-11 3Z" fill="#d2f7f8"/>
18
+ </svg>
@@ -10,6 +10,7 @@
10
10
  "0.1.3-alpha.2",
11
11
  "0.1.5-alpha.1",
12
12
  "0.1.6-alpha.1",
13
- "0.1.6-alpha.2"
13
+ "0.1.6-alpha.2",
14
+ "0.1.7-alpha.1"
14
15
  ]
15
16
  }
package/lib/client.js CHANGED
@@ -4,8 +4,31 @@ window.__ModuleLoader__.load({
4
4
  var module = { exports: {} };
5
5
  var exports = module.exports;
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
+ //#region \0rolldown/runtime.js
8
+ var __create = Object.create;
9
+ var __defProp = Object.defineProperty;
10
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
11
+ var __getOwnPropNames = Object.getOwnPropertyNames;
12
+ var __getProtoOf = Object.getPrototypeOf;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __copyProps = (to, from, except, desc) => {
15
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
16
+ key = keys[i];
17
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
18
+ get: ((k) => from[k]).bind(null, key),
19
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
20
+ });
21
+ }
22
+ return to;
23
+ };
24
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
25
+ value: mod,
26
+ enumerable: true
27
+ }) : target, mod));
28
+ //#endregion
7
29
  let react = require("react");
8
30
  let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
31
+ _deepseek_ai_dsh_client_ui_primitives = __toESM(_deepseek_ai_dsh_client_ui_primitives, 1);
9
32
  let react_jsx_runtime = require("react/jsx-runtime");
10
33
  //#region src/viewer.js
11
34
  const boundedNumber = (value, fallback) => Number.isFinite(value) && value > 0 ? value : fallback;
@@ -481,6 +504,13 @@ window.__ModuleLoader__.load({
481
504
  }
482
505
  //#endregion
483
506
  //#region src/client.jsx
507
+ const IconChevronLeftOutline14 = _deepseek_ai_dsh_client_ui_primitives.IconChevronLeftOutlineRegular ?? _deepseek_ai_dsh_client_ui_primitives.IconChevronLeftOutline14;
508
+ const IconChevronRightOutline14 = _deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutlineRegular ?? _deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutline14;
509
+ const IconCloseOutline16 = _deepseek_ai_dsh_client_ui_primitives.IconCloseOutlineRegular ?? _deepseek_ai_dsh_client_ui_primitives.IconCloseOutline16;
510
+ const IconCopyOutline16 = _deepseek_ai_dsh_client_ui_primitives.IconCopyOutlineRegular ?? _deepseek_ai_dsh_client_ui_primitives.IconCopyOutline16;
511
+ const IconDownloadOutline16 = _deepseek_ai_dsh_client_ui_primitives.IconDownloadOutlineRegular ?? _deepseek_ai_dsh_client_ui_primitives.IconDownloadOutline16;
512
+ const IconEditOutline16 = _deepseek_ai_dsh_client_ui_primitives.IconEditOutlineRegular ?? _deepseek_ai_dsh_client_ui_primitives.IconEditOutline16;
513
+ const IconFullscreenOutline16 = _deepseek_ai_dsh_client_ui_primitives.IconFullscreenOutlineRegular ?? _deepseek_ai_dsh_client_ui_primitives.IconFullscreenOutline16;
484
514
  const name = "dsh-image-viewer";
485
515
  const inject = ["locale", "slots"];
486
516
  const LOCALES = {
@@ -661,7 +691,7 @@ window.__ModuleLoader__.load({
661
691
  onClick: () => {
662
692
  invoke();
663
693
  },
664
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconDownloadOutline16, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
694
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconDownloadOutline16, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
665
695
  className: "niv-label",
666
696
  children: label
667
697
  })]
@@ -889,7 +919,7 @@ window.__ModuleLoader__.load({
889
919
  resetGesture();
890
920
  setAnnotating((value) => !value);
891
921
  },
892
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutline16, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
922
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconEditOutline16, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
893
923
  className: "niv-label",
894
924
  children: annotating ? t("cancelAnnotate") : t("annotate")
895
925
  })]
@@ -917,7 +947,7 @@ window.__ModuleLoader__.load({
917
947
  className: "niv-button",
918
948
  "aria-label": t("fit"),
919
949
  onClick: fit,
920
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconFullscreenOutline16, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
950
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconFullscreenOutline16, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
921
951
  className: "niv-label",
922
952
  children: t("fit")
923
953
  })]
@@ -945,7 +975,7 @@ window.__ModuleLoader__.load({
945
975
  onClick: () => {
946
976
  copyNotes();
947
977
  },
948
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCopyOutline16, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
978
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconCopyOutline16, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
949
979
  className: "niv-label",
950
980
  children: copyFailed ? t("copyFailed") : copied ? t("copied") : t("copyNotes")
951
981
  })]
@@ -965,7 +995,7 @@ window.__ModuleLoader__.load({
965
995
  className: "niv-close-floating",
966
996
  "aria-label": t("close"),
967
997
  onClick: () => service.close(),
968
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCloseOutline16, {})
998
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconCloseOutline16, {})
969
999
  }),
970
1000
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
971
1001
  className: "niv-workspace",
@@ -1077,7 +1107,7 @@ window.__ModuleLoader__.load({
1077
1107
  setSelected(void 0);
1078
1108
  rootRef.current?.focus();
1079
1109
  },
1080
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCloseOutline16, {})
1110
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconCloseOutline16, {})
1081
1111
  })
1082
1112
  ]
1083
1113
  }) : null]
@@ -1091,7 +1121,7 @@ window.__ModuleLoader__.load({
1091
1121
  event.stopPropagation();
1092
1122
  setIndex((value) => (value - 1 + request.items.length) % request.items.length);
1093
1123
  },
1094
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronLeftOutline14, {})
1124
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconChevronLeftOutline14, {})
1095
1125
  }),
1096
1126
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1097
1127
  type: "button",
@@ -1101,7 +1131,7 @@ window.__ModuleLoader__.load({
1101
1131
  event.stopPropagation();
1102
1132
  setIndex((value) => (value + 1) % request.items.length);
1103
1133
  },
1104
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutline14, {})
1134
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconChevronRightOutline14, {})
1105
1135
  }),
1106
1136
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1107
1137
  className: "niv-counter",
package/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["CSS","clamp","useState","useRef","useCallback","useState","useRef","IconDownloadOutline16","useSyncExternalStore","useCallback","IconEditOutline16","IconFullscreenOutline16","IconCopyOutline16","IconCloseOutline16","IconChevronLeftOutline14","IconChevronRightOutline14","VIEWER_CSS"],"sources":["../src/viewer.js","../src/styles.js","../src/image-transform.js","../src/image-download.js","../src/annotation-draft.js","../src/client.jsx"],"sourcesContent":["const boundedNumber = (value, fallback) => Number.isFinite(value) && value > 0 ? value : fallback\nconst downloadOf = value => typeof value?.onInvoke === 'function' ? {\n pendingLabel: typeof value.pendingLabel === 'string' && value.pendingLabel !== '' ? value.pendingLabel : undefined,\n errorLabel: typeof value.errorLabel === 'string' && value.errorLabel !== '' ? value.errorLabel : undefined,\n onInvoke: value.onInvoke,\n} : undefined\nconst actionsOf = value => Array.isArray(value) ? value.flatMap((action, position) => {\n if (typeof action?.onInvoke !== 'function' || typeof action?.label !== 'string' || action.label.trim() === '') return []\n return [{\n id: typeof action.id === 'string' && action.id !== '' ? action.id : `action-${position + 1}`,\n label: action.label,\n pendingLabel: typeof action.pendingLabel === 'string' && action.pendingLabel !== '' ? action.pendingLabel : action.label,\n errorLabel: typeof action.errorLabel === 'string' && action.errorLabel !== '' ? action.errorLabel : action.label,\n closeOnSuccess: action.closeOnSuccess === true,\n onInvoke: action.onInvoke,\n }]\n}) : []\n\nexport function normalizeViewerRequest(request) {\n const rawItems = Array.isArray(request?.items) ? request.items : []\n const items = rawItems.flatMap((item, position) => {\n if (typeof item?.src !== 'string' || item.src === '') return []\n return [{\n id: typeof item.id === 'string' && item.id !== '' ? item.id : item.src,\n src: item.src,\n name: typeof item.name === 'string' && item.name !== '' ? item.name : `Image ${position + 1}`,\n width: boundedNumber(item.width, undefined),\n height: boundedNumber(item.height, undefined),\n bytes: boundedNumber(item.bytes, undefined),\n download: downloadOf(item.download),\n actions: actionsOf(item.actions),\n }]\n })\n if (items.length === 0) return undefined\n const requestedIndex = Number.isInteger(request?.index) ? request.index : 0\n return {\n items,\n index: Math.max(0, Math.min(items.length - 1, requestedIndex)),\n opener: typeof HTMLElement !== 'undefined' && request?.opener instanceof HTMLElement ? request.opener : undefined,\n source: typeof request?.source === 'string' ? request.source : 'dsh',\n annotations: request?.annotations !== false,\n commitAnnotations: typeof request?.commitAnnotations === 'function' ? request.commitAnnotations : undefined,\n }\n}\n\nexport class NativeImageViewerService {\n #listeners = new Set()\n #revision = 0\n #snapshot\n #annotationsByImage = new Map()\n #openingAnnotations = new Map()\n #closing = false\n\n constructor() {\n this.subscribe = listener => {\n this.#listeners.add(listener)\n return () => { this.#listeners.delete(listener) }\n }\n this.getSnapshot = () => this.#snapshot\n this.getAnnotationsSnapshot = () => Object.fromEntries(\n [...this.#annotationsByImage].map(([id, annotations]) => [id, annotations.map(annotation => ({ ...annotation }))]),\n )\n }\n\n setAnnotations(imageId, annotations) {\n if (typeof imageId !== 'string' || imageId === '' || !Array.isArray(annotations)) return\n if (annotations.length === 0) this.#annotationsByImage.delete(imageId)\n else this.#annotationsByImage.set(imageId, annotations.map(annotation => ({ ...annotation })))\n }\n\n open(request) {\n if (this.#closing) return false\n const normalized = normalizeViewerRequest(request)\n if (normalized === undefined) return false\n this.#revision += 1\n this.#snapshot = { ...normalized, revision: this.#revision }\n this.#openingAnnotations = new Map(normalized.items.map(item => [item.id, JSON.stringify(this.#annotationsByImage.get(item.id) || [])]))\n this.#emit()\n return true\n }\n\n async close({ discard = false } = {}) {\n if (this.#snapshot === undefined) return\n if (this.#closing) return\n const pending = this.#snapshot.items.map(item => ({ item, annotations: this.#annotationsByImage.get(item.id) || [] }))\n .filter(({ item, annotations }) => annotations.some(note => note.note.trim()) && JSON.stringify(annotations) !== this.#openingAnnotations.get(item.id))\n if (!discard && pending.length && this.#snapshot.commitAnnotations) {\n this.#closing = true\n this.#snapshot = { ...this.#snapshot, committing: true, commitError: false }\n this.#emit()\n try { await this.#snapshot.commitAnnotations(pending) }\n catch {\n this.#snapshot = { ...this.#snapshot, committing: false, commitError: true }\n this.#closing = false\n this.#emit()\n return false\n }\n this.#closing = false\n }\n const opener = this.#snapshot.opener\n this.#snapshot = undefined\n this.#emit()\n if (typeof window === 'undefined') opener?.focus()\n else window.requestAnimationFrame(() => { opener?.focus() })\n }\n\n #emit() {\n for (const listener of this.#listeners) listener()\n }\n}\n\nexport function nativeImageButton(target) {\n if (!(target instanceof Element)) return undefined\n const button = target.closest('button')\n if (!(button instanceof HTMLButtonElement)) return undefined\n const image = button.querySelector(':scope > img')\n if (!(image instanceof HTMLImageElement) || image.currentSrc === '') return undefined\n if (button.matches('[data-variant=\"single\"],[data-variant=\"tile\"]')) return { button, image, group: button.parentElement, kind: 'message' }\n const rail = button.closest('[role=\"group\"]')\n if (rail !== null && button.hasAttribute('title')) return { button, image, group: rail, kind: 'composer' }\n return undefined\n}\n\nexport function imageItemsForButton(match) {\n const selector = match.kind === 'message'\n ? ':scope > button[data-variant=\"single\"],:scope > button[data-variant=\"tile\"]'\n : 'button[title]'\n const buttons = match.group?.querySelectorAll(selector)\n ?? []\n const candidates = [...buttons].flatMap((button, index) => {\n if (match.kind === 'composer' && button.closest('[role=\"group\"]') !== match.group) return []\n const image = button.querySelector(':scope > img')\n if (!(image instanceof HTMLImageElement) || image.currentSrc === '') return []\n return [{\n id: image.currentSrc,\n src: image.currentSrc,\n name: image.alt || `Image ${index + 1}`,\n width: image.naturalWidth || undefined,\n height: image.naturalHeight || undefined,\n button,\n }]\n })\n const items = candidates.length > 0 ? candidates : [{\n id: match.image.currentSrc,\n src: match.image.currentSrc,\n name: match.image.alt || 'Image',\n width: match.image.naturalWidth || undefined,\n height: match.image.naturalHeight || undefined,\n button: match.button,\n }]\n const index = Math.max(0, items.findIndex(item => item.button === match.button))\n return { items: items.map(({ button: _button, ...item }) => item), index }\n}\n","export const CSS = String.raw`\n.niv-draft-status{position:absolute;top:76px;left:50%;transform:translateX(-50%);z-index:10;max-width:calc(100% - 48px);padding:10px 16px;border-radius:12px;background:#26272a;color:#fff;font-size:13px;line-height:20px}\n.niv-root{position:fixed;inset:0;z-index:1000;pointer-events:auto;overflow:hidden;background:rgba(7,8,10,.68);color:var(--dsw-alias-label-primary-inverted,#fff);outline:0;backdrop-filter:blur(13px) saturate(.72);-webkit-backdrop-filter:blur(13px) saturate(.72)}\n.niv-sr-only{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}\n.niv-title{position:absolute;top:20px;left:24px;right:84px;display:flex;align-items:baseline;gap:12px;color:#fff;font-size:13px}.niv-title strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.niv-title small{flex:none;opacity:.7}.niv-load-status{position:absolute;z-index:7;display:flex;align-items:center;gap:12px;color:#fff;font-size:14px}\n.niv-topbar{position:absolute;right:50%;bottom:22px;z-index:6;max-width:calc(100vw - 36px);padding:5px;border:1px solid rgba(255,255,255,.12);border-radius:999px;background:rgba(38,39,43,.86);box-shadow:0 10px 34px rgba(0,0,0,.3);transform:translateX(50%);backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px)}\n.niv-actions{display:flex;align-items:center;gap:2px;overflow-x:auto;scrollbar-width:none}.niv-actions::-webkit-scrollbar{display:none}.niv-button,.niv-download{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;gap:6px;height:32px;padding:0 10px;border:0;border-radius:999px;background:transparent;color:rgba(255,255,255,.9);font:inherit;font-size:12px;text-decoration:none;white-space:nowrap;cursor:pointer}.niv-button:hover,.niv-download:hover,.niv-button[data-active=true]{background:rgba(255,255,255,.12)}.niv-button:focus-visible,.niv-download:focus-visible,.niv-close-floating:focus-visible{outline:2px solid rgba(255,255,255,.9);outline-offset:2px}.niv-button:disabled,.niv-download:disabled{opacity:.38;cursor:default}.niv-icon-only{width:32px;padding:0}.niv-zoom{min-width:44px;color:rgba(255,255,255,.68);font-size:12px;font-variant-numeric:tabular-nums;text-align:center}\n.niv-close-floating{position:absolute;top:20px;right:20px;z-index:8;display:grid;place-items:center;width:42px;height:42px;padding:0;border:1px solid rgba(255,255,255,.1);border-radius:50%;background:rgba(48,49,53,.82);box-shadow:0 8px 24px rgba(0,0,0,.28);color:#fff;cursor:pointer;backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px)}.niv-close-floating:hover{background:rgba(66,67,72,.92)}\n.niv-workspace{position:absolute;inset:0;display:grid;min-width:0;min-height:0;padding:68px 24px 72px;box-sizing:border-box}\n.niv-stage{position:relative;display:grid;place-items:center;min-width:0;min-height:0;overflow:hidden;padding:0;touch-action:none;user-select:none}.niv-stage[data-dragging=true]{cursor:grabbing}.niv-stage[data-annotating=true]{cursor:crosshair}\n.niv-surface{position:relative;display:inline-flex;max-width:100%;max-height:100%;transform-origin:center;will-change:transform}.niv-image{display:block;max-width:calc(100vw - 72px);max-height:calc(100vh - 154px);border-radius:12px;object-fit:contain;box-shadow:0 22px 60px rgba(0,0,0,.46);user-select:none;-webkit-user-drag:none}\n.niv-annotation{position:absolute;z-index:5;width:24px;height:24px;transform-origin:center;pointer-events:none}.niv-pin{position:absolute;inset:0;display:grid;place-items:center;width:24px;height:24px;padding:0;border:2px solid #fff;border-radius:50%;background:rgba(23,24,27,.94);box-shadow:0 4px 16px rgba(0,0,0,.35);color:#fff;font:inherit;font-size:11px;font-weight:700;cursor:pointer;pointer-events:auto}.niv-pin[data-active=true]{background:var(--dsw-alias-state-business-primary,#3964fe)}\n.niv-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)}.niv-annotation[data-x=right] .niv-inline-note{left:-8px}.niv-annotation[data-x=left] .niv-inline-note{right:-8px}.niv-annotation[data-x=center] .niv-inline-note{left:50%;transform:translateX(-50%)}.niv-annotation[data-y=down] .niv-inline-note{top:34px;bottom:auto}.niv-inline-note::after{position:absolute;width:9px;height:9px;background:rgba(32,33,37,.94);content:'';transform:rotate(45deg)}.niv-annotation[data-y=up] .niv-inline-note::after{bottom:-5px}.niv-annotation[data-y=down] .niv-inline-note::after{top:-5px}.niv-annotation[data-x=right] .niv-inline-note::after{left:13px}.niv-annotation[data-x=left] .niv-inline-note::after{right:13px}.niv-annotation[data-x=center] .niv-inline-note::after{left:calc(50% - 4px)}.niv-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}.niv-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}.niv-inline-note textarea::placeholder{color:rgba(255,255,255,.44)}.niv-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}.niv-note-remove:hover{background:rgba(255,255,255,.1);color:#fff}\n.niv-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)}.niv-prev{left:6px}.niv-next{right:6px}.niv-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)}\n.niv-hint{display:none}\n@media(max-width:760px){.niv-close-floating{top:12px;right:12px;width:40px;height:40px}.niv-workspace{padding:60px 12px 68px}.niv-image{max-width:calc(100vw - 24px);max-height:calc(100vh - 136px)}.niv-topbar{bottom:12px;max-width:calc(100vw - 24px)}.niv-button{padding:0 8px}.niv-button span.niv-label{display:none}.niv-inline-note{width:min(260px,calc(100vw - 40px))}}\n@media(prefers-reduced-motion:reduce){.niv-surface{transition:none}}\n`\n","import { useCallback, useEffect, useRef, useState } from 'react'\n\nconst clamp = (value, min, max) => Math.min(max, Math.max(min, value))\nconst fitted = () => ({ zoom: 1, x: 0, y: 0 })\n\n// Coordinates are relative to the fitted image; 100% uses its decoded pixel width.\nexport function useImageTransform(identity) {\n const [transform, setTransform] = useState(fitted)\n const [dragging, setDragging] = useState(false)\n const [pixelScale, setPixelScale] = useState(1)\n const [geometry, setGeometry] = useState({ width: 0, height: 0, stageWidth: 0, stageHeight: 0 })\n const stageRef = useRef(null), surfaceRef = useRef(null), imageRef = useRef(null)\n const transformRef = useRef(transform)\n const pointers = useRef(new Map()), gesture = useRef()\n transformRef.current = transform\n\n const resetGesture = useCallback(() => {\n pointers.current.clear()\n gesture.current = undefined\n setDragging(false)\n }, [])\n const fit = useCallback(() => { resetGesture(); setTransform(fitted()) }, [resetGesture])\n useEffect(() => { fit() }, [identity, fit])\n\n const actualScale = () => imageRef.current?.naturalWidth / Math.max(1, surfaceRef.current?.offsetWidth || 1) || 1\n const boundedPan = useCallback((zoom, x, y) => {\n const stage = stageRef.current, surface = surfaceRef.current\n if (!stage || !surface || zoom <= 1) return { x: 0, y: 0 }\n const limitX = Math.max(0, (surface.offsetWidth * zoom - stage.clientWidth) / 2)\n const limitY = Math.max(0, (surface.offsetHeight * zoom - stage.clientHeight) / 2)\n return { x: clamp(x, -limitX, limitX), y: clamp(y, -limitY, limitY) }\n }, [])\n const setZoomAt = useCallback((zoom, clientX, clientY) => {\n const stage = stageRef.current\n if (!stage) return\n setTransform(current => {\n const next = clamp(zoom, 0.5, Math.max(8, actualScale()))\n const box = stage.getBoundingClientRect()\n const px = clientX - box.left - box.width / 2, py = clientY - box.top - box.height / 2\n const ratio = next / current.zoom\n return { zoom: next, ...boundedPan(next, px - (px - current.x) * ratio, py - (py - current.y) * ratio) }\n })\n }, [boundedPan])\n const actual = useCallback(() => {\n if (!imageRef.current?.naturalWidth) return\n resetGesture()\n setTransform({ zoom: actualScale(), x: 0, y: 0 })\n }, [resetGesture])\n const measure = useCallback(() => {\n const next = { width: surfaceRef.current?.offsetWidth ?? 0, height: surfaceRef.current?.offsetHeight ?? 0,\n stageWidth: stageRef.current?.clientWidth ?? 0, stageHeight: stageRef.current?.clientHeight ?? 0 }\n setGeometry(current => Object.keys(next).every(key => current[key] === next[key]) ? current : next)\n setPixelScale(1 / actualScale())\n setTransform(current => ({ ...current, ...boundedPan(current.zoom, current.x, current.y) }))\n }, [boundedPan])\n useEffect(() => {\n if (!stageRef.current || !surfaceRef.current) return\n const observer = new ResizeObserver(measure)\n observer.observe(stageRef.current)\n observer.observe(surfaceRef.current)\n measure()\n return () => observer.disconnect()\n }, [identity, measure])\n useEffect(() => {\n const stage = stageRef.current\n if (!stage) return\n const wheel = event => {\n event.preventDefault()\n const delta = event.deltaY * (event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? stage.clientHeight : 1)\n setZoomAt(transformRef.current.zoom * Math.exp(-delta * 0.0015), event.clientX, event.clientY)\n }\n stage.addEventListener('wheel', wheel, { passive: false })\n return () => stage.removeEventListener('wheel', wheel)\n }, [identity, setZoomAt])\n\n const onPointerDown = event => {\n if (event.button !== 0 || event.target.closest('button,a,input,textarea,select')) return\n const current = transformRef.current\n if (event.pointerType === 'mouse' && current.zoom <= 1) return\n event.currentTarget.setPointerCapture(event.pointerId)\n pointers.current.set(event.pointerId, { x: event.clientX, y: event.clientY })\n if (pointers.current.size === 2) {\n const [a, b] = [...pointers.current.values()]\n gesture.current = { kind: 'pinch', distance: Math.hypot(a.x - b.x, a.y - b.y), transform: current }\n } else {\n gesture.current = { kind: 'pan', x: event.clientX, y: event.clientY, transform: current }\n }\n setDragging(true)\n }\n const onPointerMove = event => {\n if (!pointers.current.has(event.pointerId)) return\n pointers.current.set(event.pointerId, { x: event.clientX, y: event.clientY })\n const start = gesture.current\n if (start?.kind === 'pinch' && pointers.current.size >= 2) {\n const [a, b] = [...pointers.current.values()]\n setZoomAt(start.transform.zoom * Math.hypot(a.x - b.x, a.y - b.y) / Math.max(1, start.distance), (a.x + b.x) / 2, (a.y + b.y) / 2)\n } else if (start?.kind === 'pan') {\n setTransform({ zoom: start.transform.zoom, ...boundedPan(start.transform.zoom, start.transform.x + event.clientX - start.x, start.transform.y + event.clientY - start.y) })\n }\n }\n const endPointer = event => {\n pointers.current.delete(event.pointerId)\n const remaining = [...pointers.current.values()][0]\n if (remaining) gesture.current = { kind: 'pan', ...remaining, transform: transformRef.current }\n else resetGesture()\n }\n return { transform, transformRef, dragging, pixelScale, geometry, stageRef, surfaceRef, imageRef, fit, actual, measure, setZoomAt, resetGesture,\n pointerHandlers: { onPointerDown, onPointerMove, onPointerUp: endPointer, onPointerCancel: endPointer, onLostPointerCapture: endPointer } }\n}\n","export function downloadPercent(value) {\n const { loaded, total } = value ?? {}\n if (!Number.isFinite(loaded) || loaded < 0 || !Number.isFinite(total) || total <= 0) return undefined\n return Math.min(100, Math.floor(loaded / total * 100))\n}\n\nexport async function readImageBlob(src, { signal, onProgress }) {\n const response = await fetch(src, { signal })\n if (!response.ok) throw new Error(`Image download failed: ${response.status}`)\n if (!response.body) return response.blob()\n // Compressed transfer lengths do not describe the decoded stream's size.\n const length = response.headers.get('content-encoding') ? undefined : Number(response.headers.get('content-length'))\n const total = Number.isFinite(length) && length > 0 ? length : undefined\n const reader = response.body.getReader()\n const chunks = []\n let loaded = 0\n try {\n while (true) {\n signal.throwIfAborted()\n const { done, value } = await reader.read()\n if (done) break\n chunks.push(value)\n loaded += value.byteLength\n onProgress({ loaded, total })\n }\n signal.throwIfAborted()\n return new Blob(chunks, { type: response.headers.get('content-type') || '' })\n } finally {\n reader.releaseLock()\n }\n}\n","export async function renderAnnotationImage(blob, annotations) {\n const image = await createImageBitmap(blob)\n try {\n const canvas = document.createElement('canvas')\n canvas.width = image.width\n canvas.height = image.height\n const context = canvas.getContext('2d')\n if (!context) throw new Error('Canvas unavailable')\n context.drawImage(image, 0, 0)\n const radius = Math.max(12, Math.min(image.width, image.height) / 60)\n annotations.forEach((annotation, index) => {\n const x = Math.max(radius, Math.min(image.width - radius, annotation.x * image.width))\n const y = Math.max(radius, Math.min(image.height - radius, annotation.y * image.height))\n context.beginPath()\n context.arc(x, y, radius, 0, Math.PI * 2)\n context.fillStyle = '#26272a'\n context.fill()\n context.strokeStyle = '#ffffff'\n context.lineWidth = Math.max(2, radius / 7)\n context.stroke()\n context.fillStyle = '#ffffff'\n context.font = `600 ${radius}px sans-serif`\n context.textAlign = 'center'\n context.textBaseline = 'middle'\n context.fillText(String(index + 1), x, y)\n })\n return await new Promise((resolve, reject) => canvas.toBlob(value => value ? resolve(value) : reject(new Error('Image encoding failed')), 'image/png'))\n } finally { image.close() }\n}\n\nconst hasOwn = Object.prototype.hasOwnProperty\n\n// Legacy hosts expose the selected session as `list.current`. Alpha2 keeps\n// that selection in the UI session retention projection instead, where the\n// main view is the only owner allowed to retain the current session.\nexport function currentSessionId(snapshot) {\n if (snapshot !== null && typeof snapshot === 'object' && hasOwn.call(snapshot, 'current')) return snapshot.current\n const retained = Object.entries(snapshot?.byId ?? {}).filter(([, entry]) => (entry?.retainedBy?.mainView ?? 0) > 0)\n return retained.length === 1 ? retained[0][0] : undefined\n}\n\n// Capture the destination when the viewer opens, then validate it again after\n// asynchronous image preparation. Never send or redirect another session.\nexport function createAnnotationCommit(ctx, { readBlob, render = renderAnnotationImage, formatNotes }) {\n let sessions, conversation, sessionId\n try {\n sessions = ctx.get('sessions')\n conversation = ctx.get('conversation')\n sessionId = currentSessionId(sessions.list.getSnapshot())\n } catch { /* The viewer also works without a conversation host. */ }\n return async entries => {\n if (!sessionId || !conversation?.input?.for || currentSessionId(sessions.list.getSnapshot()) !== sessionId) throw new Error('Composer unavailable or session changed')\n const prepared = await Promise.all(entries.map(async ({ item, annotations }) => {\n const image = await render(await readBlob(item.src), annotations)\n const name = `${String(item.name || 'image').replace(/\\.[^.]+$/, '')}-annotated.png`\n return { file: new File([image], name, { type: 'image/png' }), text: `${name}\\n${formatNotes(annotations)}` }\n }))\n if (currentSessionId(sessions.list.getSnapshot()) !== sessionId) throw new Error('Session changed')\n const input = conversation.input.for(sessions.scope(sessionId))\n const state = input.state.getSnapshot()\n if (state.phase !== 'plain' || state.occurrences?.length) throw new Error('Composer busy or contains references')\n const modern = typeof conversation.createDrafts === 'function'\n const add = modern ? input.addAttachments : input.addImages\n const release = modern ? conversation.releaseDraftAttachments : conversation.releaseDraftImages\n if (typeof add !== 'function' || typeof release !== 'function') throw new Error('Composer unavailable')\n const created = modern ? conversation.createDrafts(sessionId, prepared.map(item => item.file)) : conversation.createDraftImages(prepared.map(item => item.file))\n try {\n if (!add.call(input, created.map(item => item.id))) throw new Error('Composer busy')\n } catch (error) { release.call(conversation, created); throw error }\n input.setDraft([state.draft, ...prepared.map(item => item.text)].filter(Boolean).join('\\n\\n'))\n }\n}\n","import {\n useCallback, useEffect, useRef, useState, useSyncExternalStore,\n} from 'react'\nimport {\n IconChevronLeftOutline14, IconChevronRightOutline14, IconCloseOutline16,\n IconCopyOutline16, IconDownloadOutline16, IconEditOutline16, IconFullscreenOutline16,\n} from '@deepseek-ai/dsh-client-ui-primitives'\nimport {\n imageItemsForButton, NativeImageViewerService, nativeImageButton,\n} from './viewer.js'\nimport { CSS as VIEWER_CSS } from './styles.js'\nimport { useImageTransform } from './image-transform.js'\nimport { downloadPercent, readImageBlob } from './image-download.js'\nimport { createAnnotationCommit } from './annotation-draft.js'\n\nexport const name = 'dsh-image-viewer'\nexport const inject = ['locale', 'slots']\n\nconst LOCALES = {\n en: {\n addingDraft: 'Adding image and notes to draft…', draftFailed: 'Could not add to draft. Return to the original session and keep the composer editable, then close to retry.', closeWithoutDraft: 'Close without adding',\n dialog: 'Image viewer', close: 'Close', fit: 'Fit', actual: '100%', download: 'Download',\n annotate: 'Mark region', cancelAnnotate: 'Cancel marking', regions: 'Region notes', regionHint: 'Click a point on the image, then add a note.',\n note: 'Region {value}', notePlaceholder: 'Describe what should change here…', removeNote: 'Remove region note',\n hideNotes: 'Hide notes', copyNotes: 'Copy notes', copied: 'Copied', previous: 'Previous image', next: 'Next image',\n zoomHint: 'Wheel to zoom · drag to pan · double-click for 100%', preparing: 'Preparing…', failed: 'Could not prepare this image.',\n cancelDownload: 'Cancel download', cancel: 'Cancel', loading: 'Loading image…', loadFailed: 'Image could not be loaded.', retry: 'Retry', copyFailed: 'Copy failed. Try again.',\n },\n zh: {\n addingDraft: '正在把图片和备注加入草稿…', draftFailed: '未能加入草稿。请回到原会话并确保输入框可编辑,再关闭以重试。', closeWithoutDraft: '仅关闭,不加入草稿',\n dialog: '图片查看器', close: '关闭', fit: '适应窗口', actual: '原始大小', download: '下载',\n annotate: '标记区域', cancelAnnotate: '取消标记', regions: '区域备注', regionHint: '点击图片中的位置,然后填写备注。',\n note: '区域 {value}', notePlaceholder: '描述这里需要怎样调整…', removeNote: '删除区域备注',\n hideNotes: '收起备注', copyNotes: '复制备注', copied: '已复制', previous: '上一张图片', next: '下一张图片',\n zoomHint: '滚轮缩放 · 拖动查看 · 双击切换原始大小', preparing: '正在准备…', failed: '暂时无法准备这张图片。',\n cancelDownload: '取消下载', cancel: '取消', loading: '正在加载图片…', loadFailed: '图片加载失败。', retry: '重试', copyFailed: '复制失败,请重试。',\n },\n}\n\nconst fill = (value, variables) => Object.entries(variables).reduce(\n (text, [key, replacement]) => text.replaceAll(`{${key}}`, String(replacement)),\n value,\n)\nconst clamp = (value, min, max) => Math.min(max, Math.max(min, value))\nconst bytesLabel = bytes => bytes === undefined ? undefined : bytes < 1024 * 1024\n ? `${Math.max(0.1, bytes / 1024).toLocaleString(undefined, { maximumFractionDigits: 1 })} KB`\n : `${(bytes / 1024 / 1024).toLocaleString(undefined, { maximumFractionDigits: 1 })} MB`\nconst downloadName = name => {\n const cleaned = String(name || 'image.png').replace(/[<>:\"/\\\\|?*\\u0000-\\u001f]/gu, '-').replace(/[. ]+$/u, '').trim()\n return cleaned === '' ? 'image.png' : cleaned\n}\nconst noteText = (annotations, t) => annotations.map((annotation, index) => {\n const label = fill(t('note'), { value: index + 1 })\n return `${label} (${Math.round(annotation.x * 100)}%, ${Math.round(annotation.y * 100)}%): ${annotation.note.trim()}`\n}).filter(line => !line.endsWith(': ')).join('\\n')\n\nfunction ViewerAction({ action, annotations, item, service, revision }) {\n const [state, setState] = useState('idle')\n const active = useRef(true)\n useEffect(() => { active.current = true; return () => { active.current = false } }, [])\n const invoke = async () => {\n if (state === 'pending') return\n setState('pending')\n try {\n await action.onInvoke({ annotations, item, src: item.src })\n if (!active.current || service.getSnapshot()?.revision !== revision) return\n setState('idle')\n if (action.closeOnSuccess) service.close()\n } catch { if (active.current) setState('failed') }\n }\n const label = state === 'pending' ? action.pendingLabel : state === 'failed' ? action.errorLabel : action.label\n return <button type=\"button\" className=\"niv-button\" disabled={state === 'pending'} onClick={() => { void invoke() }}><span className=\"niv-label\">{label}</span></button>\n}\n\nfunction ViewerDownload({ download, item, t }) {\n const [state, setState] = useState('idle')\n const [progress, setProgress] = useState(undefined)\n const controller = useRef(null)\n useEffect(() => () => {\n controller.current?.abort()\n controller.current = null\n }, [item.id, item.src, download])\n const invoke = async () => {\n if (controller.current !== null) {\n controller.current.abort()\n controller.current = null\n setState('idle')\n setProgress(undefined)\n return\n }\n const operation = new AbortController()\n controller.current = operation\n setState('pending')\n setProgress(undefined)\n const onProgress = value => {\n if (controller.current === operation) setProgress(downloadPercent(value))\n }\n try {\n if (download !== undefined) await download.onInvoke({ item, src: item.src, signal: operation.signal, onProgress })\n else {\n const blob = await readImageBlob(item.src, { signal: operation.signal, onProgress })\n if (operation.signal.aborted) return\n const url = URL.createObjectURL(blob)\n const link = document.createElement('a')\n link.href = url\n link.download = downloadName(item.name)\n document.body.append(link)\n link.click()\n link.remove()\n // Keep the URL alive while the browser takes ownership of the download.\n setTimeout(() => URL.revokeObjectURL(url), 60_000)\n }\n if (controller.current === operation) setState('idle')\n } catch { if (controller.current === operation) setState('failed') }\n finally { if (controller.current === operation) controller.current = null }\n }\n const label = state === 'pending' ? `${download?.pendingLabel ?? t('preparing')}${progress === undefined ? '' : ` ${progress}%`} · ${t('cancel')}` : state === 'failed' ? download?.errorLabel ?? t('failed') : t('download')\n return <button type=\"button\" className=\"niv-download\" aria-label={state === 'pending' ? t('cancelDownload') : label} title={label} onClick={() => { void invoke() }}><IconDownloadOutline16 /><span className=\"niv-label\">{label}</span></button>\n}\n\nfunction ViewerOverlay({ service, t }) {\n const request = useSyncExternalStore(service.subscribe, service.getSnapshot)\n const [cursor, setCursor] = useState({ revision: 0, index: 0 })\n const index = cursor.revision === request?.revision ? cursor.index : request?.index ?? 0\n const setIndex = update => setCursor(current => ({\n revision: request.revision,\n index: typeof update === 'function' ? update(current.revision === request.revision ? current.index : request.index) : update,\n }))\n const [imageState, setImageState] = useState('loading')\n const [attempt, setAttempt] = useState(0)\n const [copyFailed, setCopyFailed] = useState(false)\n const [annotating, setAnnotating] = useState(false)\n const [annotationsByImage, setAnnotationsByImage] = useState(service.getAnnotationsSnapshot)\n const annotationsByImageRef = useRef(annotationsByImage)\n const [selected, setSelected] = useState()\n const [focusNote, setFocusNote] = useState()\n const [copied, setCopied] = useState(false)\n const rootRef = useRef(null)\n annotationsByImageRef.current = annotationsByImage\n\n useEffect(() => {\n if (request === undefined) return\n setAnnotating(false)\n setSelected(undefined)\n setCopied(false)\n }, [request?.revision])\n\n const item = request?.items[index]\n const { transform, transformRef, dragging, pixelScale, geometry, stageRef, surfaceRef, imageRef, fit, actual, measure, setZoomAt, resetGesture, pointerHandlers } = useImageTransform(`${request?.revision}:${item?.id}:${item?.src}`)\n const annotations = item === undefined ? [] : annotationsByImage[item.id] ?? []\n const setAnnotations = useCallback((update) => {\n if (service.getSnapshot()?.committing) return\n if (item === undefined) return\n const previous = annotationsByImageRef.current[item.id] ?? []\n const next = typeof update === 'function' ? update(previous) : update\n const snapshot = { ...annotationsByImageRef.current, [item.id]: next }\n annotationsByImageRef.current = snapshot\n service.setAnnotations(item.id, next)\n setAnnotationsByImage(snapshot)\n setCopied(false)\n setCopyFailed(false)\n }, [item?.id, service])\n\n useEffect(() => {\n if (request === undefined) return undefined\n const previousOverflow = document.body.style.overflow\n document.body.style.overflow = 'hidden'\n rootRef.current?.focus()\n const onKeyDown = event => {\n if (service.getSnapshot()?.committing) { event.preventDefault(); event.stopPropagation(); return }\n if (event.defaultPrevented || event.isComposing) return\n if (event.key === 'Escape') {\n event.preventDefault()\n event.stopPropagation()\n if (event.target instanceof Element && event.target.closest('.niv-inline-note') !== null) {\n setSelected(undefined)\n rootRef.current?.focus()\n return\n }\n service.close()\n return\n }\n if (event.ctrlKey || event.metaKey || event.altKey) return\n const editing = event.target instanceof Element && event.target.closest('input,textarea,select,[contenteditable=\"true\"]') !== null\n if (!editing && ['ArrowLeft', 'ArrowRight', '+', '=', '-', 'f', 'F'].includes(event.key)) event.stopPropagation()\n if (!editing && event.key === 'ArrowLeft' && request.items.length > 1) {\n event.preventDefault(); setIndex(value => (value - 1 + request.items.length) % request.items.length)\n } else if (!editing && event.key === 'ArrowRight' && request.items.length > 1) {\n event.preventDefault(); setIndex(value => (value + 1) % request.items.length)\n } else if (!editing && (event.key === '+' || event.key === '=')) {\n event.preventDefault(); const box = stageRef.current?.getBoundingClientRect(); if (box) setZoomAt(transformRef.current.zoom * 1.2, box.left + box.width / 2, box.top + box.height / 2)\n } else if (!editing && event.key === '-') {\n event.preventDefault(); const box = stageRef.current?.getBoundingClientRect(); if (box) setZoomAt(transformRef.current.zoom / 1.2, box.left + box.width / 2, box.top + box.height / 2)\n } else if (!editing && event.key.toLowerCase() === 'f') {\n event.preventDefault(); fit()\n } else if (event.key === 'Tab') {\n const controls = [...rootRef.current.querySelectorAll('button:not(:disabled),a[href],input:not(:disabled),textarea:not(:disabled),[tabindex]:not([tabindex=\"-1\"])')]\n const first = controls[0]\n const last = controls.at(-1)\n if (event.shiftKey && (document.activeElement === first || document.activeElement === rootRef.current)) { event.preventDefault(); last?.focus() }\n else if (!event.shiftKey && (document.activeElement === last || document.activeElement === rootRef.current)) { event.preventDefault(); first?.focus() }\n }\n }\n const root = rootRef.current\n root.addEventListener('keydown', onKeyDown)\n return () => {\n document.body.style.overflow = previousOverflow\n root.removeEventListener('keydown', onKeyDown)\n }\n }, [request, service, fit, setZoomAt])\n\n useEffect(() => {\n if (focusNote === undefined) return\n const field = rootRef.current?.querySelector(`[data-note-id=\"${CSS.escape(focusNote)}\"] textarea`)\n field?.focus()\n setFocusNote(undefined)\n }, [focusNote, selected, annotations.length])\n\n useEffect(() => {\n setAnnotating(false)\n setSelected(undefined)\n setImageState('loading')\n setCopyFailed(false)\n setCopied(false)\n }, [item?.id, item?.src, request?.revision])\n\n const addAnnotation = event => {\n if (!annotating || event.target.closest('.niv-annotation')) return\n const bounds = surfaceRef.current?.getBoundingClientRect()\n if (bounds === undefined) return\n const annotation = {\n id: crypto.randomUUID(),\n x: clamp((event.clientX - bounds.left) / bounds.width, 0, 1),\n y: clamp((event.clientY - bounds.top) / bounds.height, 0, 1),\n note: '',\n }\n setAnnotations(current => [...current, annotation])\n setAnnotating(false)\n setSelected(annotation.id)\n setFocusNote(annotation.id)\n }\n const copyNotes = async () => {\n const text = noteText(annotations, t)\n if (text === '') return\n try {\n await navigator.clipboard.writeText(text)\n setCopied(true)\n setCopyFailed(false)\n } catch { setCopyFailed(true) }\n }\n\n if (request === undefined || item === undefined) return null\n const meta = [item.width && item.height ? `${item.width} × ${item.height}` : undefined, bytesLabel(item.bytes)].filter(Boolean).join(' · ')\n const showCounter = request.items.length > 1\n const annotationPosition = annotation => {\n // Only the image is scaled. Notes stay in screen coordinates so their text\n // is not rasterized inside a scaled compositor layer and then enlarged.\n const ratio = globalThis.devicePixelRatio || 1\n const align = value => Math.round(value * ratio) / ratio\n return {\n left: align(geometry.stageWidth / 2 + transform.x + (annotation.x - 0.5) * geometry.width * transform.zoom - 12),\n top: align(geometry.stageHeight / 2 + transform.y + (annotation.y - 0.5) * geometry.height * transform.zoom - 12),\n visibility: imageState === 'ready' ? 'visible' : 'hidden',\n }\n }\n return <div ref={rootRef} className=\"niv-root\" role=\"dialog\" aria-modal=\"true\" aria-label={t('dialog')} tabIndex={-1}>\n {request.committing || request.commitError ? <div className=\"niv-draft-status\" role=\"status\">{t(request.committing ? 'addingDraft' : 'draftFailed')}{request.commitError ? <button className=\"niv-button\" type=\"button\" onClick={() => { void service.close({ discard: true }) }}>{t('closeWithoutDraft')}</button> : null}</div> : null}\n <div className=\"niv-title\"><strong>{item.name}</strong>{meta !== '' ? <small>{meta}</small> : null}</div>\n <header className=\"niv-topbar\" role=\"toolbar\" aria-label={t('dialog')}>\n <div className=\"niv-actions\">\n {request.annotations ? <button type=\"button\" className=\"niv-button\" data-active={annotating} aria-label={annotating ? t('cancelAnnotate') : t('annotate')} aria-pressed={annotating} disabled={imageState !== 'ready'} onClick={() => { resetGesture(); setAnnotating(value => !value) }}><IconEditOutline16 /><span className=\"niv-label\">{annotating ? t('cancelAnnotate') : t('annotate')}</span></button> : null}\n {annotations.length > 0 ? <button type=\"button\" className=\"niv-button\" data-active={selected !== undefined} onClick={() => { const first = annotations[0]; setSelected(current => current === undefined ? first.id : undefined); if (selected === undefined) setFocusNote(first.id) }}>{annotations.length} <span className=\"niv-label\">{t('regions')}</span></button> : null}\n <button type=\"button\" className=\"niv-button\" aria-label={t('fit')} onClick={fit}><IconFullscreenOutline16 /><span className=\"niv-label\">{t('fit')}</span></button>\n <button type=\"button\" className=\"niv-button\" disabled={imageState !== 'ready'} onClick={actual}>{t('actual')}</button>\n <span className=\"niv-zoom\">{Math.round(transform.zoom * pixelScale * 100)}%</span>\n <ViewerDownload key={`${request.revision}:${index}:${item.src}`} download={item.download} item={item} t={t} />\n {annotations.some(annotation => annotation.note.trim() !== '') ? <button type=\"button\" className=\"niv-button niv-copy-notes\" aria-label={copyFailed ? t('copyFailed') : copied ? t('copied') : t('copyNotes')} onClick={() => { void copyNotes() }}><IconCopyOutline16 /><span className=\"niv-label\">{copyFailed ? t('copyFailed') : copied ? t('copied') : t('copyNotes')}</span></button> : null}\n {item.actions.map(action => <ViewerAction action={action} annotations={annotations} item={item} service={service} revision={request.revision} key={`${request.revision}:${item.src}:${action.id}`} />)}\n </div>\n </header>\n <button type=\"button\" className=\"niv-close-floating\" aria-label={t('close')} onClick={() => service.close()}><IconCloseOutline16 /></button>\n <div className=\"niv-workspace\">\n <main ref={stageRef} className=\"niv-stage\" data-dragging={dragging} data-annotating={annotating} onClick={event => { if (event.target === event.currentTarget && !annotating && transform.zoom === 1) service.close() }} {...(!annotating && imageState === 'ready' ? pointerHandlers : {})} onDoubleClick={event => { if (event.target.closest('button,a,input,textarea') || imageState !== 'ready') return; if (transform.zoom === 1) actual(); else fit() }}>\n {imageState !== 'ready' ? <div className=\"niv-load-status\" role={imageState === 'error' ? 'alert' : 'status'}>{t(imageState === 'error' ? 'loadFailed' : 'loading')}{imageState === 'error' ? <button type=\"button\" className=\"niv-button\" onClick={() => { setImageState('loading'); setAttempt(value => value + 1) }}>{t('retry')}</button> : null}</div> : null}\n <div ref={surfaceRef} className=\"niv-surface\" onClick={addAnnotation} style={{ visibility: imageState === 'ready' ? 'visible' : 'hidden', transform: `translate3d(${transform.x}px,${transform.y}px,0) scale(${transform.zoom})` }}>\n <img key={`${request.revision}:${item.id}:${attempt}`} ref={imageRef} className=\"niv-image\" src={item.src} alt={item.name} draggable=\"false\" onLoad={() => { setImageState('ready'); measure() }} onError={() => setImageState('error')} />\n </div>\n {annotations.map((annotation, position) => <div className=\"niv-annotation\" data-x={annotation.x < 0.38 ? 'right' : annotation.x > 0.62 ? 'left' : 'center'} data-y={annotation.y < 0.28 ? 'down' : 'up'} style={annotationPosition(annotation)} key={annotation.id}>\n <button type=\"button\" className=\"niv-pin\" data-active={selected === annotation.id} aria-label={fill(t('note'), { value: position + 1 })} onClick={event => { event.stopPropagation(); const opening = selected !== annotation.id; setSelected(opening ? annotation.id : undefined); if (opening) setFocusNote(annotation.id) }}>{position + 1}</button>\n {selected === annotation.id ? <div className=\"niv-inline-note\" data-note-id={annotation.id} onClick={event => event.stopPropagation()}>\n <span className=\"niv-inline-index\">{position + 1}</span>\n <textarea value={annotation.note} rows={1} aria-label={fill(t('note'), { value: position + 1 })} placeholder={t('notePlaceholder')} onChange={event => { const note = event.target.value; setAnnotations(current => current.map(entry => entry.id === annotation.id ? { ...entry, note } : entry)) }} onKeyDown={event => {\n if (event.nativeEvent?.isComposing || event.isComposing) return\n if ((event.key === 'Enter' && !event.shiftKey) || event.key === 'Escape') {\n event.preventDefault()\n event.stopPropagation()\n event.nativeEvent?.stopImmediatePropagation?.()\n setSelected(undefined)\n rootRef.current?.focus()\n }\n }} />\n <button type=\"button\" className=\"niv-note-remove\" aria-label={t('removeNote')} onClick={event => { event.stopPropagation(); setAnnotations(current => current.filter(entry => entry.id !== annotation.id)); setSelected(undefined); rootRef.current?.focus() }}><IconCloseOutline16 /></button>\n </div> : null}\n </div>)}\n {showCounter ? <>\n <button type=\"button\" className=\"niv-button niv-icon-only niv-nav niv-prev\" aria-label={t('previous')} onClick={event => { event.stopPropagation(); setIndex(value => (value - 1 + request.items.length) % request.items.length) }}><IconChevronLeftOutline14 /></button>\n <button type=\"button\" className=\"niv-button niv-icon-only niv-nav niv-next\" aria-label={t('next')} onClick={event => { event.stopPropagation(); setIndex(value => (value + 1) % request.items.length) }}><IconChevronRightOutline14 /></button>\n <span className=\"niv-counter\">{index + 1} / {request.items.length}</span>\n </> : annotating ? <span className=\"niv-hint\">{t('regionHint')}</span> : transform.zoom === 1 ? <span className=\"niv-hint\">{t('zoomHint')}</span> : null}\n </main>\n\n </div>\n </div>\n}\n\nfunction installOfficialImageBridge(service, ctx, t) {\n const onClick = event => {\n const match = nativeImageButton(event.target)\n if (match === undefined) return\n const { items, index } = imageItemsForButton(match)\n event.preventDefault()\n event.stopPropagation()\n event.stopImmediatePropagation()\n const commitAnnotations = createAnnotationCommit(ctx, {\n readBlob: src => readImageBlob(src, { signal: new AbortController().signal, onProgress: () => {} }),\n formatNotes: annotations => noteText(annotations, t),\n })\n service.open({ items, index, opener: match.button, source: 'dsh-native', annotations: true, commitAnnotations })\n }\n document.addEventListener('click', onClick, true)\n return () => { document.removeEventListener('click', onClick, true) }\n}\n\nexport function apply(ctx) {\n const service = new NativeImageViewerService()\n ctx.effect(() => ctx.locale.register(name, LOCALES), `${name}: dictionaries`)\n const t = ctx.locale.bind(name)\n ctx.effect(() => {\n const style = document.createElement('style')\n style.dataset.plugin = name\n style.textContent = VIEWER_CSS\n document.head.appendChild(style)\n return () => { style.remove() }\n }, `${name}: styles`)\n ctx.effect(() => {\n const disposeService = ctx.reflect.provide('nativeImageViewer', service)\n const disposeBridge = installOfficialImageBridge(service, ctx, t)\n return () => { disposeBridge(); void disposeService() }\n }, `${name}: optional viewer service and native image bridge`)\n ctx.slots.inject('shell.overlay', () => ctx.slots.register({\n name: 'shell.overlay', id: name, order: 20, inject: () => ({ service, t }),\n }, ViewerOverlay))\n}\n\nexport { NativeImageViewerService, normalizeViewerRequest } from './viewer.js'\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["CSS","clamp","useState","useRef","useCallback","primitives","useState","useRef","useSyncExternalStore","useCallback","VIEWER_CSS"],"sources":["../src/viewer.js","../src/styles.js","../src/image-transform.js","../src/image-download.js","../src/annotation-draft.js","../src/client.jsx"],"sourcesContent":["const boundedNumber = (value, fallback) => Number.isFinite(value) && value > 0 ? value : fallback\nconst downloadOf = value => typeof value?.onInvoke === 'function' ? {\n pendingLabel: typeof value.pendingLabel === 'string' && value.pendingLabel !== '' ? value.pendingLabel : undefined,\n errorLabel: typeof value.errorLabel === 'string' && value.errorLabel !== '' ? value.errorLabel : undefined,\n onInvoke: value.onInvoke,\n} : undefined\nconst actionsOf = value => Array.isArray(value) ? value.flatMap((action, position) => {\n if (typeof action?.onInvoke !== 'function' || typeof action?.label !== 'string' || action.label.trim() === '') return []\n return [{\n id: typeof action.id === 'string' && action.id !== '' ? action.id : `action-${position + 1}`,\n label: action.label,\n pendingLabel: typeof action.pendingLabel === 'string' && action.pendingLabel !== '' ? action.pendingLabel : action.label,\n errorLabel: typeof action.errorLabel === 'string' && action.errorLabel !== '' ? action.errorLabel : action.label,\n closeOnSuccess: action.closeOnSuccess === true,\n onInvoke: action.onInvoke,\n }]\n}) : []\n\nexport function normalizeViewerRequest(request) {\n const rawItems = Array.isArray(request?.items) ? request.items : []\n const items = rawItems.flatMap((item, position) => {\n if (typeof item?.src !== 'string' || item.src === '') return []\n return [{\n id: typeof item.id === 'string' && item.id !== '' ? item.id : item.src,\n src: item.src,\n name: typeof item.name === 'string' && item.name !== '' ? item.name : `Image ${position + 1}`,\n width: boundedNumber(item.width, undefined),\n height: boundedNumber(item.height, undefined),\n bytes: boundedNumber(item.bytes, undefined),\n download: downloadOf(item.download),\n actions: actionsOf(item.actions),\n }]\n })\n if (items.length === 0) return undefined\n const requestedIndex = Number.isInteger(request?.index) ? request.index : 0\n return {\n items,\n index: Math.max(0, Math.min(items.length - 1, requestedIndex)),\n opener: typeof HTMLElement !== 'undefined' && request?.opener instanceof HTMLElement ? request.opener : undefined,\n source: typeof request?.source === 'string' ? request.source : 'dsh',\n annotations: request?.annotations !== false,\n commitAnnotations: typeof request?.commitAnnotations === 'function' ? request.commitAnnotations : undefined,\n }\n}\n\nexport class NativeImageViewerService {\n #listeners = new Set()\n #revision = 0\n #snapshot\n #annotationsByImage = new Map()\n #openingAnnotations = new Map()\n #closing = false\n\n constructor() {\n this.subscribe = listener => {\n this.#listeners.add(listener)\n return () => { this.#listeners.delete(listener) }\n }\n this.getSnapshot = () => this.#snapshot\n this.getAnnotationsSnapshot = () => Object.fromEntries(\n [...this.#annotationsByImage].map(([id, annotations]) => [id, annotations.map(annotation => ({ ...annotation }))]),\n )\n }\n\n setAnnotations(imageId, annotations) {\n if (typeof imageId !== 'string' || imageId === '' || !Array.isArray(annotations)) return\n if (annotations.length === 0) this.#annotationsByImage.delete(imageId)\n else this.#annotationsByImage.set(imageId, annotations.map(annotation => ({ ...annotation })))\n }\n\n open(request) {\n if (this.#closing) return false\n const normalized = normalizeViewerRequest(request)\n if (normalized === undefined) return false\n this.#revision += 1\n this.#snapshot = { ...normalized, revision: this.#revision }\n this.#openingAnnotations = new Map(normalized.items.map(item => [item.id, JSON.stringify(this.#annotationsByImage.get(item.id) || [])]))\n this.#emit()\n return true\n }\n\n async close({ discard = false } = {}) {\n if (this.#snapshot === undefined) return\n if (this.#closing) return\n const pending = this.#snapshot.items.map(item => ({ item, annotations: this.#annotationsByImage.get(item.id) || [] }))\n .filter(({ item, annotations }) => annotations.some(note => note.note.trim()) && JSON.stringify(annotations) !== this.#openingAnnotations.get(item.id))\n if (!discard && pending.length && this.#snapshot.commitAnnotations) {\n this.#closing = true\n this.#snapshot = { ...this.#snapshot, committing: true, commitError: false }\n this.#emit()\n try { await this.#snapshot.commitAnnotations(pending) }\n catch {\n this.#snapshot = { ...this.#snapshot, committing: false, commitError: true }\n this.#closing = false\n this.#emit()\n return false\n }\n this.#closing = false\n }\n const opener = this.#snapshot.opener\n this.#snapshot = undefined\n this.#emit()\n if (typeof window === 'undefined') opener?.focus()\n else window.requestAnimationFrame(() => { opener?.focus() })\n }\n\n #emit() {\n for (const listener of this.#listeners) listener()\n }\n}\n\nexport function nativeImageButton(target) {\n if (!(target instanceof Element)) return undefined\n const button = target.closest('button')\n if (!(button instanceof HTMLButtonElement)) return undefined\n const image = button.querySelector(':scope > img')\n if (!(image instanceof HTMLImageElement) || image.currentSrc === '') return undefined\n if (button.matches('[data-variant=\"single\"],[data-variant=\"tile\"]')) return { button, image, group: button.parentElement, kind: 'message' }\n const rail = button.closest('[role=\"group\"]')\n if (rail !== null && button.hasAttribute('title')) return { button, image, group: rail, kind: 'composer' }\n return undefined\n}\n\nexport function imageItemsForButton(match) {\n const selector = match.kind === 'message'\n ? ':scope > button[data-variant=\"single\"],:scope > button[data-variant=\"tile\"]'\n : 'button[title]'\n const buttons = match.group?.querySelectorAll(selector)\n ?? []\n const candidates = [...buttons].flatMap((button, index) => {\n if (match.kind === 'composer' && button.closest('[role=\"group\"]') !== match.group) return []\n const image = button.querySelector(':scope > img')\n if (!(image instanceof HTMLImageElement) || image.currentSrc === '') return []\n return [{\n id: image.currentSrc,\n src: image.currentSrc,\n name: image.alt || `Image ${index + 1}`,\n width: image.naturalWidth || undefined,\n height: image.naturalHeight || undefined,\n button,\n }]\n })\n const items = candidates.length > 0 ? candidates : [{\n id: match.image.currentSrc,\n src: match.image.currentSrc,\n name: match.image.alt || 'Image',\n width: match.image.naturalWidth || undefined,\n height: match.image.naturalHeight || undefined,\n button: match.button,\n }]\n const index = Math.max(0, items.findIndex(item => item.button === match.button))\n return { items: items.map(({ button: _button, ...item }) => item), index }\n}\n","export const CSS = String.raw`\n.niv-draft-status{position:absolute;top:76px;left:50%;transform:translateX(-50%);z-index:10;max-width:calc(100% - 48px);padding:10px 16px;border-radius:12px;background:#26272a;color:#fff;font-size:13px;line-height:20px}\n.niv-root{position:fixed;inset:0;z-index:1000;pointer-events:auto;overflow:hidden;background:rgba(7,8,10,.68);color:var(--dsw-alias-label-primary-inverted,#fff);outline:0;backdrop-filter:blur(13px) saturate(.72);-webkit-backdrop-filter:blur(13px) saturate(.72)}\n.niv-sr-only{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}\n.niv-title{position:absolute;top:20px;left:24px;right:84px;display:flex;align-items:baseline;gap:12px;color:#fff;font-size:13px}.niv-title strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.niv-title small{flex:none;opacity:.7}.niv-load-status{position:absolute;z-index:7;display:flex;align-items:center;gap:12px;color:#fff;font-size:14px}\n.niv-topbar{position:absolute;right:50%;bottom:22px;z-index:6;max-width:calc(100vw - 36px);padding:5px;border:1px solid rgba(255,255,255,.12);border-radius:999px;background:rgba(38,39,43,.86);box-shadow:0 10px 34px rgba(0,0,0,.3);transform:translateX(50%);backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px)}\n.niv-actions{display:flex;align-items:center;gap:2px;overflow-x:auto;scrollbar-width:none}.niv-actions::-webkit-scrollbar{display:none}.niv-button,.niv-download{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;gap:6px;height:32px;padding:0 10px;border:0;border-radius:999px;background:transparent;color:rgba(255,255,255,.9);font:inherit;font-size:12px;text-decoration:none;white-space:nowrap;cursor:pointer}.niv-button:hover,.niv-download:hover,.niv-button[data-active=true]{background:rgba(255,255,255,.12)}.niv-button:focus-visible,.niv-download:focus-visible,.niv-close-floating:focus-visible{outline:2px solid rgba(255,255,255,.9);outline-offset:2px}.niv-button:disabled,.niv-download:disabled{opacity:.38;cursor:default}.niv-icon-only{width:32px;padding:0}.niv-zoom{min-width:44px;color:rgba(255,255,255,.68);font-size:12px;font-variant-numeric:tabular-nums;text-align:center}\n.niv-close-floating{position:absolute;top:20px;right:20px;z-index:8;display:grid;place-items:center;width:42px;height:42px;padding:0;border:1px solid rgba(255,255,255,.1);border-radius:50%;background:rgba(48,49,53,.82);box-shadow:0 8px 24px rgba(0,0,0,.28);color:#fff;cursor:pointer;backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px)}.niv-close-floating:hover{background:rgba(66,67,72,.92)}\n.niv-workspace{position:absolute;inset:0;display:grid;min-width:0;min-height:0;padding:68px 24px 72px;box-sizing:border-box}\n.niv-stage{position:relative;display:grid;place-items:center;min-width:0;min-height:0;overflow:hidden;padding:0;touch-action:none;user-select:none}.niv-stage[data-dragging=true]{cursor:grabbing}.niv-stage[data-annotating=true]{cursor:crosshair}\n.niv-surface{position:relative;display:inline-flex;max-width:100%;max-height:100%;transform-origin:center;will-change:transform}.niv-image{display:block;max-width:calc(100vw - 72px);max-height:calc(100vh - 154px);border-radius:12px;object-fit:contain;box-shadow:0 22px 60px rgba(0,0,0,.46);user-select:none;-webkit-user-drag:none}\n.niv-annotation{position:absolute;z-index:5;width:24px;height:24px;transform-origin:center;pointer-events:none}.niv-pin{position:absolute;inset:0;display:grid;place-items:center;width:24px;height:24px;padding:0;border:2px solid #fff;border-radius:50%;background:rgba(23,24,27,.94);box-shadow:0 4px 16px rgba(0,0,0,.35);color:#fff;font:inherit;font-size:11px;font-weight:700;cursor:pointer;pointer-events:auto}.niv-pin[data-active=true]{background:var(--dsw-alias-state-business-primary,#3964fe)}\n.niv-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)}.niv-annotation[data-x=right] .niv-inline-note{left:-8px}.niv-annotation[data-x=left] .niv-inline-note{right:-8px}.niv-annotation[data-x=center] .niv-inline-note{left:50%;transform:translateX(-50%)}.niv-annotation[data-y=down] .niv-inline-note{top:34px;bottom:auto}.niv-inline-note::after{position:absolute;width:9px;height:9px;background:rgba(32,33,37,.94);content:'';transform:rotate(45deg)}.niv-annotation[data-y=up] .niv-inline-note::after{bottom:-5px}.niv-annotation[data-y=down] .niv-inline-note::after{top:-5px}.niv-annotation[data-x=right] .niv-inline-note::after{left:13px}.niv-annotation[data-x=left] .niv-inline-note::after{right:13px}.niv-annotation[data-x=center] .niv-inline-note::after{left:calc(50% - 4px)}.niv-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}.niv-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}.niv-inline-note textarea::placeholder{color:rgba(255,255,255,.44)}.niv-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}.niv-note-remove:hover{background:rgba(255,255,255,.1);color:#fff}\n.niv-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)}.niv-prev{left:6px}.niv-next{right:6px}.niv-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)}\n.niv-hint{display:none}\n@media(max-width:760px){.niv-close-floating{top:12px;right:12px;width:40px;height:40px}.niv-workspace{padding:60px 12px 68px}.niv-image{max-width:calc(100vw - 24px);max-height:calc(100vh - 136px)}.niv-topbar{bottom:12px;max-width:calc(100vw - 24px)}.niv-button{padding:0 8px}.niv-button span.niv-label{display:none}.niv-inline-note{width:min(260px,calc(100vw - 40px))}}\n@media(prefers-reduced-motion:reduce){.niv-surface{transition:none}}\n`\n","import { useCallback, useEffect, useRef, useState } from 'react'\n\nconst clamp = (value, min, max) => Math.min(max, Math.max(min, value))\nconst fitted = () => ({ zoom: 1, x: 0, y: 0 })\n\n// Coordinates are relative to the fitted image; 100% uses its decoded pixel width.\nexport function useImageTransform(identity) {\n const [transform, setTransform] = useState(fitted)\n const [dragging, setDragging] = useState(false)\n const [pixelScale, setPixelScale] = useState(1)\n const [geometry, setGeometry] = useState({ width: 0, height: 0, stageWidth: 0, stageHeight: 0 })\n const stageRef = useRef(null), surfaceRef = useRef(null), imageRef = useRef(null)\n const transformRef = useRef(transform)\n const pointers = useRef(new Map()), gesture = useRef()\n transformRef.current = transform\n\n const resetGesture = useCallback(() => {\n pointers.current.clear()\n gesture.current = undefined\n setDragging(false)\n }, [])\n const fit = useCallback(() => { resetGesture(); setTransform(fitted()) }, [resetGesture])\n useEffect(() => { fit() }, [identity, fit])\n\n const actualScale = () => imageRef.current?.naturalWidth / Math.max(1, surfaceRef.current?.offsetWidth || 1) || 1\n const boundedPan = useCallback((zoom, x, y) => {\n const stage = stageRef.current, surface = surfaceRef.current\n if (!stage || !surface || zoom <= 1) return { x: 0, y: 0 }\n const limitX = Math.max(0, (surface.offsetWidth * zoom - stage.clientWidth) / 2)\n const limitY = Math.max(0, (surface.offsetHeight * zoom - stage.clientHeight) / 2)\n return { x: clamp(x, -limitX, limitX), y: clamp(y, -limitY, limitY) }\n }, [])\n const setZoomAt = useCallback((zoom, clientX, clientY) => {\n const stage = stageRef.current\n if (!stage) return\n setTransform(current => {\n const next = clamp(zoom, 0.5, Math.max(8, actualScale()))\n const box = stage.getBoundingClientRect()\n const px = clientX - box.left - box.width / 2, py = clientY - box.top - box.height / 2\n const ratio = next / current.zoom\n return { zoom: next, ...boundedPan(next, px - (px - current.x) * ratio, py - (py - current.y) * ratio) }\n })\n }, [boundedPan])\n const actual = useCallback(() => {\n if (!imageRef.current?.naturalWidth) return\n resetGesture()\n setTransform({ zoom: actualScale(), x: 0, y: 0 })\n }, [resetGesture])\n const measure = useCallback(() => {\n const next = { width: surfaceRef.current?.offsetWidth ?? 0, height: surfaceRef.current?.offsetHeight ?? 0,\n stageWidth: stageRef.current?.clientWidth ?? 0, stageHeight: stageRef.current?.clientHeight ?? 0 }\n setGeometry(current => Object.keys(next).every(key => current[key] === next[key]) ? current : next)\n setPixelScale(1 / actualScale())\n setTransform(current => ({ ...current, ...boundedPan(current.zoom, current.x, current.y) }))\n }, [boundedPan])\n useEffect(() => {\n if (!stageRef.current || !surfaceRef.current) return\n const observer = new ResizeObserver(measure)\n observer.observe(stageRef.current)\n observer.observe(surfaceRef.current)\n measure()\n return () => observer.disconnect()\n }, [identity, measure])\n useEffect(() => {\n const stage = stageRef.current\n if (!stage) return\n const wheel = event => {\n event.preventDefault()\n const delta = event.deltaY * (event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? stage.clientHeight : 1)\n setZoomAt(transformRef.current.zoom * Math.exp(-delta * 0.0015), event.clientX, event.clientY)\n }\n stage.addEventListener('wheel', wheel, { passive: false })\n return () => stage.removeEventListener('wheel', wheel)\n }, [identity, setZoomAt])\n\n const onPointerDown = event => {\n if (event.button !== 0 || event.target.closest('button,a,input,textarea,select')) return\n const current = transformRef.current\n if (event.pointerType === 'mouse' && current.zoom <= 1) return\n event.currentTarget.setPointerCapture(event.pointerId)\n pointers.current.set(event.pointerId, { x: event.clientX, y: event.clientY })\n if (pointers.current.size === 2) {\n const [a, b] = [...pointers.current.values()]\n gesture.current = { kind: 'pinch', distance: Math.hypot(a.x - b.x, a.y - b.y), transform: current }\n } else {\n gesture.current = { kind: 'pan', x: event.clientX, y: event.clientY, transform: current }\n }\n setDragging(true)\n }\n const onPointerMove = event => {\n if (!pointers.current.has(event.pointerId)) return\n pointers.current.set(event.pointerId, { x: event.clientX, y: event.clientY })\n const start = gesture.current\n if (start?.kind === 'pinch' && pointers.current.size >= 2) {\n const [a, b] = [...pointers.current.values()]\n setZoomAt(start.transform.zoom * Math.hypot(a.x - b.x, a.y - b.y) / Math.max(1, start.distance), (a.x + b.x) / 2, (a.y + b.y) / 2)\n } else if (start?.kind === 'pan') {\n setTransform({ zoom: start.transform.zoom, ...boundedPan(start.transform.zoom, start.transform.x + event.clientX - start.x, start.transform.y + event.clientY - start.y) })\n }\n }\n const endPointer = event => {\n pointers.current.delete(event.pointerId)\n const remaining = [...pointers.current.values()][0]\n if (remaining) gesture.current = { kind: 'pan', ...remaining, transform: transformRef.current }\n else resetGesture()\n }\n return { transform, transformRef, dragging, pixelScale, geometry, stageRef, surfaceRef, imageRef, fit, actual, measure, setZoomAt, resetGesture,\n pointerHandlers: { onPointerDown, onPointerMove, onPointerUp: endPointer, onPointerCancel: endPointer, onLostPointerCapture: endPointer } }\n}\n","export function downloadPercent(value) {\n const { loaded, total } = value ?? {}\n if (!Number.isFinite(loaded) || loaded < 0 || !Number.isFinite(total) || total <= 0) return undefined\n return Math.min(100, Math.floor(loaded / total * 100))\n}\n\nexport async function readImageBlob(src, { signal, onProgress }) {\n const response = await fetch(src, { signal })\n if (!response.ok) throw new Error(`Image download failed: ${response.status}`)\n if (!response.body) return response.blob()\n // Compressed transfer lengths do not describe the decoded stream's size.\n const length = response.headers.get('content-encoding') ? undefined : Number(response.headers.get('content-length'))\n const total = Number.isFinite(length) && length > 0 ? length : undefined\n const reader = response.body.getReader()\n const chunks = []\n let loaded = 0\n try {\n while (true) {\n signal.throwIfAborted()\n const { done, value } = await reader.read()\n if (done) break\n chunks.push(value)\n loaded += value.byteLength\n onProgress({ loaded, total })\n }\n signal.throwIfAborted()\n return new Blob(chunks, { type: response.headers.get('content-type') || '' })\n } finally {\n reader.releaseLock()\n }\n}\n","export async function renderAnnotationImage(blob, annotations) {\n const image = await createImageBitmap(blob)\n try {\n const canvas = document.createElement('canvas')\n canvas.width = image.width\n canvas.height = image.height\n const context = canvas.getContext('2d')\n if (!context) throw new Error('Canvas unavailable')\n context.drawImage(image, 0, 0)\n const radius = Math.max(12, Math.min(image.width, image.height) / 60)\n annotations.forEach((annotation, index) => {\n const x = Math.max(radius, Math.min(image.width - radius, annotation.x * image.width))\n const y = Math.max(radius, Math.min(image.height - radius, annotation.y * image.height))\n context.beginPath()\n context.arc(x, y, radius, 0, Math.PI * 2)\n context.fillStyle = '#26272a'\n context.fill()\n context.strokeStyle = '#ffffff'\n context.lineWidth = Math.max(2, radius / 7)\n context.stroke()\n context.fillStyle = '#ffffff'\n context.font = `600 ${radius}px sans-serif`\n context.textAlign = 'center'\n context.textBaseline = 'middle'\n context.fillText(String(index + 1), x, y)\n })\n return await new Promise((resolve, reject) => canvas.toBlob(value => value ? resolve(value) : reject(new Error('Image encoding failed')), 'image/png'))\n } finally { image.close() }\n}\n\nconst hasOwn = Object.prototype.hasOwnProperty\n\n// Legacy hosts expose the selected session as `list.current`. Alpha2 keeps\n// that selection in the UI session retention projection instead, where the\n// main view is the only owner allowed to retain the current session.\nexport function currentSessionId(snapshot) {\n if (snapshot !== null && typeof snapshot === 'object' && hasOwn.call(snapshot, 'current')) return snapshot.current\n const retained = Object.entries(snapshot?.byId ?? {}).filter(([, entry]) => (entry?.retainedBy?.mainView ?? 0) > 0)\n return retained.length === 1 ? retained[0][0] : undefined\n}\n\n// Capture the destination when the viewer opens, then validate it again after\n// asynchronous image preparation. Never send or redirect another session.\nexport function createAnnotationCommit(ctx, { readBlob, render = renderAnnotationImage, formatNotes }) {\n let sessions, conversation, sessionId\n try {\n sessions = ctx.get('sessions')\n conversation = ctx.get('conversation')\n sessionId = currentSessionId(sessions.list.getSnapshot())\n } catch { /* The viewer also works without a conversation host. */ }\n return async entries => {\n if (!sessionId || !conversation?.input?.for || currentSessionId(sessions.list.getSnapshot()) !== sessionId) throw new Error('Composer unavailable or session changed')\n const prepared = await Promise.all(entries.map(async ({ item, annotations }) => {\n const image = await render(await readBlob(item.src), annotations)\n const name = `${String(item.name || 'image').replace(/\\.[^.]+$/, '')}-annotated.png`\n return { file: new File([image], name, { type: 'image/png' }), text: `${name}\\n${formatNotes(annotations)}` }\n }))\n if (currentSessionId(sessions.list.getSnapshot()) !== sessionId) throw new Error('Session changed')\n const input = conversation.input.for(sessions.scope(sessionId))\n const state = input.state.getSnapshot()\n if (state.phase !== 'plain' || state.occurrences?.length) throw new Error('Composer busy or contains references')\n const modern = typeof conversation.createDrafts === 'function'\n const add = modern ? input.addAttachments : input.addImages\n const release = modern ? conversation.releaseDraftAttachments : conversation.releaseDraftImages\n if (typeof add !== 'function' || typeof release !== 'function') throw new Error('Composer unavailable')\n const created = modern ? conversation.createDrafts(sessionId, prepared.map(item => item.file)) : conversation.createDraftImages(prepared.map(item => item.file))\n try {\n if (!add.call(input, created.map(item => item.id))) throw new Error('Composer busy')\n } catch (error) { release.call(conversation, created); throw error }\n input.setDraft([state.draft, ...prepared.map(item => item.text)].filter(Boolean).join('\\n\\n'))\n }\n}\n","import {\n useCallback, useEffect, useRef, useState, useSyncExternalStore,\n} from 'react'\nimport * as primitives from '@deepseek-ai/dsh-client-ui-primitives'\n\n// Official 0.1.7 renamed sized icon exports; resolve from the running host,\n// retaining older verified cores without copying its icon implementation.\nconst IconChevronLeftOutline14 = primitives.IconChevronLeftOutlineRegular ?? primitives.IconChevronLeftOutline14\nconst IconChevronRightOutline14 = primitives.IconChevronRightOutlineRegular ?? primitives.IconChevronRightOutline14\nconst IconCloseOutline16 = primitives.IconCloseOutlineRegular ?? primitives.IconCloseOutline16\nconst IconCopyOutline16 = primitives.IconCopyOutlineRegular ?? primitives.IconCopyOutline16\nconst IconDownloadOutline16 = primitives.IconDownloadOutlineRegular ?? primitives.IconDownloadOutline16\nconst IconEditOutline16 = primitives.IconEditOutlineRegular ?? primitives.IconEditOutline16\nconst IconFullscreenOutline16 = primitives.IconFullscreenOutlineRegular ?? primitives.IconFullscreenOutline16\nimport {\n imageItemsForButton, NativeImageViewerService, nativeImageButton,\n} from './viewer.js'\nimport { CSS as VIEWER_CSS } from './styles.js'\nimport { useImageTransform } from './image-transform.js'\nimport { downloadPercent, readImageBlob } from './image-download.js'\nimport { createAnnotationCommit } from './annotation-draft.js'\n\nexport const name = 'dsh-image-viewer'\nexport const inject = ['locale', 'slots']\n\nconst LOCALES = {\n en: {\n addingDraft: 'Adding image and notes to draft…', draftFailed: 'Could not add to draft. Return to the original session and keep the composer editable, then close to retry.', closeWithoutDraft: 'Close without adding',\n dialog: 'Image viewer', close: 'Close', fit: 'Fit', actual: '100%', download: 'Download',\n annotate: 'Mark region', cancelAnnotate: 'Cancel marking', regions: 'Region notes', regionHint: 'Click a point on the image, then add a note.',\n note: 'Region {value}', notePlaceholder: 'Describe what should change here…', removeNote: 'Remove region note',\n hideNotes: 'Hide notes', copyNotes: 'Copy notes', copied: 'Copied', previous: 'Previous image', next: 'Next image',\n zoomHint: 'Wheel to zoom · drag to pan · double-click for 100%', preparing: 'Preparing…', failed: 'Could not prepare this image.',\n cancelDownload: 'Cancel download', cancel: 'Cancel', loading: 'Loading image…', loadFailed: 'Image could not be loaded.', retry: 'Retry', copyFailed: 'Copy failed. Try again.',\n },\n zh: {\n addingDraft: '正在把图片和备注加入草稿…', draftFailed: '未能加入草稿。请回到原会话并确保输入框可编辑,再关闭以重试。', closeWithoutDraft: '仅关闭,不加入草稿',\n dialog: '图片查看器', close: '关闭', fit: '适应窗口', actual: '原始大小', download: '下载',\n annotate: '标记区域', cancelAnnotate: '取消标记', regions: '区域备注', regionHint: '点击图片中的位置,然后填写备注。',\n note: '区域 {value}', notePlaceholder: '描述这里需要怎样调整…', removeNote: '删除区域备注',\n hideNotes: '收起备注', copyNotes: '复制备注', copied: '已复制', previous: '上一张图片', next: '下一张图片',\n zoomHint: '滚轮缩放 · 拖动查看 · 双击切换原始大小', preparing: '正在准备…', failed: '暂时无法准备这张图片。',\n cancelDownload: '取消下载', cancel: '取消', loading: '正在加载图片…', loadFailed: '图片加载失败。', retry: '重试', copyFailed: '复制失败,请重试。',\n },\n}\n\nconst fill = (value, variables) => Object.entries(variables).reduce(\n (text, [key, replacement]) => text.replaceAll(`{${key}}`, String(replacement)),\n value,\n)\nconst clamp = (value, min, max) => Math.min(max, Math.max(min, value))\nconst bytesLabel = bytes => bytes === undefined ? undefined : bytes < 1024 * 1024\n ? `${Math.max(0.1, bytes / 1024).toLocaleString(undefined, { maximumFractionDigits: 1 })} KB`\n : `${(bytes / 1024 / 1024).toLocaleString(undefined, { maximumFractionDigits: 1 })} MB`\nconst downloadName = name => {\n const cleaned = String(name || 'image.png').replace(/[<>:\"/\\\\|?*\\u0000-\\u001f]/gu, '-').replace(/[. ]+$/u, '').trim()\n return cleaned === '' ? 'image.png' : cleaned\n}\nconst noteText = (annotations, t) => annotations.map((annotation, index) => {\n const label = fill(t('note'), { value: index + 1 })\n return `${label} (${Math.round(annotation.x * 100)}%, ${Math.round(annotation.y * 100)}%): ${annotation.note.trim()}`\n}).filter(line => !line.endsWith(': ')).join('\\n')\n\nfunction ViewerAction({ action, annotations, item, service, revision }) {\n const [state, setState] = useState('idle')\n const active = useRef(true)\n useEffect(() => { active.current = true; return () => { active.current = false } }, [])\n const invoke = async () => {\n if (state === 'pending') return\n setState('pending')\n try {\n await action.onInvoke({ annotations, item, src: item.src })\n if (!active.current || service.getSnapshot()?.revision !== revision) return\n setState('idle')\n if (action.closeOnSuccess) service.close()\n } catch { if (active.current) setState('failed') }\n }\n const label = state === 'pending' ? action.pendingLabel : state === 'failed' ? action.errorLabel : action.label\n return <button type=\"button\" className=\"niv-button\" disabled={state === 'pending'} onClick={() => { void invoke() }}><span className=\"niv-label\">{label}</span></button>\n}\n\nfunction ViewerDownload({ download, item, t }) {\n const [state, setState] = useState('idle')\n const [progress, setProgress] = useState(undefined)\n const controller = useRef(null)\n useEffect(() => () => {\n controller.current?.abort()\n controller.current = null\n }, [item.id, item.src, download])\n const invoke = async () => {\n if (controller.current !== null) {\n controller.current.abort()\n controller.current = null\n setState('idle')\n setProgress(undefined)\n return\n }\n const operation = new AbortController()\n controller.current = operation\n setState('pending')\n setProgress(undefined)\n const onProgress = value => {\n if (controller.current === operation) setProgress(downloadPercent(value))\n }\n try {\n if (download !== undefined) await download.onInvoke({ item, src: item.src, signal: operation.signal, onProgress })\n else {\n const blob = await readImageBlob(item.src, { signal: operation.signal, onProgress })\n if (operation.signal.aborted) return\n const url = URL.createObjectURL(blob)\n const link = document.createElement('a')\n link.href = url\n link.download = downloadName(item.name)\n document.body.append(link)\n link.click()\n link.remove()\n // Keep the URL alive while the browser takes ownership of the download.\n setTimeout(() => URL.revokeObjectURL(url), 60_000)\n }\n if (controller.current === operation) setState('idle')\n } catch { if (controller.current === operation) setState('failed') }\n finally { if (controller.current === operation) controller.current = null }\n }\n const label = state === 'pending' ? `${download?.pendingLabel ?? t('preparing')}${progress === undefined ? '' : ` ${progress}%`} · ${t('cancel')}` : state === 'failed' ? download?.errorLabel ?? t('failed') : t('download')\n return <button type=\"button\" className=\"niv-download\" aria-label={state === 'pending' ? t('cancelDownload') : label} title={label} onClick={() => { void invoke() }}><IconDownloadOutline16 /><span className=\"niv-label\">{label}</span></button>\n}\n\nfunction ViewerOverlay({ service, t }) {\n const request = useSyncExternalStore(service.subscribe, service.getSnapshot)\n const [cursor, setCursor] = useState({ revision: 0, index: 0 })\n const index = cursor.revision === request?.revision ? cursor.index : request?.index ?? 0\n const setIndex = update => setCursor(current => ({\n revision: request.revision,\n index: typeof update === 'function' ? update(current.revision === request.revision ? current.index : request.index) : update,\n }))\n const [imageState, setImageState] = useState('loading')\n const [attempt, setAttempt] = useState(0)\n const [copyFailed, setCopyFailed] = useState(false)\n const [annotating, setAnnotating] = useState(false)\n const [annotationsByImage, setAnnotationsByImage] = useState(service.getAnnotationsSnapshot)\n const annotationsByImageRef = useRef(annotationsByImage)\n const [selected, setSelected] = useState()\n const [focusNote, setFocusNote] = useState()\n const [copied, setCopied] = useState(false)\n const rootRef = useRef(null)\n annotationsByImageRef.current = annotationsByImage\n\n useEffect(() => {\n if (request === undefined) return\n setAnnotating(false)\n setSelected(undefined)\n setCopied(false)\n }, [request?.revision])\n\n const item = request?.items[index]\n const { transform, transformRef, dragging, pixelScale, geometry, stageRef, surfaceRef, imageRef, fit, actual, measure, setZoomAt, resetGesture, pointerHandlers } = useImageTransform(`${request?.revision}:${item?.id}:${item?.src}`)\n const annotations = item === undefined ? [] : annotationsByImage[item.id] ?? []\n const setAnnotations = useCallback((update) => {\n if (service.getSnapshot()?.committing) return\n if (item === undefined) return\n const previous = annotationsByImageRef.current[item.id] ?? []\n const next = typeof update === 'function' ? update(previous) : update\n const snapshot = { ...annotationsByImageRef.current, [item.id]: next }\n annotationsByImageRef.current = snapshot\n service.setAnnotations(item.id, next)\n setAnnotationsByImage(snapshot)\n setCopied(false)\n setCopyFailed(false)\n }, [item?.id, service])\n\n useEffect(() => {\n if (request === undefined) return undefined\n const previousOverflow = document.body.style.overflow\n document.body.style.overflow = 'hidden'\n rootRef.current?.focus()\n const onKeyDown = event => {\n if (service.getSnapshot()?.committing) { event.preventDefault(); event.stopPropagation(); return }\n if (event.defaultPrevented || event.isComposing) return\n if (event.key === 'Escape') {\n event.preventDefault()\n event.stopPropagation()\n if (event.target instanceof Element && event.target.closest('.niv-inline-note') !== null) {\n setSelected(undefined)\n rootRef.current?.focus()\n return\n }\n service.close()\n return\n }\n if (event.ctrlKey || event.metaKey || event.altKey) return\n const editing = event.target instanceof Element && event.target.closest('input,textarea,select,[contenteditable=\"true\"]') !== null\n if (!editing && ['ArrowLeft', 'ArrowRight', '+', '=', '-', 'f', 'F'].includes(event.key)) event.stopPropagation()\n if (!editing && event.key === 'ArrowLeft' && request.items.length > 1) {\n event.preventDefault(); setIndex(value => (value - 1 + request.items.length) % request.items.length)\n } else if (!editing && event.key === 'ArrowRight' && request.items.length > 1) {\n event.preventDefault(); setIndex(value => (value + 1) % request.items.length)\n } else if (!editing && (event.key === '+' || event.key === '=')) {\n event.preventDefault(); const box = stageRef.current?.getBoundingClientRect(); if (box) setZoomAt(transformRef.current.zoom * 1.2, box.left + box.width / 2, box.top + box.height / 2)\n } else if (!editing && event.key === '-') {\n event.preventDefault(); const box = stageRef.current?.getBoundingClientRect(); if (box) setZoomAt(transformRef.current.zoom / 1.2, box.left + box.width / 2, box.top + box.height / 2)\n } else if (!editing && event.key.toLowerCase() === 'f') {\n event.preventDefault(); fit()\n } else if (event.key === 'Tab') {\n const controls = [...rootRef.current.querySelectorAll('button:not(:disabled),a[href],input:not(:disabled),textarea:not(:disabled),[tabindex]:not([tabindex=\"-1\"])')]\n const first = controls[0]\n const last = controls.at(-1)\n if (event.shiftKey && (document.activeElement === first || document.activeElement === rootRef.current)) { event.preventDefault(); last?.focus() }\n else if (!event.shiftKey && (document.activeElement === last || document.activeElement === rootRef.current)) { event.preventDefault(); first?.focus() }\n }\n }\n const root = rootRef.current\n root.addEventListener('keydown', onKeyDown)\n return () => {\n document.body.style.overflow = previousOverflow\n root.removeEventListener('keydown', onKeyDown)\n }\n }, [request, service, fit, setZoomAt])\n\n useEffect(() => {\n if (focusNote === undefined) return\n const field = rootRef.current?.querySelector(`[data-note-id=\"${CSS.escape(focusNote)}\"] textarea`)\n field?.focus()\n setFocusNote(undefined)\n }, [focusNote, selected, annotations.length])\n\n useEffect(() => {\n setAnnotating(false)\n setSelected(undefined)\n setImageState('loading')\n setCopyFailed(false)\n setCopied(false)\n }, [item?.id, item?.src, request?.revision])\n\n const addAnnotation = event => {\n if (!annotating || event.target.closest('.niv-annotation')) return\n const bounds = surfaceRef.current?.getBoundingClientRect()\n if (bounds === undefined) return\n const annotation = {\n id: crypto.randomUUID(),\n x: clamp((event.clientX - bounds.left) / bounds.width, 0, 1),\n y: clamp((event.clientY - bounds.top) / bounds.height, 0, 1),\n note: '',\n }\n setAnnotations(current => [...current, annotation])\n setAnnotating(false)\n setSelected(annotation.id)\n setFocusNote(annotation.id)\n }\n const copyNotes = async () => {\n const text = noteText(annotations, t)\n if (text === '') return\n try {\n await navigator.clipboard.writeText(text)\n setCopied(true)\n setCopyFailed(false)\n } catch { setCopyFailed(true) }\n }\n\n if (request === undefined || item === undefined) return null\n const meta = [item.width && item.height ? `${item.width} × ${item.height}` : undefined, bytesLabel(item.bytes)].filter(Boolean).join(' · ')\n const showCounter = request.items.length > 1\n const annotationPosition = annotation => {\n // Only the image is scaled. Notes stay in screen coordinates so their text\n // is not rasterized inside a scaled compositor layer and then enlarged.\n const ratio = globalThis.devicePixelRatio || 1\n const align = value => Math.round(value * ratio) / ratio\n return {\n left: align(geometry.stageWidth / 2 + transform.x + (annotation.x - 0.5) * geometry.width * transform.zoom - 12),\n top: align(geometry.stageHeight / 2 + transform.y + (annotation.y - 0.5) * geometry.height * transform.zoom - 12),\n visibility: imageState === 'ready' ? 'visible' : 'hidden',\n }\n }\n return <div ref={rootRef} className=\"niv-root\" role=\"dialog\" aria-modal=\"true\" aria-label={t('dialog')} tabIndex={-1}>\n {request.committing || request.commitError ? <div className=\"niv-draft-status\" role=\"status\">{t(request.committing ? 'addingDraft' : 'draftFailed')}{request.commitError ? <button className=\"niv-button\" type=\"button\" onClick={() => { void service.close({ discard: true }) }}>{t('closeWithoutDraft')}</button> : null}</div> : null}\n <div className=\"niv-title\"><strong>{item.name}</strong>{meta !== '' ? <small>{meta}</small> : null}</div>\n <header className=\"niv-topbar\" role=\"toolbar\" aria-label={t('dialog')}>\n <div className=\"niv-actions\">\n {request.annotations ? <button type=\"button\" className=\"niv-button\" data-active={annotating} aria-label={annotating ? t('cancelAnnotate') : t('annotate')} aria-pressed={annotating} disabled={imageState !== 'ready'} onClick={() => { resetGesture(); setAnnotating(value => !value) }}><IconEditOutline16 /><span className=\"niv-label\">{annotating ? t('cancelAnnotate') : t('annotate')}</span></button> : null}\n {annotations.length > 0 ? <button type=\"button\" className=\"niv-button\" data-active={selected !== undefined} onClick={() => { const first = annotations[0]; setSelected(current => current === undefined ? first.id : undefined); if (selected === undefined) setFocusNote(first.id) }}>{annotations.length} <span className=\"niv-label\">{t('regions')}</span></button> : null}\n <button type=\"button\" className=\"niv-button\" aria-label={t('fit')} onClick={fit}><IconFullscreenOutline16 /><span className=\"niv-label\">{t('fit')}</span></button>\n <button type=\"button\" className=\"niv-button\" disabled={imageState !== 'ready'} onClick={actual}>{t('actual')}</button>\n <span className=\"niv-zoom\">{Math.round(transform.zoom * pixelScale * 100)}%</span>\n <ViewerDownload key={`${request.revision}:${index}:${item.src}`} download={item.download} item={item} t={t} />\n {annotations.some(annotation => annotation.note.trim() !== '') ? <button type=\"button\" className=\"niv-button niv-copy-notes\" aria-label={copyFailed ? t('copyFailed') : copied ? t('copied') : t('copyNotes')} onClick={() => { void copyNotes() }}><IconCopyOutline16 /><span className=\"niv-label\">{copyFailed ? t('copyFailed') : copied ? t('copied') : t('copyNotes')}</span></button> : null}\n {item.actions.map(action => <ViewerAction action={action} annotations={annotations} item={item} service={service} revision={request.revision} key={`${request.revision}:${item.src}:${action.id}`} />)}\n </div>\n </header>\n <button type=\"button\" className=\"niv-close-floating\" aria-label={t('close')} onClick={() => service.close()}><IconCloseOutline16 /></button>\n <div className=\"niv-workspace\">\n <main ref={stageRef} className=\"niv-stage\" data-dragging={dragging} data-annotating={annotating} onClick={event => { if (event.target === event.currentTarget && !annotating && transform.zoom === 1) service.close() }} {...(!annotating && imageState === 'ready' ? pointerHandlers : {})} onDoubleClick={event => { if (event.target.closest('button,a,input,textarea') || imageState !== 'ready') return; if (transform.zoom === 1) actual(); else fit() }}>\n {imageState !== 'ready' ? <div className=\"niv-load-status\" role={imageState === 'error' ? 'alert' : 'status'}>{t(imageState === 'error' ? 'loadFailed' : 'loading')}{imageState === 'error' ? <button type=\"button\" className=\"niv-button\" onClick={() => { setImageState('loading'); setAttempt(value => value + 1) }}>{t('retry')}</button> : null}</div> : null}\n <div ref={surfaceRef} className=\"niv-surface\" onClick={addAnnotation} style={{ visibility: imageState === 'ready' ? 'visible' : 'hidden', transform: `translate3d(${transform.x}px,${transform.y}px,0) scale(${transform.zoom})` }}>\n <img key={`${request.revision}:${item.id}:${attempt}`} ref={imageRef} className=\"niv-image\" src={item.src} alt={item.name} draggable=\"false\" onLoad={() => { setImageState('ready'); measure() }} onError={() => setImageState('error')} />\n </div>\n {annotations.map((annotation, position) => <div className=\"niv-annotation\" data-x={annotation.x < 0.38 ? 'right' : annotation.x > 0.62 ? 'left' : 'center'} data-y={annotation.y < 0.28 ? 'down' : 'up'} style={annotationPosition(annotation)} key={annotation.id}>\n <button type=\"button\" className=\"niv-pin\" data-active={selected === annotation.id} aria-label={fill(t('note'), { value: position + 1 })} onClick={event => { event.stopPropagation(); const opening = selected !== annotation.id; setSelected(opening ? annotation.id : undefined); if (opening) setFocusNote(annotation.id) }}>{position + 1}</button>\n {selected === annotation.id ? <div className=\"niv-inline-note\" data-note-id={annotation.id} onClick={event => event.stopPropagation()}>\n <span className=\"niv-inline-index\">{position + 1}</span>\n <textarea value={annotation.note} rows={1} aria-label={fill(t('note'), { value: position + 1 })} placeholder={t('notePlaceholder')} onChange={event => { const note = event.target.value; setAnnotations(current => current.map(entry => entry.id === annotation.id ? { ...entry, note } : entry)) }} onKeyDown={event => {\n if (event.nativeEvent?.isComposing || event.isComposing) return\n if ((event.key === 'Enter' && !event.shiftKey) || event.key === 'Escape') {\n event.preventDefault()\n event.stopPropagation()\n event.nativeEvent?.stopImmediatePropagation?.()\n setSelected(undefined)\n rootRef.current?.focus()\n }\n }} />\n <button type=\"button\" className=\"niv-note-remove\" aria-label={t('removeNote')} onClick={event => { event.stopPropagation(); setAnnotations(current => current.filter(entry => entry.id !== annotation.id)); setSelected(undefined); rootRef.current?.focus() }}><IconCloseOutline16 /></button>\n </div> : null}\n </div>)}\n {showCounter ? <>\n <button type=\"button\" className=\"niv-button niv-icon-only niv-nav niv-prev\" aria-label={t('previous')} onClick={event => { event.stopPropagation(); setIndex(value => (value - 1 + request.items.length) % request.items.length) }}><IconChevronLeftOutline14 /></button>\n <button type=\"button\" className=\"niv-button niv-icon-only niv-nav niv-next\" aria-label={t('next')} onClick={event => { event.stopPropagation(); setIndex(value => (value + 1) % request.items.length) }}><IconChevronRightOutline14 /></button>\n <span className=\"niv-counter\">{index + 1} / {request.items.length}</span>\n </> : annotating ? <span className=\"niv-hint\">{t('regionHint')}</span> : transform.zoom === 1 ? <span className=\"niv-hint\">{t('zoomHint')}</span> : null}\n </main>\n\n </div>\n </div>\n}\n\nfunction installOfficialImageBridge(service, ctx, t) {\n const onClick = event => {\n const match = nativeImageButton(event.target)\n if (match === undefined) return\n const { items, index } = imageItemsForButton(match)\n event.preventDefault()\n event.stopPropagation()\n event.stopImmediatePropagation()\n const commitAnnotations = createAnnotationCommit(ctx, {\n readBlob: src => readImageBlob(src, { signal: new AbortController().signal, onProgress: () => {} }),\n formatNotes: annotations => noteText(annotations, t),\n })\n service.open({ items, index, opener: match.button, source: 'dsh-native', annotations: true, commitAnnotations })\n }\n document.addEventListener('click', onClick, true)\n return () => { document.removeEventListener('click', onClick, true) }\n}\n\nexport function apply(ctx) {\n const service = new NativeImageViewerService()\n ctx.effect(() => ctx.locale.register(name, LOCALES), `${name}: dictionaries`)\n const t = ctx.locale.bind(name)\n ctx.effect(() => {\n const style = document.createElement('style')\n style.dataset.plugin = name\n style.textContent = VIEWER_CSS\n document.head.appendChild(style)\n return () => { style.remove() }\n }, `${name}: styles`)\n ctx.effect(() => {\n const disposeService = ctx.reflect.provide('nativeImageViewer', service)\n const disposeBridge = installOfficialImageBridge(service, ctx, t)\n return () => { disposeBridge(); void disposeService() }\n }, `${name}: optional viewer service and native image bridge`)\n ctx.slots.inject('shell.overlay', () => ctx.slots.register({\n name: 'shell.overlay', id: name, order: 20, inject: () => ({ service, t }),\n }, ViewerOverlay))\n}\n\nexport { NativeImageViewerService, normalizeViewerRequest } from './viewer.js'\n"],"mappings":"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"}
package/locale/en.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "Image Viewer",
4
+ "description": "Zoom, browse, and annotate images. Send selected regions and notes to your draft."
5
+ }
6
+ }
package/locale/zh.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "图片查看器",
4
+ "description": "缩放、浏览与标注图片,将选区和备注带回输入框。"
5
+ }
6
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-image-viewer",
3
- "version": "0.1.2-beta.1",
3
+ "version": "0.1.2",
4
4
  "description": "Zoom, pan, download, gallery, and region-note image viewer for DeepSeek Harness",
5
5
  "keywords": [
6
6
  "dsh-plugin",
@@ -14,13 +14,17 @@
14
14
  "license": "MIT",
15
15
  "type": "module",
16
16
  "main": "./lib/index.js",
17
+ "icon": "./assets/icon.svg",
17
18
  "exports": {
18
19
  ".": "./lib/index.js",
19
20
  "./client": "./lib/client.js",
20
21
  "./cordis.patch.yml": "./cordis.patch.yml",
21
- "./package.json": "./package.json"
22
+ "./package.json": "./package.json",
23
+ "./locale/*": "./locale/*"
22
24
  },
23
25
  "files": [
26
+ "assets/icon.svg",
27
+ "locale/*.json",
24
28
  "lib/*.js",
25
29
  "lib/*.map",
26
30
  "cordis.patch.yml",
@@ -62,11 +66,11 @@
62
66
  "node": "^22.19.0 || >=24.0.0"
63
67
  },
64
68
  "peerDependencies": {
65
- "@deepseek-ai/cordis": "4.0.1 || 4.0.2",
66
- "@deepseek-ai/dsh-client-locale": "0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.2-alpha.2 || 0.1.2-alpha.3 || 0.1.3-alpha.2 || 0.1.5-alpha.1 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
67
- "@deepseek-ai/dsh-client-ui-layout": "0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.2-alpha.2 || 0.1.2-alpha.3 || 0.1.3-alpha.2 || 0.1.5-alpha.1 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
68
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.2-alpha.2 || 0.1.2-alpha.3 || 0.1.3-alpha.2 || 0.1.5-alpha.1 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
69
- "@deepseek-ai/dsh-client-ui-slots": "0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.2-alpha.2 || 0.1.2-alpha.3 || 0.1.3-alpha.2 || 0.1.5-alpha.1 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
69
+ "@deepseek-ai/cordis": "4.0.1 || 4.0.2 || 4.0.3",
70
+ "@deepseek-ai/dsh-client-locale": "0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.2-alpha.2 || 0.1.2-alpha.3 || 0.1.3-alpha.2 || 0.1.5-alpha.1 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1",
71
+ "@deepseek-ai/dsh-client-ui-layout": "0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.2-alpha.2 || 0.1.2-alpha.3 || 0.1.3-alpha.2 || 0.1.5-alpha.1 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1",
72
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.2-alpha.2 || 0.1.2-alpha.3 || 0.1.3-alpha.2 || 0.1.5-alpha.1 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1",
73
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.2-alpha.2 || 0.1.2-alpha.3 || 0.1.3-alpha.2 || 0.1.5-alpha.1 || 0.1.6-alpha.1 || 0.1.6-alpha.2 || 0.1.7-alpha.1",
70
74
  "react": "^18.2.0"
71
75
  },
72
76
  "peerDependenciesMeta": {