@researai/deepscientist 1.5.15 → 1.5.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +385 -104
- package/bin/ds.js +1241 -110
- package/docs/en/00_QUICK_START.md +100 -19
- package/docs/en/01_SETTINGS_REFERENCE.md +34 -1
- package/docs/en/02_START_RESEARCH_GUIDE.md +7 -0
- package/docs/en/05_TUI_GUIDE.md +6 -0
- package/docs/en/06_RUNTIME_AND_CANVAS.md +4 -3
- package/docs/en/09_DOCTOR.md +25 -8
- package/docs/en/14_PROMPT_SKILLS_AND_MCP_GUIDE.md +63 -13
- package/docs/en/15_CODEX_PROVIDER_SETUP.md +37 -11
- package/docs/en/19_EXTERNAL_CONTROLLER_GUIDE.md +226 -0
- package/docs/en/19_LOCAL_BROWSER_AUTH.md +70 -0
- package/docs/en/20_WORKSPACE_MODES_GUIDE.md +250 -0
- package/docs/en/21_LOCAL_MODEL_BACKENDS_GUIDE.md +283 -0
- package/docs/en/91_DEVELOPMENT.md +237 -0
- package/docs/en/README.md +24 -2
- package/docs/zh/00_QUICK_START.md +89 -19
- package/docs/zh/01_SETTINGS_REFERENCE.md +34 -1
- package/docs/zh/02_START_RESEARCH_GUIDE.md +7 -0
- package/docs/zh/05_TUI_GUIDE.md +6 -0
- package/docs/zh/09_DOCTOR.md +26 -9
- package/docs/zh/14_PROMPT_SKILLS_AND_MCP_GUIDE.md +63 -13
- package/docs/zh/15_CODEX_PROVIDER_SETUP.md +37 -11
- package/docs/zh/19_EXTERNAL_CONTROLLER_GUIDE.md +226 -0
- package/docs/zh/19_LOCAL_BROWSER_AUTH.md +68 -0
- package/docs/zh/20_WORKSPACE_MODES_GUIDE.md +251 -0
- package/docs/zh/21_LOCAL_MODEL_BACKENDS_GUIDE.md +281 -0
- package/docs/zh/README.md +24 -2
- package/install.sh +46 -4
- package/package.json +2 -1
- package/pyproject.toml +1 -1
- package/src/deepscientist/__init__.py +1 -1
- package/src/deepscientist/acp/envelope.py +6 -0
- package/src/deepscientist/artifact/service.py +647 -22
- package/src/deepscientist/bash_exec/service.py +234 -9
- package/src/deepscientist/bridges/connectors.py +8 -2
- package/src/deepscientist/cli.py +115 -19
- package/src/deepscientist/codex_cli_compat.py +367 -22
- package/src/deepscientist/config/models.py +2 -1
- package/src/deepscientist/config/service.py +183 -13
- package/src/deepscientist/daemon/api/handlers.py +255 -31
- package/src/deepscientist/daemon/api/router.py +9 -0
- package/src/deepscientist/daemon/app.py +1146 -105
- package/src/deepscientist/diagnostics/__init__.py +6 -0
- package/src/deepscientist/diagnostics/runner_failures.py +130 -0
- package/src/deepscientist/doctor.py +207 -3
- package/src/deepscientist/gitops/__init__.py +10 -1
- package/src/deepscientist/gitops/diff.py +129 -0
- package/src/deepscientist/gitops/service.py +4 -1
- package/src/deepscientist/mcp/server.py +39 -0
- package/src/deepscientist/prompts/builder.py +275 -34
- package/src/deepscientist/quest/layout.py +15 -2
- package/src/deepscientist/quest/service.py +707 -55
- package/src/deepscientist/quest/stage_views.py +6 -1
- package/src/deepscientist/runners/codex.py +143 -43
- package/src/deepscientist/shared.py +19 -0
- package/src/deepscientist/skills/__init__.py +2 -2
- package/src/deepscientist/skills/installer.py +196 -5
- package/src/deepscientist/skills/registry.py +66 -0
- package/src/prompts/connectors/qq.md +18 -8
- package/src/prompts/connectors/weixin.md +16 -6
- package/src/prompts/contracts/shared_interaction.md +14 -2
- package/src/prompts/system.md +23 -5
- package/src/prompts/system_copilot.md +56 -0
- package/src/skills/analysis-campaign/SKILL.md +1 -0
- package/src/skills/baseline/SKILL.md +8 -0
- package/src/skills/decision/SKILL.md +8 -0
- package/src/skills/experiment/SKILL.md +8 -0
- package/src/skills/figure-polish/SKILL.md +1 -0
- package/src/skills/finalize/SKILL.md +1 -0
- package/src/skills/idea/SKILL.md +1 -0
- package/src/skills/intake-audit/SKILL.md +8 -0
- package/src/skills/mentor/SKILL.md +217 -0
- package/src/skills/mentor/references/correction-rules.md +210 -0
- package/src/skills/mentor/references/knowledge-profile.md +91 -0
- package/src/skills/mentor/references/persona-profile.md +138 -0
- package/src/skills/mentor/references/taste-profile.md +128 -0
- package/src/skills/mentor/references/thought-style-profile.md +138 -0
- package/src/skills/mentor/references/work-profile.md +289 -0
- package/src/skills/mentor/references/workflow-profile.md +240 -0
- package/src/skills/optimize/SKILL.md +1 -0
- package/src/skills/rebuttal/SKILL.md +1 -0
- package/src/skills/review/SKILL.md +1 -0
- package/src/skills/scout/SKILL.md +8 -0
- package/src/skills/write/SKILL.md +1 -0
- package/src/tui/dist/app/AppContainer.js +19 -11
- package/src/tui/dist/index.js +4 -1
- package/src/tui/dist/lib/api.js +33 -3
- package/src/tui/package.json +1 -1
- package/src/ui/dist/assets/AiManusChatView-Bv-Z8YpU.js +204 -0
- package/src/ui/dist/assets/AnalysisPlugin-BCKAfjba.js +1 -0
- package/src/ui/dist/assets/CliPlugin-BCKcpc35.js +109 -0
- package/src/ui/dist/assets/CodeEditorPlugin-DbOfSJ8K.js +2 -0
- package/src/ui/dist/assets/CodeViewerPlugin-CbaFRrUU.js +270 -0
- package/src/ui/dist/assets/DocViewerPlugin-DAjLVeQD.js +7 -0
- package/src/ui/dist/assets/GitCommitViewerPlugin-CIUqbUDO.js +1 -0
- package/src/ui/dist/assets/GitDiffViewerPlugin-CQACjoAA.js +6 -0
- package/src/ui/dist/assets/GitSnapshotViewer-0r4nLPke.js +30 -0
- package/src/ui/dist/assets/ImageViewerPlugin-nBOmI2v_.js +26 -0
- package/src/ui/dist/assets/LabCopilotPanel-BHxOxF4z.js +14 -0
- package/src/ui/dist/assets/LabPlugin-BKoZGs95.js +22 -0
- package/src/ui/dist/assets/LatexPlugin-ZwtV8pIp.js +25 -0
- package/src/ui/dist/assets/MarkdownViewerPlugin-DKqVfKyW.js +128 -0
- package/src/ui/dist/assets/MarketplacePlugin-BwxStZ9D.js +13 -0
- package/src/ui/dist/assets/NotebookEditor-BEQhaQbt.js +81 -0
- package/src/ui/dist/assets/{NotebookEditor-CccQYZjX.css → NotebookEditor-BHH8rdGj.css} +1 -1
- package/src/ui/dist/assets/NotebookEditor-BOr3x3Ej.css +1 -0
- package/src/ui/dist/assets/NotebookEditor-DB9N_T9q.js +361 -0
- package/src/ui/dist/assets/PdfLoader-Cy5jtWrr.css +1 -0
- package/src/ui/dist/assets/PdfLoader-eWBONbQP.js +16 -0
- package/src/ui/dist/assets/PdfMarkdownPlugin-D22YOZL3.js +1 -0
- package/src/ui/dist/assets/PdfViewerPlugin-c-RK9DLM.js +17 -0
- package/src/ui/dist/assets/PdfViewerPlugin-nwwE-fjJ.css +1 -0
- package/src/ui/dist/assets/SearchPlugin-CxF9ytAx.js +16 -0
- package/src/ui/dist/assets/SearchPlugin-DA4en4hK.css +1 -0
- package/src/ui/dist/assets/TextViewerPlugin-C5xqeeUH.js +54 -0
- package/src/ui/dist/assets/VNCViewer-BoLGLnHz.js +11 -0
- package/src/ui/dist/assets/bot-DREQOxzP.js +6 -0
- package/src/ui/dist/assets/browser-CTB2jwNe.js +8 -0
- package/src/ui/dist/assets/chevron-up-C9Qpx4DE.js +6 -0
- package/src/ui/dist/assets/code-WlFHE7z_.js +6 -0
- package/src/ui/dist/assets/file-content-BZMz3RYp.js +1 -0
- package/src/ui/dist/assets/file-diff-panel-CQhw0jS2.js +1 -0
- package/src/ui/dist/assets/file-jump-queue-DA-SdG__.js +1 -0
- package/src/ui/dist/assets/file-socket-CfQPKQKj.js +1 -0
- package/src/ui/dist/assets/git-commit-horizontal-DxZ8DCZh.js +6 -0
- package/src/ui/dist/assets/image-Bgl4VIyx.js +6 -0
- package/src/ui/dist/assets/index-BpV6lusQ.css +33 -0
- package/src/ui/dist/assets/index-CBNVuWcP.js +2496 -0
- package/src/ui/dist/assets/index-CwNu1aH4.js +11 -0
- package/src/ui/dist/assets/index-DrUnlf6K.js +1 -0
- package/src/ui/dist/assets/index-NW-h8VzN.js +1 -0
- package/src/ui/dist/assets/monaco-CiHMMNH_.js +1 -0
- package/src/ui/dist/assets/pdf-effect-queue-J8OnM0jE.js +6 -0
- package/src/ui/dist/assets/plugin-monaco-C8UgLomw.js +19 -0
- package/src/ui/dist/assets/plugin-notebook-HbW2K-1c.js +169 -0
- package/src/ui/dist/assets/plugin-pdf-CR8hgQBV.js +357 -0
- package/src/ui/dist/assets/plugin-terminal-MXFIPun8.js +227 -0
- package/src/ui/dist/assets/popover-CLc0pPP8.js +1 -0
- package/src/ui/dist/assets/project-sync-C9IdzdZW.js +1 -0
- package/src/ui/dist/assets/select-Cs2PmzwL.js +11 -0
- package/src/ui/dist/assets/sigma-ClKcHAXm.js +6 -0
- package/src/ui/dist/assets/trash-DwpbFr3w.js +11 -0
- package/src/ui/dist/assets/useCliAccess-NQ8m0Let.js +1 -0
- package/src/ui/dist/assets/useFileDiffOverlay-FuhcnKiw.js +1 -0
- package/src/ui/dist/assets/wrap-text-BC-Hltpd.js +11 -0
- package/src/ui/dist/assets/zoom-out-E_gaeAxL.js +11 -0
- package/src/ui/dist/index.html +5 -2
- package/src/ui/dist/assets/AiManusChatView-DDjbFnbt.js +0 -26597
- package/src/ui/dist/assets/AnalysisPlugin-Yb5IdmaU.js +0 -123
- package/src/ui/dist/assets/CliPlugin-e64sreyu.js +0 -31037
- package/src/ui/dist/assets/CodeEditorPlugin-C4D2TIkU.js +0 -427
- package/src/ui/dist/assets/CodeViewerPlugin-BVoNZIvC.js +0 -905
- package/src/ui/dist/assets/DocViewerPlugin-CLChbllo.js +0 -278
- package/src/ui/dist/assets/GitDiffViewerPlugin-C4xeFyFQ.js +0 -2661
- package/src/ui/dist/assets/ImageViewerPlugin-OiMUAcLi.js +0 -500
- package/src/ui/dist/assets/LabCopilotPanel-BjD2ThQF.js +0 -4104
- package/src/ui/dist/assets/LabPlugin-DQPg-NrB.js +0 -2677
- package/src/ui/dist/assets/LatexPlugin-CI05XAV9.js +0 -1792
- package/src/ui/dist/assets/MarkdownViewerPlugin-DpeBLYZf.js +0 -308
- package/src/ui/dist/assets/MarketplacePlugin-DolE58Q2.js +0 -413
- package/src/ui/dist/assets/NotebookEditor-7Qm2rSWD.js +0 -4214
- package/src/ui/dist/assets/NotebookEditor-C1kWaxKi.js +0 -84873
- package/src/ui/dist/assets/NotebookEditor-C3VQ7ylN.css +0 -1405
- package/src/ui/dist/assets/PdfLoader-BfOHw8Zw.js +0 -25468
- package/src/ui/dist/assets/PdfLoader-C-Y707R3.css +0 -49
- package/src/ui/dist/assets/PdfMarkdownPlugin-BulDREv1.js +0 -409
- package/src/ui/dist/assets/PdfViewerPlugin-C-daaOaL.js +0 -3095
- package/src/ui/dist/assets/PdfViewerPlugin-DQ11QcSf.css +0 -3627
- package/src/ui/dist/assets/SearchPlugin-CjpaiJ3A.js +0 -741
- package/src/ui/dist/assets/SearchPlugin-DDMrGDkh.css +0 -379
- package/src/ui/dist/assets/TextViewerPlugin-BxIyqPQC.js +0 -472
- package/src/ui/dist/assets/VNCViewer-HAg9mF7M.js +0 -18821
- package/src/ui/dist/assets/awareness-C0NPR2Dj.js +0 -292
- package/src/ui/dist/assets/bot-0DYntytV.js +0 -21
- package/src/ui/dist/assets/browser-BAcuE0Xj.js +0 -2895
- package/src/ui/dist/assets/code-B20Slj_w.js +0 -17
- package/src/ui/dist/assets/file-content-DT24KFma.js +0 -377
- package/src/ui/dist/assets/file-diff-panel-DK13YPql.js +0 -92
- package/src/ui/dist/assets/file-jump-queue-r5XKgJEV.js +0 -16
- package/src/ui/dist/assets/file-socket-B4T2o4nR.js +0 -58
- package/src/ui/dist/assets/function-B5QZkkHC.js +0 -1895
- package/src/ui/dist/assets/image-DSeR_sDS.js +0 -18
- package/src/ui/dist/assets/index-BrFje2Uk.js +0 -120
- package/src/ui/dist/assets/index-BwRJaoTl.js +0 -25
- package/src/ui/dist/assets/index-D_E4281X.js +0 -221322
- package/src/ui/dist/assets/index-DnYB3xb1.js +0 -159
- package/src/ui/dist/assets/index-G7AcWcMu.css +0 -12594
- package/src/ui/dist/assets/monaco-LExaAN3Y.js +0 -623
- package/src/ui/dist/assets/pdf-effect-queue-BJk5okWJ.js +0 -47
- package/src/ui/dist/assets/pdf_viewer-e0g1is2C.js +0 -8206
- package/src/ui/dist/assets/popover-D3Gg_FoV.js +0 -476
- package/src/ui/dist/assets/project-sync-C_ygLlVU.js +0 -297
- package/src/ui/dist/assets/select-CpAK6uWm.js +0 -1690
- package/src/ui/dist/assets/sigma-DEccaSgk.js +0 -22
- package/src/ui/dist/assets/square-check-big-uUfyVsbD.js +0 -17
- package/src/ui/dist/assets/trash-CXvwwSe8.js +0 -32
- package/src/ui/dist/assets/useCliAccess-Bnop4mgR.js +0 -957
- package/src/ui/dist/assets/useFileDiffOverlay-B8eUAX0I.js +0 -53
- package/src/ui/dist/assets/wrap-text-9vbOBpkW.js +0 -35
- package/src/ui/dist/assets/yjs-DncrqiZ8.js +0 -11243
- package/src/ui/dist/assets/zoom-out-BgVMmOW4.js +0 -34
|
@@ -1,500 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-D_E4281X.js","assets/index-G7AcWcMu.css"])))=>i.map(i=>d[i]);
|
|
2
|
-
import { w as createLucideIcon, r as reactExports, j as jsxRuntimeExports, b as cn, ah as RotateCcw, ai as Info, a3 as Download, L as LoaderCircle, _ as __vitePreload } from './index-D_E4281X.js';
|
|
3
|
-
import { I as Image } from './image-DSeR_sDS.js';
|
|
4
|
-
import { Z as ZoomOut, a as ZoomIn } from './zoom-out-BgVMmOW4.js';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @license lucide-react v0.511.0 - ISC
|
|
8
|
-
*
|
|
9
|
-
* This source code is licensed under the ISC license.
|
|
10
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const __iconNode$2 = [
|
|
15
|
-
["line", { x1: "2", x2: "22", y1: "2", y2: "22", key: "a6p6uj" }],
|
|
16
|
-
["path", { d: "M10.41 10.41a2 2 0 1 1-2.83-2.83", key: "1bzlo9" }],
|
|
17
|
-
["line", { x1: "13.5", x2: "6", y1: "13.5", y2: "21", key: "1q0aeu" }],
|
|
18
|
-
["line", { x1: "18", x2: "21", y1: "12", y2: "15", key: "5mozeu" }],
|
|
19
|
-
[
|
|
20
|
-
"path",
|
|
21
|
-
{
|
|
22
|
-
d: "M3.59 3.59A1.99 1.99 0 0 0 3 5v14a2 2 0 0 0 2 2h14c.55 0 1.052-.22 1.41-.59",
|
|
23
|
-
key: "mmje98"
|
|
24
|
-
}
|
|
25
|
-
],
|
|
26
|
-
["path", { d: "M21 15V5a2 2 0 0 0-2-2H9", key: "43el77" }]
|
|
27
|
-
];
|
|
28
|
-
const ImageOff = createLucideIcon("image-off", __iconNode$2);
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* @license lucide-react v0.511.0 - ISC
|
|
32
|
-
*
|
|
33
|
-
* This source code is licensed under the ISC license.
|
|
34
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
35
|
-
*/
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const __iconNode$1 = [
|
|
39
|
-
["path", { d: "M8 3H5a2 2 0 0 0-2 2v3", key: "1dcmit" }],
|
|
40
|
-
["path", { d: "M21 8V5a2 2 0 0 0-2-2h-3", key: "1e4gt3" }],
|
|
41
|
-
["path", { d: "M3 16v3a2 2 0 0 0 2 2h3", key: "wsl5sc" }],
|
|
42
|
-
["path", { d: "M16 21h3a2 2 0 0 0 2-2v-3", key: "18trek" }]
|
|
43
|
-
];
|
|
44
|
-
const Maximize = createLucideIcon("maximize", __iconNode$1);
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* @license lucide-react v0.511.0 - ISC
|
|
48
|
-
*
|
|
49
|
-
* This source code is licensed under the ISC license.
|
|
50
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
51
|
-
*/
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const __iconNode = [
|
|
55
|
-
["path", { d: "M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8", key: "1p45f6" }],
|
|
56
|
-
["path", { d: "M21 3v5h-5", key: "1q7to0" }]
|
|
57
|
-
];
|
|
58
|
-
const RotateCw = createLucideIcon("rotate-cw", __iconNode);
|
|
59
|
-
|
|
60
|
-
const MIN_SCALE = 0.1;
|
|
61
|
-
const MAX_SCALE = 10;
|
|
62
|
-
const ZOOM_STEP = 0.1;
|
|
63
|
-
function ImageCanvas({
|
|
64
|
-
src,
|
|
65
|
-
alt,
|
|
66
|
-
onLoad,
|
|
67
|
-
onError,
|
|
68
|
-
rotation,
|
|
69
|
-
className
|
|
70
|
-
}) {
|
|
71
|
-
const [loading, setLoading] = reactExports.useState(true);
|
|
72
|
-
const [transform, setTransform] = reactExports.useState({
|
|
73
|
-
scale: 1,
|
|
74
|
-
translateX: 0,
|
|
75
|
-
translateY: 0
|
|
76
|
-
});
|
|
77
|
-
const [isDragging, setIsDragging] = reactExports.useState(false);
|
|
78
|
-
const [dragStart, setDragStart] = reactExports.useState({ x: 0, y: 0 });
|
|
79
|
-
const containerRef = reactExports.useRef(null);
|
|
80
|
-
const imageRef = reactExports.useRef(null);
|
|
81
|
-
reactExports.useEffect(() => {
|
|
82
|
-
setTransform({ scale: 1, translateX: 0, translateY: 0 });
|
|
83
|
-
setLoading(true);
|
|
84
|
-
}, [src]);
|
|
85
|
-
const handleLoad = reactExports.useCallback(() => {
|
|
86
|
-
setLoading(false);
|
|
87
|
-
if (imageRef.current && onLoad) {
|
|
88
|
-
onLoad({
|
|
89
|
-
width: imageRef.current.width,
|
|
90
|
-
height: imageRef.current.height,
|
|
91
|
-
naturalWidth: imageRef.current.naturalWidth,
|
|
92
|
-
naturalHeight: imageRef.current.naturalHeight
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
}, [onLoad]);
|
|
96
|
-
const handleError = reactExports.useCallback(() => {
|
|
97
|
-
setLoading(false);
|
|
98
|
-
onError?.();
|
|
99
|
-
}, [onError]);
|
|
100
|
-
reactExports.useCallback(() => {
|
|
101
|
-
setTransform((prev) => ({
|
|
102
|
-
...prev,
|
|
103
|
-
scale: Math.min(prev.scale + ZOOM_STEP, MAX_SCALE)
|
|
104
|
-
}));
|
|
105
|
-
}, []);
|
|
106
|
-
reactExports.useCallback(() => {
|
|
107
|
-
setTransform((prev) => ({
|
|
108
|
-
...prev,
|
|
109
|
-
scale: Math.max(prev.scale - ZOOM_STEP, MIN_SCALE)
|
|
110
|
-
}));
|
|
111
|
-
}, []);
|
|
112
|
-
const resetTransform = reactExports.useCallback(() => {
|
|
113
|
-
setTransform({ scale: 1, translateX: 0, translateY: 0 });
|
|
114
|
-
}, []);
|
|
115
|
-
reactExports.useCallback(() => {
|
|
116
|
-
if (!containerRef.current || !imageRef.current) return;
|
|
117
|
-
const container = containerRef.current.getBoundingClientRect();
|
|
118
|
-
const img = imageRef.current;
|
|
119
|
-
const imageWidth = img.naturalWidth;
|
|
120
|
-
const imageHeight = img.naturalHeight;
|
|
121
|
-
const scaleX = (container.width - 40) / imageWidth;
|
|
122
|
-
const scaleY = (container.height - 40) / imageHeight;
|
|
123
|
-
const scale = Math.min(scaleX, scaleY, 1);
|
|
124
|
-
setTransform({ scale, translateX: 0, translateY: 0 });
|
|
125
|
-
}, []);
|
|
126
|
-
const handleWheel = reactExports.useCallback((e) => {
|
|
127
|
-
e.preventDefault();
|
|
128
|
-
const delta = e.deltaY > 0 ? -ZOOM_STEP : ZOOM_STEP;
|
|
129
|
-
const newScale = Math.max(MIN_SCALE, Math.min(MAX_SCALE, transform.scale + delta));
|
|
130
|
-
if (containerRef.current) {
|
|
131
|
-
const rect = containerRef.current.getBoundingClientRect();
|
|
132
|
-
const x = e.clientX - rect.left - rect.width / 2;
|
|
133
|
-
const y = e.clientY - rect.top - rect.height / 2;
|
|
134
|
-
const scaleDiff = newScale / transform.scale;
|
|
135
|
-
const newTranslateX = x - scaleDiff * (x - transform.translateX);
|
|
136
|
-
const newTranslateY = y - scaleDiff * (y - transform.translateY);
|
|
137
|
-
setTransform({
|
|
138
|
-
scale: newScale,
|
|
139
|
-
translateX: newTranslateX,
|
|
140
|
-
translateY: newTranslateY
|
|
141
|
-
});
|
|
142
|
-
} else {
|
|
143
|
-
setTransform((prev) => ({ ...prev, scale: newScale }));
|
|
144
|
-
}
|
|
145
|
-
}, [transform]);
|
|
146
|
-
const handleMouseDown = reactExports.useCallback((e) => {
|
|
147
|
-
if (e.button !== 0) return;
|
|
148
|
-
e.preventDefault();
|
|
149
|
-
setIsDragging(true);
|
|
150
|
-
setDragStart({ x: e.clientX - transform.translateX, y: e.clientY - transform.translateY });
|
|
151
|
-
}, [transform.translateX, transform.translateY]);
|
|
152
|
-
const handleMouseMove = reactExports.useCallback((e) => {
|
|
153
|
-
if (!isDragging) return;
|
|
154
|
-
e.preventDefault();
|
|
155
|
-
setTransform((prev) => ({
|
|
156
|
-
...prev,
|
|
157
|
-
translateX: e.clientX - dragStart.x,
|
|
158
|
-
translateY: e.clientY - dragStart.y
|
|
159
|
-
}));
|
|
160
|
-
}, [isDragging, dragStart]);
|
|
161
|
-
const handleMouseUp = reactExports.useCallback(() => {
|
|
162
|
-
setIsDragging(false);
|
|
163
|
-
}, []);
|
|
164
|
-
const handleTouchStart = reactExports.useCallback((e) => {
|
|
165
|
-
if (e.touches.length === 1) {
|
|
166
|
-
const touch = e.touches[0];
|
|
167
|
-
setIsDragging(true);
|
|
168
|
-
setDragStart({
|
|
169
|
-
x: touch.clientX - transform.translateX,
|
|
170
|
-
y: touch.clientY - transform.translateY
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
}, [transform.translateX, transform.translateY]);
|
|
174
|
-
const handleTouchMove = reactExports.useCallback((e) => {
|
|
175
|
-
if (!isDragging || e.touches.length !== 1) return;
|
|
176
|
-
const touch = e.touches[0];
|
|
177
|
-
setTransform((prev) => ({
|
|
178
|
-
...prev,
|
|
179
|
-
translateX: touch.clientX - dragStart.x,
|
|
180
|
-
translateY: touch.clientY - dragStart.y
|
|
181
|
-
}));
|
|
182
|
-
}, [isDragging, dragStart]);
|
|
183
|
-
const handleTouchEnd = reactExports.useCallback(() => {
|
|
184
|
-
setIsDragging(false);
|
|
185
|
-
}, []);
|
|
186
|
-
const handleDoubleClick = reactExports.useCallback(() => {
|
|
187
|
-
resetTransform();
|
|
188
|
-
}, [resetTransform]);
|
|
189
|
-
const transformStyle = `
|
|
190
|
-
translate(${transform.translateX}px, ${transform.translateY}px)
|
|
191
|
-
scale(${transform.scale})
|
|
192
|
-
rotate(${rotation}deg)
|
|
193
|
-
`;
|
|
194
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
195
|
-
"div",
|
|
196
|
-
{
|
|
197
|
-
ref: containerRef,
|
|
198
|
-
className: cn(
|
|
199
|
-
"relative w-full h-full overflow-hidden select-none",
|
|
200
|
-
isDragging ? "cursor-grabbing" : "cursor-grab",
|
|
201
|
-
className
|
|
202
|
-
),
|
|
203
|
-
onWheel: handleWheel,
|
|
204
|
-
onMouseDown: handleMouseDown,
|
|
205
|
-
onMouseMove: handleMouseMove,
|
|
206
|
-
onMouseUp: handleMouseUp,
|
|
207
|
-
onMouseLeave: handleMouseUp,
|
|
208
|
-
onTouchStart: handleTouchStart,
|
|
209
|
-
onTouchMove: handleTouchMove,
|
|
210
|
-
onTouchEnd: handleTouchEnd,
|
|
211
|
-
onDoubleClick: handleDoubleClick,
|
|
212
|
-
children: [
|
|
213
|
-
loading && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-8 h-8 border-2 border-primary border-t-transparent rounded-full animate-spin" }) }),
|
|
214
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
215
|
-
"img",
|
|
216
|
-
{
|
|
217
|
-
ref: imageRef,
|
|
218
|
-
src,
|
|
219
|
-
alt,
|
|
220
|
-
className: cn(
|
|
221
|
-
"max-w-none transition-transform duration-100",
|
|
222
|
-
loading && "opacity-0"
|
|
223
|
-
),
|
|
224
|
-
style: {
|
|
225
|
-
transform: transformStyle,
|
|
226
|
-
transformOrigin: "center center"
|
|
227
|
-
},
|
|
228
|
-
onLoad: handleLoad,
|
|
229
|
-
onError: handleError,
|
|
230
|
-
draggable: false
|
|
231
|
-
}
|
|
232
|
-
) }),
|
|
233
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "absolute bottom-4 left-4 px-2 py-1 bg-background/80 backdrop-blur rounded text-xs text-muted-foreground", children: [
|
|
234
|
-
Math.round(transform.scale * 100),
|
|
235
|
-
"%"
|
|
236
|
-
] })
|
|
237
|
-
]
|
|
238
|
-
}
|
|
239
|
-
);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
const DEMO_IMAGE_URL = "https://via.placeholder.com/1920x1080?text=DeepScientist+Image+Viewer";
|
|
243
|
-
function formatFileSize(bytes) {
|
|
244
|
-
if (!bytes) return "Unknown";
|
|
245
|
-
if (bytes < 1024) return `${bytes} B`;
|
|
246
|
-
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
247
|
-
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
248
|
-
}
|
|
249
|
-
function getImageExtension(fileName) {
|
|
250
|
-
const ext = fileName.split(".").pop()?.toLowerCase() || "";
|
|
251
|
-
return ext.toUpperCase();
|
|
252
|
-
}
|
|
253
|
-
function ImageViewerPlugin({
|
|
254
|
-
context,
|
|
255
|
-
tabId,
|
|
256
|
-
setDirty,
|
|
257
|
-
setTitle
|
|
258
|
-
}) {
|
|
259
|
-
const [imageUrl, setImageUrl] = reactExports.useState("");
|
|
260
|
-
const [loading, setLoading] = reactExports.useState(true);
|
|
261
|
-
const [error, setError] = reactExports.useState(null);
|
|
262
|
-
const [imageInfo, setImageInfo] = reactExports.useState(null);
|
|
263
|
-
const [rotation, setRotation] = reactExports.useState(0);
|
|
264
|
-
const [showInfo, setShowInfo] = reactExports.useState(false);
|
|
265
|
-
const canvasRef = reactExports.useRef(null);
|
|
266
|
-
const fileName = context.resourceName || context.resourcePath || "Image";
|
|
267
|
-
reactExports.useEffect(() => {
|
|
268
|
-
setTitle(fileName);
|
|
269
|
-
}, [fileName, setTitle]);
|
|
270
|
-
reactExports.useEffect(() => {
|
|
271
|
-
let cancelled = false;
|
|
272
|
-
let objectUrl = null;
|
|
273
|
-
setLoading(true);
|
|
274
|
-
setError(null);
|
|
275
|
-
if (!context.resourceId) {
|
|
276
|
-
setImageUrl(DEMO_IMAGE_URL);
|
|
277
|
-
return () => {
|
|
278
|
-
cancelled = true;
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
const loadImageUrl = async () => {
|
|
282
|
-
try {
|
|
283
|
-
const { createFileObjectUrl } = await __vitePreload(async () => { const { createFileObjectUrl } = await import('./index-D_E4281X.js').then(n => n.ep);return { createFileObjectUrl }},true?__vite__mapDeps([0,1]):void 0);
|
|
284
|
-
objectUrl = await createFileObjectUrl(context.resourceId);
|
|
285
|
-
if (cancelled) {
|
|
286
|
-
URL.revokeObjectURL(objectUrl);
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
setImageUrl(objectUrl);
|
|
290
|
-
} catch (err) {
|
|
291
|
-
console.error("Failed to get image URL:", err);
|
|
292
|
-
setError("Failed to load image");
|
|
293
|
-
setLoading(false);
|
|
294
|
-
}
|
|
295
|
-
};
|
|
296
|
-
loadImageUrl();
|
|
297
|
-
return () => {
|
|
298
|
-
cancelled = true;
|
|
299
|
-
if (objectUrl) {
|
|
300
|
-
URL.revokeObjectURL(objectUrl);
|
|
301
|
-
}
|
|
302
|
-
};
|
|
303
|
-
}, [context.resourceId]);
|
|
304
|
-
const handleImageLoad = reactExports.useCallback((info) => {
|
|
305
|
-
setLoading(false);
|
|
306
|
-
setImageInfo(info);
|
|
307
|
-
}, []);
|
|
308
|
-
const handleImageError = reactExports.useCallback(() => {
|
|
309
|
-
setLoading(false);
|
|
310
|
-
setError("Failed to load image");
|
|
311
|
-
}, []);
|
|
312
|
-
const rotateLeft = reactExports.useCallback(() => {
|
|
313
|
-
setRotation((prev) => (prev - 90) % 360);
|
|
314
|
-
}, []);
|
|
315
|
-
const rotateRight = reactExports.useCallback(() => {
|
|
316
|
-
setRotation((prev) => (prev + 90) % 360);
|
|
317
|
-
}, []);
|
|
318
|
-
reactExports.useCallback(() => {
|
|
319
|
-
setRotation(0);
|
|
320
|
-
}, []);
|
|
321
|
-
const handleDownload = reactExports.useCallback(() => {
|
|
322
|
-
if (!imageUrl) return;
|
|
323
|
-
const link = document.createElement("a");
|
|
324
|
-
link.href = imageUrl;
|
|
325
|
-
link.download = fileName;
|
|
326
|
-
link.click();
|
|
327
|
-
}, [imageUrl, fileName]);
|
|
328
|
-
const fileSize = context.customData?.size;
|
|
329
|
-
if (error && !loading) {
|
|
330
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col h-full bg-background", children: [
|
|
331
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center px-4 py-2 border-b border-border bg-muted/30", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
332
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(Image, { className: "w-4 h-4 text-muted-foreground" }),
|
|
333
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm text-foreground", children: fileName })
|
|
334
|
-
] }) }),
|
|
335
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center gap-4 text-center", children: [
|
|
336
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(ImageOff, { className: "w-16 h-16 text-muted-foreground" }),
|
|
337
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
338
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-lg font-medium text-foreground", children: "Failed to load image" }),
|
|
339
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-muted-foreground mt-1", children: error })
|
|
340
|
-
] }),
|
|
341
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
342
|
-
"button",
|
|
343
|
-
{
|
|
344
|
-
className: "px-4 py-2 text-sm bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors",
|
|
345
|
-
onClick: () => window.location.reload(),
|
|
346
|
-
children: "Retry"
|
|
347
|
-
}
|
|
348
|
-
)
|
|
349
|
-
] }) })
|
|
350
|
-
] });
|
|
351
|
-
}
|
|
352
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col h-full bg-muted/30", children: [
|
|
353
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between px-4 py-2 border-b border-border bg-background", children: [
|
|
354
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
355
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(Image, { className: "w-4 h-4 text-muted-foreground" }),
|
|
356
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm text-foreground", children: fileName }),
|
|
357
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs px-2 py-0.5 rounded bg-muted text-muted-foreground", children: getImageExtension(fileName) }),
|
|
358
|
-
imageInfo && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-muted-foreground", children: [
|
|
359
|
-
imageInfo.naturalWidth,
|
|
360
|
-
" x ",
|
|
361
|
-
imageInfo.naturalHeight
|
|
362
|
-
] })
|
|
363
|
-
] }),
|
|
364
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
365
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
366
|
-
"button",
|
|
367
|
-
{
|
|
368
|
-
onClick: () => canvasRef.current?.zoomOut?.(),
|
|
369
|
-
className: "p-2 rounded hover:bg-accent transition-colors text-muted-foreground hover:text-foreground",
|
|
370
|
-
title: "Zoom out",
|
|
371
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ZoomOut, { className: "w-4 h-4" })
|
|
372
|
-
}
|
|
373
|
-
),
|
|
374
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
375
|
-
"button",
|
|
376
|
-
{
|
|
377
|
-
onClick: () => canvasRef.current?.resetTransform?.(),
|
|
378
|
-
className: "p-2 rounded hover:bg-accent transition-colors text-muted-foreground hover:text-foreground",
|
|
379
|
-
title: "Reset zoom (double-click image)",
|
|
380
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Maximize, { className: "w-4 h-4" })
|
|
381
|
-
}
|
|
382
|
-
),
|
|
383
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
384
|
-
"button",
|
|
385
|
-
{
|
|
386
|
-
onClick: () => canvasRef.current?.zoomIn?.(),
|
|
387
|
-
className: "p-2 rounded hover:bg-accent transition-colors text-muted-foreground hover:text-foreground",
|
|
388
|
-
title: "Zoom in",
|
|
389
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ZoomIn, { className: "w-4 h-4" })
|
|
390
|
-
}
|
|
391
|
-
),
|
|
392
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-px h-6 bg-border mx-1" }),
|
|
393
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
394
|
-
"button",
|
|
395
|
-
{
|
|
396
|
-
onClick: rotateLeft,
|
|
397
|
-
className: "p-2 rounded hover:bg-accent transition-colors text-muted-foreground hover:text-foreground",
|
|
398
|
-
title: "Rotate left",
|
|
399
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCcw, { className: "w-4 h-4" })
|
|
400
|
-
}
|
|
401
|
-
),
|
|
402
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
403
|
-
"button",
|
|
404
|
-
{
|
|
405
|
-
onClick: rotateRight,
|
|
406
|
-
className: "p-2 rounded hover:bg-accent transition-colors text-muted-foreground hover:text-foreground",
|
|
407
|
-
title: "Rotate right",
|
|
408
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCw, { className: "w-4 h-4" })
|
|
409
|
-
}
|
|
410
|
-
),
|
|
411
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-px h-6 bg-border mx-1" }),
|
|
412
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
413
|
-
"button",
|
|
414
|
-
{
|
|
415
|
-
onClick: () => setShowInfo(!showInfo),
|
|
416
|
-
className: cn(
|
|
417
|
-
"p-2 rounded transition-colors",
|
|
418
|
-
showInfo ? "bg-primary text-primary-foreground" : "hover:bg-accent text-muted-foreground hover:text-foreground"
|
|
419
|
-
),
|
|
420
|
-
title: "Image info",
|
|
421
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Info, { className: "w-4 h-4" })
|
|
422
|
-
}
|
|
423
|
-
),
|
|
424
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
425
|
-
"button",
|
|
426
|
-
{
|
|
427
|
-
onClick: handleDownload,
|
|
428
|
-
className: "p-2 rounded hover:bg-accent transition-colors text-muted-foreground hover:text-foreground",
|
|
429
|
-
title: "Download image",
|
|
430
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Download, { className: "w-4 h-4" })
|
|
431
|
-
}
|
|
432
|
-
)
|
|
433
|
-
] })
|
|
434
|
-
] }),
|
|
435
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 relative overflow-hidden bg-[#1a1a1a]", children: [
|
|
436
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
437
|
-
"div",
|
|
438
|
-
{
|
|
439
|
-
className: "absolute inset-0 opacity-20",
|
|
440
|
-
style: {
|
|
441
|
-
backgroundImage: `
|
|
442
|
-
linear-gradient(45deg, #808080 25%, transparent 25%),
|
|
443
|
-
linear-gradient(-45deg, #808080 25%, transparent 25%),
|
|
444
|
-
linear-gradient(45deg, transparent 75%, #808080 75%),
|
|
445
|
-
linear-gradient(-45deg, transparent 75%, #808080 75%)
|
|
446
|
-
`,
|
|
447
|
-
backgroundSize: "20px 20px",
|
|
448
|
-
backgroundPosition: "0 0, 0 10px, 10px -10px, -10px 0px"
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
),
|
|
452
|
-
loading && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute inset-0 flex items-center justify-center z-10", children: /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "w-8 h-8 animate-spin text-muted-foreground" }) }),
|
|
453
|
-
imageUrl && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
454
|
-
ImageCanvas,
|
|
455
|
-
{
|
|
456
|
-
src: imageUrl,
|
|
457
|
-
alt: fileName,
|
|
458
|
-
rotation,
|
|
459
|
-
onLoad: handleImageLoad,
|
|
460
|
-
onError: handleImageError
|
|
461
|
-
}
|
|
462
|
-
),
|
|
463
|
-
showInfo && imageInfo && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "absolute top-4 right-4 p-4 bg-background/90 backdrop-blur rounded-lg shadow-lg border border-border", children: [
|
|
464
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-medium text-foreground mb-3", children: "Image Information" }),
|
|
465
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("dl", { className: "space-y-2 text-sm", children: [
|
|
466
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between gap-8", children: [
|
|
467
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("dt", { className: "text-muted-foreground", children: "Filename" }),
|
|
468
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("dd", { className: "text-foreground font-mono", children: fileName })
|
|
469
|
-
] }),
|
|
470
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between gap-8", children: [
|
|
471
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("dt", { className: "text-muted-foreground", children: "Dimensions" }),
|
|
472
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("dd", { className: "text-foreground font-mono", children: [
|
|
473
|
-
imageInfo.naturalWidth,
|
|
474
|
-
" x ",
|
|
475
|
-
imageInfo.naturalHeight
|
|
476
|
-
] })
|
|
477
|
-
] }),
|
|
478
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between gap-8", children: [
|
|
479
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("dt", { className: "text-muted-foreground", children: "Format" }),
|
|
480
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("dd", { className: "text-foreground font-mono", children: getImageExtension(fileName) })
|
|
481
|
-
] }),
|
|
482
|
-
fileSize && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between gap-8", children: [
|
|
483
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("dt", { className: "text-muted-foreground", children: "Size" }),
|
|
484
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("dd", { className: "text-foreground font-mono", children: formatFileSize(fileSize) })
|
|
485
|
-
] }),
|
|
486
|
-
rotation !== 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between gap-8", children: [
|
|
487
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("dt", { className: "text-muted-foreground", children: "Rotation" }),
|
|
488
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("dd", { className: "text-foreground font-mono", children: [
|
|
489
|
-
rotation,
|
|
490
|
-
"deg"
|
|
491
|
-
] })
|
|
492
|
-
] })
|
|
493
|
-
] })
|
|
494
|
-
] })
|
|
495
|
-
] }),
|
|
496
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center gap-2 px-4 py-2 border-t border-border bg-background", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground", children: "Scroll to zoom | Drag to pan | Double-click to reset" }) })
|
|
497
|
-
] });
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
export { ImageViewerPlugin as default };
|