Compare commits
3 Commits
078f051e8a
...
f2aab1ab33
Author | SHA1 | Date | |
---|---|---|---|
f2aab1ab33 | |||
1973ff4304 | |||
89488d9921 |
1303
package-lock.json
generated
1303
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -12,6 +12,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.14.0",
|
"@emotion/react": "^11.14.0",
|
||||||
"@emotion/styled": "^11.14.0",
|
"@emotion/styled": "^11.14.0",
|
||||||
|
"@hello-pangea/dnd": "^18.0.1",
|
||||||
"@mui/material": "^7.1.0",
|
"@mui/material": "^7.1.0",
|
||||||
"@photo-sphere-viewer/core": "^5.13.2",
|
"@photo-sphere-viewer/core": "^5.13.2",
|
||||||
"@react-three/drei": "^10.1.2",
|
"@react-three/drei": "^10.1.2",
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
|
||||||
import { BrowserRouter } from "react-router-dom";
|
|
||||||
|
|
||||||
import { Router } from "./router";
|
import { Router } from "./router";
|
||||||
import { CustomTheme } from "@shared";
|
import { CustomTheme } from "@shared";
|
||||||
import { ThemeProvider } from "@mui/material/styles";
|
import { ThemeProvider } from "@mui/material/styles";
|
||||||
@ -10,8 +8,7 @@ import { ToastContainer } from "react-toastify";
|
|||||||
export const App: React.FC = () => (
|
export const App: React.FC = () => (
|
||||||
<ThemeProvider theme={CustomTheme.Light}>
|
<ThemeProvider theme={CustomTheme.Light}>
|
||||||
<ToastContainer />
|
<ToastContainer />
|
||||||
<BrowserRouter>
|
|
||||||
<Router />
|
<Router />
|
||||||
</BrowserRouter>
|
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
);
|
);
|
||||||
|
@ -9,37 +9,45 @@ import {
|
|||||||
MediaListPage,
|
MediaListPage,
|
||||||
PreviewMediaPage,
|
PreviewMediaPage,
|
||||||
EditMediaPage,
|
EditMediaPage,
|
||||||
// CreateMediaPage,
|
|
||||||
} from "@pages";
|
} from "@pages";
|
||||||
import { authStore, createSightStore, editSightStore } from "@shared";
|
import { authStore, createSightStore, editSightStore } from "@shared";
|
||||||
import { Layout } from "@widgets";
|
import { Layout } from "@widgets";
|
||||||
import { runInAction } from "mobx";
|
import { runInAction } from "mobx";
|
||||||
import { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
|
|
||||||
import { Navigate, Outlet, Route, Routes, useLocation } from "react-router-dom";
|
import {
|
||||||
|
createBrowserRouter,
|
||||||
|
RouterProvider,
|
||||||
|
Navigate,
|
||||||
|
Outlet,
|
||||||
|
useLocation,
|
||||||
|
} from "react-router-dom";
|
||||||
|
|
||||||
const PublicRoute = ({ children }: { children: React.ReactNode }) => {
|
const PublicRoute = ({ children }: { children: React.ReactNode }) => {
|
||||||
const { isAuthenticated } = authStore;
|
const { isAuthenticated } = authStore;
|
||||||
if (isAuthenticated) {
|
if (isAuthenticated) {
|
||||||
return <Navigate to="/sight" />;
|
return <Navigate to="/sight" replace />;
|
||||||
}
|
}
|
||||||
return children;
|
return <>{children}</>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ProtectedRoute = ({ children }: { children: React.ReactNode }) => {
|
const ProtectedRoute = ({ children }: { children: React.ReactNode }) => {
|
||||||
const { isAuthenticated } = authStore;
|
const { isAuthenticated } = authStore;
|
||||||
const pathname = useLocation();
|
const location = useLocation();
|
||||||
if (!isAuthenticated) {
|
if (!isAuthenticated) {
|
||||||
return <Navigate to="/login" />;
|
return <Navigate to="/login" replace />;
|
||||||
}
|
}
|
||||||
if (pathname.pathname === "/") {
|
if (location.pathname === "/") {
|
||||||
return <Navigate to="/sight" />;
|
return <Navigate to="/sight" replace />;
|
||||||
}
|
}
|
||||||
return children;
|
return <>{children}</>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Router = () => {
|
// Чтобы очистка сторов происходила при смене локации
|
||||||
const pathname = useLocation();
|
const ClearStoresWrapper: React.FC<{ children: React.ReactNode }> = ({
|
||||||
|
children,
|
||||||
|
}) => {
|
||||||
|
const location = useLocation();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
editSightStore.clearSightInfo();
|
editSightStore.clearSightInfo();
|
||||||
@ -47,41 +55,46 @@ export const Router = () => {
|
|||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
editSightStore.hasLoadedCommon = false;
|
editSightStore.hasLoadedCommon = false;
|
||||||
});
|
});
|
||||||
}, [pathname]);
|
}, [location]);
|
||||||
|
|
||||||
return (
|
return <>{children}</>;
|
||||||
<Routes>
|
};
|
||||||
<Route
|
|
||||||
path="/login"
|
const router = createBrowserRouter([
|
||||||
element={
|
{
|
||||||
|
path: "/login",
|
||||||
|
element: (
|
||||||
<PublicRoute>
|
<PublicRoute>
|
||||||
<LoginPage />
|
<LoginPage />
|
||||||
</PublicRoute>
|
</PublicRoute>
|
||||||
}
|
),
|
||||||
/>
|
},
|
||||||
|
{
|
||||||
{/* Protected routes with layout */}
|
path: "/",
|
||||||
<Route
|
element: (
|
||||||
path="/"
|
|
||||||
element={
|
|
||||||
<ProtectedRoute>
|
<ProtectedRoute>
|
||||||
<Layout>
|
<Layout>
|
||||||
|
<ClearStoresWrapper>
|
||||||
<Outlet />
|
<Outlet />
|
||||||
|
</ClearStoresWrapper>
|
||||||
</Layout>
|
</Layout>
|
||||||
</ProtectedRoute>
|
</ProtectedRoute>
|
||||||
}
|
),
|
||||||
>
|
children: [
|
||||||
<Route index element={<MainPage />} />
|
{ index: true, element: <MainPage /> },
|
||||||
<Route path="sight" element={<SightPage />} />
|
{ path: "sight", element: <SightPage /> },
|
||||||
<Route path="sight/:id" element={<EditSightPage />} />
|
{ path: "sight/create", element: <CreateSightPage /> },
|
||||||
<Route path="sight/create" element={<CreateSightPage />} />
|
{ path: "sight/:id", element: <EditSightPage /> },
|
||||||
<Route path="devices" element={<DevicesPage />} />
|
{ path: "devices", element: <DevicesPage /> },
|
||||||
<Route path="map" element={<MapPage />} />
|
{ path: "map", element: <MapPage /> },
|
||||||
<Route path="media" element={<MediaListPage />} />
|
{ path: "media", element: <MediaListPage /> },
|
||||||
<Route path="media/:id" element={<PreviewMediaPage />} />
|
{ path: "media/:id", element: <PreviewMediaPage /> },
|
||||||
<Route path="media/:id/edit" element={<EditMediaPage />} />
|
{ path: "media/:id/edit", element: <EditMediaPage /> },
|
||||||
{/* <Route path="media/create" element={<CreateMediaPage />} /> */}
|
// { path: "media/create", element: <CreateMediaPage /> },
|
||||||
</Route>
|
],
|
||||||
</Routes>
|
},
|
||||||
);
|
]);
|
||||||
|
|
||||||
|
export const Router = () => {
|
||||||
|
return <RouterProvider router={router} />;
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
import { Box, Tab, Tabs } from "@mui/material";
|
import { Box, Tab, Tabs } from "@mui/material";
|
||||||
import { articlesStore, cityStore, languageStore } from "@shared";
|
import { articlesStore, cityStore, languageStore } from "@shared";
|
||||||
import { CreateInformationTab, CreateLeftTab, CreateRightTab } from "@widgets";
|
import {
|
||||||
|
CreateInformationTab,
|
||||||
|
CreateLeftTab,
|
||||||
|
CreateRightTab,
|
||||||
|
LeaveAgree,
|
||||||
|
} from "@widgets";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
|
|
||||||
@ -11,6 +16,8 @@ function a11yProps(index: number) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
import { useBlocker } from "react-router";
|
||||||
|
|
||||||
export const CreateSightPage = observer(() => {
|
export const CreateSightPage = observer(() => {
|
||||||
const [value, setValue] = useState(0);
|
const [value, setValue] = useState(0);
|
||||||
const { getCities } = cityStore;
|
const { getCities } = cityStore;
|
||||||
@ -19,6 +26,11 @@ export const CreateSightPage = observer(() => {
|
|||||||
setValue(newValue);
|
setValue(newValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let blocker = useBlocker(
|
||||||
|
({ currentLocation, nextLocation }) =>
|
||||||
|
true && currentLocation.pathname !== nextLocation.pathname
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
await getCities();
|
await getCities();
|
||||||
@ -34,6 +46,7 @@ export const CreateSightPage = observer(() => {
|
|||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
minHeight: "100vh",
|
minHeight: "100vh",
|
||||||
|
z: 10,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
@ -66,6 +79,8 @@ export const CreateSightPage = observer(() => {
|
|||||||
<CreateLeftTab value={value} index={1} />
|
<CreateLeftTab value={value} index={1} />
|
||||||
<CreateRightTab value={value} index={2} />
|
<CreateRightTab value={value} index={2} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{blocker.state === "blocked" ? <LeaveAgree blocker={blocker} /> : null}
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -34,6 +34,7 @@ export const EditMediaPage = observer(() => {
|
|||||||
const [mediaName, setMediaName] = useState(media?.media_name ?? "");
|
const [mediaName, setMediaName] = useState(media?.media_name ?? "");
|
||||||
const [mediaFilename, setMediaFilename] = useState(media?.filename ?? "");
|
const [mediaFilename, setMediaFilename] = useState(media?.filename ?? "");
|
||||||
const [mediaType, setMediaType] = useState(media?.media_type ?? 1);
|
const [mediaType, setMediaType] = useState(media?.media_type ?? 1);
|
||||||
|
const [availableMediaTypes, setAvailableMediaTypes] = useState<number[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (id) {
|
if (id) {
|
||||||
@ -48,6 +49,18 @@ export const EditMediaPage = observer(() => {
|
|||||||
setMediaName(media.media_name);
|
setMediaName(media.media_name);
|
||||||
setMediaFilename(media.filename);
|
setMediaFilename(media.filename);
|
||||||
setMediaType(media.media_type);
|
setMediaType(media.media_type);
|
||||||
|
|
||||||
|
// Set available media types based on current file extension
|
||||||
|
const extension = media.filename.split(".").pop()?.toLowerCase();
|
||||||
|
if (extension) {
|
||||||
|
if (["glb", "gltf"].includes(extension)) {
|
||||||
|
setAvailableMediaTypes([6]); // 3D model
|
||||||
|
} else if (["jpg", "jpeg", "png", "gif"].includes(extension)) {
|
||||||
|
setAvailableMediaTypes([1, 3, 4, 5]); // Photo, Icon, Watermark, Panorama
|
||||||
|
} else if (["mp4", "webm", "mov"].includes(extension)) {
|
||||||
|
setAvailableMediaTypes([2]); // Video
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [media]);
|
}, [media]);
|
||||||
|
|
||||||
@ -76,8 +89,25 @@ export const EditMediaPage = observer(() => {
|
|||||||
const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const files = e.target.files;
|
const files = e.target.files;
|
||||||
if (files && files.length > 0) {
|
if (files && files.length > 0) {
|
||||||
setNewFile(files[0]);
|
const file = files[0];
|
||||||
setMediaFilename(files[0].name);
|
setNewFile(file);
|
||||||
|
setMediaFilename(file.name);
|
||||||
|
|
||||||
|
// Determine media type based on file extension
|
||||||
|
const extension = file.name.split(".").pop()?.toLowerCase();
|
||||||
|
if (extension) {
|
||||||
|
if (["glb", "gltf"].includes(extension)) {
|
||||||
|
setAvailableMediaTypes([6]); // 3D model
|
||||||
|
setMediaType(6);
|
||||||
|
} else if (["jpg", "jpeg", "png", "gif"].includes(extension)) {
|
||||||
|
setAvailableMediaTypes([1, 3, 4, 5]); // Photo, Icon, Watermark, Panorama
|
||||||
|
setMediaType(1); // Default to Photo
|
||||||
|
} else if (["mp4", "webm", "mov"].includes(extension)) {
|
||||||
|
setAvailableMediaTypes([2]); // Video
|
||||||
|
setMediaType(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setUploadDialogOpen(true); // Open dialog on file selection
|
setUploadDialogOpen(true); // Open dialog on file selection
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -175,7 +205,17 @@ export const EditMediaPage = observer(() => {
|
|||||||
onChange={(e) => setMediaType(Number(e.target.value))}
|
onChange={(e) => setMediaType(Number(e.target.value))}
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
>
|
>
|
||||||
{Object.entries(MEDIA_TYPE_LABELS).map(([type, label]) => (
|
{availableMediaTypes.length > 0
|
||||||
|
? availableMediaTypes.map((type) => (
|
||||||
|
<MenuItem key={type} value={type}>
|
||||||
|
{
|
||||||
|
MEDIA_TYPE_LABELS[
|
||||||
|
type as keyof typeof MEDIA_TYPE_LABELS
|
||||||
|
]
|
||||||
|
}
|
||||||
|
</MenuItem>
|
||||||
|
))
|
||||||
|
: Object.entries(MEDIA_TYPE_LABELS).map(([type, label]) => (
|
||||||
<MenuItem key={type} value={Number(type)}>
|
<MenuItem key={type} value={Number(type)}>
|
||||||
{label}
|
{label}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Box, Tab, Tabs } from "@mui/material";
|
import { Box, Tab, Tabs } from "@mui/material";
|
||||||
import { InformationTab, RightWidgetTab } from "@widgets";
|
import { InformationTab, LeaveAgree, RightWidgetTab } from "@widgets";
|
||||||
import { LeftWidgetTab } from "@widgets";
|
import { LeftWidgetTab } from "@widgets";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
@ -9,7 +9,7 @@ import {
|
|||||||
editSightStore,
|
editSightStore,
|
||||||
languageStore,
|
languageStore,
|
||||||
} from "@shared";
|
} from "@shared";
|
||||||
import { useParams } from "react-router-dom";
|
import { useBlocker, useParams } from "react-router-dom";
|
||||||
|
|
||||||
function a11yProps(index: number) {
|
function a11yProps(index: number) {
|
||||||
return {
|
return {
|
||||||
@ -26,6 +26,11 @@ export const EditSightPage = observer(() => {
|
|||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const { getCities } = cityStore;
|
const { getCities } = cityStore;
|
||||||
|
|
||||||
|
let blocker = useBlocker(
|
||||||
|
({ currentLocation, nextLocation }) =>
|
||||||
|
true && currentLocation.pathname !== nextLocation.pathname
|
||||||
|
);
|
||||||
|
|
||||||
const handleChange = (_: React.SyntheticEvent, newValue: number) => {
|
const handleChange = (_: React.SyntheticEvent, newValue: number) => {
|
||||||
setValue(newValue);
|
setValue(newValue);
|
||||||
};
|
};
|
||||||
@ -82,6 +87,8 @@ export const EditSightPage = observer(() => {
|
|||||||
<RightWidgetTab value={value} index={2} />
|
<RightWidgetTab value={value} index={2} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{blocker.state === "blocked" ? <LeaveAgree blocker={blocker} /> : null}
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -28,8 +28,8 @@ import { FeatureLike } from "ol/Feature";
|
|||||||
|
|
||||||
// --- CONFIGURATION ---
|
// --- CONFIGURATION ---
|
||||||
export const mapConfig = {
|
export const mapConfig = {
|
||||||
center: [37.6173, 55.7558] as [number, number],
|
center: [30.311, 59.94] as [number, number],
|
||||||
zoom: 10,
|
zoom: 13,
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- SVG ICONS ---
|
// --- SVG ICONS ---
|
||||||
@ -1128,7 +1128,7 @@ const MapControls: React.FC<MapControlsProps> = ({
|
|||||||
const controls = [
|
const controls = [
|
||||||
{
|
{
|
||||||
mode: "edit",
|
mode: "edit",
|
||||||
title: "Редакт.",
|
title: "Редактировать",
|
||||||
longTitle: "Редактирование",
|
longTitle: "Редактирование",
|
||||||
icon: <EditIcon />,
|
icon: <EditIcon />,
|
||||||
action: () => mapService.activateEditMode(),
|
action: () => mapService.activateEditMode(),
|
||||||
@ -1156,7 +1156,7 @@ const MapControls: React.FC<MapControlsProps> = ({
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
return (
|
return (
|
||||||
<div className="absolute top-4 left-1/2 -translate-x-1/2 z-20 flex flex-wrap justify-center p-2 bg-white/90 backdrop-blur-sm rounded-lg shadow-xl space-x-1 sm:space-x-2">
|
<div className="absolute top-4 left-1/2 -translate-x-1/2 z-20 flex flex-nowrap justify-center p-2 bg-white/90 backdrop-blur-sm rounded-lg shadow-xl space-x-1 sm:space-x-2">
|
||||||
{controls.map((c) => (
|
{controls.map((c) => (
|
||||||
<button
|
<button
|
||||||
key={c.mode}
|
key={c.mode}
|
||||||
|
@ -2,10 +2,11 @@ import { TableBody } from "@mui/material";
|
|||||||
import { TableRow, TableCell } from "@mui/material";
|
import { TableRow, TableCell } from "@mui/material";
|
||||||
import { Table, TableHead } from "@mui/material";
|
import { Table, TableHead } from "@mui/material";
|
||||||
import { mediaStore, MEDIA_TYPE_LABELS } from "@shared";
|
import { mediaStore, MEDIA_TYPE_LABELS } from "@shared";
|
||||||
import { useEffect } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { Eye, Pencil, Trash2 } from "lucide-react";
|
import { Eye, Pencil, Trash2 } from "lucide-react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { DeleteModal } from "@widgets";
|
||||||
|
|
||||||
const rows = (media: any[]) => {
|
const rows = (media: any[]) => {
|
||||||
return media.map((row) => ({
|
return media.map((row) => ({
|
||||||
@ -24,7 +25,8 @@ export const MediaListPage = observer(() => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const currentRows = rows(media);
|
const currentRows = rows(media);
|
||||||
|
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||||
|
const [rowId, setRowId] = useState<number | null>(null);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Table sx={{ minWidth: 650 }} aria-label="simple table">
|
<Table sx={{ minWidth: 650 }} aria-label="simple table">
|
||||||
@ -53,7 +55,12 @@ export const MediaListPage = observer(() => {
|
|||||||
<Pencil size={20} className="text-blue-500" />
|
<Pencil size={20} className="text-blue-500" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button onClick={() => deleteMedia(row.id)}>
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
setIsDeleteModalOpen(true);
|
||||||
|
setRowId(row.id);
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Trash2 size={20} className="text-red-500" />
|
<Trash2 size={20} className="text-red-500" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -62,6 +69,20 @@ export const MediaListPage = observer(() => {
|
|||||||
))}
|
))}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
|
<DeleteModal
|
||||||
|
open={isDeleteModalOpen}
|
||||||
|
onDelete={async () => {
|
||||||
|
if (rowId) {
|
||||||
|
await deleteMedia(rowId.toString());
|
||||||
|
}
|
||||||
|
setIsDeleteModalOpen(false);
|
||||||
|
setRowId(null);
|
||||||
|
}}
|
||||||
|
onCancel={() => {
|
||||||
|
setIsDeleteModalOpen(false);
|
||||||
|
setRowId(null);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -7,3 +7,14 @@ export const MEDIA_TYPE_LABELS = {
|
|||||||
5: "Панорама",
|
5: "Панорама",
|
||||||
6: "3Д-модель",
|
6: "3Д-модель",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const MEDIA_TYPE_VALUES = {
|
||||||
|
photo: 1,
|
||||||
|
video: 2,
|
||||||
|
icon: 3,
|
||||||
|
thumbnail: 3,
|
||||||
|
watermark_lu: 4,
|
||||||
|
watermark_rd: 4,
|
||||||
|
panorama: 5,
|
||||||
|
model: 6,
|
||||||
|
};
|
||||||
|
@ -17,7 +17,7 @@ import {
|
|||||||
InputAdornment,
|
InputAdornment,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { ImagePlus, Search } from "lucide-react";
|
import { ImagePlus, Search } from "lucide-react";
|
||||||
import { ReactMarkdownComponent } from "@widgets";
|
import { MediaViewer, ReactMarkdownComponent } from "@widgets";
|
||||||
|
|
||||||
interface SelectArticleModalProps {
|
interface SelectArticleModalProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@ -106,7 +106,6 @@ export const SelectArticleModal = observer(
|
|||||||
// article.service_name.toLowerCase().includes(searchQuery.toLowerCase())
|
// article.service_name.toLowerCase().includes(searchQuery.toLowerCase())
|
||||||
// );
|
// );
|
||||||
|
|
||||||
const token = localStorage.getItem("token");
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
open={open}
|
open={open}
|
||||||
@ -128,10 +127,12 @@ export const SelectArticleModal = observer(
|
|||||||
height: "600px",
|
height: "600px",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
|
||||||
p: 2,
|
p: 2,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Paper className="w-[66%] flex flex-col" elevation={2}>
|
<Paper className="w-[66%] flex flex-col h-full" elevation={2}>
|
||||||
<TextField
|
<TextField
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Поиск статей..."
|
placeholder="Поиск статей..."
|
||||||
@ -201,108 +202,86 @@ export const SelectArticleModal = observer(
|
|||||||
)}
|
)}
|
||||||
</List>
|
</List>
|
||||||
</Paper>
|
</Paper>
|
||||||
<Paper className="flex-1 flex flex-col" elevation={2}>
|
<Paper
|
||||||
<Box
|
elevation={3}
|
||||||
className="rounded-2xl overflow-hidden"
|
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
height: "100%",
|
minWidth: 320,
|
||||||
background: "#877361",
|
maxWidth: 310,
|
||||||
borderColor: "grey.300",
|
|
||||||
|
background:
|
||||||
|
"#806c59 linear-gradient(90deg, rgba(255, 255, 255, 0.2) 12.5%, rgba(255, 255, 255, 0.2) 100%)",
|
||||||
|
|
||||||
|
padding: 0,
|
||||||
|
margin: "0px auto",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{isLoading ? (
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
height: "100%",
|
height: 175,
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
|
padding: "3px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography color="white">Загрузка...</Typography>
|
{articlesStore.articleMedia ? (
|
||||||
</Box>
|
<MediaViewer
|
||||||
) : (
|
media={{
|
||||||
<>
|
id: articlesStore.articleMedia.id,
|
||||||
{articlesStore.articleMedia && (
|
media_type: articlesStore.articleMedia.media_type,
|
||||||
<Box sx={{ p: 2, backgroundColor: "rgba(0,0,0,0.1)" }}>
|
filename: articlesStore.articleMedia.filename,
|
||||||
<img
|
|
||||||
src={`${import.meta.env.VITE_KRBL_MEDIA}${
|
|
||||||
articlesStore.articleMedia.id
|
|
||||||
}/download?token=${token}`}
|
|
||||||
alt={articlesStore.articleMedia.filename}
|
|
||||||
style={{
|
|
||||||
maxWidth: "100%",
|
|
||||||
height: "auto",
|
|
||||||
maxHeight: "300px",
|
|
||||||
objectFit: "contain",
|
|
||||||
borderRadius: 8,
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
) : (
|
||||||
)}
|
|
||||||
{!articlesStore.articleMedia && (
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
width: "100%",
|
|
||||||
height: 200,
|
|
||||||
flexShrink: 0,
|
|
||||||
backgroundColor: "rgba(0,0,0,0.1)",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ImagePlus size={48} color="white" />
|
<ImagePlus size={48} color="white" />
|
||||||
</Box>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
width: "100%",
|
|
||||||
minHeight: "70px",
|
|
||||||
background: "#877361",
|
|
||||||
display: "flex",
|
|
||||||
flexShrink: 0,
|
|
||||||
alignItems: "center",
|
|
||||||
borderBottom: "1px solid rgba(255,255,255,0.1)",
|
|
||||||
px: 2,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Typography variant="h6" color="white">
|
|
||||||
{articlesStore.articleData?.heading || "Выберите статью"}
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
px: 2,
|
background:
|
||||||
flexGrow: 1,
|
"#806c59 linear-gradient(90deg, rgba(255, 255, 255, 0.2) 12.5%, rgba(255, 255, 255, 0.2) 100%)",
|
||||||
overflowY: "auto",
|
|
||||||
backgroundColor: "#877361",
|
|
||||||
color: "white",
|
color: "white",
|
||||||
py: 1,
|
margin: "5px 0px 5px 0px",
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
gap: 1,
|
||||||
|
padding: 1,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{articlesStore.articleData?.body ? (
|
|
||||||
<ReactMarkdownComponent
|
|
||||||
value={articlesStore.articleData.body}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<Typography
|
<Typography
|
||||||
color="rgba(255,255,255,0.7)"
|
variant="h5"
|
||||||
sx={{ textAlign: "center", mt: 4 }}
|
component="h2"
|
||||||
|
sx={{
|
||||||
|
wordBreak: "break-word",
|
||||||
|
fontSize: "24px",
|
||||||
|
fontWeight: 700,
|
||||||
|
lineHeight: "120%",
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Предпросмотр статьи появится здесь
|
{articlesStore.articleData?.heading || "Название cтатьи"}
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
|
||||||
</Box>
|
</Box>
|
||||||
</>
|
|
||||||
)}
|
{articlesStore.articleData?.body && (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
padding: 1,
|
||||||
|
maxHeight: "200px",
|
||||||
|
overflowY: "scroll",
|
||||||
|
background:
|
||||||
|
"#806c59 linear-gradient(90deg, rgba(255, 255, 255, 0.2) 12.5%, rgba(255, 255, 255, 0.2) 100%)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ReactMarkdownComponent
|
||||||
|
value={articlesStore.articleData?.body || "Описание"}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
)}
|
||||||
</Paper>
|
</Paper>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions sx={{ p: 2 }}>
|
<DialogActions sx={{ p: 2 }}>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { mediaStore } from "@shared";
|
import { Media, mediaStore } from "@shared";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import {
|
import {
|
||||||
@ -29,6 +29,7 @@ interface SelectMediaDialogProps {
|
|||||||
}) => void; // Renamed from onSelectArticle
|
}) => void; // Renamed from onSelectArticle
|
||||||
onSelectForSightMedia?: (mediaId: string) => void;
|
onSelectForSightMedia?: (mediaId: string) => void;
|
||||||
linkedMediaIds?: string[]; // Renamed from linkedArticleIds, assuming it refers to media already in use
|
linkedMediaIds?: string[]; // Renamed from linkedArticleIds, assuming it refers to media already in use
|
||||||
|
mediaType?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SelectMediaDialog = observer(
|
export const SelectMediaDialog = observer(
|
||||||
@ -38,12 +39,29 @@ export const SelectMediaDialog = observer(
|
|||||||
onSelectMedia, // Renamed prop
|
onSelectMedia, // Renamed prop
|
||||||
onSelectForSightMedia,
|
onSelectForSightMedia,
|
||||||
linkedMediaIds = [], // Default to empty array if not provided, renamed
|
linkedMediaIds = [], // Default to empty array if not provided, renamed
|
||||||
|
mediaType,
|
||||||
}: SelectMediaDialogProps) => {
|
}: SelectMediaDialogProps) => {
|
||||||
const { media, getMedia } = mediaStore;
|
const { media, getMedia } = mediaStore;
|
||||||
const [searchQuery, setSearchQuery] = useState("");
|
const [searchQuery, setSearchQuery] = useState("");
|
||||||
const [hoveredMediaId, setHoveredMediaId] = useState<string | null>(null);
|
const [hoveredMediaId, setHoveredMediaId] = useState<string | null>(null);
|
||||||
|
const [currentHoveredMedia, setCurrentHoveredMedia] =
|
||||||
|
useState<Media | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (hoveredMediaId) {
|
||||||
|
setCurrentHoveredMedia(
|
||||||
|
media.find((m) => m.id === hoveredMediaId) ?? null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, [hoveredMediaId]);
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setHoveredMediaId(null);
|
||||||
|
setCurrentHoveredMedia(null);
|
||||||
|
onClose();
|
||||||
|
setSearchQuery("");
|
||||||
|
};
|
||||||
|
|
||||||
// Fetch media on component mount
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getMedia();
|
getMedia();
|
||||||
}, [getMedia]);
|
}, [getMedia]);
|
||||||
@ -63,7 +81,7 @@ export const SelectMediaDialog = observer(
|
|||||||
onSelectMedia(mediaItem);
|
onSelectMedia(mediaItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onClose();
|
handleClose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -74,19 +92,21 @@ export const SelectMediaDialog = observer(
|
|||||||
};
|
};
|
||||||
}, [hoveredMediaId, onSelectMedia, onClose]); // Dependencies for keyboard listener
|
}, [hoveredMediaId, onSelectMedia, onClose]); // Dependencies for keyboard listener
|
||||||
|
|
||||||
const filteredMedia = media
|
let filteredMedia = media
|
||||||
.filter((mediaItem) => !linkedMediaIds.includes(mediaItem.id)) // Use mediaItem to avoid name collision
|
.filter((mediaItem) => !linkedMediaIds.includes(mediaItem.id)) // Use mediaItem to avoid name collision
|
||||||
.filter((mediaItem) =>
|
.filter((mediaItem) =>
|
||||||
mediaItem.media_name.toLowerCase().includes(searchQuery.toLowerCase())
|
mediaItem.media_name.toLowerCase().includes(searchQuery.toLowerCase())
|
||||||
);
|
);
|
||||||
|
|
||||||
// Find the currently hovered media object for MediaViewer
|
if (mediaType) {
|
||||||
const currentHoveredMedia = hoveredMediaId
|
filteredMedia = filteredMedia.filter(
|
||||||
? media.find((m) => m.id === hoveredMediaId)
|
(mediaItem) => mediaItem.media_type === mediaType
|
||||||
: null;
|
);
|
||||||
|
console.log(filteredMedia);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={open} onClose={onClose} maxWidth="lg" fullWidth>
|
<Dialog open={open} onClose={handleClose} maxWidth="lg" fullWidth>
|
||||||
<DialogTitle>Выберите существующее медиа</DialogTitle>
|
<DialogTitle>Выберите существующее медиа</DialogTitle>
|
||||||
<DialogContent
|
<DialogContent
|
||||||
className="flex gap-4"
|
className="flex gap-4"
|
||||||
@ -125,14 +145,22 @@ export const SelectMediaDialog = observer(
|
|||||||
} else if (onSelectMedia) {
|
} else if (onSelectMedia) {
|
||||||
onSelectMedia(mediaItem);
|
onSelectMedia(mediaItem);
|
||||||
}
|
}
|
||||||
onClose();
|
handleClose();
|
||||||
}}
|
}}
|
||||||
|
selected={hoveredMediaId === mediaItem.id}
|
||||||
sx={{
|
sx={{
|
||||||
borderRadius: 1,
|
borderRadius: 1,
|
||||||
mb: 0.5,
|
mb: 0.5,
|
||||||
"&:hover": {
|
"&:hover": {
|
||||||
backgroundColor: "action.hover",
|
backgroundColor: "action.hover",
|
||||||
},
|
},
|
||||||
|
"&.Mui-selected": {
|
||||||
|
backgroundColor: "primary.main",
|
||||||
|
color: "primary.contrastText",
|
||||||
|
"&:hover": {
|
||||||
|
backgroundColor: "primary.dark",
|
||||||
|
},
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ListItemText primary={mediaItem.media_name} />
|
<ListItemText primary={mediaItem.media_name} />
|
||||||
@ -149,7 +177,7 @@ export const SelectMediaDialog = observer(
|
|||||||
)}
|
)}
|
||||||
</List>
|
</List>
|
||||||
</Paper>
|
</Paper>
|
||||||
{currentHoveredMedia ? ( // Only render MediaViewer if currentHoveredMedia is found
|
{currentHoveredMedia !== null && hoveredMediaId !== null ? ( // Only render MediaViewer if currentHoveredMedia is found
|
||||||
<Paper className="w-[33%] h-[100%] flex justify-center items-center">
|
<Paper className="w-[33%] h-[100%] flex justify-center items-center">
|
||||||
<MediaViewer
|
<MediaViewer
|
||||||
media={{
|
media={{
|
||||||
@ -167,8 +195,28 @@ export const SelectMediaDialog = observer(
|
|||||||
</Paper>
|
</Paper>
|
||||||
)}
|
)}
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
|
||||||
<Button onClick={onClose}>Отмена</Button>
|
<DialogActions sx={{ p: 2 }}>
|
||||||
|
<Button onClick={handleClose}>Отмена</Button>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
onClick={() => {
|
||||||
|
if (hoveredMediaId) {
|
||||||
|
const mediaItem = media.find((m) => m.id === hoveredMediaId);
|
||||||
|
if (mediaItem) {
|
||||||
|
if (onSelectForSightMedia) {
|
||||||
|
onSelectForSightMedia(mediaItem.id);
|
||||||
|
} else if (onSelectMedia) {
|
||||||
|
onSelectMedia(mediaItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handleClose();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
disabled={hoveredMediaId === null}
|
||||||
|
>
|
||||||
|
Выбрать
|
||||||
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
|
@ -586,6 +586,12 @@ class CreateSightStore {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
updateRightArticles = async (articles: any[], language: Language) => {
|
||||||
|
runInAction(() => {
|
||||||
|
this.sight[language].right = articles;
|
||||||
|
});
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createSightStore = new CreateSightStore();
|
export const createSightStore = new CreateSightStore();
|
||||||
|
@ -121,35 +121,32 @@ class EditSightStore {
|
|||||||
let responseEn = await languageInstance("en").get(`/sight/${id}/article`);
|
let responseEn = await languageInstance("en").get(`/sight/${id}/article`);
|
||||||
let responseZh = await languageInstance("zh").get(`/sight/${id}/article`);
|
let responseZh = await languageInstance("zh").get(`/sight/${id}/article`);
|
||||||
|
|
||||||
// Function to fetch media for a given set of articles
|
// Create a map of article IDs to their media
|
||||||
const fetchMediaForArticles = async (articles: any[]) => {
|
const mediaMap = new Map();
|
||||||
const articlesWithMedia = [];
|
for (const article of responseRu.data) {
|
||||||
for (const article of articles) {
|
|
||||||
const responseMedia = await authInstance.get(
|
const responseMedia = await authInstance.get(
|
||||||
`/article/${article.id}/media`
|
`/article/${article.id}/media`
|
||||||
);
|
);
|
||||||
articlesWithMedia.push({
|
mediaMap.set(article.id, responseMedia.data);
|
||||||
...article,
|
|
||||||
media: responseMedia.data,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return articlesWithMedia;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Fetch media for articles in each language
|
// Function to add media to articles
|
||||||
const ruArticlesWithMedia = await fetchMediaForArticles(responseRu.data);
|
const addMediaToArticles = (articles: any[]) => {
|
||||||
const enArticlesWithMedia = await fetchMediaForArticles(responseEn.data);
|
return articles.map((article) => ({
|
||||||
const zhArticlesWithMedia = await fetchMediaForArticles(responseZh.data);
|
...article,
|
||||||
|
media: mediaMap.get(article.id),
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
ru: {
|
ru: {
|
||||||
right: ruArticlesWithMedia,
|
right: addMediaToArticles(responseRu.data),
|
||||||
},
|
},
|
||||||
en: {
|
en: {
|
||||||
right: enArticlesWithMedia,
|
right: addMediaToArticles(responseEn.data),
|
||||||
},
|
},
|
||||||
zh: {
|
zh: {
|
||||||
right: zhArticlesWithMedia,
|
right: addMediaToArticles(responseZh.data),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -673,6 +670,16 @@ class EditSightStore {
|
|||||||
this.sight[language].right[index].heading = heading;
|
this.sight[language].right[index].heading = heading;
|
||||||
this.sight[language].right[index].body = body;
|
this.sight[language].right[index].body = body;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
updateRightArticles = async (articles: any[], language: Language) => {
|
||||||
|
this.sight[language].right = articles;
|
||||||
|
const articleIdsInObject = articles.map((article) => ({
|
||||||
|
id: article.id,
|
||||||
|
}));
|
||||||
|
await authInstance.post(`/sight/${this.sight.common.id}/article/order`, {
|
||||||
|
articles: articleIdsInObject,
|
||||||
|
});
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const editSightStore = new EditSightStore();
|
export const editSightStore = new EditSightStore();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { makeAutoObservable, runInAction } from "mobx";
|
import { makeAutoObservable, runInAction } from "mobx";
|
||||||
import { authInstance } from "@shared";
|
import { authInstance } from "@shared";
|
||||||
|
|
||||||
type Media = {
|
export type Media = {
|
||||||
id: string;
|
id: string;
|
||||||
filename: string;
|
filename: string;
|
||||||
media_name: string;
|
media_name: string;
|
||||||
|
33
src/widgets/DeleteModal/index.tsx
Normal file
33
src/widgets/DeleteModal/index.tsx
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { Button } from "@mui/material";
|
||||||
|
|
||||||
|
export const DeleteModal = ({
|
||||||
|
onDelete,
|
||||||
|
onCancel,
|
||||||
|
open,
|
||||||
|
}: {
|
||||||
|
onDelete: () => void;
|
||||||
|
onCancel: () => void;
|
||||||
|
open: boolean;
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`fixed top-0 left-0 w-screen h-screen flex justify-center items-center z-10000 bg-black/30 transition-all duration-300 ${
|
||||||
|
open ? "block" : "hidden"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="bg-white p-4 w-100 rounded-lg flex flex-col gap-4 items-center">
|
||||||
|
<p className="text-black w-100 text-center">
|
||||||
|
Вы уверены, что хотите удалить этот элемент?
|
||||||
|
</p>
|
||||||
|
<div className="flex gap-4 justify-center">
|
||||||
|
<Button variant="contained" color="error" onClick={onDelete}>
|
||||||
|
Да
|
||||||
|
</Button>
|
||||||
|
<Button variant="outlined" onClick={onCancel}>
|
||||||
|
Нет
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -1,6 +1,6 @@
|
|||||||
import React, { useRef, useState, DragEvent, useEffect } from "react";
|
import React, { useRef, useState, DragEvent, useEffect } from "react";
|
||||||
import { Paper, Box, Typography, Button, Tooltip } from "@mui/material";
|
import { Paper, Box, Typography, Button, Tooltip } from "@mui/material";
|
||||||
import { X, Info } from "lucide-react"; // Assuming lucide-react for icons
|
import { X, Info, MousePointer } from "lucide-react"; // Assuming lucide-react for icons
|
||||||
import { editSightStore } from "@shared";
|
import { editSightStore } from "@shared";
|
||||||
|
|
||||||
interface ImageUploadCardProps {
|
interface ImageUploadCardProps {
|
||||||
@ -159,6 +159,7 @@ export const ImageUploadCard: React.FC<ImageUploadCardProps> = ({
|
|||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
|
startIcon={<MousePointer color="white" size={18} />}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation(); // Prevent `handleZoneClick` from firing
|
e.stopPropagation(); // Prevent `handleZoneClick` from firing
|
||||||
onSelectFileClick(); // This button might trigger a different modal
|
onSelectFileClick(); // This button might trigger a different modal
|
||||||
|
21
src/widgets/LeaveAgree/index.tsx
Normal file
21
src/widgets/LeaveAgree/index.tsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { Button } from "@mui/material";
|
||||||
|
|
||||||
|
export const LeaveAgree = ({ blocker }: { blocker: any }) => {
|
||||||
|
return (
|
||||||
|
<div className="fixed top-0 left-0 w-screen h-screen flex justify-center items-center z-10000 bg-black/30">
|
||||||
|
<div className="bg-white p-4 w-100 rounded-lg flex flex-col gap-4 items-center">
|
||||||
|
<p className="text-black w-100 text-center">
|
||||||
|
При выходе со страницы, несохраненные данные будут потеряны.
|
||||||
|
</p>
|
||||||
|
<div className="flex gap-4 justify-center">
|
||||||
|
<Button variant="contained" onClick={() => blocker.proceed()}>
|
||||||
|
Да
|
||||||
|
</Button>
|
||||||
|
<Button variant="outlined" onClick={() => blocker.reset()}>
|
||||||
|
Нет
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -69,7 +69,7 @@ export const MediaAreaForSight = observer(
|
|||||||
<Box className="w-full flex flex-col items-center justify-center border rounded-md p-4">
|
<Box className="w-full flex flex-col items-center justify-center border rounded-md p-4">
|
||||||
<div className="w-full flex flex-col items-center justify-center">
|
<div className="w-full flex flex-col items-center justify-center">
|
||||||
<div
|
<div
|
||||||
className={`w-full h-40 flex flex-col justify-center items-center text-gray-400 border-dashed border-2 rounded-md border-gray-400 p-4 cursor-pointer hover:bg-gray-50 ${
|
className={`w-full h-40 flex text-center flex-col justify-center items-center text-gray-400 border-dashed border-2 rounded-md border-gray-400 p-4 cursor-pointer hover:bg-gray-50 ${
|
||||||
isDragging ? "bg-blue-100 border-blue-400" : ""
|
isDragging ? "bg-blue-100 border-blue-400" : ""
|
||||||
}`}
|
}`}
|
||||||
onDrop={handleDrop}
|
onDrop={handleDrop}
|
||||||
|
@ -17,13 +17,11 @@ export function MediaViewer({
|
|||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
width: "80%",
|
width: "100%",
|
||||||
height: "100%",
|
height: "100%",
|
||||||
maxWidth: "600px",
|
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
margin: "0 auto",
|
|
||||||
}}
|
}}
|
||||||
className={className}
|
className={className}
|
||||||
>
|
>
|
||||||
@ -34,10 +32,9 @@ export function MediaViewer({
|
|||||||
}/download?token=${token}`}
|
}/download?token=${token}`}
|
||||||
alt={media?.filename}
|
alt={media?.filename}
|
||||||
style={{
|
style={{
|
||||||
maxWidth: "100%",
|
width: "100%",
|
||||||
height: "auto",
|
|
||||||
objectFit: "contain",
|
objectFit: "cover",
|
||||||
borderRadius: 8,
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -48,11 +45,10 @@ export function MediaViewer({
|
|||||||
media?.id
|
media?.id
|
||||||
}/download?token=${token}`}
|
}/download?token=${token}`}
|
||||||
style={{
|
style={{
|
||||||
margin: "auto 0",
|
width: "100%",
|
||||||
height: "fit-content",
|
height: "100%",
|
||||||
width: "fit-content",
|
objectFit: "cover",
|
||||||
objectFit: "contain",
|
borderRadius: 8,
|
||||||
borderRadius: 30,
|
|
||||||
}}
|
}}
|
||||||
controls
|
controls
|
||||||
autoPlay
|
autoPlay
|
||||||
@ -66,9 +62,9 @@ export function MediaViewer({
|
|||||||
}/download?token=${token}`}
|
}/download?token=${token}`}
|
||||||
alt={media?.filename}
|
alt={media?.filename}
|
||||||
style={{
|
style={{
|
||||||
maxWidth: "100%",
|
width: "100%",
|
||||||
height: "100%",
|
height: "100%",
|
||||||
objectFit: "contain",
|
objectFit: "cover",
|
||||||
borderRadius: 8,
|
borderRadius: 8,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@ -80,9 +76,9 @@ export function MediaViewer({
|
|||||||
}/download?token=${token}`}
|
}/download?token=${token}`}
|
||||||
alt={media?.filename}
|
alt={media?.filename}
|
||||||
style={{
|
style={{
|
||||||
maxWidth: "100%",
|
width: "100%",
|
||||||
height: "100%",
|
height: "100%",
|
||||||
objectFit: "contain",
|
objectFit: "cover",
|
||||||
borderRadius: 8,
|
borderRadius: 8,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -18,8 +18,10 @@ import {
|
|||||||
SightCommonInfo,
|
SightCommonInfo,
|
||||||
createSightStore,
|
createSightStore,
|
||||||
UploadMediaDialog,
|
UploadMediaDialog,
|
||||||
|
MEDIA_TYPE_VALUES,
|
||||||
} from "@shared";
|
} from "@shared";
|
||||||
import { ImageUploadCard, LanguageSwitcher } from "@widgets";
|
import { ImageUploadCard, LanguageSwitcher } from "@widgets";
|
||||||
|
import { Save } from "lucide-react";
|
||||||
|
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
@ -331,6 +333,7 @@ export const CreateInformationTab = observer(
|
|||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="success"
|
color="success"
|
||||||
|
startIcon={<Save color="white" size={18} />}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await createSight(language);
|
await createSight(language);
|
||||||
toast.success("Достопримечательность создана");
|
toast.success("Достопримечательность создана");
|
||||||
@ -369,6 +372,13 @@ export const CreateInformationTab = observer(
|
|||||||
onSelectMedia={(media) => {
|
onSelectMedia={(media) => {
|
||||||
handleMediaSelect(media, activeMenuType ?? "thumbnail");
|
handleMediaSelect(media, activeMenuType ?? "thumbnail");
|
||||||
}}
|
}}
|
||||||
|
mediaType={
|
||||||
|
activeMenuType
|
||||||
|
? MEDIA_TYPE_VALUES[
|
||||||
|
activeMenuType as keyof typeof MEDIA_TYPE_VALUES
|
||||||
|
]
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<PreviewMediaDialog
|
<PreviewMediaDialog
|
||||||
|
@ -16,8 +16,16 @@ import {
|
|||||||
ReactMarkdownComponent,
|
ReactMarkdownComponent,
|
||||||
ReactMarkdownEditor,
|
ReactMarkdownEditor,
|
||||||
MediaViewer,
|
MediaViewer,
|
||||||
|
DeleteModal,
|
||||||
} from "@widgets";
|
} from "@widgets";
|
||||||
import { Trash2, ImagePlus } from "lucide-react";
|
import {
|
||||||
|
Trash2,
|
||||||
|
ImagePlus,
|
||||||
|
Unlink,
|
||||||
|
MousePointer,
|
||||||
|
Plus,
|
||||||
|
Save,
|
||||||
|
} from "lucide-react";
|
||||||
import { useState, useCallback } from "react";
|
import { useState, useCallback } from "react";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
@ -47,7 +55,7 @@ export const CreateLeftTab = observer(
|
|||||||
useState(false);
|
useState(false);
|
||||||
const [isSelectMediaDialogOpen, setIsSelectMediaDialogOpen] =
|
const [isSelectMediaDialogOpen, setIsSelectMediaDialogOpen] =
|
||||||
useState(false);
|
useState(false);
|
||||||
|
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||||
// const handleMediaSelected = useCallback(() => {
|
// const handleMediaSelected = useCallback(() => {
|
||||||
// // При выборе медиа, обновляем данные для ТЕКУЩЕГО ЯЗЫКА
|
// // При выборе медиа, обновляем данные для ТЕКУЩЕГО ЯЗЫКА
|
||||||
// // сохраняя текущие heading и body.
|
// // сохраняя текущие heading и body.
|
||||||
@ -123,6 +131,7 @@ export const CreateLeftTab = observer(
|
|||||||
color="primary"
|
color="primary"
|
||||||
size="small"
|
size="small"
|
||||||
style={{ transition: "0" }}
|
style={{ transition: "0" }}
|
||||||
|
startIcon={<Unlink size={18} />}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
unlinkLeftArticle();
|
unlinkLeftArticle();
|
||||||
toast.success("Статья откреплена");
|
toast.success("Статья откреплена");
|
||||||
@ -136,10 +145,7 @@ export const CreateLeftTab = observer(
|
|||||||
style={{ transition: "0" }}
|
style={{ transition: "0" }}
|
||||||
startIcon={<Trash2 size={18} />}
|
startIcon={<Trash2 size={18} />}
|
||||||
size="small"
|
size="small"
|
||||||
onClick={() => {
|
onClick={() => setIsDeleteModalOpen(true)}
|
||||||
deleteLeftArticle(sight.left_article);
|
|
||||||
toast.success("Статья откреплена");
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
Удалить
|
Удалить
|
||||||
</Button>
|
</Button>
|
||||||
@ -150,6 +156,7 @@ export const CreateLeftTab = observer(
|
|||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
size="small"
|
size="small"
|
||||||
|
startIcon={<MousePointer color="white" size={18} />}
|
||||||
onClick={() => setIsSelectArticleDialogOpen(true)}
|
onClick={() => setIsSelectArticleDialogOpen(true)}
|
||||||
>
|
>
|
||||||
Выбрать статью
|
Выбрать статью
|
||||||
@ -158,6 +165,7 @@ export const CreateLeftTab = observer(
|
|||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
size="small"
|
size="small"
|
||||||
|
startIcon={<Plus color="white" size={18} />}
|
||||||
style={{ transition: "0" }}
|
style={{ transition: "0" }}
|
||||||
onClick={createLeftArticle}
|
onClick={createLeftArticle}
|
||||||
>
|
>
|
||||||
@ -301,6 +309,7 @@ export const CreateLeftTab = observer(
|
|||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
gap: 1.5,
|
gap: 1.5,
|
||||||
|
maxWidth: "320px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Paper
|
<Paper
|
||||||
@ -405,10 +414,11 @@ export const CreateLeftTab = observer(
|
|||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="success"
|
color="success"
|
||||||
|
startIcon={<Save color="white" size={18} />}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
try {
|
try {
|
||||||
await createSight(language);
|
await createSight(language);
|
||||||
toast.success("Странца создана");
|
toast.success("Страница создана");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
@ -445,6 +455,14 @@ export const CreateLeftTab = observer(
|
|||||||
onClose={handleCloseArticleDialog}
|
onClose={handleCloseArticleDialog}
|
||||||
onSelectArticle={handleArticleSelect}
|
onSelectArticle={handleArticleSelect}
|
||||||
/>
|
/>
|
||||||
|
<DeleteModal
|
||||||
|
open={isDeleteModalOpen}
|
||||||
|
onDelete={() => {
|
||||||
|
deleteLeftArticle(sight.left_article);
|
||||||
|
toast.success("Статья откреплена");
|
||||||
|
}}
|
||||||
|
onCancel={() => setIsDeleteModalOpen(false)}
|
||||||
|
/>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,8 @@ import {
|
|||||||
SelectArticleModal,
|
SelectArticleModal,
|
||||||
TabPanel,
|
TabPanel,
|
||||||
SelectMediaDialog, // Import
|
SelectMediaDialog, // Import
|
||||||
UploadMediaDialog, // Import
|
UploadMediaDialog,
|
||||||
|
Media, // Import
|
||||||
} from "@shared";
|
} from "@shared";
|
||||||
import {
|
import {
|
||||||
LanguageSwitcher,
|
LanguageSwitcher,
|
||||||
@ -22,12 +23,15 @@ import {
|
|||||||
MediaAreaForSight, // Import
|
MediaAreaForSight, // Import
|
||||||
ReactMarkdownComponent,
|
ReactMarkdownComponent,
|
||||||
ReactMarkdownEditor,
|
ReactMarkdownEditor,
|
||||||
|
DeleteModal,
|
||||||
} from "@widgets";
|
} from "@widgets";
|
||||||
import { ImagePlus, Plus, X } from "lucide-react"; // Import X
|
import { ImagePlus, Plus, Save, Trash2, Unlink, X } from "lucide-react"; // Import X
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { useState, useEffect } from "react"; // Added useEffect
|
import { useState, useEffect } from "react"; // Added useEffect
|
||||||
import { MediaViewer } from "../../MediaViewer/index";
|
import { MediaViewer } from "../../MediaViewer/index";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
|
import { authInstance } from "@shared";
|
||||||
|
import { DragDropContext, Droppable, Draggable } from "@hello-pangea/dnd";
|
||||||
|
|
||||||
type MediaItemShared = {
|
type MediaItemShared = {
|
||||||
// Define if not already available from @shared
|
// Define if not already available from @shared
|
||||||
@ -56,6 +60,7 @@ export const CreateRightTab = observer(
|
|||||||
linkExistingRightArticle,
|
linkExistingRightArticle,
|
||||||
createSight,
|
createSight,
|
||||||
clearCreateSight, // For resetting form
|
clearCreateSight, // For resetting form
|
||||||
|
updateRightArticles,
|
||||||
} = createSightStore;
|
} = createSightStore;
|
||||||
const { language } = languageStore;
|
const { language } = languageStore;
|
||||||
|
|
||||||
@ -65,14 +70,27 @@ export const CreateRightTab = observer(
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
const [type, setType] = useState<"article" | "media">("media");
|
const [type, setType] = useState<"article" | "media">("media");
|
||||||
|
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||||
const [isSelectMediaDialogOpen, setIsSelectMediaDialogOpen] =
|
const [isSelectMediaDialogOpen, setIsSelectMediaDialogOpen] =
|
||||||
useState(false);
|
useState(false);
|
||||||
const [mediaTarget, setMediaTarget] = useState<
|
const [mediaTarget, setMediaTarget] = useState<
|
||||||
"sightPreview" | "rightArticle" | null
|
"sightPreview" | "rightArticle" | null
|
||||||
>(null);
|
>(null);
|
||||||
|
|
||||||
|
const [previewMedia, setPreviewMedia] = useState<Media | null>(null);
|
||||||
// Reset activeArticleIndex if language changes and index is out of bounds
|
// Reset activeArticleIndex if language changes and index is out of bounds
|
||||||
|
useEffect(() => {
|
||||||
|
if (sight.preview_media) {
|
||||||
|
const fetchMedia = async () => {
|
||||||
|
const response = await authInstance.get(
|
||||||
|
`/media/${sight.preview_media}`
|
||||||
|
);
|
||||||
|
setPreviewMedia(response.data);
|
||||||
|
};
|
||||||
|
fetchMedia();
|
||||||
|
}
|
||||||
|
}, [sight.preview_media]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
activeArticleIndex !== null &&
|
activeArticleIndex !== null &&
|
||||||
@ -168,6 +186,7 @@ export const CreateRightTab = observer(
|
|||||||
|
|
||||||
const handleMediaSelectedFromDialog = async (media: MediaItemShared) => {
|
const handleMediaSelectedFromDialog = async (media: MediaItemShared) => {
|
||||||
setIsSelectMediaDialogOpen(false);
|
setIsSelectMediaDialogOpen(false);
|
||||||
|
|
||||||
if (mediaTarget === "sightPreview") {
|
if (mediaTarget === "sightPreview") {
|
||||||
await linkPreviewMedia(media.id);
|
await linkPreviewMedia(media.id);
|
||||||
} else if (mediaTarget === "rightArticle" && currentRightArticle) {
|
} else if (mediaTarget === "rightArticle" && currentRightArticle) {
|
||||||
@ -176,6 +195,11 @@ export const CreateRightTab = observer(
|
|||||||
setMediaTarget(null);
|
setMediaTarget(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleUnlinkPreviewMedia = async () => {
|
||||||
|
await unlinkPreviewMedia();
|
||||||
|
setPreviewMedia(null);
|
||||||
|
};
|
||||||
|
|
||||||
const handleMediaUploaded = async (media: MediaItemShared) => {
|
const handleMediaUploaded = async (media: MediaItemShared) => {
|
||||||
// After UploadMediaDialog finishes
|
// After UploadMediaDialog finishes
|
||||||
setUploadMediaOpen(false);
|
setUploadMediaOpen(false);
|
||||||
@ -188,6 +212,36 @@ export const CreateRightTab = observer(
|
|||||||
setMediaTarget(null); // Reset target
|
setMediaTarget(null); // Reset target
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleDragEnd = (result: any) => {
|
||||||
|
const { source, destination } = result;
|
||||||
|
|
||||||
|
// 1. Guard clause: If dropped outside any droppable area, do nothing.
|
||||||
|
if (!destination) return;
|
||||||
|
|
||||||
|
// Extract source and destination indices
|
||||||
|
const sourceIndex = source.index;
|
||||||
|
const destinationIndex = destination.index;
|
||||||
|
|
||||||
|
// 2. Guard clause: If dropped in the same position, do nothing.
|
||||||
|
if (sourceIndex === destinationIndex) return;
|
||||||
|
|
||||||
|
// 3. Create a new array with reordered articles:
|
||||||
|
// - Create a shallow copy of the current articles array.
|
||||||
|
// This is important for immutability and triggering re-renders.
|
||||||
|
const newRightArticles = [...sight[language].right];
|
||||||
|
|
||||||
|
// - Remove the dragged article from its original position.
|
||||||
|
// `splice` returns an array of removed items, so we destructure the first (and only) one.
|
||||||
|
const [movedArticle] = newRightArticles.splice(sourceIndex, 1);
|
||||||
|
|
||||||
|
// - Insert the moved article into its new position.
|
||||||
|
newRightArticles.splice(destinationIndex, 0, movedArticle);
|
||||||
|
|
||||||
|
// 4. Update the store with the new order:
|
||||||
|
// This will typically trigger a re-render of the component with the updated list.
|
||||||
|
updateRightArticles(newRightArticles, language);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TabPanel value={value} index={index}>
|
<TabPanel value={value} index={index}>
|
||||||
<LanguageSwitcher />
|
<LanguageSwitcher />
|
||||||
@ -223,22 +277,56 @@ export const CreateRightTab = observer(
|
|||||||
>
|
>
|
||||||
<Typography>Предпросмотр медиа</Typography>
|
<Typography>Предпросмотр медиа</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
<Box>
|
||||||
{sight[language].right.map((article, artIdx) => (
|
<DragDropContext onDragEnd={handleDragEnd}>
|
||||||
|
<Droppable droppableId="articles">
|
||||||
|
{(provided) => (
|
||||||
<Box
|
<Box
|
||||||
key={article.id || artIdx} // article.id should be preferred
|
ref={provided.innerRef}
|
||||||
className={`w-full p-4 rounded-2xl text-sm cursor-pointer hover:bg-gray-300 transition-all duration-300 ${
|
{...provided.droppableProps}
|
||||||
type === "article" && activeArticleIndex === artIdx
|
className="flex flex-col gap-2"
|
||||||
? "bg-blue-300 font-semibold"
|
|
||||||
: "bg-gray-200"
|
|
||||||
}`}
|
|
||||||
onClick={() => handleDisplayArticleFromList(artIdx)}
|
|
||||||
>
|
>
|
||||||
<Typography noWrap title={article.heading}>
|
{sight[language].right.length > 0
|
||||||
{article.heading || "Без названия"}
|
? sight[language].right.map(
|
||||||
|
(article, index) => (
|
||||||
|
<Draggable
|
||||||
|
key={article.id.toString()}
|
||||||
|
draggableId={article.id.toString()}
|
||||||
|
index={index}
|
||||||
|
>
|
||||||
|
{(provided, snapshot) => (
|
||||||
|
<Box
|
||||||
|
ref={provided.innerRef}
|
||||||
|
{...provided.draggableProps}
|
||||||
|
className={`w-full bg-gray-200 p-4 rounded-2xl text-sm cursor-pointer hover:bg-gray-300 ${
|
||||||
|
snapshot.isDragging
|
||||||
|
? "shadow-lg"
|
||||||
|
: ""
|
||||||
|
}`}
|
||||||
|
onClick={() => {
|
||||||
|
handleDisplayArticleFromList(
|
||||||
|
index
|
||||||
|
);
|
||||||
|
setType("article");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box {...provided.dragHandleProps}>
|
||||||
|
<Typography>
|
||||||
|
{article.heading}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
))}
|
</Box>
|
||||||
|
)}
|
||||||
|
</Draggable>
|
||||||
|
)
|
||||||
|
)
|
||||||
|
: null}
|
||||||
|
{provided.placeholder}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Droppable>
|
||||||
|
</DragDropContext>
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
<button
|
<button
|
||||||
className="w-10 h-10 bg-blue-500 rounded-full absolute bottom-5 left-5 flex items-center justify-center hover:bg-blue-600"
|
className="w-10 h-10 bg-blue-500 rounded-full absolute bottom-5 left-5 flex items-center justify-center hover:bg-blue-600"
|
||||||
@ -273,12 +361,13 @@ export const CreateRightTab = observer(
|
|||||||
|
|
||||||
{/* Main content area: Article Editor or Sight Media Preview */}
|
{/* Main content area: Article Editor or Sight Media Preview */}
|
||||||
{type === "article" && currentRightArticle ? (
|
{type === "article" && currentRightArticle ? (
|
||||||
<Box className="w-[80%] border border-gray-300 rounded-2xl p-3 flex flex-col gap-2 overflow-hidden">
|
<Box className="w-[80%] border border-gray-300 p-3 flex flex-col gap-2 overflow-hidden">
|
||||||
<Box className="flex justify-end gap-2 mb-1 flex-shrink-0">
|
<Box className="flex justify-end gap-2 mb-1 flex-shrink-0">
|
||||||
<Button
|
<Button
|
||||||
variant="outlined"
|
variant="contained"
|
||||||
color="warning"
|
color="primary"
|
||||||
size="small"
|
size="small"
|
||||||
|
startIcon={<Unlink color="white" size={18} />}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (currentRightArticle) {
|
if (currentRightArticle) {
|
||||||
unlinkRightAritcle(currentRightArticle.id); // Corrected function name
|
unlinkRightAritcle(currentRightArticle.id); // Corrected function name
|
||||||
@ -293,22 +382,9 @@ export const CreateRightTab = observer(
|
|||||||
variant="contained"
|
variant="contained"
|
||||||
color="error"
|
color="error"
|
||||||
size="small"
|
size="small"
|
||||||
|
startIcon={<Trash2 size={18} />}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
if (
|
setIsDeleteModalOpen(true);
|
||||||
currentRightArticle &&
|
|
||||||
window.confirm(
|
|
||||||
`Удалить статью "${currentRightArticle.heading}" окончательно?`
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
try {
|
|
||||||
await deleteRightArticle(currentRightArticle.id);
|
|
||||||
setActiveArticleIndex(null);
|
|
||||||
setType("media");
|
|
||||||
toast.success("Статья удалена");
|
|
||||||
} catch {
|
|
||||||
toast.error("Не удалось удалить статью");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Удалить
|
Удалить
|
||||||
@ -371,30 +447,34 @@ export const CreateRightTab = observer(
|
|||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
) : type === "media" ? (
|
) : type === "media" ? (
|
||||||
<Box className="w-[80%] h-[70vh] border border-gray-300 rounded-2xl p-3 relative flex justify-center items-center">
|
<Box className="w-[80%] border border-gray-300 rounded-2xl relative flex items-center justify-center">
|
||||||
{type === "media" && (
|
|
||||||
<Box className="w-[80%] border border-gray-300 rounded-2xl relative">
|
|
||||||
{sight.preview_media && (
|
{sight.preview_media && (
|
||||||
<>
|
<>
|
||||||
<Box className="absolute top-4 right-4">
|
{type === "media" && (
|
||||||
|
<Box className="w-[80%] h-full rounded-2xl relative flex items-center justify-center">
|
||||||
|
{previewMedia && (
|
||||||
|
<>
|
||||||
|
<Box className="absolute top-4 right-4 z-10">
|
||||||
<button
|
<button
|
||||||
className="w-10 h-10 flex items-center justify-center"
|
className="w-10 h-10 flex items-center justify-center z-10"
|
||||||
onClick={unlinkPreviewMedia}
|
onClick={handleUnlinkPreviewMedia}
|
||||||
>
|
>
|
||||||
<X size={20} color="red" />
|
<X size={20} color="red" />
|
||||||
</button>
|
</button>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
<Box className="w-1/2 h-1/2">
|
||||||
<MediaViewer
|
<MediaViewer
|
||||||
media={{
|
media={{
|
||||||
id: sight.preview_media || "",
|
id: previewMedia.id || "",
|
||||||
media_type: 1,
|
media_type: previewMedia.media_type,
|
||||||
filename: sight.preview_media || "",
|
filename: previewMedia.filename || "",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
</Box>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{!sight.preview_media && (
|
{!previewMedia && (
|
||||||
<MediaAreaForSight
|
<MediaAreaForSight
|
||||||
onFinishUpload={(mediaId) => {
|
onFinishUpload={(mediaId) => {
|
||||||
linkPreviewMedia(mediaId);
|
linkPreviewMedia(mediaId);
|
||||||
@ -404,6 +484,16 @@ export const CreateRightTab = observer(
|
|||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{!previewMedia && (
|
||||||
|
<MediaAreaForSight
|
||||||
|
onFinishUpload={(mediaId) => {
|
||||||
|
linkPreviewMedia(mediaId);
|
||||||
|
}}
|
||||||
|
onFilesDrop={() => {}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
) : (
|
) : (
|
||||||
<Box className="w-[80%] h-[70vh] border border-gray-300 rounded-2xl p-3 flex justify-center items-center">
|
<Box className="w-[80%] h-[70vh] border border-gray-300 rounded-2xl p-3 flex justify-center items-center">
|
||||||
@ -417,31 +507,52 @@ export const CreateRightTab = observer(
|
|||||||
|
|
||||||
{/* Right Column: Live Preview */}
|
{/* Right Column: Live Preview */}
|
||||||
<Box className="w-[25%] mr-10">
|
<Box className="w-[25%] mr-10">
|
||||||
{type === "article" && currentRightArticle && (
|
{type === "article" && activeArticleIndex !== null && (
|
||||||
<Paper
|
<Paper
|
||||||
className="flex-1 flex flex-col rounded-2xl"
|
className="flex-1 flex flex-col max-w-[500px]"
|
||||||
|
sx={{
|
||||||
|
borderRadius: "16px",
|
||||||
|
overflow: "hidden",
|
||||||
|
}}
|
||||||
elevation={2}
|
elevation={2}
|
||||||
sx={{ height: "75vh", overflow: "hidden" }}
|
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
className="rounded-2xl overflow-hidden"
|
className=" overflow-hidden"
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
height: "100%",
|
|
||||||
background: "#877361", // Theme background
|
background: "#877361",
|
||||||
|
borderColor: "grey.300",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{currentRightArticle.media &&
|
{sight[language].right[activeArticleIndex].media.length >
|
||||||
currentRightArticle.media.length > 0 ? (
|
0 ? (
|
||||||
<MediaViewer media={currentRightArticle.media[0]} />
|
<Box
|
||||||
|
sx={{
|
||||||
|
width: "100%",
|
||||||
|
maxHeight: "290px",
|
||||||
|
flexShrink: 0,
|
||||||
|
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MediaViewer
|
||||||
|
media={
|
||||||
|
sight[language].right[activeArticleIndex].media[0]
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
) : (
|
) : (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
height: 200,
|
height: 200,
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
|
|
||||||
backgroundColor: "rgba(0,0,0,0.1)",
|
backgroundColor: "rgba(0,0,0,0.1)",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
@ -451,84 +562,85 @@ export const CreateRightTab = observer(
|
|||||||
<ImagePlus size={48} color="white" />
|
<ImagePlus size={48} color="white" />
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
p: 1,
|
||||||
minHeight: "70px", // Fixed height for heading container
|
wordBreak: "break-word",
|
||||||
background: "#877361", // Consistent with theme
|
fontSize: "24px",
|
||||||
display: "flex",
|
fontWeight: 700,
|
||||||
flexShrink: 0,
|
lineHeight: "120%",
|
||||||
flex: 1,
|
backdropFilter: "blur(12px)",
|
||||||
alignItems: "center",
|
boxShadow:
|
||||||
borderBottom: "1px solid rgba(255,255,255,0.1)",
|
"inset 4px 4px 12px 0 rgba(255,255,255,0.12)",
|
||||||
px: 2,
|
background:
|
||||||
py: 1,
|
"#806c59 linear-gradient(90deg, rgba(255, 255, 255, 0.2) 12.5%, rgba(255, 255, 255, 0.2) 100%)",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography
|
<Typography variant="h6" color="white">
|
||||||
variant="h6"
|
{sight[language].right[activeArticleIndex].heading ||
|
||||||
color="white"
|
"Выберите статью"}
|
||||||
noWrap
|
|
||||||
title={currentRightArticle.heading}
|
|
||||||
>
|
|
||||||
{currentRightArticle.heading || "Заголовок"}
|
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
px: 2,
|
padding: 1,
|
||||||
py: 1,
|
minHeight: "200px",
|
||||||
|
maxHeight: "300px",
|
||||||
|
overflowY: "scroll",
|
||||||
|
background:
|
||||||
|
"rgba(179, 165, 152, 0.4), linear-gradient(180deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.2) 100%)",
|
||||||
|
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
overflowY: "auto",
|
|
||||||
backgroundColor: "#877361",
|
|
||||||
color: "white",
|
|
||||||
"&::-webkit-scrollbar": { width: "8px" },
|
|
||||||
"&::-webkit-scrollbar-thumb": {
|
|
||||||
backgroundColor: "rgba(255,255,255,0.3)",
|
|
||||||
borderRadius: "4px",
|
|
||||||
},
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{currentRightArticle.body ? (
|
{sight[language].right[activeArticleIndex].body ? (
|
||||||
<ReactMarkdownComponent
|
<ReactMarkdownComponent
|
||||||
value={currentRightArticle.body}
|
value={sight[language].right[activeArticleIndex].body}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Typography
|
<Typography
|
||||||
color="rgba(255,255,255,0.7)"
|
color="rgba(255,255,255,0.7)"
|
||||||
sx={{ textAlign: "center", mt: 4 }}
|
sx={{ textAlign: "center", mt: 4 }}
|
||||||
>
|
>
|
||||||
Содержимое статьи...
|
Предпросмотр статьи появится здесь
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
|
||||||
</Paper>
|
|
||||||
)}
|
|
||||||
{/* Optional: Preview for sight.preview_media when type === "media" */}
|
|
||||||
{type === "media" && sight.preview_media && (
|
|
||||||
<Paper
|
|
||||||
className="flex-1 flex flex-col rounded-2xl"
|
|
||||||
elevation={2}
|
|
||||||
sx={{ height: "75vh", overflow: "hidden" }}
|
|
||||||
>
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
p: 2,
|
||||||
height: "100%",
|
|
||||||
background: "#877361",
|
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
justifyContent: "space-between",
|
||||||
justifyContent: "center",
|
fontSize: "24px",
|
||||||
|
fontWeight: 700,
|
||||||
|
lineHeight: "120%",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
|
||||||
|
gap: 1,
|
||||||
|
backdropFilter: "blur(12px)",
|
||||||
|
boxShadow:
|
||||||
|
"inset 4px 4px 12px 0 rgba(255,255,255,0.12)",
|
||||||
|
background:
|
||||||
|
"#806c59 linear-gradient(90deg, rgba(255, 255, 255, 0.2) 12.5%, rgba(255, 255, 255, 0.2) 100%)",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<MediaViewer
|
{sight[language].right.length > 0 &&
|
||||||
media={{
|
sight[language].right.map((article, index) => (
|
||||||
id: sight.preview_media,
|
<button
|
||||||
filename: sight.preview_media,
|
className={`inline-block text-left text-xs text-white ${
|
||||||
media_type: 1,
|
activeArticleIndex === index ? "underline" : ""
|
||||||
|
}`}
|
||||||
|
onClick={() => {
|
||||||
|
setActiveArticleIndex(index);
|
||||||
|
setType("article");
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
|
{article.heading}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Paper>
|
</Paper>
|
||||||
)}
|
)}
|
||||||
@ -539,17 +651,15 @@ export const CreateRightTab = observer(
|
|||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
bottom: 0,
|
bottom: "-20px",
|
||||||
left: 0, // ensure it spans from left
|
left: 0, // ensure it spans from left
|
||||||
right: 0,
|
right: 0,
|
||||||
padding: 2,
|
padding: 2,
|
||||||
backgroundColor: "background.paper",
|
backgroundColor: "background.paper",
|
||||||
borderTop: "1px solid", // Add a subtle top border
|
|
||||||
borderColor: "divider", // Use theme's divider color
|
|
||||||
width: "100%",
|
width: "100%",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
justifyContent: "flex-end",
|
justifyContent: "flex-end",
|
||||||
boxShadow: "0 -2px 5px rgba(0,0,0,0.1)", // Optional shadow
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
@ -557,8 +667,9 @@ export const CreateRightTab = observer(
|
|||||||
color="success"
|
color="success"
|
||||||
onClick={handleSave}
|
onClick={handleSave}
|
||||||
size="large"
|
size="large"
|
||||||
|
startIcon={<Save color="white" size={18} />}
|
||||||
>
|
>
|
||||||
Сохранить достопримечательность
|
Сохранить
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
@ -588,6 +699,20 @@ export const CreateRightTab = observer(
|
|||||||
}}
|
}}
|
||||||
onSelectMedia={handleMediaSelectedFromDialog}
|
onSelectMedia={handleMediaSelectedFromDialog}
|
||||||
/>
|
/>
|
||||||
|
<DeleteModal
|
||||||
|
open={isDeleteModalOpen}
|
||||||
|
onDelete={async () => {
|
||||||
|
try {
|
||||||
|
await deleteRightArticle(currentRightArticle?.id || 0);
|
||||||
|
setActiveArticleIndex(null);
|
||||||
|
setType("media");
|
||||||
|
toast.success("Статья удалена");
|
||||||
|
} catch {
|
||||||
|
toast.error("Не удалось удалить статью");
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onCancel={() => setIsDeleteModalOpen(false)}
|
||||||
|
/>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,10 @@ import {
|
|||||||
SightLanguageInfo,
|
SightLanguageInfo,
|
||||||
SightCommonInfo,
|
SightCommonInfo,
|
||||||
UploadMediaDialog,
|
UploadMediaDialog,
|
||||||
|
MEDIA_TYPE_VALUES,
|
||||||
} from "@shared";
|
} from "@shared";
|
||||||
import { ImageUploadCard, LanguageSwitcher } from "@widgets";
|
import { ImageUploadCard, LanguageSwitcher } from "@widgets";
|
||||||
|
import { Save } from "lucide-react";
|
||||||
|
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
@ -335,6 +337,7 @@ export const InformationTab = observer(
|
|||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="success"
|
color="success"
|
||||||
|
startIcon={<Save color="white" size={18} />}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await updateSight();
|
await updateSight();
|
||||||
toast.success("Достопримечательность сохранена");
|
toast.success("Достопримечательность сохранена");
|
||||||
@ -371,6 +374,13 @@ export const InformationTab = observer(
|
|||||||
setActiveMenuType(null);
|
setActiveMenuType(null);
|
||||||
}}
|
}}
|
||||||
onSelectMedia={handleMediaSelect}
|
onSelectMedia={handleMediaSelect}
|
||||||
|
mediaType={
|
||||||
|
activeMenuType
|
||||||
|
? MEDIA_TYPE_VALUES[
|
||||||
|
activeMenuType as keyof typeof MEDIA_TYPE_VALUES
|
||||||
|
]
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<UploadMediaDialog
|
<UploadMediaDialog
|
||||||
|
@ -8,6 +8,7 @@ import {
|
|||||||
editSightStore,
|
editSightStore,
|
||||||
SelectArticleModal,
|
SelectArticleModal,
|
||||||
UploadMediaDialog,
|
UploadMediaDialog,
|
||||||
|
Language,
|
||||||
} from "@shared";
|
} from "@shared";
|
||||||
import {
|
import {
|
||||||
LanguageSwitcher,
|
LanguageSwitcher,
|
||||||
@ -15,8 +16,16 @@ import {
|
|||||||
ReactMarkdownEditor,
|
ReactMarkdownEditor,
|
||||||
MediaArea,
|
MediaArea,
|
||||||
MediaViewer,
|
MediaViewer,
|
||||||
|
DeleteModal,
|
||||||
} from "@widgets";
|
} from "@widgets";
|
||||||
import { Trash2, ImagePlus } from "lucide-react";
|
import {
|
||||||
|
Trash2,
|
||||||
|
ImagePlus,
|
||||||
|
Unlink,
|
||||||
|
Plus,
|
||||||
|
MousePointer,
|
||||||
|
Save,
|
||||||
|
} from "lucide-react";
|
||||||
import { useState, useCallback } from "react";
|
import { useState, useCallback } from "react";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
@ -40,12 +49,18 @@ export const LeftWidgetTab = observer(
|
|||||||
|
|
||||||
const { language } = languageStore;
|
const { language } = languageStore;
|
||||||
const data = sight[language];
|
const data = sight[language];
|
||||||
|
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||||
|
|
||||||
const [isSelectMediaDialogOpen, setIsSelectMediaDialogOpen] =
|
const [isSelectMediaDialogOpen, setIsSelectMediaDialogOpen] =
|
||||||
useState(false);
|
useState(false);
|
||||||
const [isSelectArticleDialogOpen, setIsSelectArticleDialogOpen] =
|
const [isSelectArticleDialogOpen, setIsSelectArticleDialogOpen] =
|
||||||
useState(false);
|
useState(false);
|
||||||
|
|
||||||
|
const handleDeleteLeftArticle = useCallback(() => {
|
||||||
|
deleteLeftArticle(sight.common.left_article);
|
||||||
|
setIsDeleteModalOpen(false);
|
||||||
|
}, [deleteLeftArticle, sight.common.left_article]);
|
||||||
|
|
||||||
const handleMediaSelected = useCallback(
|
const handleMediaSelected = useCallback(
|
||||||
async (media: {
|
async (media: {
|
||||||
id: string;
|
id: string;
|
||||||
@ -130,6 +145,7 @@ export const LeftWidgetTab = observer(
|
|||||||
color="primary"
|
color="primary"
|
||||||
size="small"
|
size="small"
|
||||||
style={{ transition: "0" }}
|
style={{ transition: "0" }}
|
||||||
|
startIcon={<Unlink size={18} />}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
unlinkLeftArticle();
|
unlinkLeftArticle();
|
||||||
toast.success("Статья откреплена");
|
toast.success("Статья откреплена");
|
||||||
@ -144,8 +160,7 @@ export const LeftWidgetTab = observer(
|
|||||||
startIcon={<Trash2 size={18} />}
|
startIcon={<Trash2 size={18} />}
|
||||||
size="small"
|
size="small"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
deleteLeftArticle(sight.common.left_article);
|
setIsDeleteModalOpen(true);
|
||||||
toast.success("Статья откреплена");
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Удалить
|
Удалить
|
||||||
@ -157,6 +172,7 @@ export const LeftWidgetTab = observer(
|
|||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
size="small"
|
size="small"
|
||||||
|
startIcon={<MousePointer color="white" size={18} />}
|
||||||
onClick={() => setIsSelectArticleDialogOpen(true)}
|
onClick={() => setIsSelectArticleDialogOpen(true)}
|
||||||
>
|
>
|
||||||
Выбрать статью
|
Выбрать статью
|
||||||
@ -166,6 +182,7 @@ export const LeftWidgetTab = observer(
|
|||||||
color="primary"
|
color="primary"
|
||||||
size="small"
|
size="small"
|
||||||
style={{ transition: "0" }}
|
style={{ transition: "0" }}
|
||||||
|
startIcon={<Plus color="white" size={18} />}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
createLeftArticle();
|
createLeftArticle();
|
||||||
toast.success("Статья создана");
|
toast.success("Статья создана");
|
||||||
@ -234,7 +251,8 @@ export const LeftWidgetTab = observer(
|
|||||||
flex: 1,
|
flex: 1,
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
gap: 1.5,
|
maxWidth: "320px",
|
||||||
|
gap: 0.5,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Paper
|
<Paper
|
||||||
@ -242,10 +260,9 @@ export const LeftWidgetTab = observer(
|
|||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
minWidth: 320,
|
minWidth: 320,
|
||||||
maxWidth: 400,
|
|
||||||
height: "auto",
|
background:
|
||||||
minHeight: 500,
|
"#806c59 linear-gradient(90deg, rgba(255, 255, 255, 0.2) 12.5%, rgba(255, 255, 255, 0.2) 100%)",
|
||||||
backgroundColor: "#877361",
|
|
||||||
overflowY: "auto",
|
overflowY: "auto",
|
||||||
padding: 0,
|
padding: 0,
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@ -255,11 +272,10 @@ export const LeftWidgetTab = observer(
|
|||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
height: 200,
|
height: 175,
|
||||||
backgroundColor: "grey.300",
|
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "center",
|
padding: "3px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{data.left.media.length > 0 ? (
|
{data.left.media.length > 0 ? (
|
||||||
@ -277,24 +293,50 @@ export const LeftWidgetTab = observer(
|
|||||||
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
backgroundColor: "#877361",
|
background:
|
||||||
|
"#806c59 linear-gradient(90deg, rgba(255, 255, 255, 0.2) 12.5%, rgba(255, 255, 255, 0.2) 100%)",
|
||||||
color: "white",
|
color: "white",
|
||||||
padding: 1.5,
|
margin: "5px 0px 5px 0px",
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
gap: 1,
|
||||||
|
padding: 1,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography
|
<Typography
|
||||||
variant="h5"
|
variant="h5"
|
||||||
component="h2"
|
component="h2"
|
||||||
sx={{ wordBreak: "break-word" }}
|
sx={{
|
||||||
|
wordBreak: "break-word",
|
||||||
|
fontSize: "24px",
|
||||||
|
fontWeight: 700,
|
||||||
|
lineHeight: "120%",
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{data?.left?.heading || "Название информации"}
|
{data?.left?.heading || "Название информации"}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
<Typography
|
||||||
|
variant="h6"
|
||||||
|
component="h2"
|
||||||
|
sx={{
|
||||||
|
wordBreak: "break-word",
|
||||||
|
fontSize: "18px",
|
||||||
|
|
||||||
|
lineHeight: "120%",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{sight[language as Language].address}
|
||||||
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{data?.left?.body && (
|
{data?.left?.body && (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
padding: 2,
|
padding: 1,
|
||||||
|
maxHeight: "300px",
|
||||||
|
overflowY: "scroll",
|
||||||
|
background:
|
||||||
|
"#806c59 linear-gradient(90deg, rgba(255, 255, 255, 0.2) 12.5%, rgba(255, 255, 255, 0.2) 100%)",
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -310,6 +352,7 @@ export const LeftWidgetTab = observer(
|
|||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="success"
|
color="success"
|
||||||
|
startIcon={<Save color="white" size={18} />}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await updateSight();
|
await updateSight();
|
||||||
toast.success("Достопримечательность сохранена");
|
toast.success("Достопримечательность сохранена");
|
||||||
@ -339,6 +382,11 @@ export const LeftWidgetTab = observer(
|
|||||||
onClose={handleCloseArticleDialog}
|
onClose={handleCloseArticleDialog}
|
||||||
onSelectArticle={handleSelectArticle}
|
onSelectArticle={handleSelectArticle}
|
||||||
/>
|
/>
|
||||||
|
<DeleteModal
|
||||||
|
open={isDeleteModalOpen}
|
||||||
|
onDelete={handleDeleteLeftArticle}
|
||||||
|
onCancel={() => setIsDeleteModalOpen(false)}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import {
|
|||||||
TextField,
|
TextField,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import {
|
import {
|
||||||
|
authInstance,
|
||||||
BackButton,
|
BackButton,
|
||||||
editSightStore,
|
editSightStore,
|
||||||
languageStore,
|
languageStore,
|
||||||
@ -17,17 +18,24 @@ import {
|
|||||||
UploadMediaDialog,
|
UploadMediaDialog,
|
||||||
} from "@shared";
|
} from "@shared";
|
||||||
import {
|
import {
|
||||||
|
DeleteModal,
|
||||||
LanguageSwitcher,
|
LanguageSwitcher,
|
||||||
MediaArea,
|
MediaArea,
|
||||||
MediaAreaForSight,
|
MediaAreaForSight,
|
||||||
ReactMarkdownComponent,
|
ReactMarkdownComponent,
|
||||||
ReactMarkdownEditor,
|
ReactMarkdownEditor,
|
||||||
} from "@widgets";
|
} from "@widgets";
|
||||||
import { ImagePlus, Plus, X } from "lucide-react";
|
import { ImagePlus, Plus, Save, Trash2, Unlink, X } from "lucide-react";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
import { MediaViewer } from "../../MediaViewer/index";
|
import { MediaViewer } from "../../MediaViewer/index";
|
||||||
|
import {
|
||||||
|
DragDropContext,
|
||||||
|
Droppable,
|
||||||
|
Draggable,
|
||||||
|
DropResult,
|
||||||
|
} from "@hello-pangea/dnd";
|
||||||
|
|
||||||
export const RightWidgetTab = observer(
|
export const RightWidgetTab = observer(
|
||||||
({ value, index }: { value: number; index: number }) => {
|
({ value, index }: { value: number; index: number }) => {
|
||||||
@ -47,8 +55,28 @@ export const RightWidgetTab = observer(
|
|||||||
createLinkWithRightArticle,
|
createLinkWithRightArticle,
|
||||||
setFileToUpload,
|
setFileToUpload,
|
||||||
createNewRightArticle,
|
createNewRightArticle,
|
||||||
|
updateRightArticles,
|
||||||
} = editSightStore;
|
} = editSightStore;
|
||||||
|
|
||||||
|
const [previewMedia, setPreviewMedia] = useState<any | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchPreviewMedia = async () => {
|
||||||
|
if (sight.common.preview_media) {
|
||||||
|
const response = await authInstance.get(
|
||||||
|
`/media/${sight.common.preview_media}`
|
||||||
|
);
|
||||||
|
setPreviewMedia(response.data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchPreviewMedia();
|
||||||
|
}, [sight.common.preview_media]);
|
||||||
|
|
||||||
|
const handleUnlinkPreviewMedia = () => {
|
||||||
|
unlinkPreviewMedia();
|
||||||
|
setPreviewMedia(null);
|
||||||
|
};
|
||||||
|
|
||||||
const [uploadMediaOpen, setUploadMediaOpen] = useState(false);
|
const [uploadMediaOpen, setUploadMediaOpen] = useState(false);
|
||||||
const { language } = languageStore;
|
const { language } = languageStore;
|
||||||
const [type, setType] = useState<"article" | "media">("media");
|
const [type, setType] = useState<"article" | "media">("media");
|
||||||
@ -67,8 +95,15 @@ export const RightWidgetTab = observer(
|
|||||||
);
|
);
|
||||||
const [isSelectModalOpen, setIsSelectModalOpen] = useState(false);
|
const [isSelectModalOpen, setIsSelectModalOpen] = useState(false);
|
||||||
const [isSelectMediaModalOpen, setIsSelectMediaModalOpen] = useState(false);
|
const [isSelectMediaModalOpen, setIsSelectMediaModalOpen] = useState(false);
|
||||||
|
const [isDeleteArticleModalOpen, setIsDeleteArticleModalOpen] =
|
||||||
|
useState(false);
|
||||||
const open = Boolean(anchorEl);
|
const open = Boolean(anchorEl);
|
||||||
|
|
||||||
|
const handleDeleteArticle = () => {
|
||||||
|
deleteRightArticle(sight[language].right[activeArticleIndex || 0].id);
|
||||||
|
setActiveArticleIndex(null);
|
||||||
|
};
|
||||||
|
|
||||||
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
setAnchorEl(event.currentTarget);
|
setAnchorEl(event.currentTarget);
|
||||||
};
|
};
|
||||||
@ -120,6 +155,36 @@ export const RightWidgetTab = observer(
|
|||||||
console.log(sight[language].right);
|
console.log(sight[language].right);
|
||||||
}, [sight[language].right]);
|
}, [sight[language].right]);
|
||||||
|
|
||||||
|
const handleDragEnd = (result: DropResult) => {
|
||||||
|
const { source, destination } = result;
|
||||||
|
|
||||||
|
// 1. Guard clause: If dropped outside any droppable area, do nothing.
|
||||||
|
if (!destination) return;
|
||||||
|
|
||||||
|
// Extract source and destination indices
|
||||||
|
const sourceIndex = source.index;
|
||||||
|
const destinationIndex = destination.index;
|
||||||
|
|
||||||
|
// 2. Guard clause: If dropped in the same position, do nothing.
|
||||||
|
if (sourceIndex === destinationIndex) return;
|
||||||
|
|
||||||
|
// 3. Create a new array with reordered articles:
|
||||||
|
// - Create a shallow copy of the current articles array.
|
||||||
|
// This is important for immutability and triggering re-renders.
|
||||||
|
const newRightArticles = [...sight[language].right];
|
||||||
|
|
||||||
|
// - Remove the dragged article from its original position.
|
||||||
|
// `splice` returns an array of removed items, so we destructure the first (and only) one.
|
||||||
|
const [movedArticle] = newRightArticles.splice(sourceIndex, 1);
|
||||||
|
|
||||||
|
// - Insert the moved article into its new position.
|
||||||
|
newRightArticles.splice(destinationIndex, 0, movedArticle);
|
||||||
|
|
||||||
|
// 4. Update the store with the new order:
|
||||||
|
// This will typically trigger a re-render of the component with the updated list.
|
||||||
|
updateRightArticles(newRightArticles, language);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TabPanel value={value} index={index}>
|
<TabPanel value={value} index={index}>
|
||||||
<LanguageSwitcher />
|
<LanguageSwitcher />
|
||||||
@ -140,26 +205,61 @@ export const RightWidgetTab = observer(
|
|||||||
<Box className="flex flex-col w-[75%] gap-2">
|
<Box className="flex flex-col w-[75%] gap-2">
|
||||||
<Box className="w-full flex gap-2">
|
<Box className="w-full flex gap-2">
|
||||||
<Box className="relative w-[20%] h-[70vh] flex flex-col rounded-2xl overflow-y-auto gap-3 border border-gray-300 p-3">
|
<Box className="relative w-[20%] h-[70vh] flex flex-col rounded-2xl overflow-y-auto gap-3 border border-gray-300 p-3">
|
||||||
<Box className="flex flex-col gap-3 max-h-[60vh] overflow-y-auto ">
|
<Box className="flex flex-col gap-3 max-h-[60vh] overflow-y-auto">
|
||||||
<Box
|
<Box
|
||||||
onClick={() => setType("media")}
|
onClick={() => setType("media")}
|
||||||
className="w-full bg-green-200 p-4 rounded-2xl cursor-pointer text-sm hover:bg-gray-300 transition-all duration-300"
|
className="w-full bg-green-200 p-4 rounded-2xl cursor-pointer text-sm hover:bg-gray-300 transition-all duration-300"
|
||||||
>
|
>
|
||||||
<Typography>Предпросмотр медиа</Typography>
|
<Typography>Предпросмотр медиа</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
{sight[language].right.length > 0 &&
|
<Box>
|
||||||
sight[language].right.map((article, index) => (
|
<DragDropContext onDragEnd={handleDragEnd}>
|
||||||
|
<Droppable droppableId="articles">
|
||||||
|
{(provided) => (
|
||||||
<Box
|
<Box
|
||||||
key={index}
|
ref={provided.innerRef}
|
||||||
className="w-full bg-gray-200 p-4 rounded-2xl text-sm cursor-pointer hover:bg-gray-300 transition-all duration-300"
|
{...provided.droppableProps}
|
||||||
|
className="flex flex-col gap-2"
|
||||||
|
>
|
||||||
|
{sight[language].right.length > 0
|
||||||
|
? sight[language].right.map(
|
||||||
|
(article, index) => (
|
||||||
|
<Draggable
|
||||||
|
key={article.id.toString()}
|
||||||
|
draggableId={article.id.toString()}
|
||||||
|
index={index}
|
||||||
|
>
|
||||||
|
{(provided, snapshot) => (
|
||||||
|
<Box
|
||||||
|
ref={provided.innerRef}
|
||||||
|
{...provided.draggableProps}
|
||||||
|
className={`w-full bg-gray-200 p-4 rounded-2xl text-sm cursor-pointer hover:bg-gray-300 ${
|
||||||
|
snapshot.isDragging
|
||||||
|
? "shadow-lg"
|
||||||
|
: ""
|
||||||
|
}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
handleSelectArticle(index);
|
handleSelectArticle(index);
|
||||||
setType("article");
|
setType("article");
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography>{article.heading}</Typography>
|
<Box {...provided.dragHandleProps}>
|
||||||
|
<Typography>
|
||||||
|
{article.heading}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Draggable>
|
||||||
|
)
|
||||||
|
)
|
||||||
|
: null}
|
||||||
|
{provided.placeholder}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Droppable>
|
||||||
|
</DragDropContext>
|
||||||
</Box>
|
</Box>
|
||||||
))}
|
|
||||||
</Box>
|
</Box>
|
||||||
<button
|
<button
|
||||||
className="w-10 h-10 bg-blue-500 rounded-full absolute bottom-5 left-5 flex items-center justify-center"
|
className="w-10 h-10 bg-blue-500 rounded-full absolute bottom-5 left-5 flex items-center justify-center"
|
||||||
@ -187,13 +287,14 @@ export const RightWidgetTab = observer(
|
|||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{type === "article" && (
|
{type === "article" && (
|
||||||
<Box className="w-[80%] border border-gray-300 rounded-2xl p-3">
|
<Box className="w-[80%] border border-gray-300 p-3">
|
||||||
{activeArticleIndex !== null && (
|
{activeArticleIndex !== null && (
|
||||||
<>
|
<>
|
||||||
<Box className="flex justify-end gap-2 mb-3">
|
<Box className="flex justify-end gap-2 mb-3">
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
|
startIcon={<Unlink color="white" size={18} />}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
unlinkRightArticle(
|
unlinkRightArticle(
|
||||||
sight[language].right[activeArticleIndex].id
|
sight[language].right[activeArticleIndex].id
|
||||||
@ -205,12 +306,10 @@ export const RightWidgetTab = observer(
|
|||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="success"
|
color="error"
|
||||||
|
startIcon={<Trash2 size={18} />}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
deleteRightArticle(
|
setIsDeleteArticleModalOpen(true);
|
||||||
sight[language].right[activeArticleIndex].id
|
|
||||||
);
|
|
||||||
setActiveArticleIndex(null);
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Удалить
|
Удалить
|
||||||
@ -285,25 +384,31 @@ export const RightWidgetTab = observer(
|
|||||||
<Box className="w-[80%] border border-gray-300 rounded-2xl relative">
|
<Box className="w-[80%] border border-gray-300 rounded-2xl relative">
|
||||||
{sight.common.preview_media && (
|
{sight.common.preview_media && (
|
||||||
<>
|
<>
|
||||||
<Box className="absolute top-4 right-4">
|
{type === "media" && (
|
||||||
|
<Box className="w-[80%] h-full rounded-2xl relative flex items-center justify-center">
|
||||||
|
{previewMedia && (
|
||||||
|
<>
|
||||||
|
<Box className="absolute top-4 right-4 z-10">
|
||||||
<button
|
<button
|
||||||
className="w-10 h-10 flex items-center justify-center"
|
className="w-10 h-10 flex items-center justify-center z-10"
|
||||||
onClick={unlinkPreviewMedia}
|
onClick={handleUnlinkPreviewMedia}
|
||||||
>
|
>
|
||||||
<X size={20} color="red" />
|
<X size={20} color="red" />
|
||||||
</button>
|
</button>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
<Box className="w-1/2 h-1/2">
|
||||||
<MediaViewer
|
<MediaViewer
|
||||||
media={{
|
media={{
|
||||||
id: sight.common.preview_media || "",
|
id: previewMedia.id || "",
|
||||||
media_type: 1,
|
media_type: previewMedia.media_type,
|
||||||
filename: sight.common.preview_media || "",
|
filename: previewMedia.filename || "",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
</Box>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{!sight.common.preview_media && (
|
{!previewMedia && (
|
||||||
<MediaAreaForSight
|
<MediaAreaForSight
|
||||||
onFinishUpload={(mediaId) => {
|
onFinishUpload={(mediaId) => {
|
||||||
linkPreviewMedia(mediaId);
|
linkPreviewMedia(mediaId);
|
||||||
@ -313,6 +418,32 @@ export const RightWidgetTab = observer(
|
|||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!sight.common.preview_media && (
|
||||||
|
<Box className="w-full h-full flex justify-center items-center">
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
maxWidth: "500px",
|
||||||
|
maxHeight: "100%",
|
||||||
|
display: "flex",
|
||||||
|
flexGrow: 1,
|
||||||
|
margin: "0 auto",
|
||||||
|
justifyContent: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MediaAreaForSight
|
||||||
|
onFinishUpload={(mediaId) => {
|
||||||
|
linkPreviewMedia(mediaId);
|
||||||
|
}}
|
||||||
|
onFilesDrop={() => {}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
@ -320,14 +451,18 @@ export const RightWidgetTab = observer(
|
|||||||
<Box className="w-[25%] mr-10">
|
<Box className="w-[25%] mr-10">
|
||||||
{activeArticleIndex !== null && (
|
{activeArticleIndex !== null && (
|
||||||
<Paper
|
<Paper
|
||||||
className="flex-1 flex flex-col rounded-2xl"
|
className="flex-1 flex flex-col max-w-[500px]"
|
||||||
|
sx={{
|
||||||
|
borderRadius: "16px",
|
||||||
|
overflow: "hidden",
|
||||||
|
}}
|
||||||
elevation={2}
|
elevation={2}
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
className="rounded-2xl overflow-hidden"
|
className=" overflow-hidden"
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
height: "75vh",
|
|
||||||
background: "#877361",
|
background: "#877361",
|
||||||
borderColor: "grey.300",
|
borderColor: "grey.300",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@ -336,11 +471,23 @@ export const RightWidgetTab = observer(
|
|||||||
>
|
>
|
||||||
{sight[language].right[activeArticleIndex].media.length >
|
{sight[language].right[activeArticleIndex].media.length >
|
||||||
0 ? (
|
0 ? (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
width: "100%",
|
||||||
|
maxHeight: "290px",
|
||||||
|
flexShrink: 0,
|
||||||
|
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
<MediaViewer
|
<MediaViewer
|
||||||
media={
|
media={
|
||||||
sight[language].right[activeArticleIndex].media[0]
|
sight[language].right[activeArticleIndex].media[0]
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
</Box>
|
||||||
) : (
|
) : (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
@ -360,15 +507,16 @@ export const RightWidgetTab = observer(
|
|||||||
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
p: 1,
|
||||||
height: "70px",
|
wordBreak: "break-word",
|
||||||
background: "#877361",
|
fontSize: "24px",
|
||||||
display: "flex",
|
fontWeight: 700,
|
||||||
flexShrink: 0,
|
lineHeight: "120%",
|
||||||
|
backdropFilter: "blur(12px)",
|
||||||
alignItems: "center",
|
boxShadow:
|
||||||
borderBottom: "1px solid rgba(255,255,255,0.1)",
|
"inset 4px 4px 12px 0 rgba(255,255,255,0.12)",
|
||||||
px: 2,
|
background:
|
||||||
|
"#806c59 linear-gradient(90deg, rgba(255, 255, 255, 0.2) 12.5%, rgba(255, 255, 255, 0.2) 100%)",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="h6" color="white">
|
<Typography variant="h6" color="white">
|
||||||
@ -379,14 +527,14 @@ export const RightWidgetTab = observer(
|
|||||||
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
px: 2,
|
padding: 1,
|
||||||
|
minHeight: "200px",
|
||||||
|
maxHeight: "300px",
|
||||||
|
overflowY: "scroll",
|
||||||
|
background:
|
||||||
|
"rgba(179, 165, 152, 0.4), linear-gradient(180deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.2) 100%)",
|
||||||
|
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
flex: 1,
|
|
||||||
minHeight: "300px",
|
|
||||||
overflowY: "auto",
|
|
||||||
backgroundColor: "#877361",
|
|
||||||
color: "white",
|
|
||||||
py: 1,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{sight[language].right[activeArticleIndex].body ? (
|
{sight[language].right[activeArticleIndex].body ? (
|
||||||
@ -404,6 +552,39 @@ export const RightWidgetTab = observer(
|
|||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
p: 2,
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
fontSize: "24px",
|
||||||
|
fontWeight: 700,
|
||||||
|
lineHeight: "120%",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
|
||||||
|
gap: 1,
|
||||||
|
backdropFilter: "blur(12px)",
|
||||||
|
boxShadow:
|
||||||
|
"inset 4px 4px 12px 0 rgba(255,255,255,0.12)",
|
||||||
|
background:
|
||||||
|
"#806c59 linear-gradient(90deg, rgba(255, 255, 255, 0.2) 12.5%, rgba(255, 255, 255, 0.2) 100%)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{sight[language].right.length > 0 &&
|
||||||
|
sight[language].right.map((article, index) => (
|
||||||
|
<button
|
||||||
|
className={`inline-block text-left text-xs text-white ${
|
||||||
|
activeArticleIndex === index ? "underline" : ""
|
||||||
|
}`}
|
||||||
|
onClick={() => {
|
||||||
|
handleSelectArticle(index);
|
||||||
|
setType("article");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{article.heading}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Paper>
|
</Paper>
|
||||||
)}
|
)}
|
||||||
@ -423,8 +604,13 @@ export const RightWidgetTab = observer(
|
|||||||
justifyContent: "flex-end",
|
justifyContent: "flex-end",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Button variant="contained" color="success" onClick={handleSave}>
|
<Button
|
||||||
Сохранить изменения
|
variant="contained"
|
||||||
|
startIcon={<Save color="white" size={18} />}
|
||||||
|
color="success"
|
||||||
|
onClick={handleSave}
|
||||||
|
>
|
||||||
|
Сохранить
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
@ -442,10 +628,20 @@ export const RightWidgetTab = observer(
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<DeleteModal
|
||||||
|
open={isDeleteArticleModalOpen}
|
||||||
|
onCancel={() => setIsDeleteArticleModalOpen(false)}
|
||||||
|
onDelete={() => {
|
||||||
|
handleDeleteArticle();
|
||||||
|
setIsDeleteArticleModalOpen(false);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
<SelectArticleModal
|
<SelectArticleModal
|
||||||
open={isSelectModalOpen}
|
open={isSelectModalOpen}
|
||||||
onClose={handleCloseSelectModal}
|
onClose={handleCloseSelectModal}
|
||||||
onSelectArticle={handleArticleSelect}
|
onSelectArticle={handleArticleSelect}
|
||||||
|
linkedArticleIds={sight[language].right.map((article) => article.id)}
|
||||||
/>
|
/>
|
||||||
<SelectMediaDialog
|
<SelectMediaDialog
|
||||||
open={isSelectMediaModalOpen}
|
open={isSelectMediaModalOpen}
|
||||||
|
@ -6,10 +6,10 @@ import TableHead from "@mui/material/TableHead";
|
|||||||
import TableRow from "@mui/material/TableRow";
|
import TableRow from "@mui/material/TableRow";
|
||||||
import Paper from "@mui/material/Paper";
|
import Paper from "@mui/material/Paper";
|
||||||
import { authInstance, cityStore, languageStore, sightsStore } from "@shared";
|
import { authInstance, cityStore, languageStore, sightsStore } from "@shared";
|
||||||
import { useEffect } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { Button } from "@mui/material";
|
import { Button } from "@mui/material";
|
||||||
import { LanguageSwitcher } from "@widgets";
|
import { DeleteModal, LanguageSwitcher } from "@widgets";
|
||||||
import { Pencil, Trash2 } from "lucide-react";
|
import { Pencil, Trash2 } from "lucide-react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
@ -29,6 +29,8 @@ export const SightsTable = observer(() => {
|
|||||||
const { language } = languageStore;
|
const { language } = languageStore;
|
||||||
const { sights, getSights } = sightsStore;
|
const { sights, getSights } = sightsStore;
|
||||||
const { cities, getCities } = cityStore;
|
const { cities, getCities } = cityStore;
|
||||||
|
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||||
|
const [rowId, setRowId] = useState<number | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
@ -92,7 +94,10 @@ export const SightsTable = observer(() => {
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className="rounded-md px-3 py-1.5 transition-transform transform hover:scale-105"
|
className="rounded-md px-3 py-1.5 transition-transform transform hover:scale-105"
|
||||||
onClick={() => handleDelete(row?.id)}
|
onClick={() => {
|
||||||
|
setIsDeleteModalOpen(true);
|
||||||
|
setRowId(row?.id);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Trash2 size={18} className="text-red-500" />
|
<Trash2 size={18} className="text-red-500" />
|
||||||
</button>
|
</button>
|
||||||
@ -103,6 +108,17 @@ export const SightsTable = observer(() => {
|
|||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
</TableContainer>
|
</TableContainer>
|
||||||
|
<DeleteModal
|
||||||
|
open={isDeleteModalOpen}
|
||||||
|
onDelete={async () => {
|
||||||
|
if (rowId) {
|
||||||
|
await handleDelete(rowId);
|
||||||
|
}
|
||||||
|
setIsDeleteModalOpen(false);
|
||||||
|
setRowId(null);
|
||||||
|
}}
|
||||||
|
onCancel={() => setIsDeleteModalOpen(false)}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -12,3 +12,5 @@ export * from "./MediaArea";
|
|||||||
export * from "./ModelViewer3D";
|
export * from "./ModelViewer3D";
|
||||||
export * from "./MediaAreaForSight";
|
export * from "./MediaAreaForSight";
|
||||||
export * from "./ImageUploadCard";
|
export * from "./ImageUploadCard";
|
||||||
|
export * from "./LeaveAgree";
|
||||||
|
export * from "./DeleteModal";
|
||||||
|
@ -1 +1 @@
|
|||||||
{"root":["./src/main.tsx","./src/vite-env.d.ts","./src/app/index.tsx","./src/app/router/index.tsx","./src/entities/index.ts","./src/entities/navigation/index.ts","./src/entities/navigation/model/index.ts","./src/entities/navigation/ui/index.tsx","./src/features/index.ts","./src/features/navigation/index.ts","./src/features/navigation/ui/index.tsx","./src/pages/index.ts","./src/pages/createmediapage/index.tsx","./src/pages/createsightpage/index.tsx","./src/pages/devicespage/index.tsx","./src/pages/editmediapage/index.tsx","./src/pages/editsightpage/index.tsx","./src/pages/loginpage/index.tsx","./src/pages/mainpage/index.tsx","./src/pages/mappage/index.tsx","./src/pages/medialistpage/index.tsx","./src/pages/previewmediapage/index.tsx","./src/pages/sightpage/index.tsx","./src/shared/index.tsx","./src/shared/api/index.tsx","./src/shared/config/constants.tsx","./src/shared/config/index.ts","./src/shared/const/index.ts","./src/shared/lib/index.ts","./src/shared/lib/decodejwt/index.ts","./src/shared/lib/mui/theme.ts","./src/shared/modals/index.ts","./src/shared/modals/previewmediadialog/index.tsx","./src/shared/modals/selectarticledialog/index.tsx","./src/shared/modals/selectmediadialog/index.tsx","./src/shared/modals/uploadmediadialog/index.tsx","./src/shared/store/index.ts","./src/shared/store/articlesstore/index.tsx","./src/shared/store/authstore/index.tsx","./src/shared/store/citystore/index.tsx","./src/shared/store/createsightstore/index.tsx","./src/shared/store/devicesstore/index.tsx","./src/shared/store/editsightstore/index.tsx","./src/shared/store/languagestore/index.tsx","./src/shared/store/mediastore/index.tsx","./src/shared/store/sightsstore/index.tsx","./src/shared/store/snapshotstore/index.ts","./src/shared/store/vehiclestore/index.ts","./src/shared/ui/index.ts","./src/shared/ui/backbutton/index.tsx","./src/shared/ui/coordinatesinput/index.tsx","./src/shared/ui/input/index.tsx","./src/shared/ui/modal/index.tsx","./src/shared/ui/tabpanel/index.tsx","./src/widgets/index.ts","./src/widgets/devicestable/index.tsx","./src/widgets/imageuploadcard/index.tsx","./src/widgets/languageswitcher/index.tsx","./src/widgets/layout/index.tsx","./src/widgets/layout/ui/appbar.tsx","./src/widgets/layout/ui/drawer.tsx","./src/widgets/layout/ui/drawerheader.tsx","./src/widgets/mediaarea/index.tsx","./src/widgets/mediaareaforsight/index.tsx","./src/widgets/mediaviewer/threeview.tsx","./src/widgets/mediaviewer/index.tsx","./src/widgets/modelviewer3d/index.tsx","./src/widgets/reactmarkdown/index.tsx","./src/widgets/reactmarkdowneditor/index.tsx","./src/widgets/sightedit/index.tsx","./src/widgets/sightheader/index.ts","./src/widgets/sightheader/ui/index.tsx","./src/widgets/sighttabs/index.ts","./src/widgets/sighttabs/createinformationtab/mediauploadbox.tsx","./src/widgets/sighttabs/createinformationtab/index.tsx","./src/widgets/sighttabs/createlefttab/index.tsx","./src/widgets/sighttabs/createrighttab/index.tsx","./src/widgets/sighttabs/informationtab/index.tsx","./src/widgets/sighttabs/leftwidgettab/index.tsx","./src/widgets/sighttabs/rightwidgettab/index.tsx","./src/widgets/sightstable/index.tsx","./src/widgets/modals/index.ts","./src/widgets/modals/selectarticledialog/index.tsx"],"version":"5.8.3"}
|
{"root":["./src/main.tsx","./src/vite-env.d.ts","./src/app/index.tsx","./src/app/router/index.tsx","./src/entities/index.ts","./src/entities/navigation/index.ts","./src/entities/navigation/model/index.ts","./src/entities/navigation/ui/index.tsx","./src/features/index.ts","./src/features/navigation/index.ts","./src/features/navigation/ui/index.tsx","./src/pages/index.ts","./src/pages/createmediapage/index.tsx","./src/pages/createsightpage/index.tsx","./src/pages/devicespage/index.tsx","./src/pages/editmediapage/index.tsx","./src/pages/editsightpage/index.tsx","./src/pages/loginpage/index.tsx","./src/pages/mainpage/index.tsx","./src/pages/mappage/index.tsx","./src/pages/medialistpage/index.tsx","./src/pages/previewmediapage/index.tsx","./src/pages/sightpage/index.tsx","./src/shared/index.tsx","./src/shared/api/index.tsx","./src/shared/config/constants.tsx","./src/shared/config/index.ts","./src/shared/const/index.ts","./src/shared/lib/index.ts","./src/shared/lib/decodejwt/index.ts","./src/shared/lib/mui/theme.ts","./src/shared/modals/index.ts","./src/shared/modals/previewmediadialog/index.tsx","./src/shared/modals/selectarticledialog/index.tsx","./src/shared/modals/selectmediadialog/index.tsx","./src/shared/modals/uploadmediadialog/index.tsx","./src/shared/store/index.ts","./src/shared/store/articlesstore/index.tsx","./src/shared/store/authstore/index.tsx","./src/shared/store/citystore/index.tsx","./src/shared/store/createsightstore/index.tsx","./src/shared/store/devicesstore/index.tsx","./src/shared/store/editsightstore/index.tsx","./src/shared/store/languagestore/index.tsx","./src/shared/store/mediastore/index.tsx","./src/shared/store/sightsstore/index.tsx","./src/shared/store/snapshotstore/index.ts","./src/shared/store/vehiclestore/index.ts","./src/shared/ui/index.ts","./src/shared/ui/backbutton/index.tsx","./src/shared/ui/coordinatesinput/index.tsx","./src/shared/ui/input/index.tsx","./src/shared/ui/modal/index.tsx","./src/shared/ui/tabpanel/index.tsx","./src/widgets/index.ts","./src/widgets/deletemodal/index.tsx","./src/widgets/devicestable/index.tsx","./src/widgets/imageuploadcard/index.tsx","./src/widgets/languageswitcher/index.tsx","./src/widgets/layout/index.tsx","./src/widgets/layout/ui/appbar.tsx","./src/widgets/layout/ui/drawer.tsx","./src/widgets/layout/ui/drawerheader.tsx","./src/widgets/leaveagree/index.tsx","./src/widgets/mediaarea/index.tsx","./src/widgets/mediaareaforsight/index.tsx","./src/widgets/mediaviewer/threeview.tsx","./src/widgets/mediaviewer/index.tsx","./src/widgets/modelviewer3d/index.tsx","./src/widgets/reactmarkdown/index.tsx","./src/widgets/reactmarkdowneditor/index.tsx","./src/widgets/sightedit/index.tsx","./src/widgets/sightheader/index.ts","./src/widgets/sightheader/ui/index.tsx","./src/widgets/sighttabs/index.ts","./src/widgets/sighttabs/createinformationtab/mediauploadbox.tsx","./src/widgets/sighttabs/createinformationtab/index.tsx","./src/widgets/sighttabs/createlefttab/index.tsx","./src/widgets/sighttabs/createrighttab/index.tsx","./src/widgets/sighttabs/informationtab/index.tsx","./src/widgets/sighttabs/leftwidgettab/index.tsx","./src/widgets/sighttabs/rightwidgettab/index.tsx","./src/widgets/sightstable/index.tsx","./src/widgets/modals/index.ts","./src/widgets/modals/selectarticledialog/index.tsx"],"version":"5.8.3"}
|
286
yarn.lock
286
yarn.lock
@ -133,12 +133,12 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@babel/helper-plugin-utils" "^7.27.1"
|
"@babel/helper-plugin-utils" "^7.27.1"
|
||||||
|
|
||||||
"@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.27.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7":
|
"@babel/runtime@^7.12.5", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.26.0", "@babel/runtime@^7.27.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7":
|
||||||
version "7.27.3"
|
version "7.27.3"
|
||||||
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.3.tgz"
|
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.3.tgz"
|
||||||
integrity sha512-7EYtGezsdiDMyY80+65EzwiGmcJqpmcZCojSXaRgdrBaGtWTgDZKq69cPIVped6MkIM78cTQ2GOiEYjwOlG4xw==
|
integrity sha512-7EYtGezsdiDMyY80+65EzwiGmcJqpmcZCojSXaRgdrBaGtWTgDZKq69cPIVped6MkIM78cTQ2GOiEYjwOlG4xw==
|
||||||
|
|
||||||
"@babel/runtime@^7.17.8", "@babel/runtime@^7.26.0":
|
"@babel/runtime@^7.26.7":
|
||||||
version "7.27.4"
|
version "7.27.4"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.4.tgz#a91ec580e6c00c67118127777c316dfd5a5a6abf"
|
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.4.tgz#a91ec580e6c00c67118127777c316dfd5a5a6abf"
|
||||||
integrity sha512-t3yaEOuGu9NlIZ+hIeGbBjFtZT7j2cb2tg0fuaJKeGotchRjjLfrBA9Kwf8quhpP1EUuxModQg04q/mBwyg8uA==
|
integrity sha512-t3yaEOuGu9NlIZ+hIeGbBjFtZT7j2cb2tg0fuaJKeGotchRjjLfrBA9Kwf8quhpP1EUuxModQg04q/mBwyg8uA==
|
||||||
@ -173,9 +173,9 @@
|
|||||||
"@babel/helper-string-parser" "^7.27.1"
|
"@babel/helper-string-parser" "^7.27.1"
|
||||||
"@babel/helper-validator-identifier" "^7.27.1"
|
"@babel/helper-validator-identifier" "^7.27.1"
|
||||||
|
|
||||||
"@dimforge/rapier3d-compat@^0.12.0":
|
"@dimforge/rapier3d-compat@~0.12.0":
|
||||||
version "0.12.0"
|
version "0.12.0"
|
||||||
resolved "https://registry.yarnpkg.com/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz#7b3365e1dfdc5cd957b45afe920b4ac06c7cd389"
|
resolved "https://registry.npmjs.org/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz"
|
||||||
integrity sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==
|
integrity sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==
|
||||||
|
|
||||||
"@emnapi/core@^1.4.3":
|
"@emnapi/core@^1.4.3":
|
||||||
@ -498,6 +498,17 @@
|
|||||||
"@eslint/core" "^0.14.0"
|
"@eslint/core" "^0.14.0"
|
||||||
levn "^0.4.1"
|
levn "^0.4.1"
|
||||||
|
|
||||||
|
"@hello-pangea/dnd@^18.0.1":
|
||||||
|
version "18.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@hello-pangea/dnd/-/dnd-18.0.1.tgz#7d5ef7fe8bddf195307b16e03635b1be582b7b8d"
|
||||||
|
integrity sha512-xojVWG8s/TGrKT1fC8K2tIWeejJYTAeJuj36zM//yEm/ZrnZUSFGS15BpO+jGZT1ybWvyXmeDJwPYb4dhWlbZQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.26.7"
|
||||||
|
css-box-model "^1.2.1"
|
||||||
|
raf-schd "^4.0.3"
|
||||||
|
react-redux "^9.2.0"
|
||||||
|
redux "^5.0.1"
|
||||||
|
|
||||||
"@humanfs/core@^0.19.1":
|
"@humanfs/core@^0.19.1":
|
||||||
version "0.19.1"
|
version "0.19.1"
|
||||||
resolved "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz"
|
resolved "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz"
|
||||||
@ -567,12 +578,12 @@
|
|||||||
|
|
||||||
"@mediapipe/tasks-vision@0.10.17":
|
"@mediapipe/tasks-vision@0.10.17":
|
||||||
version "0.10.17"
|
version "0.10.17"
|
||||||
resolved "https://registry.yarnpkg.com/@mediapipe/tasks-vision/-/tasks-vision-0.10.17.tgz#2c1c73ed81902b21d37336a587b96183bb6882d5"
|
resolved "https://registry.npmjs.org/@mediapipe/tasks-vision/-/tasks-vision-0.10.17.tgz"
|
||||||
integrity sha512-CZWV/q6TTe8ta61cZXjfnnHsfWIdFhms03M9T7Cnd5y2mdpylJM0rF1qRq+wsQVRMLz1OYPVEBU9ph2Bx8cxrg==
|
integrity sha512-CZWV/q6TTe8ta61cZXjfnnHsfWIdFhms03M9T7Cnd5y2mdpylJM0rF1qRq+wsQVRMLz1OYPVEBU9ph2Bx8cxrg==
|
||||||
|
|
||||||
"@monogrid/gainmap-js@^3.0.6":
|
"@monogrid/gainmap-js@^3.0.6":
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@monogrid/gainmap-js/-/gainmap-js-3.1.0.tgz#4ac1f88abd6affdf0b51d79318109183b499c502"
|
resolved "https://registry.npmjs.org/@monogrid/gainmap-js/-/gainmap-js-3.1.0.tgz"
|
||||||
integrity sha512-Obb0/gEd/HReTlg8ttaYk+0m62gQJmCblMOjHSMHRrBP2zdfKMHLCRbh/6ex9fSUJMKdjjIEiohwkbGD3wj2Nw==
|
integrity sha512-Obb0/gEd/HReTlg8ttaYk+0m62gQJmCblMOjHSMHRrBP2zdfKMHLCRbh/6ex9fSUJMKdjjIEiohwkbGD3wj2Nw==
|
||||||
dependencies:
|
dependencies:
|
||||||
promise-worker-transferable "^1.0.4"
|
promise-worker-transferable "^1.0.4"
|
||||||
@ -686,12 +697,12 @@
|
|||||||
|
|
||||||
"@petamoriken/float16@^3.4.7":
|
"@petamoriken/float16@^3.4.7":
|
||||||
version "3.9.2"
|
version "3.9.2"
|
||||||
resolved "https://registry.yarnpkg.com/@petamoriken/float16/-/float16-3.9.2.tgz#217a5d349f3655b8e286be447e0ed1eae063a78f"
|
resolved "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.9.2.tgz"
|
||||||
integrity sha512-VgffxawQde93xKxT3qap3OH+meZf7VaSB5Sqd4Rqc+FP5alWbpOyan/7tRbOAvynjpG3GpdtAuGU/NdhQpmrog==
|
integrity sha512-VgffxawQde93xKxT3qap3OH+meZf7VaSB5Sqd4Rqc+FP5alWbpOyan/7tRbOAvynjpG3GpdtAuGU/NdhQpmrog==
|
||||||
|
|
||||||
"@photo-sphere-viewer/core@^5.13.2":
|
"@photo-sphere-viewer/core@^5.13.2":
|
||||||
version "5.13.2"
|
version "5.13.2"
|
||||||
resolved "https://registry.yarnpkg.com/@photo-sphere-viewer/core/-/core-5.13.2.tgz#518f27a2b7ca5a80068d8922183a9999a1b33ad1"
|
resolved "https://registry.npmjs.org/@photo-sphere-viewer/core/-/core-5.13.2.tgz"
|
||||||
integrity sha512-rL4Ey39Prx4Iyxt1f2tAqlXvqu4/ovXfUvIpLt540OpZJiFjWccs6qLywof9vuhBJ7PXHudHWCjRPce0W8kx8w==
|
integrity sha512-rL4Ey39Prx4Iyxt1f2tAqlXvqu4/ovXfUvIpLt540OpZJiFjWccs6qLywof9vuhBJ7PXHudHWCjRPce0W8kx8w==
|
||||||
dependencies:
|
dependencies:
|
||||||
three "^0.175.0"
|
three "^0.175.0"
|
||||||
@ -703,7 +714,7 @@
|
|||||||
|
|
||||||
"@react-three/drei@^10.1.2":
|
"@react-three/drei@^10.1.2":
|
||||||
version "10.1.2"
|
version "10.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/@react-three/drei/-/drei-10.1.2.tgz#3c41a0b19460aee7604067309cebe737147cf85a"
|
resolved "https://registry.npmjs.org/@react-three/drei/-/drei-10.1.2.tgz"
|
||||||
integrity sha512-CCcLAqZEvYiUErOcJgGzovY3RH6KgdrqD4ubeAx1nyGbSPLnKR9a8ynYbPdtZhIyiWqGc07z+RYQzpaOfN4ZIA==
|
integrity sha512-CCcLAqZEvYiUErOcJgGzovY3RH6KgdrqD4ubeAx1nyGbSPLnKR9a8ynYbPdtZhIyiWqGc07z+RYQzpaOfN4ZIA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.26.0"
|
"@babel/runtime" "^7.26.0"
|
||||||
@ -730,7 +741,7 @@
|
|||||||
|
|
||||||
"@react-three/fiber@^9.1.2":
|
"@react-three/fiber@^9.1.2":
|
||||||
version "9.1.2"
|
version "9.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/@react-three/fiber/-/fiber-9.1.2.tgz#c988f3aa916f64771483784ca3bb6ba4b116395e"
|
resolved "https://registry.npmjs.org/@react-three/fiber/-/fiber-9.1.2.tgz"
|
||||||
integrity sha512-k8FR9yVHV9kIF3iuOD0ds5hVymXYXfgdKklqziBVod9ZEJ8uk05Zjw29J/omU3IKeUfLNAIHfxneN3TUYM4I2w==
|
integrity sha512-k8FR9yVHV9kIF3iuOD0ds5hVymXYXfgdKklqziBVod9ZEJ8uk05Zjw29J/omU3IKeUfLNAIHfxneN3TUYM4I2w==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.17.8"
|
"@babel/runtime" "^7.17.8"
|
||||||
@ -973,7 +984,7 @@
|
|||||||
|
|
||||||
"@tweenjs/tween.js@~23.1.3":
|
"@tweenjs/tween.js@~23.1.3":
|
||||||
version "23.1.3"
|
version "23.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/@tweenjs/tween.js/-/tween.js-23.1.3.tgz#eff0245735c04a928bb19c026b58c2a56460539d"
|
resolved "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz"
|
||||||
integrity sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==
|
integrity sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==
|
||||||
|
|
||||||
"@tybys/wasm-util@^0.9.0":
|
"@tybys/wasm-util@^0.9.0":
|
||||||
@ -1032,7 +1043,7 @@
|
|||||||
|
|
||||||
"@types/draco3d@^1.4.0":
|
"@types/draco3d@^1.4.0":
|
||||||
version "1.4.10"
|
version "1.4.10"
|
||||||
resolved "https://registry.yarnpkg.com/@types/draco3d/-/draco3d-1.4.10.tgz#63ec0ba78b30bd58203ec031f4e4f0198c596dca"
|
resolved "https://registry.npmjs.org/@types/draco3d/-/draco3d-1.4.10.tgz"
|
||||||
integrity sha512-AX22jp8Y7wwaBgAixaSvkoG4M/+PlAcm3Qs4OW8yT9DM4xUpWKeFhLueTAyZF39pviAdcDdeJoACapiAceqNcw==
|
integrity sha512-AX22jp8Y7wwaBgAixaSvkoG4M/+PlAcm3Qs4OW8yT9DM4xUpWKeFhLueTAyZF39pviAdcDdeJoACapiAceqNcw==
|
||||||
|
|
||||||
"@types/estree-jsx@^1.0.0":
|
"@types/estree-jsx@^1.0.0":
|
||||||
@ -1085,7 +1096,7 @@
|
|||||||
|
|
||||||
"@types/offscreencanvas@^2019.6.4":
|
"@types/offscreencanvas@^2019.6.4":
|
||||||
version "2019.7.3"
|
version "2019.7.3"
|
||||||
resolved "https://registry.yarnpkg.com/@types/offscreencanvas/-/offscreencanvas-2019.7.3.tgz#90267db13f64d6e9ccb5ae3eac92786a7c77a516"
|
resolved "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.3.tgz"
|
||||||
integrity sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A==
|
integrity sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A==
|
||||||
|
|
||||||
"@types/parse-json@^4.0.0":
|
"@types/parse-json@^4.0.0":
|
||||||
@ -1100,7 +1111,7 @@
|
|||||||
|
|
||||||
"@types/rbush@4.0.0":
|
"@types/rbush@4.0.0":
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/rbush/-/rbush-4.0.0.tgz#b327bf54952e9c924ea6702c36904c2ce1d47f35"
|
resolved "https://registry.npmjs.org/@types/rbush/-/rbush-4.0.0.tgz"
|
||||||
integrity sha512-+N+2H39P8X+Hy1I5mC6awlTX54k3FhiUmvt7HWzGJZvF+syUAAxP/stwppS8JE84YHqFgRMv6fCy31202CMFxQ==
|
integrity sha512-+N+2H39P8X+Hy1I5mC6awlTX54k3FhiUmvt7HWzGJZvF+syUAAxP/stwppS8JE84YHqFgRMv6fCy31202CMFxQ==
|
||||||
|
|
||||||
"@types/react-dom@^19.1.2":
|
"@types/react-dom@^19.1.2":
|
||||||
@ -1110,7 +1121,7 @@
|
|||||||
|
|
||||||
"@types/react-reconciler@^0.28.9":
|
"@types/react-reconciler@^0.28.9":
|
||||||
version "0.28.9"
|
version "0.28.9"
|
||||||
resolved "https://registry.yarnpkg.com/@types/react-reconciler/-/react-reconciler-0.28.9.tgz#d24b4864c384e770c83275b3fe73fba00269c83b"
|
resolved "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.9.tgz"
|
||||||
integrity sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg==
|
integrity sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg==
|
||||||
|
|
||||||
"@types/react-transition-group@^4.4.12":
|
"@types/react-transition-group@^4.4.12":
|
||||||
@ -1127,7 +1138,7 @@
|
|||||||
|
|
||||||
"@types/stats.js@*":
|
"@types/stats.js@*":
|
||||||
version "0.17.4"
|
version "0.17.4"
|
||||||
resolved "https://registry.yarnpkg.com/@types/stats.js/-/stats.js-0.17.4.tgz#1933e5ff153a23c7664487833198d685c22e791e"
|
resolved "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.4.tgz"
|
||||||
integrity sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==
|
integrity sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==
|
||||||
|
|
||||||
"@types/tern@*":
|
"@types/tern@*":
|
||||||
@ -1138,11 +1149,11 @@
|
|||||||
"@types/estree" "*"
|
"@types/estree" "*"
|
||||||
|
|
||||||
"@types/three@*":
|
"@types/three@*":
|
||||||
version "0.176.0"
|
version "0.177.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/three/-/three-0.176.0.tgz#b6eced2b05e839395a6171e066c4631bc5b0a1e0"
|
resolved "https://registry.npmjs.org/@types/three/-/three-0.177.0.tgz"
|
||||||
integrity sha512-FwfPXxCqOtP7EdYMagCFePNKoG1AGBDUEVKtluv2BTVRpSt7b+X27xNsirPCTCqY1pGYsPUzaM3jgWP7dXSxlw==
|
integrity sha512-/ZAkn4OLUijKQySNci47lFO+4JLE1TihEjsGWPUT+4jWqxtwOPPEwJV1C3k5MEx0mcBPCdkFjzRzDOnHEI1R+A==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@dimforge/rapier3d-compat" "^0.12.0"
|
"@dimforge/rapier3d-compat" "~0.12.0"
|
||||||
"@tweenjs/tween.js" "~23.1.3"
|
"@tweenjs/tween.js" "~23.1.3"
|
||||||
"@types/stats.js" "*"
|
"@types/stats.js" "*"
|
||||||
"@types/webxr" "*"
|
"@types/webxr" "*"
|
||||||
@ -1160,9 +1171,14 @@
|
|||||||
resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz"
|
resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz"
|
||||||
integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==
|
integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==
|
||||||
|
|
||||||
|
"@types/use-sync-external-store@^0.0.6":
|
||||||
|
version "0.0.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz#60be8d21baab8c305132eb9cb912ed497852aadc"
|
||||||
|
integrity sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==
|
||||||
|
|
||||||
"@types/webxr@*", "@types/webxr@^0.5.2":
|
"@types/webxr@*", "@types/webxr@^0.5.2":
|
||||||
version "0.5.22"
|
version "0.5.22"
|
||||||
resolved "https://registry.yarnpkg.com/@types/webxr/-/webxr-0.5.22.tgz#d8a14c12bbfaaa4a13de21ec2d4a8197b3e1b532"
|
resolved "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.22.tgz"
|
||||||
integrity sha512-Vr6Stjv5jPRqH690f5I5GLjVk8GSsoQSYJ2FVd/3jJF7KaqfwPi3ehfBS96mlQ2kPCwZaX6U0rG2+NGHBKkA/A==
|
integrity sha512-Vr6Stjv5jPRqH690f5I5GLjVk8GSsoQSYJ2FVd/3jJF7KaqfwPi3ehfBS96mlQ2kPCwZaX6U0rG2+NGHBKkA/A==
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin@8.33.0":
|
"@typescript-eslint/eslint-plugin@8.33.0":
|
||||||
@ -1269,12 +1285,12 @@
|
|||||||
|
|
||||||
"@use-gesture/core@10.3.1":
|
"@use-gesture/core@10.3.1":
|
||||||
version "10.3.1"
|
version "10.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/@use-gesture/core/-/core-10.3.1.tgz#976c9421e905f0079d49822cfd5c2e56b808fc56"
|
resolved "https://registry.npmjs.org/@use-gesture/core/-/core-10.3.1.tgz"
|
||||||
integrity sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw==
|
integrity sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw==
|
||||||
|
|
||||||
"@use-gesture/react@^10.3.1":
|
"@use-gesture/react@^10.3.1":
|
||||||
version "10.3.1"
|
version "10.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/@use-gesture/react/-/react-10.3.1.tgz#17a743a894d9bd9a0d1980c618f37f0164469867"
|
resolved "https://registry.npmjs.org/@use-gesture/react/-/react-10.3.1.tgz"
|
||||||
integrity sha512-Yy19y6O2GJq8f7CHf7L0nxL8bf4PZCPaVOCgJrusOeFHY1LvHgYXnmnXg6N5iwAnbgbZCDjo60SiM6IPJi9C5g==
|
integrity sha512-Yy19y6O2GJq8f7CHf7L0nxL8bf4PZCPaVOCgJrusOeFHY1LvHgYXnmnXg6N5iwAnbgbZCDjo60SiM6IPJi9C5g==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@use-gesture/core" "10.3.1"
|
"@use-gesture/core" "10.3.1"
|
||||||
@ -1293,7 +1309,7 @@
|
|||||||
|
|
||||||
"@webgpu/types@*":
|
"@webgpu/types@*":
|
||||||
version "0.1.61"
|
version "0.1.61"
|
||||||
resolved "https://registry.yarnpkg.com/@webgpu/types/-/types-0.1.61.tgz#60ac1756bbeeae778b5357a94d4e6e160592d6f1"
|
resolved "https://registry.npmjs.org/@webgpu/types/-/types-0.1.61.tgz"
|
||||||
integrity sha512-w2HbBvH+qO19SB5pJOJFKs533CdZqxl3fcGonqL321VHkW7W/iBo6H8bjDy6pr/+pbMwIu5dnuaAxH7NxBqUrQ==
|
integrity sha512-w2HbBvH+qO19SB5pJOJFKs533CdZqxl3fcGonqL321VHkW7W/iBo6H8bjDy6pr/+pbMwIu5dnuaAxH7NxBqUrQ==
|
||||||
|
|
||||||
acorn-jsx@^5.3.2:
|
acorn-jsx@^5.3.2:
|
||||||
@ -1330,17 +1346,17 @@ argparse@^2.0.1:
|
|||||||
|
|
||||||
asynckit@^0.4.0:
|
asynckit@^0.4.0:
|
||||||
version "0.4.0"
|
version "0.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz"
|
||||||
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
|
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
|
||||||
|
|
||||||
attr-accept@^2.2.4:
|
attr-accept@^2.2.4:
|
||||||
version "2.2.5"
|
version "2.2.5"
|
||||||
resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.2.5.tgz#d7061d958e6d4f97bf8665c68b75851a0713ab5e"
|
resolved "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.5.tgz"
|
||||||
integrity sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==
|
integrity sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==
|
||||||
|
|
||||||
axios@^1.9.0:
|
axios@^1.9.0:
|
||||||
version "1.9.0"
|
version "1.9.0"
|
||||||
resolved "https://registry.yarnpkg.com/axios/-/axios-1.9.0.tgz#25534e3b72b54540077d33046f77e3b8d7081901"
|
resolved "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz"
|
||||||
integrity sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==
|
integrity sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==
|
||||||
dependencies:
|
dependencies:
|
||||||
follow-redirects "^1.15.6"
|
follow-redirects "^1.15.6"
|
||||||
@ -1368,12 +1384,12 @@ balanced-match@^1.0.0:
|
|||||||
|
|
||||||
base64-js@^1.3.1, base64-js@^1.5.1:
|
base64-js@^1.3.1, base64-js@^1.5.1:
|
||||||
version "1.5.1"
|
version "1.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
|
resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz"
|
||||||
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
|
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
|
||||||
|
|
||||||
bidi-js@^1.0.2:
|
bidi-js@^1.0.2:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/bidi-js/-/bidi-js-1.0.3.tgz#6f8bcf3c877c4d9220ddf49b9bb6930c88f877d2"
|
resolved "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz"
|
||||||
integrity sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==
|
integrity sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==
|
||||||
dependencies:
|
dependencies:
|
||||||
require-from-string "^2.0.2"
|
require-from-string "^2.0.2"
|
||||||
@ -1412,7 +1428,7 @@ browserslist@^4.24.0:
|
|||||||
|
|
||||||
buffer@^6.0.3:
|
buffer@^6.0.3:
|
||||||
version "6.0.3"
|
version "6.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6"
|
resolved "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz"
|
||||||
integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
|
integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
|
||||||
dependencies:
|
dependencies:
|
||||||
base64-js "^1.3.1"
|
base64-js "^1.3.1"
|
||||||
@ -1420,7 +1436,7 @@ buffer@^6.0.3:
|
|||||||
|
|
||||||
call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2:
|
call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6"
|
resolved "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz"
|
||||||
integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==
|
integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
es-errors "^1.3.0"
|
es-errors "^1.3.0"
|
||||||
@ -1433,7 +1449,7 @@ callsites@^3.0.0:
|
|||||||
|
|
||||||
camera-controls@^2.9.0:
|
camera-controls@^2.9.0:
|
||||||
version "2.10.1"
|
version "2.10.1"
|
||||||
resolved "https://registry.yarnpkg.com/camera-controls/-/camera-controls-2.10.1.tgz#78bc58001a2d5925c29312154ce77d16967dec56"
|
resolved "https://registry.npmjs.org/camera-controls/-/camera-controls-2.10.1.tgz"
|
||||||
integrity sha512-KnaKdcvkBJ1Irbrzl8XD6WtZltkRjp869Jx8c0ujs9K+9WD+1D7ryBsCiVqJYUqt6i/HR5FxT7RLASieUD+Q5w==
|
integrity sha512-KnaKdcvkBJ1Irbrzl8XD6WtZltkRjp869Jx8c0ujs9K+9WD+1D7ryBsCiVqJYUqt6i/HR5FxT7RLASieUD+Q5w==
|
||||||
|
|
||||||
caniuse-lite@^1.0.30001716:
|
caniuse-lite@^1.0.30001716:
|
||||||
@ -1510,7 +1526,7 @@ color-name@~1.1.4:
|
|||||||
|
|
||||||
combined-stream@^1.0.8:
|
combined-stream@^1.0.8:
|
||||||
version "1.0.8"
|
version "1.0.8"
|
||||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz"
|
||||||
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
|
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
|
||||||
dependencies:
|
dependencies:
|
||||||
delayed-stream "~1.0.0"
|
delayed-stream "~1.0.0"
|
||||||
@ -1537,7 +1553,7 @@ convert-source-map@^2.0.0:
|
|||||||
|
|
||||||
cookie@^1.0.1:
|
cookie@^1.0.1:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz"
|
resolved "https://registry.yarnpkg.com/cookie/-/cookie-1.0.2.tgz#27360701532116bd3f1f9416929d176afe1e4610"
|
||||||
integrity sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==
|
integrity sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==
|
||||||
|
|
||||||
cosmiconfig@^7.0.0:
|
cosmiconfig@^7.0.0:
|
||||||
@ -1553,7 +1569,7 @@ cosmiconfig@^7.0.0:
|
|||||||
|
|
||||||
cross-env@^7.0.3:
|
cross-env@^7.0.3:
|
||||||
version "7.0.3"
|
version "7.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf"
|
resolved "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz"
|
||||||
integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==
|
integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==
|
||||||
dependencies:
|
dependencies:
|
||||||
cross-spawn "^7.0.1"
|
cross-spawn "^7.0.1"
|
||||||
@ -1567,6 +1583,13 @@ cross-spawn@^7.0.1, cross-spawn@^7.0.6:
|
|||||||
shebang-command "^2.0.0"
|
shebang-command "^2.0.0"
|
||||||
which "^2.0.1"
|
which "^2.0.1"
|
||||||
|
|
||||||
|
css-box-model@^1.2.1:
|
||||||
|
version "1.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/css-box-model/-/css-box-model-1.2.1.tgz#59951d3b81fd6b2074a62d49444415b0d2b4d7c1"
|
||||||
|
integrity sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==
|
||||||
|
dependencies:
|
||||||
|
tiny-invariant "^1.0.6"
|
||||||
|
|
||||||
cssesc@^3.0.0:
|
cssesc@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz"
|
resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz"
|
||||||
@ -1598,7 +1621,7 @@ deep-is@^0.1.3:
|
|||||||
|
|
||||||
delayed-stream@~1.0.0:
|
delayed-stream@~1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
|
||||||
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
|
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
|
||||||
|
|
||||||
dequal@^2.0.0:
|
dequal@^2.0.0:
|
||||||
@ -1608,7 +1631,7 @@ dequal@^2.0.0:
|
|||||||
|
|
||||||
detect-gpu@^5.0.56:
|
detect-gpu@^5.0.56:
|
||||||
version "5.0.70"
|
version "5.0.70"
|
||||||
resolved "https://registry.yarnpkg.com/detect-gpu/-/detect-gpu-5.0.70.tgz#db2202d3cd440714ba6e789ff8b62d1b584eabf7"
|
resolved "https://registry.npmjs.org/detect-gpu/-/detect-gpu-5.0.70.tgz"
|
||||||
integrity sha512-bqerEP1Ese6nt3rFkwPnGbsUF9a4q+gMmpTVVOEzoCyeCc+y7/RvJnQZJx1JwhgQI5Ntg0Kgat8Uu7XpBqnz1w==
|
integrity sha512-bqerEP1Ese6nt3rFkwPnGbsUF9a4q+gMmpTVVOEzoCyeCc+y7/RvJnQZJx1JwhgQI5Ntg0Kgat8Uu7XpBqnz1w==
|
||||||
dependencies:
|
dependencies:
|
||||||
webgl-constants "^1.1.1"
|
webgl-constants "^1.1.1"
|
||||||
@ -1635,12 +1658,12 @@ dom-helpers@^5.0.1:
|
|||||||
|
|
||||||
draco3d@^1.4.1:
|
draco3d@^1.4.1:
|
||||||
version "1.5.7"
|
version "1.5.7"
|
||||||
resolved "https://registry.yarnpkg.com/draco3d/-/draco3d-1.5.7.tgz#94f9bce293eb8920c159dc91a4ce9124a9e899e0"
|
resolved "https://registry.npmjs.org/draco3d/-/draco3d-1.5.7.tgz"
|
||||||
integrity sha512-m6WCKt/erDXcw+70IJXnG7M3awwQPAsZvJGX5zY7beBqpELw6RDGkYVU0W43AFxye4pDZ5i2Lbyc/NNGqwjUVQ==
|
integrity sha512-m6WCKt/erDXcw+70IJXnG7M3awwQPAsZvJGX5zY7beBqpELw6RDGkYVU0W43AFxye4pDZ5i2Lbyc/NNGqwjUVQ==
|
||||||
|
|
||||||
dunder-proto@^1.0.1:
|
dunder-proto@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a"
|
resolved "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz"
|
||||||
integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==
|
integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==
|
||||||
dependencies:
|
dependencies:
|
||||||
call-bind-apply-helpers "^1.0.1"
|
call-bind-apply-helpers "^1.0.1"
|
||||||
@ -1649,7 +1672,7 @@ dunder-proto@^1.0.1:
|
|||||||
|
|
||||||
earcut@^3.0.0:
|
earcut@^3.0.0:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/earcut/-/earcut-3.0.1.tgz#f60b3f671c5657cca9d3e131c5527c5dde00ef38"
|
resolved "https://registry.npmjs.org/earcut/-/earcut-3.0.1.tgz"
|
||||||
integrity sha512-0l1/0gOjESMeQyYaK5IDiPNvFeu93Z/cO0TjZh9eZ1vyCtZnA7KMZ8rQggpsJHIbGSdrqYq9OhuveadOVHCshw==
|
integrity sha512-0l1/0gOjESMeQyYaK5IDiPNvFeu93Z/cO0TjZh9eZ1vyCtZnA7KMZ8rQggpsJHIbGSdrqYq9OhuveadOVHCshw==
|
||||||
|
|
||||||
easymde@^2.20.0:
|
easymde@^2.20.0:
|
||||||
@ -1690,24 +1713,24 @@ error-ex@^1.3.1:
|
|||||||
|
|
||||||
es-define-property@^1.0.1:
|
es-define-property@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa"
|
resolved "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz"
|
||||||
integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==
|
integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==
|
||||||
|
|
||||||
es-errors@^1.3.0:
|
es-errors@^1.3.0:
|
||||||
version "1.3.0"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
|
resolved "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz"
|
||||||
integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
|
integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
|
||||||
|
|
||||||
es-object-atoms@^1.0.0, es-object-atoms@^1.1.1:
|
es-object-atoms@^1.0.0, es-object-atoms@^1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1"
|
resolved "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz"
|
||||||
integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==
|
integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==
|
||||||
dependencies:
|
dependencies:
|
||||||
es-errors "^1.3.0"
|
es-errors "^1.3.0"
|
||||||
|
|
||||||
es-set-tostringtag@^2.1.0:
|
es-set-tostringtag@^2.1.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz#f31dbbe0c183b00a6d26eb6325c810c0fd18bd4d"
|
resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz"
|
||||||
integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==
|
integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==
|
||||||
dependencies:
|
dependencies:
|
||||||
es-errors "^1.3.0"
|
es-errors "^1.3.0"
|
||||||
@ -1865,7 +1888,7 @@ esutils@^2.0.2:
|
|||||||
|
|
||||||
eventemitter3@^5.0.1:
|
eventemitter3@^5.0.1:
|
||||||
version "5.0.1"
|
version "5.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4"
|
resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz"
|
||||||
integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==
|
integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==
|
||||||
|
|
||||||
extend@^3.0.0:
|
extend@^3.0.0:
|
||||||
@ -1913,12 +1936,12 @@ fdir@^6.4.4:
|
|||||||
|
|
||||||
fflate@^0.6.9:
|
fflate@^0.6.9:
|
||||||
version "0.6.10"
|
version "0.6.10"
|
||||||
resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.6.10.tgz#5f40f9659205936a2d18abf88b2e7781662b6d43"
|
resolved "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz"
|
||||||
integrity sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==
|
integrity sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==
|
||||||
|
|
||||||
fflate@~0.8.2:
|
fflate@~0.8.2:
|
||||||
version "0.8.2"
|
version "0.8.2"
|
||||||
resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.8.2.tgz#fc8631f5347812ad6028bbe4a2308b2792aa1dea"
|
resolved "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz"
|
||||||
integrity sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==
|
integrity sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==
|
||||||
|
|
||||||
file-entry-cache@^8.0.0:
|
file-entry-cache@^8.0.0:
|
||||||
@ -1930,7 +1953,7 @@ file-entry-cache@^8.0.0:
|
|||||||
|
|
||||||
file-selector@^2.1.0:
|
file-selector@^2.1.0:
|
||||||
version "2.1.2"
|
version "2.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/file-selector/-/file-selector-2.1.2.tgz#fe7c7ee9e550952dfbc863d73b14dc740d7de8b4"
|
resolved "https://registry.npmjs.org/file-selector/-/file-selector-2.1.2.tgz"
|
||||||
integrity sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==
|
integrity sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib "^2.7.0"
|
tslib "^2.7.0"
|
||||||
@ -1970,12 +1993,12 @@ flatted@^3.2.9:
|
|||||||
|
|
||||||
follow-redirects@^1.15.6:
|
follow-redirects@^1.15.6:
|
||||||
version "1.15.9"
|
version "1.15.9"
|
||||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1"
|
resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz"
|
||||||
integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==
|
integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==
|
||||||
|
|
||||||
form-data@^4.0.0:
|
form-data@^4.0.0:
|
||||||
version "4.0.2"
|
version "4.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.2.tgz#35cabbdd30c3ce73deb2c42d3c8d3ed9ca51794c"
|
resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz"
|
||||||
integrity sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==
|
integrity sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==
|
||||||
dependencies:
|
dependencies:
|
||||||
asynckit "^0.4.0"
|
asynckit "^0.4.0"
|
||||||
@ -2000,7 +2023,7 @@ gensync@^1.0.0-beta.2:
|
|||||||
|
|
||||||
geotiff@^2.1.3:
|
geotiff@^2.1.3:
|
||||||
version "2.1.3"
|
version "2.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/geotiff/-/geotiff-2.1.3.tgz#993f40f2aa6aa65fb1e0451d86dd22ca8e66910c"
|
resolved "https://registry.npmjs.org/geotiff/-/geotiff-2.1.3.tgz"
|
||||||
integrity sha512-PT6uoF5a1+kbC3tHmZSUsLHBp2QJlHasxxxxPW47QIY1VBKpFB+FcDvX+MxER6UzgLQZ0xDzJ9s48B9JbOCTqA==
|
integrity sha512-PT6uoF5a1+kbC3tHmZSUsLHBp2QJlHasxxxxPW47QIY1VBKpFB+FcDvX+MxER6UzgLQZ0xDzJ9s48B9JbOCTqA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@petamoriken/float16" "^3.4.7"
|
"@petamoriken/float16" "^3.4.7"
|
||||||
@ -2014,7 +2037,7 @@ geotiff@^2.1.3:
|
|||||||
|
|
||||||
get-intrinsic@^1.2.6:
|
get-intrinsic@^1.2.6:
|
||||||
version "1.3.0"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01"
|
resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz"
|
||||||
integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==
|
integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
call-bind-apply-helpers "^1.0.2"
|
call-bind-apply-helpers "^1.0.2"
|
||||||
@ -2030,7 +2053,7 @@ get-intrinsic@^1.2.6:
|
|||||||
|
|
||||||
get-proto@^1.0.1:
|
get-proto@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1"
|
resolved "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz"
|
||||||
integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==
|
integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==
|
||||||
dependencies:
|
dependencies:
|
||||||
dunder-proto "^1.0.1"
|
dunder-proto "^1.0.1"
|
||||||
@ -2067,12 +2090,12 @@ globals@^16.0.0:
|
|||||||
|
|
||||||
glsl-noise@^0.0.0:
|
glsl-noise@^0.0.0:
|
||||||
version "0.0.0"
|
version "0.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/glsl-noise/-/glsl-noise-0.0.0.tgz#367745f3a33382c0eeec4cb54b7e99cfc1d7670b"
|
resolved "https://registry.npmjs.org/glsl-noise/-/glsl-noise-0.0.0.tgz"
|
||||||
integrity sha512-b/ZCF6amfAUb7dJM/MxRs7AetQEahYzJ8PtgfrmEdtw6uyGOr+ZSGtgjFm6mfsBkxJ4d2W7kg+Nlqzqvn3Bc0w==
|
integrity sha512-b/ZCF6amfAUb7dJM/MxRs7AetQEahYzJ8PtgfrmEdtw6uyGOr+ZSGtgjFm6mfsBkxJ4d2W7kg+Nlqzqvn3Bc0w==
|
||||||
|
|
||||||
gopd@^1.2.0:
|
gopd@^1.2.0:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1"
|
resolved "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz"
|
||||||
integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==
|
integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==
|
||||||
|
|
||||||
graceful-fs@^4.2.4:
|
graceful-fs@^4.2.4:
|
||||||
@ -2092,12 +2115,12 @@ has-flag@^4.0.0:
|
|||||||
|
|
||||||
has-symbols@^1.0.3, has-symbols@^1.1.0:
|
has-symbols@^1.0.3, has-symbols@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338"
|
resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz"
|
||||||
integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==
|
integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==
|
||||||
|
|
||||||
has-tostringtag@^1.0.2:
|
has-tostringtag@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc"
|
resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz"
|
||||||
integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==
|
integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==
|
||||||
dependencies:
|
dependencies:
|
||||||
has-symbols "^1.0.3"
|
has-symbols "^1.0.3"
|
||||||
@ -2202,9 +2225,9 @@ hastscript@^9.0.0:
|
|||||||
space-separated-tokens "^2.0.0"
|
space-separated-tokens "^2.0.0"
|
||||||
|
|
||||||
hls.js@^1.5.17:
|
hls.js@^1.5.17:
|
||||||
version "1.6.4"
|
version "1.6.5"
|
||||||
resolved "https://registry.yarnpkg.com/hls.js/-/hls.js-1.6.4.tgz#0c4070f5f719eda2687e2ab13b061dbb01967dd8"
|
resolved "https://registry.npmjs.org/hls.js/-/hls.js-1.6.5.tgz"
|
||||||
integrity sha512-sxFS61suCMJBvpOhmi4WLnarOZ8S8JAxK5J1icvrkopE8aRMc1pRB9WZWMX5Obh9nieVEML6uLLeyGksapyX5A==
|
integrity sha512-KMn5n7JBK+olC342740hDPHnGWfE8FiHtGMOdJPfUjRdARTWj9OB+8c13fnsf9sk1VtpuU2fKSgUjHvg4rNbzQ==
|
||||||
|
|
||||||
hoist-non-react-statics@^3.3.1:
|
hoist-non-react-statics@^3.3.1:
|
||||||
version "3.3.2"
|
version "3.3.2"
|
||||||
@ -2225,7 +2248,7 @@ html-void-elements@^3.0.0:
|
|||||||
|
|
||||||
ieee754@^1.2.1:
|
ieee754@^1.2.1:
|
||||||
version "1.2.1"
|
version "1.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
|
resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz"
|
||||||
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
|
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
|
||||||
|
|
||||||
ignore@^5.2.0:
|
ignore@^5.2.0:
|
||||||
@ -2240,7 +2263,7 @@ ignore@^7.0.0:
|
|||||||
|
|
||||||
immediate@~3.0.5:
|
immediate@~3.0.5:
|
||||||
version "3.0.6"
|
version "3.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
|
resolved "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz"
|
||||||
integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==
|
integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==
|
||||||
|
|
||||||
import-fresh@^3.2.1:
|
import-fresh@^3.2.1:
|
||||||
@ -2325,7 +2348,7 @@ is-plain-obj@^4.0.0:
|
|||||||
|
|
||||||
is-promise@^2.1.0:
|
is-promise@^2.1.0:
|
||||||
version "2.2.2"
|
version "2.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1"
|
resolved "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz"
|
||||||
integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==
|
integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==
|
||||||
|
|
||||||
isexe@^2.0.0:
|
isexe@^2.0.0:
|
||||||
@ -2335,7 +2358,7 @@ isexe@^2.0.0:
|
|||||||
|
|
||||||
its-fine@^2.0.0:
|
its-fine@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/its-fine/-/its-fine-2.0.0.tgz#a90b18a3ee4c211a1fb6faac2abcc2b682ce1f21"
|
resolved "https://registry.npmjs.org/its-fine/-/its-fine-2.0.0.tgz"
|
||||||
integrity sha512-KLViCmWx94zOvpLwSlsx6yOCeMhZYaxrJV87Po5k/FoZzcPSahvK5qJ7fYhS61sZi5ikmh2S3Hz55A2l3U69ng==
|
integrity sha512-KLViCmWx94zOvpLwSlsx6yOCeMhZYaxrJV87Po5k/FoZzcPSahvK5qJ7fYhS61sZi5ikmh2S3Hz55A2l3U69ng==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/react-reconciler" "^0.28.9"
|
"@types/react-reconciler" "^0.28.9"
|
||||||
@ -2396,7 +2419,7 @@ keyv@^4.5.4:
|
|||||||
|
|
||||||
lerc@^3.0.0:
|
lerc@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/lerc/-/lerc-3.0.0.tgz#36f36fbd4ba46f0abf4833799fff2e7d6865f5cb"
|
resolved "https://registry.npmjs.org/lerc/-/lerc-3.0.0.tgz"
|
||||||
integrity sha512-Rm4J/WaHhRa93nCN2mwWDZFoRVF18G1f47C+kvQWyHGEZxFpTUi73p7lMVSAndyxGt6lJ2/CFbOcf9ra5p8aww==
|
integrity sha512-Rm4J/WaHhRa93nCN2mwWDZFoRVF18G1f47C+kvQWyHGEZxFpTUi73p7lMVSAndyxGt6lJ2/CFbOcf9ra5p8aww==
|
||||||
|
|
||||||
levn@^0.4.1:
|
levn@^0.4.1:
|
||||||
@ -2409,7 +2432,7 @@ levn@^0.4.1:
|
|||||||
|
|
||||||
lie@^3.0.2:
|
lie@^3.0.2:
|
||||||
version "3.3.0"
|
version "3.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a"
|
resolved "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz"
|
||||||
integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==
|
integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
immediate "~3.0.5"
|
immediate "~3.0.5"
|
||||||
@ -2535,7 +2558,7 @@ lucide-react@^0.511.0:
|
|||||||
|
|
||||||
maath@^0.10.8:
|
maath@^0.10.8:
|
||||||
version "0.10.8"
|
version "0.10.8"
|
||||||
resolved "https://registry.yarnpkg.com/maath/-/maath-0.10.8.tgz#cf647544430141bf6982da6e878abb6c4b804e24"
|
resolved "https://registry.npmjs.org/maath/-/maath-0.10.8.tgz"
|
||||||
integrity sha512-tRvbDF0Pgqz+9XUa4jjfgAQ8/aPKmQdWXilFu2tMy4GWj4NOsx99HlULO4IeREfbO3a0sA145DZYyvXPkybm0g==
|
integrity sha512-tRvbDF0Pgqz+9XUa4jjfgAQ8/aPKmQdWXilFu2tMy4GWj4NOsx99HlULO4IeREfbO3a0sA145DZYyvXPkybm0g==
|
||||||
|
|
||||||
magic-string@^0.30.17:
|
magic-string@^0.30.17:
|
||||||
@ -2552,7 +2575,7 @@ marked@^4.1.0:
|
|||||||
|
|
||||||
math-intrinsics@^1.1.0:
|
math-intrinsics@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9"
|
resolved "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz"
|
||||||
integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==
|
integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==
|
||||||
|
|
||||||
mdast-util-from-markdown@^2.0.0:
|
mdast-util-from-markdown@^2.0.0:
|
||||||
@ -2667,12 +2690,12 @@ merge2@^1.3.0:
|
|||||||
|
|
||||||
meshline@^3.3.1:
|
meshline@^3.3.1:
|
||||||
version "3.3.1"
|
version "3.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/meshline/-/meshline-3.3.1.tgz#20decfd5cdd25c8469e862ddf0ab1ad167759734"
|
resolved "https://registry.npmjs.org/meshline/-/meshline-3.3.1.tgz"
|
||||||
integrity sha512-/TQj+JdZkeSUOl5Mk2J7eLcYTLiQm2IDzmlSvYm7ov15anEcDJ92GHqqazxTSreeNgfnYu24kiEvvv0WlbCdFQ==
|
integrity sha512-/TQj+JdZkeSUOl5Mk2J7eLcYTLiQm2IDzmlSvYm7ov15anEcDJ92GHqqazxTSreeNgfnYu24kiEvvv0WlbCdFQ==
|
||||||
|
|
||||||
meshoptimizer@~0.18.1:
|
meshoptimizer@~0.18.1:
|
||||||
version "0.18.1"
|
version "0.18.1"
|
||||||
resolved "https://registry.yarnpkg.com/meshoptimizer/-/meshoptimizer-0.18.1.tgz#cdb90907f30a7b5b1190facd3b7ee6b7087797d8"
|
resolved "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.18.1.tgz"
|
||||||
integrity sha512-ZhoIoL7TNV4s5B6+rx5mC//fw8/POGyNxS/DZyCJeiZ12ScLfVwRE/GfsxwiTkMYYD5DmK2/JXnEVXqL4rF+Sw==
|
integrity sha512-ZhoIoL7TNV4s5B6+rx5mC//fw8/POGyNxS/DZyCJeiZ12ScLfVwRE/GfsxwiTkMYYD5DmK2/JXnEVXqL4rF+Sw==
|
||||||
|
|
||||||
micromark-core-commonmark@^2.0.0:
|
micromark-core-commonmark@^2.0.0:
|
||||||
@ -2879,12 +2902,12 @@ micromatch@^4.0.8:
|
|||||||
|
|
||||||
mime-db@1.52.0:
|
mime-db@1.52.0:
|
||||||
version "1.52.0"
|
version "1.52.0"
|
||||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
|
resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz"
|
||||||
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
|
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
|
||||||
|
|
||||||
mime-types@^2.1.12:
|
mime-types@^2.1.12:
|
||||||
version "2.1.35"
|
version "2.1.35"
|
||||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
|
resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz"
|
||||||
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
|
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
|
||||||
dependencies:
|
dependencies:
|
||||||
mime-db "1.52.0"
|
mime-db "1.52.0"
|
||||||
@ -2959,7 +2982,7 @@ object-assign@^4.1.1:
|
|||||||
|
|
||||||
ol@^10.5.0:
|
ol@^10.5.0:
|
||||||
version "10.5.0"
|
version "10.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/ol/-/ol-10.5.0.tgz#5831dc55fe5eb5a09cb4193c9289c1b5a0a0f0ca"
|
resolved "https://registry.npmjs.org/ol/-/ol-10.5.0.tgz"
|
||||||
integrity sha512-nHFx8gkGmvYImsa7iKkwUnZidd5gn1XbMZd9GNOorvm9orjW9gQvT3Naw/MjIasVJ3cB9EJUdCGR2EFAulMHsQ==
|
integrity sha512-nHFx8gkGmvYImsa7iKkwUnZidd5gn1XbMZd9GNOorvm9orjW9gQvT3Naw/MjIasVJ3cB9EJUdCGR2EFAulMHsQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/rbush" "4.0.0"
|
"@types/rbush" "4.0.0"
|
||||||
@ -2996,7 +3019,7 @@ p-locate@^5.0.0:
|
|||||||
|
|
||||||
pako@^2.0.4:
|
pako@^2.0.4:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86"
|
resolved "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz"
|
||||||
integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==
|
integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==
|
||||||
|
|
||||||
parent-module@^1.0.0:
|
parent-module@^1.0.0:
|
||||||
@ -3021,7 +3044,7 @@ parse-entities@^4.0.0:
|
|||||||
|
|
||||||
parse-headers@^2.0.2:
|
parse-headers@^2.0.2:
|
||||||
version "2.0.6"
|
version "2.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.6.tgz#7940f0abe5fe65df2dd25d4ce8800cb35b49d01c"
|
resolved "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.6.tgz"
|
||||||
integrity sha512-Tz11t3uKztEW5FEVZnj1ox8GKblWn+PvHY9TmJV5Mll2uHEwRdR/5Li1OlXoECjLYkApdhWy44ocONwXLiKO5A==
|
integrity sha512-Tz11t3uKztEW5FEVZnj1ox8GKblWn+PvHY9TmJV5Mll2uHEwRdR/5Li1OlXoECjLYkApdhWy44ocONwXLiKO5A==
|
||||||
|
|
||||||
parse-json@^5.0.0:
|
parse-json@^5.0.0:
|
||||||
@ -3071,7 +3094,7 @@ path@^0.12.7:
|
|||||||
|
|
||||||
pbf@4.0.1:
|
pbf@4.0.1:
|
||||||
version "4.0.1"
|
version "4.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/pbf/-/pbf-4.0.1.tgz#ad9015e022b235dcdbe05fc468a9acadf483f0d4"
|
resolved "https://registry.npmjs.org/pbf/-/pbf-4.0.1.tgz"
|
||||||
integrity sha512-SuLdBvS42z33m8ejRbInMapQe8n0D3vN/Xd5fmWM3tufNgRQFBpaW2YVJxQZV4iPNqb0vEFvssMEo5w9c6BTIA==
|
integrity sha512-SuLdBvS42z33m8ejRbInMapQe8n0D3vN/Xd5fmWM3tufNgRQFBpaW2YVJxQZV4iPNqb0vEFvssMEo5w9c6BTIA==
|
||||||
dependencies:
|
dependencies:
|
||||||
resolve-protobuf-schema "^2.1.0"
|
resolve-protobuf-schema "^2.1.0"
|
||||||
@ -3110,7 +3133,7 @@ postcss@^8.5.3:
|
|||||||
|
|
||||||
potpack@^1.0.1:
|
potpack@^1.0.1:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/potpack/-/potpack-1.0.2.tgz#23b99e64eb74f5741ffe7656b5b5c4ddce8dfc14"
|
resolved "https://registry.npmjs.org/potpack/-/potpack-1.0.2.tgz"
|
||||||
integrity sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==
|
integrity sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==
|
||||||
|
|
||||||
prelude-ls@^1.2.1:
|
prelude-ls@^1.2.1:
|
||||||
@ -3125,7 +3148,7 @@ process@^0.11.1:
|
|||||||
|
|
||||||
promise-worker-transferable@^1.0.4:
|
promise-worker-transferable@^1.0.4:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/promise-worker-transferable/-/promise-worker-transferable-1.0.4.tgz#2c72861ba053e5ae42b487b4a83b1ed3ae3786e8"
|
resolved "https://registry.npmjs.org/promise-worker-transferable/-/promise-worker-transferable-1.0.4.tgz"
|
||||||
integrity sha512-bN+0ehEnrXfxV2ZQvU2PetO0n4gqBD4ulq3MI1WOPLgr7/Mg9yRQkX5+0v1vagr74ZTsl7XtzlaYDo2EuCeYJw==
|
integrity sha512-bN+0ehEnrXfxV2ZQvU2PetO0n4gqBD4ulq3MI1WOPLgr7/Mg9yRQkX5+0v1vagr74ZTsl7XtzlaYDo2EuCeYJw==
|
||||||
dependencies:
|
dependencies:
|
||||||
is-promise "^2.1.0"
|
is-promise "^2.1.0"
|
||||||
@ -3152,12 +3175,12 @@ property-information@^7.0.0:
|
|||||||
|
|
||||||
protocol-buffers-schema@^3.3.1:
|
protocol-buffers-schema@^3.3.1:
|
||||||
version "3.6.0"
|
version "3.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz#77bc75a48b2ff142c1ad5b5b90c94cd0fa2efd03"
|
resolved "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz"
|
||||||
integrity sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==
|
integrity sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==
|
||||||
|
|
||||||
proxy-from-env@^1.1.0:
|
proxy-from-env@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
|
resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz"
|
||||||
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
|
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
|
||||||
|
|
||||||
punycode@^2.1.0:
|
punycode@^2.1.0:
|
||||||
@ -3172,17 +3195,22 @@ queue-microtask@^1.2.2:
|
|||||||
|
|
||||||
quick-lru@^6.1.1:
|
quick-lru@^6.1.1:
|
||||||
version "6.1.2"
|
version "6.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-6.1.2.tgz#e9a90524108629be35287d0b864e7ad6ceb3659e"
|
resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-6.1.2.tgz"
|
||||||
integrity sha512-AAFUA5O1d83pIHEhJwWCq/RQcRukCkn/NSm2QsTEMle5f2hP0ChI2+3Xb051PZCkLryI/Ir1MVKviT2FIloaTQ==
|
integrity sha512-AAFUA5O1d83pIHEhJwWCq/RQcRukCkn/NSm2QsTEMle5f2hP0ChI2+3Xb051PZCkLryI/Ir1MVKviT2FIloaTQ==
|
||||||
|
|
||||||
quickselect@^3.0.0:
|
quickselect@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/quickselect/-/quickselect-3.0.0.tgz#a37fc953867d56f095a20ac71c6d27063d2de603"
|
resolved "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz"
|
||||||
integrity sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==
|
integrity sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==
|
||||||
|
|
||||||
|
raf-schd@^4.0.3:
|
||||||
|
version "4.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/raf-schd/-/raf-schd-4.0.3.tgz#5d6c34ef46f8b2a0e880a8fcdb743efc5bfdbc1a"
|
||||||
|
integrity sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==
|
||||||
|
|
||||||
rbush@^4.0.0:
|
rbush@^4.0.0:
|
||||||
version "4.0.1"
|
version "4.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/rbush/-/rbush-4.0.1.tgz#1f55afa64a978f71bf9e9a99bc14ff84f3cb0d6d"
|
resolved "https://registry.npmjs.org/rbush/-/rbush-4.0.1.tgz"
|
||||||
integrity sha512-IP0UpfeWQujYC8Jg162rMNc01Rf0gWMMAb2Uxus/Q0qOFw4lCcq6ZnQEZwUoJqWyUGJ9th7JjwI4yIWo+uvoAQ==
|
integrity sha512-IP0UpfeWQujYC8Jg162rMNc01Rf0gWMMAb2Uxus/Q0qOFw4lCcq6ZnQEZwUoJqWyUGJ9th7JjwI4yIWo+uvoAQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
quickselect "^3.0.0"
|
quickselect "^3.0.0"
|
||||||
@ -3196,7 +3224,7 @@ react-dom@^19.1.0:
|
|||||||
|
|
||||||
react-dropzone@^14.3.8:
|
react-dropzone@^14.3.8:
|
||||||
version "14.3.8"
|
version "14.3.8"
|
||||||
resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-14.3.8.tgz#a7eab118f8a452fe3f8b162d64454e81ba830582"
|
resolved "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.3.8.tgz"
|
||||||
integrity sha512-sBgODnq+lcA4P296DY4wacOZz3JFpD99fp+hb//iBO2HHnyeZU3FwWyXJ6salNpqQdsZrgMrotuko/BdJMV8Ug==
|
integrity sha512-sBgODnq+lcA4P296DY4wacOZz3JFpD99fp+hb//iBO2HHnyeZU3FwWyXJ6salNpqQdsZrgMrotuko/BdJMV8Ug==
|
||||||
dependencies:
|
dependencies:
|
||||||
attr-accept "^2.2.4"
|
attr-accept "^2.2.4"
|
||||||
@ -3232,34 +3260,42 @@ react-markdown@^10.1.0:
|
|||||||
|
|
||||||
react-photo-sphere-viewer@^6.2.3:
|
react-photo-sphere-viewer@^6.2.3:
|
||||||
version "6.2.3"
|
version "6.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/react-photo-sphere-viewer/-/react-photo-sphere-viewer-6.2.3.tgz#bdbe33a03315077b1d49f2d4690f0dc72563ac9a"
|
resolved "https://registry.npmjs.org/react-photo-sphere-viewer/-/react-photo-sphere-viewer-6.2.3.tgz"
|
||||||
integrity sha512-VzG0aY9CI8OIQjdIoJCjYF1QlnLFpN2pM+zKm1JrpAKQrBZ6B+Uxy94vpVQkGDERgn8FWE0+LIntTgAr60pLyQ==
|
integrity sha512-VzG0aY9CI8OIQjdIoJCjYF1QlnLFpN2pM+zKm1JrpAKQrBZ6B+Uxy94vpVQkGDERgn8FWE0+LIntTgAr60pLyQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
eventemitter3 "^5.0.1"
|
eventemitter3 "^5.0.1"
|
||||||
|
|
||||||
react-reconciler@^0.31.0:
|
react-reconciler@^0.31.0:
|
||||||
version "0.31.0"
|
version "0.31.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-reconciler/-/react-reconciler-0.31.0.tgz#6b7390fe8fab59210daf523d7400943973de1458"
|
resolved "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.31.0.tgz"
|
||||||
integrity sha512-7Ob7Z+URmesIsIVRjnLoDGwBEG/tVitidU0nMsqX/eeJaLY89RISO/10ERe0MqmzuKUUB1rmY+h1itMbUHg9BQ==
|
integrity sha512-7Ob7Z+URmesIsIVRjnLoDGwBEG/tVitidU0nMsqX/eeJaLY89RISO/10ERe0MqmzuKUUB1rmY+h1itMbUHg9BQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
scheduler "^0.25.0"
|
scheduler "^0.25.0"
|
||||||
|
|
||||||
|
react-redux@^9.2.0:
|
||||||
|
version "9.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-9.2.0.tgz#96c3ab23fb9a3af2cb4654be4b51c989e32366f5"
|
||||||
|
integrity sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==
|
||||||
|
dependencies:
|
||||||
|
"@types/use-sync-external-store" "^0.0.6"
|
||||||
|
use-sync-external-store "^1.4.0"
|
||||||
|
|
||||||
react-refresh@^0.17.0:
|
react-refresh@^0.17.0:
|
||||||
version "0.17.0"
|
version "0.17.0"
|
||||||
resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz"
|
resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz"
|
||||||
integrity sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==
|
integrity sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==
|
||||||
|
|
||||||
react-router-dom@^7.6.1:
|
react-router-dom@^7.6.1:
|
||||||
version "7.6.1"
|
version "7.6.2"
|
||||||
resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.6.1.tgz"
|
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-7.6.2.tgz#e97e386ab390b6503a2a7968124b7a3237fb10c7"
|
||||||
integrity sha512-vxU7ei//UfPYQ3iZvHuO1D/5fX3/JOqhNTbRR+WjSBWxf9bIvpWK+ftjmdfJHzPOuMQKe2fiEdG+dZX6E8uUpA==
|
integrity sha512-Q8zb6VlTbdYKK5JJBLQEN06oTUa/RAbG/oQS1auK1I0TbJOXktqm+QENEVJU6QvWynlXPRBXI3fiOQcSEA78rA==
|
||||||
dependencies:
|
dependencies:
|
||||||
react-router "7.6.1"
|
react-router "7.6.2"
|
||||||
|
|
||||||
react-router@7.6.1:
|
react-router@7.6.2:
|
||||||
version "7.6.1"
|
version "7.6.2"
|
||||||
resolved "https://registry.npmjs.org/react-router/-/react-router-7.6.1.tgz"
|
resolved "https://registry.yarnpkg.com/react-router/-/react-router-7.6.2.tgz#9f48b343bead7d0a94e28342fc4f9ae29131520e"
|
||||||
integrity sha512-hPJXXxHJZEsPFNVbtATH7+MMX43UDeOauz+EAU4cgqTn7ojdI9qQORqS8Z0qmDlL1TclO/6jLRYUEtbWidtdHQ==
|
integrity sha512-U7Nv3y+bMimgWjhlT5CRdzHPu2/KVmqPwKUCChW8en5P3znxUqwlYFlbmyj8Rgp1SF6zs5X4+77kBVknkg6a0w==
|
||||||
dependencies:
|
dependencies:
|
||||||
cookie "^1.0.1"
|
cookie "^1.0.1"
|
||||||
set-cookie-parser "^2.6.0"
|
set-cookie-parser "^2.6.0"
|
||||||
@ -3273,7 +3309,7 @@ react-simplemde-editor@^5.2.0:
|
|||||||
|
|
||||||
react-toastify@^11.0.5:
|
react-toastify@^11.0.5:
|
||||||
version "11.0.5"
|
version "11.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/react-toastify/-/react-toastify-11.0.5.tgz#ce4c42d10eeb433988ab2264d3e445c4e9d13313"
|
resolved "https://registry.npmjs.org/react-toastify/-/react-toastify-11.0.5.tgz"
|
||||||
integrity sha512-EpqHBGvnSTtHYhCPLxML05NLY2ZX0JURbAdNYa6BUkk+amz4wbKBQvoKQAB0ardvSarUBuY4Q4s1sluAzZwkmA==
|
integrity sha512-EpqHBGvnSTtHYhCPLxML05NLY2ZX0JURbAdNYa6BUkk+amz4wbKBQvoKQAB0ardvSarUBuY4Q4s1sluAzZwkmA==
|
||||||
dependencies:
|
dependencies:
|
||||||
clsx "^2.1.1"
|
clsx "^2.1.1"
|
||||||
@ -3290,7 +3326,7 @@ react-transition-group@^4.4.5:
|
|||||||
|
|
||||||
react-use-measure@^2.1.7:
|
react-use-measure@^2.1.7:
|
||||||
version "2.1.7"
|
version "2.1.7"
|
||||||
resolved "https://registry.yarnpkg.com/react-use-measure/-/react-use-measure-2.1.7.tgz#36b8a2e7fd2fa58109ab851b3addcb0aad66ad1d"
|
resolved "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.7.tgz"
|
||||||
integrity sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==
|
integrity sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==
|
||||||
|
|
||||||
react@^19.1.0:
|
react@^19.1.0:
|
||||||
@ -3298,6 +3334,11 @@ react@^19.1.0:
|
|||||||
resolved "https://registry.npmjs.org/react/-/react-19.1.0.tgz"
|
resolved "https://registry.npmjs.org/react/-/react-19.1.0.tgz"
|
||||||
integrity sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==
|
integrity sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==
|
||||||
|
|
||||||
|
redux@^5.0.1:
|
||||||
|
version "5.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/redux/-/redux-5.0.1.tgz#97fa26881ce5746500125585d5642c77b6e9447b"
|
||||||
|
integrity sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==
|
||||||
|
|
||||||
rehype-raw@^7.0.0:
|
rehype-raw@^7.0.0:
|
||||||
version "7.0.0"
|
version "7.0.0"
|
||||||
resolved "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz"
|
resolved "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz"
|
||||||
@ -3330,7 +3371,7 @@ remark-rehype@^11.0.0:
|
|||||||
|
|
||||||
require-from-string@^2.0.2:
|
require-from-string@^2.0.2:
|
||||||
version "2.0.2"
|
version "2.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
|
resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz"
|
||||||
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
|
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
|
||||||
|
|
||||||
resolve-from@^4.0.0:
|
resolve-from@^4.0.0:
|
||||||
@ -3340,7 +3381,7 @@ resolve-from@^4.0.0:
|
|||||||
|
|
||||||
resolve-protobuf-schema@^2.1.0:
|
resolve-protobuf-schema@^2.1.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz#9ca9a9e69cf192bbdaf1006ec1973948aa4a3758"
|
resolved "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz"
|
||||||
integrity sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==
|
integrity sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
protocol-buffers-schema "^3.3.1"
|
protocol-buffers-schema "^3.3.1"
|
||||||
@ -3397,7 +3438,7 @@ run-parallel@^1.1.9:
|
|||||||
|
|
||||||
scheduler@^0.25.0:
|
scheduler@^0.25.0:
|
||||||
version "0.25.0"
|
version "0.25.0"
|
||||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.25.0.tgz#336cd9768e8cceebf52d3c80e3dcf5de23e7e015"
|
resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0.tgz"
|
||||||
integrity sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==
|
integrity sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==
|
||||||
|
|
||||||
scheduler@^0.26.0:
|
scheduler@^0.26.0:
|
||||||
@ -3417,7 +3458,7 @@ semver@^7.6.0:
|
|||||||
|
|
||||||
set-cookie-parser@^2.6.0:
|
set-cookie-parser@^2.6.0:
|
||||||
version "2.7.1"
|
version "2.7.1"
|
||||||
resolved "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz"
|
resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz#3016f150072202dfbe90fadee053573cc89d2943"
|
||||||
integrity sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==
|
integrity sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==
|
||||||
|
|
||||||
shebang-command@^2.0.0:
|
shebang-command@^2.0.0:
|
||||||
@ -3449,7 +3490,7 @@ space-separated-tokens@^2.0.0:
|
|||||||
|
|
||||||
stats-gl@^2.2.8:
|
stats-gl@^2.2.8:
|
||||||
version "2.4.2"
|
version "2.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/stats-gl/-/stats-gl-2.4.2.tgz#28a6c869fc3a36a8be608ef21df63c0aad99d1ba"
|
resolved "https://registry.npmjs.org/stats-gl/-/stats-gl-2.4.2.tgz"
|
||||||
integrity sha512-g5O9B0hm9CvnM36+v7SFl39T7hmAlv541tU81ME8YeSb3i1CIP5/QdDeSB3A0la0bKNHpxpwxOVRo2wFTYEosQ==
|
integrity sha512-g5O9B0hm9CvnM36+v7SFl39T7hmAlv541tU81ME8YeSb3i1CIP5/QdDeSB3A0la0bKNHpxpwxOVRo2wFTYEosQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/three" "*"
|
"@types/three" "*"
|
||||||
@ -3457,7 +3498,7 @@ stats-gl@^2.2.8:
|
|||||||
|
|
||||||
stats.js@^0.17.0:
|
stats.js@^0.17.0:
|
||||||
version "0.17.0"
|
version "0.17.0"
|
||||||
resolved "https://registry.yarnpkg.com/stats.js/-/stats.js-0.17.0.tgz#b1c3dc46d94498b578b7fd3985b81ace7131cc7d"
|
resolved "https://registry.npmjs.org/stats.js/-/stats.js-0.17.0.tgz"
|
||||||
integrity sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==
|
integrity sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==
|
||||||
|
|
||||||
stringify-entities@^4.0.0:
|
stringify-entities@^4.0.0:
|
||||||
@ -3506,7 +3547,7 @@ supports-preserve-symlinks-flag@^1.0.0:
|
|||||||
|
|
||||||
suspend-react@^0.1.3:
|
suspend-react@^0.1.3:
|
||||||
version "0.1.3"
|
version "0.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/suspend-react/-/suspend-react-0.1.3.tgz#a52f49d21cfae9a2fb70bd0c68413d3f9d90768e"
|
resolved "https://registry.npmjs.org/suspend-react/-/suspend-react-0.1.3.tgz"
|
||||||
integrity sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ==
|
integrity sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ==
|
||||||
|
|
||||||
tailwindcss@4.1.8, tailwindcss@^4.1.8:
|
tailwindcss@4.1.8, tailwindcss@^4.1.8:
|
||||||
@ -3533,12 +3574,12 @@ tar@^7.4.3:
|
|||||||
|
|
||||||
three-mesh-bvh@^0.8.3:
|
three-mesh-bvh@^0.8.3:
|
||||||
version "0.8.3"
|
version "0.8.3"
|
||||||
resolved "https://registry.yarnpkg.com/three-mesh-bvh/-/three-mesh-bvh-0.8.3.tgz#c5e72472e7f062ff79084157a25c122d73184163"
|
resolved "https://registry.npmjs.org/three-mesh-bvh/-/three-mesh-bvh-0.8.3.tgz"
|
||||||
integrity sha512-4G5lBaF+g2auKX3P0yqx+MJC6oVt6sB5k+CchS6Ob0qvH0YIhuUk1eYr7ktsIpY+albCqE80/FVQGV190PmiAg==
|
integrity sha512-4G5lBaF+g2auKX3P0yqx+MJC6oVt6sB5k+CchS6Ob0qvH0YIhuUk1eYr7ktsIpY+albCqE80/FVQGV190PmiAg==
|
||||||
|
|
||||||
three-stdlib@^2.35.6:
|
three-stdlib@^2.35.6:
|
||||||
version "2.36.0"
|
version "2.36.0"
|
||||||
resolved "https://registry.yarnpkg.com/three-stdlib/-/three-stdlib-2.36.0.tgz#1d806b8db9156a6c87ed10f61f56f8a3ab634b42"
|
resolved "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.36.0.tgz"
|
||||||
integrity sha512-kv0Byb++AXztEGsULgMAs8U2jgUdz6HPpAB/wDJnLiLlaWQX2APHhiTJIN7rqW+Of0eRgcp7jn05U1BsCP3xBA==
|
integrity sha512-kv0Byb++AXztEGsULgMAs8U2jgUdz6HPpAB/wDJnLiLlaWQX2APHhiTJIN7rqW+Of0eRgcp7jn05U1BsCP3xBA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/draco3d" "^1.4.0"
|
"@types/draco3d" "^1.4.0"
|
||||||
@ -3550,19 +3591,24 @@ three-stdlib@^2.35.6:
|
|||||||
|
|
||||||
three@^0.170.0:
|
three@^0.170.0:
|
||||||
version "0.170.0"
|
version "0.170.0"
|
||||||
resolved "https://registry.yarnpkg.com/three/-/three-0.170.0.tgz#6087f97aab79e9e9312f9c89fcef6808642dfbb7"
|
resolved "https://registry.npmjs.org/three/-/three-0.170.0.tgz"
|
||||||
integrity sha512-FQK+LEpYc0fBD+J8g6oSEyyNzjp+Q7Ks1C568WWaoMRLW+TkNNWmenWeGgJjV105Gd+p/2ql1ZcjYvNiPZBhuQ==
|
integrity sha512-FQK+LEpYc0fBD+J8g6oSEyyNzjp+Q7Ks1C568WWaoMRLW+TkNNWmenWeGgJjV105Gd+p/2ql1ZcjYvNiPZBhuQ==
|
||||||
|
|
||||||
three@^0.175.0:
|
three@^0.175.0:
|
||||||
version "0.175.0"
|
version "0.175.0"
|
||||||
resolved "https://registry.yarnpkg.com/three/-/three-0.175.0.tgz#67b357b0b1ee8ef0445b9a768f59363ab1fa7921"
|
resolved "https://registry.npmjs.org/three/-/three-0.175.0.tgz"
|
||||||
integrity sha512-nNE3pnTHxXN/Phw768u0Grr7W4+rumGg/H6PgeseNJojkJtmeHJfZWi41Gp2mpXl1pg1pf1zjwR4McM1jTqkpg==
|
integrity sha512-nNE3pnTHxXN/Phw768u0Grr7W4+rumGg/H6PgeseNJojkJtmeHJfZWi41Gp2mpXl1pg1pf1zjwR4McM1jTqkpg==
|
||||||
|
|
||||||
three@^0.177.0:
|
three@^0.177.0:
|
||||||
version "0.177.0"
|
version "0.177.0"
|
||||||
resolved "https://registry.yarnpkg.com/three/-/three-0.177.0.tgz#e51f2eb2b921fbab535bdfa81c403f9993b9dd83"
|
resolved "https://registry.npmjs.org/three/-/three-0.177.0.tgz"
|
||||||
integrity sha512-EiXv5/qWAaGI+Vz2A+JfavwYCMdGjxVsrn3oBwllUoqYeaBO75J63ZfyaQKoiLrqNHoTlUc6PFgMXnS0kI45zg==
|
integrity sha512-EiXv5/qWAaGI+Vz2A+JfavwYCMdGjxVsrn3oBwllUoqYeaBO75J63ZfyaQKoiLrqNHoTlUc6PFgMXnS0kI45zg==
|
||||||
|
|
||||||
|
tiny-invariant@^1.0.6:
|
||||||
|
version "1.3.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127"
|
||||||
|
integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==
|
||||||
|
|
||||||
tinyglobby@^0.2.13:
|
tinyglobby@^0.2.13:
|
||||||
version "0.2.14"
|
version "0.2.14"
|
||||||
resolved "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz"
|
resolved "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz"
|
||||||
@ -3585,7 +3631,7 @@ trim-lines@^3.0.0:
|
|||||||
|
|
||||||
troika-three-text@^0.52.4:
|
troika-three-text@^0.52.4:
|
||||||
version "0.52.4"
|
version "0.52.4"
|
||||||
resolved "https://registry.yarnpkg.com/troika-three-text/-/troika-three-text-0.52.4.tgz#f7b2389a2067d9506a5757457771cf4f6356e738"
|
resolved "https://registry.npmjs.org/troika-three-text/-/troika-three-text-0.52.4.tgz"
|
||||||
integrity sha512-V50EwcYGruV5rUZ9F4aNsrytGdKcXKALjEtQXIOBfhVoZU9VAqZNIoGQ3TMiooVqFAbR1w15T+f+8gkzoFzawg==
|
integrity sha512-V50EwcYGruV5rUZ9F4aNsrytGdKcXKALjEtQXIOBfhVoZU9VAqZNIoGQ3TMiooVqFAbR1w15T+f+8gkzoFzawg==
|
||||||
dependencies:
|
dependencies:
|
||||||
bidi-js "^1.0.2"
|
bidi-js "^1.0.2"
|
||||||
@ -3595,12 +3641,12 @@ troika-three-text@^0.52.4:
|
|||||||
|
|
||||||
troika-three-utils@^0.52.4:
|
troika-three-utils@^0.52.4:
|
||||||
version "0.52.4"
|
version "0.52.4"
|
||||||
resolved "https://registry.yarnpkg.com/troika-three-utils/-/troika-three-utils-0.52.4.tgz#9292019e93cab97582af1cf491c4c895e5c03b66"
|
resolved "https://registry.npmjs.org/troika-three-utils/-/troika-three-utils-0.52.4.tgz"
|
||||||
integrity sha512-NORAStSVa/BDiG52Mfudk4j1FG4jC4ILutB3foPnfGbOeIs9+G5vZLa0pnmnaftZUGm4UwSoqEpWdqvC7zms3A==
|
integrity sha512-NORAStSVa/BDiG52Mfudk4j1FG4jC4ILutB3foPnfGbOeIs9+G5vZLa0pnmnaftZUGm4UwSoqEpWdqvC7zms3A==
|
||||||
|
|
||||||
troika-worker-utils@^0.52.0:
|
troika-worker-utils@^0.52.0:
|
||||||
version "0.52.0"
|
version "0.52.0"
|
||||||
resolved "https://registry.yarnpkg.com/troika-worker-utils/-/troika-worker-utils-0.52.0.tgz#ba5525fc444345006ebab0bc9cabdd66f1561e66"
|
resolved "https://registry.npmjs.org/troika-worker-utils/-/troika-worker-utils-0.52.0.tgz"
|
||||||
integrity sha512-W1CpvTHykaPH5brv5VHLfQo9D1OYuo0cSBEUQFFT/nBUzM8iD6Lq2/tgG/f1OelbAS1WtaTPQzE5uM49egnngw==
|
integrity sha512-W1CpvTHykaPH5brv5VHLfQo9D1OYuo0cSBEUQFFT/nBUzM8iD6Lq2/tgG/f1OelbAS1WtaTPQzE5uM49egnngw==
|
||||||
|
|
||||||
trough@^2.0.0:
|
trough@^2.0.0:
|
||||||
@ -3620,7 +3666,7 @@ tslib@^2.4.0, tslib@^2.7.0, tslib@^2.8.0:
|
|||||||
|
|
||||||
tunnel-rat@^0.1.2:
|
tunnel-rat@^0.1.2:
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/tunnel-rat/-/tunnel-rat-0.1.2.tgz#1717efbc474ea2d8aa05a91622457a6e201c0aeb"
|
resolved "https://registry.npmjs.org/tunnel-rat/-/tunnel-rat-0.1.2.tgz"
|
||||||
integrity sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ==
|
integrity sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
zustand "^4.3.2"
|
zustand "^4.3.2"
|
||||||
@ -3741,7 +3787,7 @@ util@^0.10.3:
|
|||||||
|
|
||||||
utility-types@^3.11.0:
|
utility-types@^3.11.0:
|
||||||
version "3.11.0"
|
version "3.11.0"
|
||||||
resolved "https://registry.yarnpkg.com/utility-types/-/utility-types-3.11.0.tgz#607c40edb4f258915e901ea7995607fdf319424c"
|
resolved "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz"
|
||||||
integrity sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==
|
integrity sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==
|
||||||
|
|
||||||
vfile-location@^5.0.0:
|
vfile-location@^5.0.0:
|
||||||
@ -3789,17 +3835,17 @@ web-namespaces@^2.0.0:
|
|||||||
|
|
||||||
web-worker@^1.2.0:
|
web-worker@^1.2.0:
|
||||||
version "1.5.0"
|
version "1.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/web-worker/-/web-worker-1.5.0.tgz#71b2b0fbcc4293e8f0aa4f6b8a3ffebff733dcc5"
|
resolved "https://registry.npmjs.org/web-worker/-/web-worker-1.5.0.tgz"
|
||||||
integrity sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==
|
integrity sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==
|
||||||
|
|
||||||
webgl-constants@^1.1.1:
|
webgl-constants@^1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/webgl-constants/-/webgl-constants-1.1.1.tgz#f9633ee87fea56647a60b9ce735cbdfb891c6855"
|
resolved "https://registry.npmjs.org/webgl-constants/-/webgl-constants-1.1.1.tgz"
|
||||||
integrity sha512-LkBXKjU5r9vAW7Gcu3T5u+5cvSvh5WwINdr0C+9jpzVB41cjQAP5ePArDtk/WHYdVj0GefCgM73BA7FlIiNtdg==
|
integrity sha512-LkBXKjU5r9vAW7Gcu3T5u+5cvSvh5WwINdr0C+9jpzVB41cjQAP5ePArDtk/WHYdVj0GefCgM73BA7FlIiNtdg==
|
||||||
|
|
||||||
webgl-sdf-generator@1.1.1:
|
webgl-sdf-generator@1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/webgl-sdf-generator/-/webgl-sdf-generator-1.1.1.tgz#3e1b422b3d87cd3cc77f2602c9db63bc0f6accbd"
|
resolved "https://registry.npmjs.org/webgl-sdf-generator/-/webgl-sdf-generator-1.1.1.tgz"
|
||||||
integrity sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA==
|
integrity sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA==
|
||||||
|
|
||||||
which@^2.0.1:
|
which@^2.0.1:
|
||||||
@ -3816,7 +3862,7 @@ word-wrap@^1.2.5:
|
|||||||
|
|
||||||
xml-utils@^1.0.2:
|
xml-utils@^1.0.2:
|
||||||
version "1.10.2"
|
version "1.10.2"
|
||||||
resolved "https://registry.yarnpkg.com/xml-utils/-/xml-utils-1.10.2.tgz#436b39ccc25a663ce367ea21abb717afdea5d6b1"
|
resolved "https://registry.npmjs.org/xml-utils/-/xml-utils-1.10.2.tgz"
|
||||||
integrity sha512-RqM+2o1RYs6T8+3DzDSoTRAUfrvaejbVHcp3+thnAtDKo8LskR+HomLajEy5UjTz24rpka7AxVBRR3g2wTUkJA==
|
integrity sha512-RqM+2o1RYs6T8+3DzDSoTRAUfrvaejbVHcp3+thnAtDKo8LskR+HomLajEy5UjTz24rpka7AxVBRR3g2wTUkJA==
|
||||||
|
|
||||||
yallist@^3.0.2:
|
yallist@^3.0.2:
|
||||||
@ -3841,19 +3887,19 @@ yocto-queue@^0.1.0:
|
|||||||
|
|
||||||
zstddec@^0.1.0:
|
zstddec@^0.1.0:
|
||||||
version "0.1.0"
|
version "0.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/zstddec/-/zstddec-0.1.0.tgz#7050f3f0e0c3978562d0c566b3e5a427d2bad7ec"
|
resolved "https://registry.npmjs.org/zstddec/-/zstddec-0.1.0.tgz"
|
||||||
integrity sha512-w2NTI8+3l3eeltKAdK8QpiLo/flRAr2p8AGeakfMZOXBxOg9HIu4LVDxBi81sYgVhFhdJjv1OrB5ssI8uFPoLg==
|
integrity sha512-w2NTI8+3l3eeltKAdK8QpiLo/flRAr2p8AGeakfMZOXBxOg9HIu4LVDxBi81sYgVhFhdJjv1OrB5ssI8uFPoLg==
|
||||||
|
|
||||||
zustand@^4.3.2:
|
zustand@^4.3.2:
|
||||||
version "4.5.7"
|
version "4.5.7"
|
||||||
resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.5.7.tgz#7d6bb2026a142415dd8be8891d7870e6dbe65f55"
|
resolved "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz"
|
||||||
integrity sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==
|
integrity sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==
|
||||||
dependencies:
|
dependencies:
|
||||||
use-sync-external-store "^1.2.2"
|
use-sync-external-store "^1.2.2"
|
||||||
|
|
||||||
zustand@^5.0.1, zustand@^5.0.3:
|
zustand@^5.0.1, zustand@^5.0.3:
|
||||||
version "5.0.5"
|
version "5.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/zustand/-/zustand-5.0.5.tgz#3e236f6a953142d975336d179bc735d97db17e84"
|
resolved "https://registry.npmjs.org/zustand/-/zustand-5.0.5.tgz"
|
||||||
integrity sha512-mILtRfKW9xM47hqxGIxCv12gXusoY/xTSHBYApXozR0HmQv299whhBeeAcRy+KrPPybzosvJBCOmVjq6x12fCg==
|
integrity sha512-mILtRfKW9xM47hqxGIxCv12gXusoY/xTSHBYApXozR0HmQv299whhBeeAcRy+KrPPybzosvJBCOmVjq6x12fCg==
|
||||||
|
|
||||||
zwitch@^2.0.0:
|
zwitch@^2.0.0:
|
||||||
|
Loading…
Reference in New Issue
Block a user