dsh-image-viewer 0.1.0-beta.10

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","names":["#listeners","#snapshot","#annotationsByImage","#revision","#emit","CSS","IconDownloadOutline16","IconEditOutline16","IconFullscreenOutline16","IconCloseOutline16","IconChevronLeftOutline14","IconChevronRightOutline14","IconCopyOutline16","VIEWER_CSS"],"sources":["../src/viewer.js","../src/styles.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 : `image-${position + 1}`,\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 }\n}\n\nexport class NativeImageViewerService {\n #listeners = new Set()\n #revision = 0\n #snapshot\n #annotationsByImage = new Map()\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 const normalized = normalizeViewerRequest(request)\n if (normalized === undefined) return false\n this.#revision += 1\n this.#snapshot = { ...normalized, revision: this.#revision }\n this.#emit()\n return true\n }\n\n close() {\n if (this.#snapshot === undefined) return\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 }\n const rail = button.closest('[role=\"group\"]')\n if (rail !== null && button.hasAttribute('title')) return { button, image, group: rail }\n return undefined\n}\n\nexport function imageItemsForButton(match) {\n const buttons = match.group?.querySelectorAll('button[data-variant=\"single\"],button[data-variant=\"tile\"],button[title]')\n ?? []\n const candidates = [...buttons].flatMap((button, index) => {\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-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-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.niv-copy-notes{position:absolute;right:20px;bottom:22px;z-index:6;display:inline-flex;align-items:center;gap:6px;height:32px;padding:0 11px;border:1px solid rgba(255,255,255,.1);border-radius:999px;background:rgba(38,39,43,.86);color:rgba(255,255,255,.82);font:inherit;font-size:12px;cursor:pointer;backdrop-filter:blur(16px)}\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))}.niv-copy-notes{display:none}}\n@media(prefers-reduced-motion:reduce){.niv-surface{transition:none}}\n`\n","import {\n useCallback, useEffect, useMemo, 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'\n\nexport const name = 'dsh-image-viewer'\nexport const inject = ['locale', 'slots']\n\nconst LOCALES = {\n en: {\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 },\n zh: {\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 },\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 }) {\n const [state, setState] = useState('idle')\n const invoke = async () => {\n if (state === 'pending') return\n setState('pending')\n try {\n await action.onInvoke({ annotations, item, src: item.src })\n setState('idle')\n if (action.closeOnSuccess) service.close()\n } catch { 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 invoke = async () => {\n if (state === 'pending') return\n setState('pending')\n try { await download.onInvoke({ item, src: item.src }); setState('idle') } catch { setState('failed') }\n }\n const label = state === 'pending' ? download.pendingLabel ?? t('preparing') : state === 'failed' ? download.errorLabel ?? t('failed') : t('download')\n return <button type=\"button\" className=\"niv-download\" disabled={state === 'pending'} 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 [index, setIndex] = useState(0)\n const [transform, setTransform] = useState({ zoom: 1, x: 0, y: 0 })\n const [dragging, setDragging] = 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 const stageRef = useRef(null)\n const surfaceRef = useRef(null)\n const imageRef = useRef(null)\n const pointersRef = useRef(new Map())\n const gestureRef = useRef()\n const transformRef = useRef(transform)\n transformRef.current = transform\n annotationsByImageRef.current = annotationsByImage\n\n useEffect(() => {\n if (request === undefined) return\n setIndex(request.index)\n setTransform({ zoom: 1, x: 0, y: 0 })\n setDragging(false)\n setAnnotating(false)\n setSelected(undefined)\n setCopied(false)\n }, [request?.revision])\n\n const item = request?.items[index]\n const annotations = item === undefined ? [] : annotationsByImage[item.id] ?? []\n const setAnnotations = useCallback((update) => {\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 }, [item?.id, service])\n\n const boundedPan = useCallback((zoom, x, y) => {\n const stage = stageRef.current\n const surface = surfaceRef.current\n if (stage === null || surface === null || zoom <= 1) return { x: 0, y: 0 }\n const limitX = Math.max(0, (surface.offsetWidth * zoom - stage.clientWidth) / 2) + 28\n const limitY = Math.max(0, (surface.offsetHeight * zoom - stage.clientHeight) / 2) + 28\n return { x: clamp(x, -limitX, limitX), y: clamp(y, -limitY, limitY) }\n }, [])\n\n const setZoomAt = useCallback((nextZoom, clientX, clientY) => {\n const stage = stageRef.current\n if (stage === null) return\n setTransform(current => {\n const next = clamp(nextZoom, 0.5, 8)\n const box = stage.getBoundingClientRect()\n const px = clientX - box.left - box.width / 2\n const py = clientY - box.top - box.height / 2\n const ratio = next / current.zoom\n const pan = boundedPan(next, px - (px - current.x) * ratio, py - (py - current.y) * ratio)\n return { zoom: next, ...pan }\n })\n }, [boundedPan])\n\n const fit = useCallback(() => { setTransform({ zoom: 1, x: 0, y: 0 }) }, [])\n const actual = useCallback(() => {\n const image = imageRef.current\n const surface = surfaceRef.current\n if (image === null || surface === null || image.naturalWidth === 0) return\n const zoom = clamp(image.naturalWidth / Math.max(1, surface.offsetWidth), 1, 8)\n setTransform({ zoom, x: 0, y: 0 })\n }, [])\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 (event.key === 'Escape') {\n event.preventDefault()\n if (event.target instanceof Element && event.target.closest('.niv-inline-note') !== null) {\n setSelected(undefined)\n return\n }\n service.close()\n return\n }\n const editing = event.target instanceof HTMLInputElement || event.target instanceof HTMLTextAreaElement\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) { event.preventDefault(); last?.focus() }\n else if (!event.shiftKey && document.activeElement === last) { event.preventDefault(); first?.focus() }\n }\n }\n document.addEventListener('keydown', onKeyDown)\n return () => {\n document.body.style.overflow = previousOverflow\n document.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 setTransform({ zoom: 1, x: 0, y: 0 })\n setDragging(false)\n setAnnotating(false)\n setSelected(undefined)\n }, [item?.id])\n\n const onWheel = useCallback(event => {\n event.preventDefault()\n setZoomAt(transformRef.current.zoom * Math.exp(-event.deltaY * 0.0015), event.clientX, event.clientY)\n }, [setZoomAt])\n useEffect(() => {\n const stage = stageRef.current\n if (stage === null || request === undefined) return undefined\n stage.addEventListener('wheel', onWheel, { passive: false })\n return () => stage.removeEventListener('wheel', onWheel)\n }, [onWheel, request])\n const onPointerDown = event => {\n if (event.button !== 0 || annotating) return\n if (event.target instanceof Element && event.target.closest('button,a,input,textarea,select')) return\n if (event.pointerType === 'mouse' && transform.zoom <= 1) return\n event.currentTarget.setPointerCapture(event.pointerId)\n pointersRef.current.set(event.pointerId, { x: event.clientX, y: event.clientY })\n if (pointersRef.current.size === 2) {\n const [a, b] = [...pointersRef.current.values()]\n gestureRef.current = { kind: 'pinch', distance: Math.hypot(a.x - b.x, a.y - b.y), transform }\n } else if (!annotating && transform.zoom > 1) {\n gestureRef.current = { kind: 'pan', x: event.clientX, y: event.clientY, transform }\n setDragging(true)\n }\n }\n const onPointerMove = event => {\n if (!pointersRef.current.has(event.pointerId)) return\n pointersRef.current.set(event.pointerId, { x: event.clientX, y: event.clientY })\n const gesture = gestureRef.current\n if (gesture?.kind === 'pinch' && pointersRef.current.size >= 2) {\n const [a, b] = [...pointersRef.current.values()]\n const distance = Math.max(1, Math.hypot(a.x - b.x, a.y - b.y))\n setZoomAt(gesture.transform.zoom * distance / Math.max(1, gesture.distance), (a.x + b.x) / 2, (a.y + b.y) / 2)\n } else if (gesture?.kind === 'pan') {\n const pan = boundedPan(gesture.transform.zoom, gesture.transform.x + event.clientX - gesture.x, gesture.transform.y + event.clientY - gesture.y)\n setTransform({ zoom: gesture.transform.zoom, ...pan })\n }\n }\n const endPointer = event => {\n pointersRef.current.delete(event.pointerId)\n if (pointersRef.current.size === 0) { gestureRef.current = undefined; setDragging(false) }\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 await navigator.clipboard.writeText(text)\n setCopied(true)\n window.setTimeout(() => { setCopied(false) }, 1200)\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 return <div ref={rootRef} className=\"niv-root\" role=\"dialog\" aria-modal=\"true\" aria-label={t('dialog')} tabIndex={-1}>\n <div className=\"niv-title niv-sr-only\"><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} onClick={() => 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\" onClick={actual}>{t('actual')}</button>\n <span className=\"niv-zoom\">{Math.round(transform.zoom * 100)}%</span>\n {item.download === undefined\n ? <a className=\"niv-download\" href={item.src} download={downloadName(item.name)}><IconDownloadOutline16 /><span className=\"niv-label\">{t('download')}</span></a>\n : <ViewerDownload download={item.download} item={item} t={t} />}\n {item.actions.map(action => <ViewerAction action={action} annotations={annotations} item={item} service={service} key={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() }} onPointerDown={onPointerDown} onPointerMove={onPointerMove} onPointerUp={endPointer} onPointerCancel={endPointer} onDoubleClick={() => { if (transform.zoom === 1) actual(); else fit() }}>\n <div ref={surfaceRef} className=\"niv-surface\" onClick={addAnnotation} style={{ transform: `translate3d(${transform.x}px,${transform.y}px,0) scale(${transform.zoom})` }}>\n <img ref={imageRef} className=\"niv-image\" src={item.src} alt={item.name} draggable=\"false\" />\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={{ left: `${annotation.x * 100}%`, top: `${annotation.y * 100}%`, transform: `translate(-50%,-50%) scale(${1 / transform.zoom})` }} 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.key === 'Enter' && !event.shiftKey) || event.key === 'Escape') {\n event.preventDefault()\n event.stopPropagation()\n event.nativeEvent?.stopImmediatePropagation?.()\n setSelected(undefined)\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) }}><IconCloseOutline16 /></button>\n </div> : null}\n </div>)}\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 {annotations.some(annotation => annotation.note.trim() !== '') ? <button type=\"button\" className=\"niv-copy-notes\" onClick={() => { void copyNotes() }}><IconCopyOutline16 />{copied ? t('copied') : t('copyNotes')}</button> : null}\n </div>\n </div>\n}\n\nfunction installOfficialImageBridge(service) {\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 service.open({ items, index, opener: match.button, source: 'dsh-native', annotations: true })\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 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)\n return () => { disposeBridge(); void disposeService() }\n }, `${name}: optional viewer service and native image bridge`)\n const t = ctx.locale.bind(name)\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/lib/index.js ADDED
@@ -0,0 +1,5 @@
1
+ //#region src/index.js
2
+ const name = "native-image-viewer";
3
+ function apply() {}
4
+ //#endregion
5
+ export { apply, name };
package/package.json ADDED
@@ -0,0 +1,109 @@
1
+ {
2
+ "name": "dsh-image-viewer",
3
+ "version": "0.1.0-beta.10",
4
+ "description": "Zoom, pan, download, gallery, and region-note image viewer for DeepSeek Harness",
5
+ "keywords": [
6
+ "dsh-plugin",
7
+ "deepseek-harness",
8
+ "image-viewer",
9
+ "lightbox",
10
+ "zoom",
11
+ "annotation"
12
+ ],
13
+ "author": "WSL043",
14
+ "license": "MIT",
15
+ "type": "module",
16
+ "main": "./lib/index.js",
17
+ "exports": {
18
+ ".": "./lib/index.js",
19
+ "./client": "./lib/client.js",
20
+ "./cordis.patch.yml": "./cordis.patch.yml",
21
+ "./package.json": "./package.json"
22
+ },
23
+ "files": [
24
+ "lib/*.js",
25
+ "lib/*.map",
26
+ "cordis.patch.yml",
27
+ "README.md",
28
+ "README.zh-CN.md",
29
+ "compatibility.json",
30
+ "AGENTS.md",
31
+ "LICENSE",
32
+ "SECURITY.md",
33
+ "THIRD_PARTY_NOTICES.md"
34
+ ],
35
+ "dsh": {
36
+ "bundle": {
37
+ "patch": "./cordis.patch.yml"
38
+ },
39
+ "client": {
40
+ "inject": [
41
+ "@deepseek-ai/dsh-client-locale",
42
+ "@deepseek-ai/dsh-client-ui-layout",
43
+ "@deepseek-ai/dsh-client-ui-primitives",
44
+ "@deepseek-ai/dsh-client-ui-slots"
45
+ ],
46
+ "platform": "web"
47
+ }
48
+ },
49
+ "repository": {
50
+ "type": "git",
51
+ "url": "git+https://github.com/WSL043/dsh-image-viewer.git"
52
+ },
53
+ "bugs": {
54
+ "url": "https://github.com/WSL043/dsh-image-viewer/issues"
55
+ },
56
+ "homepage": "https://github.com/WSL043/dsh-image-viewer#readme",
57
+ "publishConfig": {
58
+ "access": "public",
59
+ "tag": "beta"
60
+ },
61
+ "engines": {
62
+ "node": "^22.19.0 || >=24.0.0"
63
+ },
64
+ "peerDependencies": {
65
+ "@deepseek-ai/cordis": "4.0.1 || 4.0.2",
66
+ "@deepseek-ai/dsh-client-locale": "0.1.1-rc.2 || 0.1.2-rc.1 || 0.1.2-alpha.2 || 0.1.2-alpha.3 || 0.1.3-alpha.2",
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",
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",
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",
70
+ "react": "^18.2.0"
71
+ },
72
+ "peerDependenciesMeta": {
73
+ "@deepseek-ai/cordis": {
74
+ "optional": true
75
+ },
76
+ "@deepseek-ai/dsh-client-locale": {
77
+ "optional": true
78
+ },
79
+ "@deepseek-ai/dsh-client-ui-layout": {
80
+ "optional": true
81
+ },
82
+ "@deepseek-ai/dsh-client-ui-primitives": {
83
+ "optional": true
84
+ },
85
+ "@deepseek-ai/dsh-client-ui-slots": {
86
+ "optional": true
87
+ },
88
+ "react": {
89
+ "optional": true
90
+ }
91
+ },
92
+ "devDependencies": {
93
+ "@deepseek-ai/cordis": "4.0.2",
94
+ "@deepseek-ai/dsh-client-locale": "0.1.2-rc.1",
95
+ "@deepseek-ai/dsh-client-ui-layout": "0.1.2-rc.1",
96
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.2-rc.1",
97
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.2-rc.1",
98
+ "playwright": "1.62.1",
99
+ "react": "18.3.1",
100
+ "tsdown": "0.22.2"
101
+ },
102
+ "scripts": {
103
+ "build": "tsdown --config tsdown.config.mjs",
104
+ "test:behavior": "node --test tests/viewer.test.mjs",
105
+ "test:delivery": "node --test tests/package-contract.test.mjs",
106
+ "test": "node --test tests/*.test.mjs",
107
+ "check": "pnpm run test && pnpm run build && pnpm pack --pack-destination .artifacts"
108
+ }
109
+ }