dsh-image-viewer 0.1.1 → 0.1.2-beta.1
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/compatibility.json +2 -1
- package/lib/client.js +10 -4
- package/lib/client.js.map +1 -1
- package/package.json +7 -7
package/compatibility.json
CHANGED
package/lib/client.js
CHANGED
|
@@ -438,15 +438,21 @@ window.__ModuleLoader__.load({
|
|
|
438
438
|
image.close();
|
|
439
439
|
}
|
|
440
440
|
}
|
|
441
|
+
const hasOwn = Object.prototype.hasOwnProperty;
|
|
442
|
+
function currentSessionId(snapshot) {
|
|
443
|
+
if (snapshot !== null && typeof snapshot === "object" && hasOwn.call(snapshot, "current")) return snapshot.current;
|
|
444
|
+
const retained = Object.entries(snapshot?.byId ?? {}).filter(([, entry]) => (entry?.retainedBy?.mainView ?? 0) > 0);
|
|
445
|
+
return retained.length === 1 ? retained[0][0] : void 0;
|
|
446
|
+
}
|
|
441
447
|
function createAnnotationCommit(ctx, { readBlob, render = renderAnnotationImage, formatNotes }) {
|
|
442
448
|
let sessions, conversation, sessionId;
|
|
443
449
|
try {
|
|
444
450
|
sessions = ctx.get("sessions");
|
|
445
451
|
conversation = ctx.get("conversation");
|
|
446
|
-
sessionId = sessions.list.getSnapshot()
|
|
452
|
+
sessionId = currentSessionId(sessions.list.getSnapshot());
|
|
447
453
|
} catch {}
|
|
448
454
|
return async (entries) => {
|
|
449
|
-
if (!sessionId || !conversation?.input?.for || sessions.list.getSnapshot()
|
|
455
|
+
if (!sessionId || !conversation?.input?.for || currentSessionId(sessions.list.getSnapshot()) !== sessionId) throw new Error("Composer unavailable or session changed");
|
|
450
456
|
const prepared = await Promise.all(entries.map(async ({ item, annotations }) => {
|
|
451
457
|
const image = await render(await readBlob(item.src), annotations);
|
|
452
458
|
const name = `${String(item.name || "image").replace(/\.[^.]+$/, "")}-annotated.png`;
|
|
@@ -455,7 +461,7 @@ window.__ModuleLoader__.load({
|
|
|
455
461
|
text: `${name}\n${formatNotes(annotations)}`
|
|
456
462
|
};
|
|
457
463
|
}));
|
|
458
|
-
if (sessions.list.getSnapshot()
|
|
464
|
+
if (currentSessionId(sessions.list.getSnapshot()) !== sessionId) throw new Error("Session changed");
|
|
459
465
|
const input = conversation.input.for(sessions.scope(sessionId));
|
|
460
466
|
const state = input.state.getSnapshot();
|
|
461
467
|
if (state.phase !== "plain" || state.occurrences?.length) throw new Error("Composer busy or contains references");
|
|
@@ -543,7 +549,7 @@ window.__ModuleLoader__.load({
|
|
|
543
549
|
};
|
|
544
550
|
const fill = (value, variables) => Object.entries(variables).reduce((text, [key, replacement]) => text.replaceAll(`{${key}}`, String(replacement)), value);
|
|
545
551
|
const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
546
|
-
const bytesLabel = (bytes) => bytes === void 0 ? void 0 : bytes <
|
|
552
|
+
const bytesLabel = (bytes) => bytes === void 0 ? void 0 : bytes < 1048576 ? `${Math.max(.1, bytes / 1024).toLocaleString(void 0, { maximumFractionDigits: 1 })} KB` : `${(bytes / 1024 / 1024).toLocaleString(void 0, { maximumFractionDigits: 1 })} MB`;
|
|
547
553
|
const downloadName = (name) => {
|
|
548
554
|
const cleaned = String(name || "image.png").replace(/[<>:"/\\|?*\u0000-\u001f]/gu, "-").replace(/[. ]+$/u, "").trim();
|
|
549
555
|
return cleaned === "" ? "image.png" : cleaned;
|
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["#listeners","#snapshot","#annotationsByImage","#closing","#revision","#openingAnnotations","#emit","CSS","clamp","IconDownloadOutline16","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\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 = sessions.list.getSnapshot().current\n } catch { /* The viewer also works without a conversation host. */ }\n return async entries => {\n if (!sessionId || !conversation?.input?.for || sessions.list.getSnapshot().current !== 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 (sessions.list.getSnapshot().current !== 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","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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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-image-viewer",
|
|
3
|
-
"version": "0.1.1",
|
|
3
|
+
"version": "0.1.2-beta.1",
|
|
4
4
|
"description": "Zoom, pan, download, gallery, and region-note image viewer for DeepSeek Harness",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dsh-plugin",
|
|
@@ -63,10 +63,10 @@
|
|
|
63
63
|
},
|
|
64
64
|
"peerDependencies": {
|
|
65
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",
|
|
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",
|
|
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",
|
|
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",
|
|
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",
|
|
70
70
|
"react": "^18.2.0"
|
|
71
71
|
},
|
|
72
72
|
"peerDependenciesMeta": {
|
|
@@ -95,10 +95,10 @@
|
|
|
95
95
|
"@deepseek-ai/dsh-client-ui-layout": "0.1.2-rc.1",
|
|
96
96
|
"@deepseek-ai/dsh-client-ui-primitives": "0.1.2-rc.1",
|
|
97
97
|
"@deepseek-ai/dsh-client-ui-slots": "0.1.2-rc.1",
|
|
98
|
-
"playwright": "1.
|
|
98
|
+
"playwright": "1.63.0",
|
|
99
99
|
"react": "18.3.1",
|
|
100
100
|
"react-dom": "18.3.1",
|
|
101
|
-
"tsdown": "0.
|
|
101
|
+
"tsdown": "0.23.0"
|
|
102
102
|
},
|
|
103
103
|
"scripts": {
|
|
104
104
|
"build": "tsdown --config tsdown.config.mjs",
|