feat: preview components
This commit is contained in:
@@ -7,7 +7,10 @@ import type {
|
|||||||
} from "../../services/api";
|
} from "../../services/api";
|
||||||
import { scriptIcon } from "./WorkspaceTree";
|
import { scriptIcon } from "./WorkspaceTree";
|
||||||
import type { MouseEvent as ReactMouseEvent, RefObject } from "react";
|
import type { MouseEvent as ReactMouseEvent, RefObject } from "react";
|
||||||
import { useRef, useEffect } from "react";
|
import Editor from "@monaco-editor/react";
|
||||||
|
import { useRef, useLayoutEffect } from "react";
|
||||||
|
|
||||||
|
import { useScriptWorkspaceStore } from "./state/scriptWorkspaceStore";
|
||||||
|
|
||||||
type ToastState = {
|
type ToastState = {
|
||||||
tone: "success" | "error" | "info";
|
tone: "success" | "error" | "info";
|
||||||
@@ -129,9 +132,9 @@ export function ScriptWorkspace({
|
|||||||
left: direction === "left" ? -scrollAmount : scrollAmount,
|
left: direction === "left" ? -scrollAmount : scrollAmount,
|
||||||
behavior: "smooth",
|
behavior: "smooth",
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useLayoutEffect(() => {
|
||||||
const tabbar = tabbarRef.current;
|
const tabbar = tabbarRef.current;
|
||||||
if (!tabbar) return;
|
if (!tabbar) return;
|
||||||
const activeTab = tabbar.querySelector(".editor-tab--active") as HTMLElement | null;
|
const activeTab = tabbar.querySelector(".editor-tab--active") as HTMLElement | null;
|
||||||
@@ -232,13 +235,11 @@ export function ScriptWorkspace({
|
|||||||
</button>
|
</button>
|
||||||
<span className={`stage-badge${isEditing ? " is-editing" : ""}`}>
|
<span className={`stage-badge${isEditing ? " is-editing" : ""}`}>
|
||||||
<span />
|
<span />
|
||||||
{isEditing
|
{
|
||||||
? isNotebook
|
latestVersion
|
||||||
? "Demo 无锁模式 · Kernel 已连接"
|
|
||||||
: "Demo 无锁模式 · 编辑中"
|
|
||||||
: latestVersion
|
|
||||||
? `最新 ${latestVersion.version_label}`
|
? `最新 ${latestVersion.version_label}`
|
||||||
: "工作副本已就绪"}
|
: "工作副本已就绪"
|
||||||
|
}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -378,13 +379,13 @@ export function ScriptWorkspace({
|
|||||||
<span>Python 预览</span>
|
<span>Python 预览</span>
|
||||||
<em>{isEditing ? "Jupyter 中可编辑" : "平台只读预览"}</em>
|
<em>{isEditing ? "Jupyter 中可编辑" : "平台只读预览"}</em>
|
||||||
</div>
|
</div>
|
||||||
<PythonPreview />
|
<PythonPreview workspaceId={script.workspace_id} filePath={`${script.script_id}.py`}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="integrity-row">
|
<div className="integrity-row">
|
||||||
<span>
|
<span>
|
||||||
<Icon name="check" size={15} />
|
<Icon name="check" size={15} />
|
||||||
{isEditing ? "Demo 无锁编辑会话已连接" : "工作副本已同步"}
|
{/*{isEditing ? "Demo 无锁编辑会话已连接" : "工作副本已同步"}*/}
|
||||||
</span>
|
</span>
|
||||||
<span>SHA-256 {shortHash(script.content_hash)}</span>
|
<span>SHA-256 {shortHash(script.content_hash)}</span>
|
||||||
<span>
|
<span>
|
||||||
@@ -403,19 +404,59 @@ export function ScriptWorkspace({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function PythonPreview() {
|
|
||||||
|
interface PythonPreviewProps {
|
||||||
|
workspaceId: string;
|
||||||
|
filePath: string;
|
||||||
|
}
|
||||||
|
export function PythonPreview({
|
||||||
|
workspaceId,
|
||||||
|
filePath,
|
||||||
|
}: PythonPreviewProps) {
|
||||||
|
const previewKey = `${workspaceId}::${filePath}`;
|
||||||
|
const storeKey = useScriptWorkspaceStore((s) => s.previewKey);
|
||||||
|
const previewCode = useScriptWorkspaceStore((s) => s.previewCode);
|
||||||
|
const previewCodeSize = useScriptWorkspaceStore((s) => s.previewCodeSize);
|
||||||
|
const previewLoading = useScriptWorkspaceStore((s) => s.previewLoading);
|
||||||
|
const previewError = useScriptWorkspaceStore((s) => s.previewError);
|
||||||
|
const loadPreview = useScriptWorkspaceStore((s) => s.loadPreview);
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
void loadPreview(workspaceId, filePath);
|
||||||
|
}, [previewKey]);
|
||||||
|
|
||||||
|
if (storeKey !== previewKey) {
|
||||||
|
return <div>Loading...</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (previewLoading) {
|
||||||
|
return <div>Loading...</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (previewError) {
|
||||||
|
return <div>Failed to load: {previewError}</div>;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="python-preview">
|
<Editor
|
||||||
<div className="line-numbers">
|
height="550px"
|
||||||
1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9
|
language="python"
|
||||||
</div>
|
value={previewCode ?? ""}
|
||||||
<pre>
|
theme="vs"
|
||||||
<span className="code-comment">"""模型实验开发平台构建脚本。"""</span>
|
options={{
|
||||||
{"\n\n"}<b>def</b> <span className="code-function">main</span>() -> <b>None</b>:
|
readOnly: true,
|
||||||
{"\n"} print(<i>"Hello, Model Platform!"</i>)
|
domReadOnly: true,
|
||||||
{"\n\n\n"}<b>if</b> __name__ == <i>"__main__"</i>:
|
minimap: {
|
||||||
{"\n"} main()
|
enabled: previewCodeSize !== null && previewCodeSize > 1000,
|
||||||
</pre>
|
},
|
||||||
</div>
|
lineNumbers: "off",
|
||||||
|
folding: true,
|
||||||
|
wordWrap: "on",
|
||||||
|
contextmenu: false,
|
||||||
|
dragAndDrop: false,
|
||||||
|
automaticLayout: true,
|
||||||
|
renderLineHighlight: "none",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import type {
|
|||||||
Visibility,
|
Visibility,
|
||||||
WorkspaceBoundApi,
|
WorkspaceBoundApi,
|
||||||
WorkspaceDirectory,
|
WorkspaceDirectory,
|
||||||
} from "../../../services/api";
|
} from "~/services/api";
|
||||||
|
|
||||||
import type { NewScriptForm } from "./uiStore";
|
import type { NewScriptForm } from "./uiStore";
|
||||||
import { useUiStore } from "./uiStore";
|
import { useUiStore } from "./uiStore";
|
||||||
@@ -27,6 +27,8 @@ let _editSession: ActiveEditSession | null = null;
|
|||||||
let _editorOpening = false;
|
let _editorOpening = false;
|
||||||
let _editorOpenRequest = 0;
|
let _editorOpenRequest = 0;
|
||||||
let _api: WorkspaceBoundApi | null = null;
|
let _api: WorkspaceBoundApi | null = null;
|
||||||
|
let _previewController: AbortController | null = null;
|
||||||
|
let _previewRequest = 0;
|
||||||
|
|
||||||
export const bindScriptWorkspaceApi = (api: WorkspaceBoundApi | null) => {
|
export const bindScriptWorkspaceApi = (api: WorkspaceBoundApi | null) => {
|
||||||
_api = api;
|
_api = api;
|
||||||
@@ -60,6 +62,12 @@ type State = {
|
|||||||
latestVersion: LatestVersion | null;
|
latestVersion: LatestVersion | null;
|
||||||
latestVersionLoading: boolean;
|
latestVersionLoading: boolean;
|
||||||
|
|
||||||
|
previewKey: string | null;
|
||||||
|
previewCode: string | null;
|
||||||
|
previewCodeSize: number | null;
|
||||||
|
previewLoading: boolean;
|
||||||
|
previewError: string | null;
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
setApiOnline: (online: boolean) => void;
|
setApiOnline: (online: boolean) => void;
|
||||||
setKeyword: (keyword: string) => void;
|
setKeyword: (keyword: string) => void;
|
||||||
@@ -72,6 +80,7 @@ type State = {
|
|||||||
openScriptEditor: (script: ScriptItem, showToast?: boolean) => Promise<void>;
|
openScriptEditor: (script: ScriptItem, showToast?: boolean) => Promise<void>;
|
||||||
endEditing: (closeTabFlag?: boolean, showToast?: boolean) => Promise<void>;
|
endEditing: (closeTabFlag?: boolean, showToast?: boolean) => Promise<void>;
|
||||||
loadLatestVersion: (scriptId: string) => Promise<void>;
|
loadLatestVersion: (scriptId: string) => Promise<void>;
|
||||||
|
loadPreview: (workspaceId: string, filePath: string) => Promise<void>;
|
||||||
createScript: (form: NewScriptForm) => Promise<ScriptItem | null>;
|
createScript: (form: NewScriptForm) => Promise<ScriptItem | null>;
|
||||||
uploadScripts: (files: File[], parentPath: string) => Promise<void>;
|
uploadScripts: (files: File[], parentPath: string) => Promise<void>;
|
||||||
createFolder: (name: string, parentPath: string) => Promise<void>;
|
createFolder: (name: string, parentPath: string) => Promise<void>;
|
||||||
@@ -132,10 +141,21 @@ export const useScriptWorkspaceStore = create<State>((set, get) => {
|
|||||||
latestVersion: null,
|
latestVersion: null,
|
||||||
latestVersionLoading: false,
|
latestVersionLoading: false,
|
||||||
|
|
||||||
|
previewKey: null,
|
||||||
|
previewCode: null,
|
||||||
|
previewCodeSize: null,
|
||||||
|
previewLoading: false,
|
||||||
|
previewError: null,
|
||||||
|
|
||||||
setApiOnline: (online) => set({ apiOnline: online }),
|
setApiOnline: (online) => set({ apiOnline: online }),
|
||||||
setKeyword: (keyword) => set({ keyword }),
|
setKeyword: (keyword) => set({ keyword }),
|
||||||
|
|
||||||
reset: () => {
|
reset: () => {
|
||||||
|
if (_previewController) {
|
||||||
|
_previewController.abort();
|
||||||
|
_previewController = null;
|
||||||
|
}
|
||||||
|
_previewRequest += 1;
|
||||||
_selectedId = null;
|
_selectedId = null;
|
||||||
_editSession = null;
|
_editSession = null;
|
||||||
editSessionHandle.current = null;
|
editSessionHandle.current = null;
|
||||||
@@ -150,6 +170,11 @@ export const useScriptWorkspaceStore = create<State>((set, get) => {
|
|||||||
editorOpenError: null,
|
editorOpenError: null,
|
||||||
latestVersion: null,
|
latestVersion: null,
|
||||||
latestVersionLoading: false,
|
latestVersionLoading: false,
|
||||||
|
previewKey: null,
|
||||||
|
previewCode: null,
|
||||||
|
previewCodeSize: null,
|
||||||
|
previewLoading: false,
|
||||||
|
previewError: null,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -390,6 +415,58 @@ export const useScriptWorkspaceStore = create<State>((set, get) => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
loadPreview: async (workspaceId, filePath) => {
|
||||||
|
if (_previewController) {
|
||||||
|
_previewController.abort();
|
||||||
|
}
|
||||||
|
_previewRequest += 1;
|
||||||
|
const requestId = _previewRequest;
|
||||||
|
const previewKey = `${workspaceId}::${filePath}`;
|
||||||
|
|
||||||
|
set({ previewKey, previewLoading: true, previewError: null });
|
||||||
|
|
||||||
|
const controller = new AbortController();
|
||||||
|
_previewController = controller;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const url =
|
||||||
|
`/jupyter/${workspaceId}/api/contents/${filePath}` +
|
||||||
|
`?type=file&content=1&hash=1&format=text`;
|
||||||
|
const response = await fetch(url, {
|
||||||
|
signal: controller.signal,
|
||||||
|
credentials: "include",
|
||||||
|
cache: "no-store",
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Failed to load file: ${response.status}`);
|
||||||
|
}
|
||||||
|
const data = await response.json();
|
||||||
|
if (_previewRequest !== requestId) return;
|
||||||
|
set({
|
||||||
|
previewKey,
|
||||||
|
previewCode: data.content ?? "",
|
||||||
|
previewCodeSize: data.size ?? 0,
|
||||||
|
previewLoading: false,
|
||||||
|
previewError: null,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
if (_previewRequest !== requestId) return;
|
||||||
|
if (error instanceof Error && error.name === "AbortError") return;
|
||||||
|
set({
|
||||||
|
previewKey,
|
||||||
|
previewCode: null,
|
||||||
|
previewCodeSize: null,
|
||||||
|
previewLoading: false,
|
||||||
|
previewError:
|
||||||
|
error instanceof Error ? error.message : "加载预览失败",
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
if (_previewRequest === requestId) {
|
||||||
|
_previewController = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
createScript: async (form) => {
|
createScript: async (form) => {
|
||||||
const api = requireApi();
|
const api = requireApi();
|
||||||
const suffix = form.scriptType === "notebook" ? ".ipynb" : ".py";
|
const suffix = form.scriptType === "notebook" ? ".ipynb" : ".py";
|
||||||
@@ -666,4 +743,4 @@ export const useScriptWorkspaceStore = create<State>((set, get) => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"typecheck": "react-router typegen && tsc"
|
"typecheck": "react-router typegen && tsc"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@monaco-editor/react": "^4.7.0",
|
||||||
"@react-router/node": "^8",
|
"@react-router/node": "^8",
|
||||||
"@react-router/serve": "^8",
|
"@react-router/serve": "^8",
|
||||||
"isbot": "^5.1.36",
|
"isbot": "^5.1.36",
|
||||||
@@ -27,5 +28,5 @@
|
|||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
"vite": "^8.0.3"
|
"vite": "^8.0.3"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@10.15.1"
|
"packageManager": "pnpm@11.21.0"
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+57
@@ -8,6 +8,9 @@ importers:
|
|||||||
|
|
||||||
.:
|
.:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@monaco-editor/react':
|
||||||
|
specifier: ^4.7.0
|
||||||
|
version: 4.7.0(monaco-editor@0.56.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||||
'@react-router/node':
|
'@react-router/node':
|
||||||
specifier: ^8
|
specifier: ^8
|
||||||
version: 8.3.0(react-router@8.3.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(typescript@5.9.3)
|
version: 8.3.0(react-router@8.3.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(typescript@5.9.3)
|
||||||
@@ -228,6 +231,16 @@ packages:
|
|||||||
'@jridgewell/trace-mapping@0.3.31':
|
'@jridgewell/trace-mapping@0.3.31':
|
||||||
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
|
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
|
||||||
|
|
||||||
|
'@monaco-editor/loader@1.7.0':
|
||||||
|
resolution: {integrity: sha512-gIwR1HrJrrx+vfyOhYmCZ0/JcWqG5kbfG7+d3f/C1LXk2EvzAbHSg3MQ5lO2sMlo9izoAZ04shohfKLVT6crVA==}
|
||||||
|
|
||||||
|
'@monaco-editor/react@4.7.0':
|
||||||
|
resolution: {integrity: sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA==}
|
||||||
|
peerDependencies:
|
||||||
|
monaco-editor: '>= 0.25.0 < 1'
|
||||||
|
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
|
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
|
|
||||||
'@napi-rs/wasm-runtime@1.2.0':
|
'@napi-rs/wasm-runtime@1.2.0':
|
||||||
resolution: {integrity: sha512-kDoONqMa+VnZ4vvvu/ZUurpJ4gkZU57e7g69qpNgWhYcZFPUHZM2CEMKm+cG6ufDVALbjMvfmMjFVqaK7uEMnA==}
|
resolution: {integrity: sha512-kDoONqMa+VnZ4vvvu/ZUurpJ4gkZU57e7g69qpNgWhYcZFPUHZM2CEMKm+cG6ufDVALbjMvfmMjFVqaK7uEMnA==}
|
||||||
engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0}
|
engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0}
|
||||||
@@ -499,6 +512,9 @@ packages:
|
|||||||
'@types/react@19.2.17':
|
'@types/react@19.2.17':
|
||||||
resolution: {integrity: sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==}
|
resolution: {integrity: sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==}
|
||||||
|
|
||||||
|
'@types/trusted-types@2.0.7':
|
||||||
|
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
|
||||||
|
|
||||||
accepts@2.0.0:
|
accepts@2.0.0:
|
||||||
resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==}
|
resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
@@ -619,6 +635,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
|
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
dompurify@3.4.8:
|
||||||
|
resolution: {integrity: sha512-yb1cEmaOum7wFvOCSQxyfgVlv5D47Rc30iZWoMpbDIWTnJ6grDDQyu2KFJzB2k7u0pMuJcQ1zphH//fFnw2tjQ==}
|
||||||
|
|
||||||
dunder-proto@1.0.1:
|
dunder-proto@1.0.1:
|
||||||
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
|
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -926,6 +945,11 @@ packages:
|
|||||||
magic-string@0.30.21:
|
magic-string@0.30.21:
|
||||||
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
|
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
|
||||||
|
|
||||||
|
marked@14.0.0:
|
||||||
|
resolution: {integrity: sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==}
|
||||||
|
engines: {node: '>= 18'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
math-intrinsics@1.1.0:
|
math-intrinsics@1.1.0:
|
||||||
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
|
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -946,6 +970,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==}
|
resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
monaco-editor@0.56.0:
|
||||||
|
resolution: {integrity: sha512-sXboRm3BeBeLm938eaiyLMe0OxzfXIlZvbv4ir/jVgQy1zDhWjgmny0WoN45fuDKhCCQsYMbBJrv/A6jd8aCUg==}
|
||||||
|
|
||||||
morgan@1.11.0:
|
morgan@1.11.0:
|
||||||
resolution: {integrity: sha512-zSkVu3t18r39pw4ixfBKvfZi3y2UOqr7d4WYwcj3m8nXpEQK4rPO6GLzs/CExoRgmX3y9EjmmcXqv6jq0SK46g==}
|
resolution: {integrity: sha512-zSkVu3t18r39pw4ixfBKvfZi3y2UOqr7d4WYwcj3m8nXpEQK4rPO6GLzs/CExoRgmX3y9EjmmcXqv6jq0SK46g==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
@@ -1132,6 +1159,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-mTozplhTX4tLKIHYji92OTZzVyZvi+Z1qRZDeBvQFI2XUB89wrRoj/xXad3c9NZ1GPJXXRvB+k41PQCPTMC+aA==}
|
resolution: {integrity: sha512-mTozplhTX4tLKIHYji92OTZzVyZvi+Z1qRZDeBvQFI2XUB89wrRoj/xXad3c9NZ1GPJXXRvB+k41PQCPTMC+aA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
state-local@1.0.7:
|
||||||
|
resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==}
|
||||||
|
|
||||||
statuses@2.0.2:
|
statuses@2.0.2:
|
||||||
resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==}
|
resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
@@ -1492,6 +1522,17 @@ snapshots:
|
|||||||
'@jridgewell/resolve-uri': 3.1.2
|
'@jridgewell/resolve-uri': 3.1.2
|
||||||
'@jridgewell/sourcemap-codec': 1.4.14
|
'@jridgewell/sourcemap-codec': 1.4.14
|
||||||
|
|
||||||
|
'@monaco-editor/loader@1.7.0':
|
||||||
|
dependencies:
|
||||||
|
state-local: 1.0.7
|
||||||
|
|
||||||
|
'@monaco-editor/react@4.7.0(monaco-editor@0.56.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
|
||||||
|
dependencies:
|
||||||
|
'@monaco-editor/loader': 1.7.0
|
||||||
|
monaco-editor: 0.56.0
|
||||||
|
react: 19.2.8
|
||||||
|
react-dom: 19.2.8(react@19.2.8)
|
||||||
|
|
||||||
'@napi-rs/wasm-runtime@1.2.0(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)':
|
'@napi-rs/wasm-runtime@1.2.0(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@emnapi/core': 1.11.1
|
'@emnapi/core': 1.11.1
|
||||||
@@ -1705,6 +1746,9 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
csstype: 3.2.3
|
csstype: 3.2.3
|
||||||
|
|
||||||
|
'@types/trusted-types@2.0.7':
|
||||||
|
optional: true
|
||||||
|
|
||||||
accepts@2.0.0:
|
accepts@2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
mime-types: 3.0.2
|
mime-types: 3.0.2
|
||||||
@@ -1815,6 +1859,10 @@ snapshots:
|
|||||||
|
|
||||||
detect-libc@2.1.2: {}
|
detect-libc@2.1.2: {}
|
||||||
|
|
||||||
|
dompurify@3.4.8:
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/trusted-types': 2.0.7
|
||||||
|
|
||||||
dunder-proto@1.0.1:
|
dunder-proto@1.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
call-bind-apply-helpers: 1.0.2
|
call-bind-apply-helpers: 1.0.2
|
||||||
@@ -2075,6 +2123,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@jridgewell/sourcemap-codec': 1.5.5
|
'@jridgewell/sourcemap-codec': 1.5.5
|
||||||
|
|
||||||
|
marked@14.0.0: {}
|
||||||
|
|
||||||
math-intrinsics@1.1.0: {}
|
math-intrinsics@1.1.0: {}
|
||||||
|
|
||||||
media-typer@1.1.1: {}
|
media-typer@1.1.1: {}
|
||||||
@@ -2087,6 +2137,11 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
mime-db: 1.54.0
|
mime-db: 1.54.0
|
||||||
|
|
||||||
|
monaco-editor@0.56.0:
|
||||||
|
dependencies:
|
||||||
|
dompurify: 3.4.8
|
||||||
|
marked: 14.0.0
|
||||||
|
|
||||||
morgan@1.11.0:
|
morgan@1.11.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
basic-auth: 2.0.1
|
basic-auth: 2.0.1
|
||||||
@@ -2291,6 +2346,8 @@ snapshots:
|
|||||||
|
|
||||||
source-map@0.6.0: {}
|
source-map@0.6.0: {}
|
||||||
|
|
||||||
|
state-local@1.0.7: {}
|
||||||
|
|
||||||
statuses@2.0.2: {}
|
statuses@2.0.2: {}
|
||||||
|
|
||||||
tailwindcss@4.3.3: {}
|
tailwindcss@4.3.3: {}
|
||||||
|
|||||||
Reference in New Issue
Block a user