diff --git a/package.json b/package.json
index bb35152..5076d9e 100644
--- a/package.json
+++ b/package.json
@@ -17,6 +17,7 @@
"@mui/material": "^7.1.0",
"@mui/x-data-grid": "^8.5.1",
"@photo-sphere-viewer/core": "^5.13.2",
+ "@pixi/react": "^8.0.2",
"@react-three/drei": "^10.1.2",
"@react-three/fiber": "^9.1.2",
"@tailwindcss/vite": "^4.1.8",
@@ -27,6 +28,7 @@
"mobx-react-lite": "^4.1.0",
"ol": "^10.5.0",
"path": "^0.12.7",
+ "pixi.js": "^8.10.1",
"react": "^19.1.0",
"react-colorful": "^5.6.1",
"react-dom": "^19.1.0",
diff --git a/src/app/router/index.tsx b/src/app/router/index.tsx
index b698aa2..8f77f1b 100644
--- a/src/app/router/index.tsx
+++ b/src/app/router/index.tsx
@@ -37,6 +37,7 @@ import {
StationPreviewPage,
StationEditPage,
RouteCreatePage,
+ RoutePreview,
} from "@pages";
import { authStore, createSightStore, editSightStore } from "@shared";
import { Layout } from "@widgets";
@@ -140,6 +141,7 @@ const router = createBrowserRouter([
// Route
{ path: "route", element: },
{ path: "route/create", element: },
+ { path: "route-preview/:id", element: },
// User
{ path: "user", element: },
diff --git a/src/pages/Route/index.ts b/src/pages/Route/index.ts
index b9991ad..2b54a5a 100644
--- a/src/pages/Route/index.ts
+++ b/src/pages/Route/index.ts
@@ -1,2 +1,3 @@
export * from "./RouteListPage";
export * from "./RouteCreatePage";
+export { RoutePreview } from "./route-preview";
diff --git a/src/pages/Route/route-preview/Constants.ts b/src/pages/Route/route-preview/Constants.ts
new file mode 100644
index 0000000..a4b646f
--- /dev/null
+++ b/src/pages/Route/route-preview/Constants.ts
@@ -0,0 +1,9 @@
+export const UP_SCALE = 30000;
+export const PATH_WIDTH = 15;
+export const STATION_RADIUS = 20;
+export const STATION_OUTLINE_WIDTH = 10;
+export const SIGHT_SIZE = 60;
+export const SCALE_FACTOR = 50;
+
+export const BACKGROUND_COLOR = 0x111111;
+export const PATH_COLOR = 0xff4d4d;
\ No newline at end of file
diff --git a/src/pages/Route/route-preview/InfiniteCanvas.tsx b/src/pages/Route/route-preview/InfiniteCanvas.tsx
new file mode 100644
index 0000000..516d307
--- /dev/null
+++ b/src/pages/Route/route-preview/InfiniteCanvas.tsx
@@ -0,0 +1,230 @@
+import { FederatedMouseEvent, FederatedWheelEvent } from "pixi.js";
+import { Component, ReactNode, useEffect, useState, useRef } from "react";
+import { useTransform } from "./TransformContext";
+import { useMapData } from "./MapDataContext";
+import { SCALE_FACTOR } from "./Constants";
+import { useApplication } from "@pixi/react";
+
+class ErrorBoundary extends Component<
+ { children: ReactNode },
+ { hasError: boolean }
+> {
+ state = { hasError: false };
+
+ static getDerivedStateFromError() {
+ return { hasError: true };
+ }
+
+ componentDidCatch(error: Error, info: React.ErrorInfo) {
+ console.error("Error caught:", error, info);
+ }
+
+ render() {
+ return this.state.hasError ?
Whoopsie Daisy!
: this.props.children;
+ }
+}
+
+export function InfiniteCanvas({
+ children,
+}: Readonly<{ children?: ReactNode }>) {
+ const {
+ position,
+ setPosition,
+ scale,
+ setScale,
+ rotation,
+ setRotation,
+ setScreenCenter,
+ screenCenter,
+ } = useTransform();
+ const { routeData, originalRouteData } = useMapData();
+
+ const applicationRef = useApplication();
+
+ const [isDragging, setIsDragging] = useState(false);
+ const [startMousePosition, setStartMousePosition] = useState({ x: 0, y: 0 });
+ const [startRotation, setStartRotation] = useState(0);
+ const [startPosition, setStartPosition] = useState({ x: 0, y: 0 });
+
+ // Флаг для предотвращения конфликта между пользовательским вводом и данными маршрута
+ const [isUserInteracting, setIsUserInteracting] = useState(false);
+
+ // Реф для отслеживания последнего значения originalRouteData?.rotate
+ const lastOriginalRotation = useRef(undefined);
+
+ useEffect(() => {
+ const canvas = applicationRef?.app.canvas;
+ if (!canvas) return;
+
+ const canvasRect = canvas.getBoundingClientRect();
+ const canvasLeft = canvasRect.left;
+ const canvasTop = canvasRect.top;
+ const centerX = window.innerWidth / 2 - canvasLeft;
+ const centerY = window.innerHeight / 2 - canvasTop;
+ setScreenCenter({ x: centerX, y: centerY });
+ }, [applicationRef?.app.canvas, setScreenCenter]);
+
+ const handlePointerDown = (e: FederatedMouseEvent) => {
+ setIsDragging(true);
+ setIsUserInteracting(true); // Устанавливаем флаг взаимодействия пользователя
+ setStartPosition({
+ x: position.x,
+ y: position.y,
+ });
+ setStartMousePosition({
+ x: e.globalX,
+ y: e.globalY,
+ });
+ setStartRotation(rotation);
+ e.stopPropagation();
+ };
+
+ // Устанавливаем rotation только при изменении originalRouteData и отсутствии взаимодействия пользователя
+ useEffect(() => {
+ const newRotation = originalRouteData?.rotate ?? 0;
+
+ // Обновляем rotation только если:
+ // 1. Пользователь не взаимодействует с канвасом
+ // 2. Значение действительно изменилось
+ if (!isUserInteracting && lastOriginalRotation.current !== newRotation) {
+ setRotation((newRotation * Math.PI) / 180);
+ lastOriginalRotation.current = newRotation;
+ }
+ }, [originalRouteData?.rotate, isUserInteracting, setRotation]);
+
+ const handlePointerMove = (e: FederatedMouseEvent) => {
+ if (!isDragging) return;
+
+ if (e.shiftKey) {
+ const center = screenCenter ?? { x: 0, y: 0 };
+ const startAngle = Math.atan2(
+ startMousePosition.y - center.y,
+ startMousePosition.x - center.x
+ );
+ const currentAngle = Math.atan2(
+ e.globalY - center.y,
+ e.globalX - center.x
+ );
+
+ // Calculate rotation difference in radians
+ const rotationDiff = currentAngle - startAngle;
+
+ // Update rotation
+ setRotation(startRotation + rotationDiff);
+
+ const cosDelta = Math.cos(rotationDiff);
+ const sinDelta = Math.sin(rotationDiff);
+
+ setPosition({
+ x:
+ center.x * (1 - cosDelta) +
+ startPosition.x * cosDelta +
+ (center.y - startPosition.y) * sinDelta,
+ y:
+ center.y * (1 - cosDelta) +
+ startPosition.y * cosDelta +
+ (startPosition.x - center.x) * sinDelta,
+ });
+ } else {
+ setRotation(startRotation);
+ setPosition({
+ x: startPosition.x - startMousePosition.x + e.globalX,
+ y: startPosition.y - startMousePosition.y + e.globalY,
+ });
+ }
+ e.stopPropagation();
+ };
+
+ const handlePointerUp = (e: FederatedMouseEvent) => {
+ setIsDragging(false);
+ // Сбрасываем флаг взаимодействия через небольшую задержку
+ // чтобы избежать немедленного срабатывания useEffect
+ setTimeout(() => {
+ setIsUserInteracting(false);
+ }, 100);
+ e.stopPropagation();
+ };
+
+ const handleWheel = (e: FederatedWheelEvent) => {
+ e.stopPropagation();
+ setIsUserInteracting(true); // Устанавливаем флаг при зуме
+
+ // Get mouse position relative to canvas
+ const mouseX = e.globalX - position.x;
+ const mouseY = e.globalY - position.y;
+
+ // Calculate new scale
+ const scaleMin = (routeData?.scale_min ?? 10) / SCALE_FACTOR;
+ const scaleMax = (routeData?.scale_max ?? 20) / SCALE_FACTOR;
+
+ const zoomFactor = e.deltaY > 0 ? 0.9 : 1.1; // Zoom out/in
+ const newScale = Math.max(scaleMin, Math.min(scaleMax, scale * zoomFactor));
+ const actualZoomFactor = newScale / scale;
+
+ if (scale === newScale) {
+ // Сбрасываем флаг, если зум не изменился
+ setTimeout(() => {
+ setIsUserInteracting(false);
+ }, 100);
+ return;
+ }
+
+ // Update position to zoom towards mouse cursor
+ setPosition({
+ x: position.x + mouseX * (1 - actualZoomFactor),
+ y: position.y + mouseY * (1 - actualZoomFactor),
+ });
+
+ setScale(newScale);
+
+ // Сбрасываем флаг взаимодействия через задержку
+ setTimeout(() => {
+ setIsUserInteracting(false);
+ }, 100);
+ };
+
+ useEffect(() => {
+ applicationRef?.app.render();
+ console.log(position, scale, rotation);
+ }, [position, scale, rotation]);
+
+ return (
+
+ {applicationRef?.app && (
+ {
+ const canvas = applicationRef.app.canvas;
+ g.clear();
+ g.rect(0, 0, canvas?.width ?? 0, canvas?.height ?? 0);
+ g.fill("#111");
+ }}
+ eventMode={"static"}
+ interactive
+ onPointerDown={handlePointerDown}
+ onGlobalPointerMove={handlePointerMove}
+ onPointerUp={handlePointerUp}
+ onPointerUpOutside={handlePointerUp}
+ onWheel={handleWheel}
+ />
+ )}
+
+ {children}
+
+ {/* Show center of the screen.
+ {
+ g.clear();
+ const center = screenCenter ?? {x: 0, y: 0};
+ g.circle(center.x, center.y, 1);
+ g.fill("#fff");
+ }}
+ /> */}
+
+ );
+}
diff --git a/src/pages/Route/route-preview/LeftSidebar.tsx b/src/pages/Route/route-preview/LeftSidebar.tsx
new file mode 100644
index 0000000..0e87c0e
--- /dev/null
+++ b/src/pages/Route/route-preview/LeftSidebar.tsx
@@ -0,0 +1,89 @@
+import { Stack, Typography, Button } from "@mui/material";
+
+import { useNavigate, useNavigationType } from "react-router";
+
+export function LeftSidebar() {
+ const navigate = useNavigate();
+ const navigationType = useNavigationType(); // PUSH, POP, REPLACE
+
+ const handleBack = () => {
+ if (navigationType === "PUSH") {
+ navigate(-1);
+ } else {
+ navigate("/route");
+ }
+ };
+
+ return (
+
+
+
+
+
+
+ При поддержке Правительства Санкт-Петербурга
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #ВсемПоПути
+
+
+ );
+}
diff --git a/src/pages/Route/route-preview/MapDataContext.tsx b/src/pages/Route/route-preview/MapDataContext.tsx
new file mode 100644
index 0000000..dacb7ff
--- /dev/null
+++ b/src/pages/Route/route-preview/MapDataContext.tsx
@@ -0,0 +1,307 @@
+import { useParams } from "react-router";
+import { authInstance, languageInstance } from "@shared";
+import {
+ createContext,
+ ReactNode,
+ useContext,
+ useEffect,
+ useMemo,
+ useState,
+} from "react";
+import {
+ RouteData,
+ SightData,
+ SightPatchData,
+ StationData,
+ StationPatchData,
+} from "./types";
+
+import { observer } from "mobx-react-lite";
+
+const MapDataContext = createContext<{
+ originalRouteData?: RouteData;
+ originalStationData?: StationData[];
+ originalSightData?: SightData[];
+ routeData?: RouteData;
+ stationData?: StationDataWithLanguage;
+ sightData?: SightData[];
+
+ isRouteLoading: boolean;
+ isStationLoading: boolean;
+ isSightLoading: boolean;
+ setScaleRange: (min: number, max: number) => void;
+ setMapRotation: (rotation: number) => void;
+ setMapCenter: (x: number, y: number) => void;
+ setStationOffset: (stationId: number, x: number, y: number) => void;
+ setSightCoordinates: (
+ sightId: number,
+ latitude: number,
+ longitude: number
+ ) => void;
+ saveChanges: () => void;
+}>({
+ originalRouteData: undefined,
+ originalStationData: undefined,
+ originalSightData: undefined,
+ routeData: undefined,
+ stationData: undefined,
+ sightData: undefined,
+
+ isRouteLoading: true,
+ isStationLoading: true,
+ isSightLoading: true,
+ setScaleRange: () => {},
+ setMapRotation: () => {},
+ setMapCenter: () => {},
+ setStationOffset: () => {},
+ setSightCoordinates: () => {},
+ saveChanges: () => {},
+});
+
+type StationDataWithLanguage = {
+ [key: string]: StationData[];
+};
+export const MapDataProvider = observer(
+ ({ children }: Readonly<{ children: ReactNode }>) => {
+ const { id: routeId } = useParams<{ id: string }>();
+
+ const [originalRouteData, setOriginalRouteData] = useState();
+ const [originalStationData, setOriginalStationData] =
+ useState();
+ const [originalSightData, setOriginalSightData] = useState();
+
+ const [routeData, setRouteData] = useState();
+ const [stationData, setStationData] = useState({
+ RU: [],
+ EN: [],
+ ZH: [],
+ });
+ const [sightData, setSightData] = useState();
+
+ const [routeChanges, setRouteChanges] = useState>({});
+ const [stationChanges, setStationChanges] = useState(
+ []
+ );
+ const [sightChanges, setSightChanges] = useState([]);
+
+ const [isRouteLoading, setIsRouteLoading] = useState(true);
+ const [isStationLoading, setIsStationLoading] = useState(true);
+ const [isSightLoading, setIsSightLoading] = useState(true);
+
+ useEffect(() => {
+ const fetchData = async () => {
+ try {
+ setIsRouteLoading(true);
+ setIsStationLoading(true);
+ setIsSightLoading(true);
+
+ const [
+ routeResponse,
+ ruStationResponse,
+ enStationResponse,
+ zhStationResponse,
+ sightResponse,
+ ] = await Promise.all([
+ authInstance.get(`/route/${routeId}`),
+ languageInstance("ru").get(`/route/${routeId}/station`),
+ languageInstance("en").get(`/route/${routeId}/station`),
+ languageInstance("zh").get(`/route/${routeId}/station`),
+ authInstance.get(`/route/${routeId}/sight`),
+ ]);
+
+ setOriginalRouteData(routeResponse.data as RouteData);
+ setOriginalStationData(ruStationResponse.data as StationData[]);
+ setStationData({
+ ru: ruStationResponse.data as StationData[],
+ en: enStationResponse.data as StationData[],
+ zh: zhStationResponse.data as StationData[],
+ });
+ setOriginalSightData(sightResponse as unknown as SightData[]);
+
+ setIsRouteLoading(false);
+ setIsStationLoading(false);
+ setIsSightLoading(false);
+ } catch (error) {
+ console.error("Error fetching data:", error);
+ setIsRouteLoading(false);
+ setIsStationLoading(false);
+ setIsSightLoading(false);
+ }
+ };
+
+ fetchData();
+ }, [routeId]);
+
+ useEffect(() => {
+ // combine changes with original data
+ if (originalRouteData)
+ setRouteData({ ...originalRouteData, ...routeChanges });
+ if (originalSightData) setSightData(originalSightData);
+ }, [
+ originalRouteData,
+ originalSightData,
+ routeChanges,
+ stationChanges,
+ sightChanges,
+ ]);
+
+ function setScaleRange(min: number, max: number) {
+ setRouteChanges((prev) => {
+ return { ...prev, scale_min: min, scale_max: max };
+ });
+ }
+
+ function setMapRotation(rotation: number) {
+ setRouteChanges((prev) => {
+ return { ...prev, rotate: rotation };
+ });
+ }
+
+ function setMapCenter(x: number, y: number) {
+ setRouteChanges((prev) => {
+ return { ...prev, center_latitude: x, center_longitude: y };
+ });
+ }
+
+ async function saveChanges() {
+ await authInstance.patch(`/route/${routeId}`, routeData);
+ await saveStationChanges();
+ await saveSightChanges();
+ }
+
+ async function saveStationChanges() {
+ for (const station of stationChanges) {
+ const response = await authInstance.patch(
+ `/route/${routeId}/station`,
+ station
+ );
+ }
+ }
+
+ async function saveSightChanges() {
+ console.log("sightChanges", sightChanges);
+ for (const sight of sightChanges) {
+ const response = await authInstance.patch(
+ `/route/${routeId}/sight`,
+ sight
+ );
+ }
+ }
+
+ function setStationOffset(stationId: number, x: number, y: number) {
+ setStationChanges((prev) => {
+ let found = prev.find((station) => station.station_id === stationId);
+ if (found) {
+ found.offset_x = x;
+ found.offset_y = y;
+
+ return prev.map((station) => {
+ if (station.station_id === stationId) {
+ return found;
+ }
+ return station;
+ });
+ } else {
+ const foundStation = stationData.ru?.find(
+ (station) => station.id === stationId
+ );
+ if (foundStation) {
+ return [
+ ...prev,
+ {
+ station_id: stationId,
+ offset_x: x,
+ offset_y: y,
+ transfers: foundStation.transfers,
+ },
+ ];
+ }
+ return prev;
+ }
+ });
+ }
+
+ function setSightCoordinates(
+ sightId: number,
+ latitude: number,
+ longitude: number
+ ) {
+ setSightChanges((prev) => {
+ let found = prev.find((sight) => sight.sight_id === sightId);
+ if (found) {
+ found.latitude = latitude;
+ found.longitude = longitude;
+
+ return prev.map((sight) => {
+ if (sight.sight_id === sightId) {
+ return found;
+ }
+ return sight;
+ });
+ } else {
+ const foundSight = sightData?.find((sight) => sight.id === sightId);
+ if (foundSight) {
+ return [
+ ...prev,
+ {
+ sight_id: sightId,
+ latitude,
+ longitude,
+ },
+ ];
+ }
+ return prev;
+ }
+ });
+ }
+
+ useEffect(() => {
+ console.log("sightChanges", sightChanges);
+ }, [sightChanges]);
+
+ const value = useMemo(
+ () => ({
+ originalRouteData,
+ originalStationData,
+ originalSightData,
+ routeData,
+ stationData,
+ sightData,
+ isRouteLoading,
+ isStationLoading,
+ isSightLoading,
+ setScaleRange,
+ setMapRotation,
+ setMapCenter,
+ saveChanges,
+ setStationOffset,
+ setSightCoordinates,
+ }),
+ [
+ originalRouteData,
+ originalStationData,
+ originalSightData,
+ routeData,
+ stationData,
+ sightData,
+ isRouteLoading,
+ isStationLoading,
+ isSightLoading,
+ ]
+ );
+
+ return (
+
+ {children}
+
+ );
+ }
+);
+
+export const useMapData = () => {
+ const context = useContext(MapDataContext);
+ if (!context) {
+ throw new Error("useMapData must be used within a MapDataProvider");
+ }
+ return context;
+};
diff --git a/src/pages/Route/route-preview/RightSidebar.tsx b/src/pages/Route/route-preview/RightSidebar.tsx
new file mode 100644
index 0000000..09a7347
--- /dev/null
+++ b/src/pages/Route/route-preview/RightSidebar.tsx
@@ -0,0 +1,232 @@
+import { Button, Stack, TextField, Typography } from "@mui/material";
+import { useMapData } from "./MapDataContext";
+import { useEffect, useState } from "react";
+import { useTransform } from "./TransformContext";
+import { coordinatesToLocal, localToCoordinates } from "./utils";
+
+export function RightSidebar() {
+ const {
+ routeData,
+ setScaleRange,
+ saveChanges,
+ originalRouteData,
+ setMapRotation,
+ setMapCenter,
+ } = useMapData();
+ const {
+ rotation,
+ position,
+ screenToLocal,
+ screenCenter,
+ rotateToAngle,
+ setTransform,
+ } = useTransform();
+ const [minScale, setMinScale] = useState(1);
+ const [maxScale, setMaxScale] = useState(10);
+ const [localCenter, setLocalCenter] = useState<{ x: number; y: number }>({
+ x: 0,
+ y: 0,
+ });
+ const [rotationDegrees, setRotationDegrees] = useState(0);
+
+ useEffect(() => {
+ if (originalRouteData) {
+ setMinScale(originalRouteData.scale_min ?? 1);
+ setMaxScale(originalRouteData.scale_max ?? 10);
+ setRotationDegrees(originalRouteData.rotate ?? 0);
+ setLocalCenter({
+ x: originalRouteData.center_latitude ?? 0,
+ y: originalRouteData.center_longitude ?? 0,
+ });
+ }
+ }, [originalRouteData]);
+
+ useEffect(() => {
+ if (minScale && maxScale) {
+ setScaleRange(minScale, maxScale);
+ }
+ }, [minScale, maxScale]);
+
+ useEffect(() => {
+ setRotationDegrees(
+ ((Math.round((rotation * 180) / Math.PI) % 360) + 360) % 360
+ );
+ }, [rotation]);
+ useEffect(() => {
+ setMapRotation(rotationDegrees);
+ }, [rotationDegrees]);
+
+ useEffect(() => {
+ const center = screenCenter ?? { x: 0, y: 0 };
+ const localCenter = screenToLocal(center.x, center.y);
+ const coordinates = localToCoordinates(localCenter.x, localCenter.y);
+ setLocalCenter({ x: coordinates.latitude, y: coordinates.longitude });
+ }, [position]);
+
+ useEffect(() => {
+ setMapCenter(localCenter.x, localCenter.y);
+ }, [localCenter]);
+
+ function setRotationFromDegrees(degrees: number) {
+ rotateToAngle((degrees * Math.PI) / 180);
+ }
+
+ function pan({ x, y }: { x: number; y: number }) {
+ const coordinates = coordinatesToLocal(x, y);
+ setTransform(coordinates.x, coordinates.y);
+ }
+
+ if (!routeData) {
+ console.error("routeData is null");
+ return null;
+ }
+
+ return (
+
+
+ Детали о достопримечательностях
+
+
+
+ setMinScale(Number(e.target.value))}
+ style={{ backgroundColor: "#222", borderRadius: 4 }}
+ sx={{
+ "& .MuiInputLabel-root": {
+ color: "#fff",
+ },
+ "& .MuiInputBase-input": {
+ color: "#fff",
+ },
+ }}
+ slotProps={{
+ input: {
+ min: 0.1,
+ },
+ }}
+ />
+ setMaxScale(Number(e.target.value))}
+ style={{ backgroundColor: "#222", borderRadius: 4, color: "#fff" }}
+ sx={{
+ "& .MuiInputLabel-root": {
+ color: "#fff",
+ },
+ "& .MuiInputBase-input": {
+ color: "#fff",
+ },
+ }}
+ slotProps={{
+ input: {
+ min: 0.1,
+ },
+ }}
+ />
+
+
+ {
+ const value = Number(e.target.value);
+ if (!isNaN(value)) {
+ setRotationFromDegrees(value);
+ }
+ }}
+ onKeyDown={(e) => {
+ if (e.key === "Enter") {
+ e.currentTarget.blur();
+ }
+ }}
+ style={{ backgroundColor: "#222", borderRadius: 4 }}
+ sx={{
+ "& .MuiInputLabel-root": {
+ color: "#fff",
+ },
+ "& .MuiInputBase-input": {
+ color: "#fff",
+ },
+ }}
+ slotProps={{
+ input: {
+ min: 0,
+ max: 360,
+ },
+ }}
+ />
+
+
+ {
+ setLocalCenter((prev) => ({ ...prev, x: Number(e.target.value) }));
+ pan({ x: Number(e.target.value), y: localCenter.y });
+ }}
+ style={{ backgroundColor: "#222", borderRadius: 4 }}
+ sx={{
+ "& .MuiInputLabel-root": {
+ color: "#fff",
+ },
+ "& .MuiInputBase-input": {
+ color: "#fff",
+ },
+ }}
+ />
+ {
+ setLocalCenter((prev) => ({ ...prev, y: Number(e.target.value) }));
+ pan({ x: localCenter.x, y: Number(e.target.value) });
+ }}
+ style={{ backgroundColor: "#222", borderRadius: 4 }}
+ sx={{
+ "& .MuiInputLabel-root": {
+ color: "#fff",
+ },
+ "& .MuiInputBase-input": {
+ color: "#fff",
+ },
+ }}
+ />
+
+
+
+
+ );
+}
diff --git a/src/pages/Route/route-preview/Sight.tsx b/src/pages/Route/route-preview/Sight.tsx
new file mode 100644
index 0000000..039ecfa
--- /dev/null
+++ b/src/pages/Route/route-preview/Sight.tsx
@@ -0,0 +1,119 @@
+import { useEffect, useState } from "react";
+import { useTransform } from "./TransformContext";
+import { SightData } from "./types";
+import { Assets, FederatedMouseEvent, Graphics, Texture } from "pixi.js";
+import { COLORS } from "../../contexts/color-mode/theme";
+import { SIGHT_SIZE, UP_SCALE } from "./Constants";
+import { coordinatesToLocal, localToCoordinates } from "./utils";
+import { useMapData } from "./MapDataContext";
+
+interface SightProps {
+ sight: SightData;
+ id: number;
+}
+
+export function Sight({
+ sight, id
+}: Readonly) {
+ const { rotation, scale } = useTransform();
+ const { setSightCoordinates } = useMapData();
+
+ const [position, setPosition] = useState(coordinatesToLocal(sight.latitude, sight.longitude));
+ const [isDragging, setIsDragging] = useState(false);
+ const [startPosition, setStartPosition] = useState({ x: 0, y: 0 });
+ const [startMousePosition, setStartMousePosition] = useState({ x: 0, y: 0 });
+
+ const handlePointerDown = (e: FederatedMouseEvent) => {
+ setIsDragging(true);
+ setStartPosition({
+ x: position.x,
+ y: position.y
+ });
+ setStartMousePosition({
+ x: e.globalX,
+ y: e.globalY
+ });
+
+ e.stopPropagation();
+ };
+ const handlePointerMove = (e: FederatedMouseEvent) => {
+ if (!isDragging) return;
+ const dx = (e.globalX - startMousePosition.x) / scale / UP_SCALE;
+ const dy = (e.globalY - startMousePosition.y) / scale / UP_SCALE;
+ const cos = Math.cos(rotation);
+ const sin = Math.sin(rotation);
+ const newPosition = {
+ x: startPosition.x + dx * cos + dy * sin,
+ y: startPosition.y - dx * sin + dy * cos
+ };
+ setPosition(newPosition);
+ const coordinates = localToCoordinates(newPosition.x, newPosition.y);
+ setSightCoordinates(sight.id, coordinates.latitude, coordinates.longitude);
+ e.stopPropagation();
+ };
+
+ const handlePointerUp = (e: FederatedMouseEvent) => {
+ setIsDragging(false);
+ e.stopPropagation();
+ };
+
+ const [texture, setTexture] = useState(Texture.EMPTY);
+ useEffect(() => {
+ if (texture === Texture.EMPTY) {
+ Assets
+ .load('/SightIcon.png')
+ .then((result) => {
+ setTexture(result)
+ });
+ }
+ }, [texture]);
+
+ function draw(g: Graphics) {
+ g.clear();
+ g.circle(0, 0, 20);
+ g.fill({color: COLORS.primary}); // Fill circle with primary color
+ }
+
+ if(!sight) {
+ console.error("sight is null");
+ return null;
+ }
+
+ const coordinates = coordinatesToLocal(sight.latitude, sight.longitude);
+
+ return (
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/pages/Route/route-preview/Station.tsx b/src/pages/Route/route-preview/Station.tsx
new file mode 100644
index 0000000..fbdea11
--- /dev/null
+++ b/src/pages/Route/route-preview/Station.tsx
@@ -0,0 +1,148 @@
+import { FederatedMouseEvent, Graphics } from "pixi.js";
+import {
+ BACKGROUND_COLOR,
+ PATH_COLOR,
+ STATION_RADIUS,
+ STATION_OUTLINE_WIDTH,
+ UP_SCALE,
+} from "./Constants";
+import { useTransform } from "./TransformContext";
+import { useCallback, useEffect, useRef, useState } from "react";
+import { StationData } from "./types";
+import { useMapData } from "./MapDataContext";
+import { coordinatesToLocal } from "./utils";
+import { observer } from "mobx-react-lite";
+import { languageStore } from "@shared";
+
+interface StationProps {
+ station: StationData;
+ ruLabel: string | null;
+}
+
+export const Station = observer(
+ ({ station, ruLabel }: Readonly) => {
+ const draw = useCallback((g: Graphics) => {
+ g.clear();
+ const coordinates = coordinatesToLocal(
+ station.latitude,
+ station.longitude
+ );
+ g.circle(
+ coordinates.x * UP_SCALE,
+ coordinates.y * UP_SCALE,
+ STATION_RADIUS
+ );
+ g.fill({ color: PATH_COLOR });
+ g.stroke({ color: BACKGROUND_COLOR, width: STATION_OUTLINE_WIDTH });
+ }, []);
+
+ return (
+
+
+
+
+ );
+ }
+);
+
+export const StationLabel = observer(
+ ({ station, ruLabel }: Readonly) => {
+ const { language } = languageStore;
+ const { rotation, scale } = useTransform();
+ const { setStationOffset } = useMapData();
+
+ const [position, setPosition] = useState({
+ x: station.offset_x,
+ y: station.offset_y,
+ });
+ const [isDragging, setIsDragging] = useState(false);
+ const [startPosition, setStartPosition] = useState({ x: 0, y: 0 });
+ const [startMousePosition, setStartMousePosition] = useState({
+ x: 0,
+ y: 0,
+ });
+
+ if (!station) {
+ console.error("station is null");
+ return null;
+ }
+
+ const handlePointerDown = (e: FederatedMouseEvent) => {
+ setIsDragging(true);
+ setStartPosition({
+ x: position.x,
+ y: position.y,
+ });
+ setStartMousePosition({
+ x: e.globalX,
+ y: e.globalY,
+ });
+
+ e.stopPropagation();
+ };
+ const handlePointerMove = (e: FederatedMouseEvent) => {
+ if (!isDragging) return;
+ const dx = e.globalX - startMousePosition.x;
+ const dy = e.globalY - startMousePosition.y;
+ const newPosition = {
+ x: startPosition.x + dx,
+ y: startPosition.y + dy,
+ };
+ setPosition(newPosition);
+ setStationOffset(station.id, newPosition.x, newPosition.y);
+ e.stopPropagation();
+ };
+
+ const handlePointerUp = (e: FederatedMouseEvent) => {
+ setIsDragging(false);
+ e.stopPropagation();
+ };
+ const coordinates = coordinatesToLocal(station.latitude, station.longitude);
+
+ return (
+
+
+
+ {ruLabel && (
+
+ )}
+
+ );
+ }
+);
diff --git a/src/pages/Route/route-preview/TransformContext.tsx b/src/pages/Route/route-preview/TransformContext.tsx
new file mode 100644
index 0000000..9e38225
--- /dev/null
+++ b/src/pages/Route/route-preview/TransformContext.tsx
@@ -0,0 +1,204 @@
+import {
+ createContext,
+ ReactNode,
+ useContext,
+ useMemo,
+ useState,
+ useCallback,
+} from "react";
+import { SCALE_FACTOR, UP_SCALE } from "./Constants";
+
+const TransformContext = createContext<{
+ position: { x: number; y: number };
+ scale: number;
+ rotation: number;
+ screenCenter?: { x: number; y: number };
+
+ setPosition: React.Dispatch>;
+ setScale: React.Dispatch>;
+ setRotation: React.Dispatch>;
+ screenToLocal: (x: number, y: number) => { x: number; y: number };
+ localToScreen: (x: number, y: number) => { x: number; y: number };
+ rotateToAngle: (to: number, fromPosition?: { x: number; y: number }) => void;
+ setTransform: (
+ latitude: number,
+ longitude: number,
+ rotationDegrees?: number,
+ scale?: number
+ ) => void;
+ setScreenCenter: React.Dispatch<
+ React.SetStateAction<{ x: number; y: number } | undefined>
+ >;
+}>({
+ position: { x: 0, y: 0 },
+ scale: 1,
+ rotation: 0,
+ screenCenter: undefined,
+ setPosition: () => {},
+ setScale: () => {},
+ setRotation: () => {},
+ screenToLocal: () => ({ x: 0, y: 0 }),
+ localToScreen: () => ({ x: 0, y: 0 }),
+ rotateToAngle: () => {},
+ setTransform: () => {},
+ setScreenCenter: () => {},
+});
+
+// Provider component
+export const TransformProvider = ({ children }: { children: ReactNode }) => {
+ const [position, setPosition] = useState({ x: 0, y: 0 });
+ const [scale, setScale] = useState(1);
+ const [rotation, setRotation] = useState(0);
+ const [screenCenter, setScreenCenter] = useState<{ x: number; y: number }>();
+
+ const screenToLocal = useCallback(
+ (screenX: number, screenY: number) => {
+ // Translate point relative to current pan position
+ const translatedX = (screenX - position.x) / scale;
+ const translatedY = (screenY - position.y) / scale;
+
+ // Rotate point around center
+ const cosRotation = Math.cos(-rotation); // Negative rotation to reverse transform
+ const sinRotation = Math.sin(-rotation);
+ const rotatedX = translatedX * cosRotation - translatedY * sinRotation;
+ const rotatedY = translatedX * sinRotation + translatedY * cosRotation;
+
+ return {
+ x: rotatedX / UP_SCALE,
+ y: rotatedY / UP_SCALE,
+ };
+ },
+ [position.x, position.y, scale, rotation]
+ );
+
+ // Inverse of screenToLocal
+ const localToScreen = useCallback(
+ (localX: number, localY: number) => {
+ const upscaledX = localX * UP_SCALE;
+ const upscaledY = localY * UP_SCALE;
+
+ const cosRotation = Math.cos(rotation);
+ const sinRotation = Math.sin(rotation);
+ const rotatedX = upscaledX * cosRotation - upscaledY * sinRotation;
+ const rotatedY = upscaledX * sinRotation + upscaledY * cosRotation;
+
+ const translatedX = rotatedX * scale + position.x;
+ const translatedY = rotatedY * scale + position.y;
+
+ return {
+ x: translatedX,
+ y: translatedY,
+ };
+ },
+ [position.x, position.y, scale, rotation]
+ );
+
+ const rotateToAngle = useCallback(
+ (to: number, fromPosition?: { x: number; y: number }) => {
+ const rotationDiff = to - rotation;
+
+ const center = screenCenter ?? { x: 0, y: 0 };
+ const cosDelta = Math.cos(rotationDiff);
+ const sinDelta = Math.sin(rotationDiff);
+
+ const currentFromPosition = fromPosition ?? position;
+
+ const newPosition = {
+ x:
+ center.x * (1 - cosDelta) +
+ currentFromPosition.x * cosDelta +
+ (center.y - currentFromPosition.y) * sinDelta,
+ y:
+ center.y * (1 - cosDelta) +
+ currentFromPosition.y * cosDelta +
+ (currentFromPosition.x - center.x) * sinDelta,
+ };
+
+ // Update both rotation and position in a single batch to avoid stale closure
+ setRotation(to);
+ setPosition(newPosition);
+ },
+ [rotation, position, screenCenter]
+ );
+
+ const setTransform = useCallback(
+ (
+ latitude: number,
+ longitude: number,
+ rotationDegrees?: number,
+ useScale?: number
+ ) => {
+ const selectedRotation =
+ rotationDegrees !== undefined
+ ? (rotationDegrees * Math.PI) / 180
+ : rotation;
+ const selectedScale =
+ useScale !== undefined ? useScale / SCALE_FACTOR : scale;
+ const center = screenCenter ?? { x: 0, y: 0 };
+
+ console.log("center", center.x, center.y);
+
+ const newPosition = {
+ x: -latitude * UP_SCALE * selectedScale,
+ y: -longitude * UP_SCALE * selectedScale,
+ };
+
+ const cosRot = Math.cos(selectedRotation);
+ const sinRot = Math.sin(selectedRotation);
+
+ // Translate point relative to center, rotate, then translate back
+ const dx = newPosition.x;
+ const dy = newPosition.y;
+ newPosition.x = dx * cosRot - dy * sinRot + center.x;
+ newPosition.y = dx * sinRot + dy * cosRot + center.y;
+
+ // Batch state updates to avoid intermediate renders
+ setPosition(newPosition);
+ setRotation(selectedRotation);
+ setScale(selectedScale);
+ },
+ [rotation, scale, screenCenter]
+ );
+
+ const value = useMemo(
+ () => ({
+ position,
+ scale,
+ rotation,
+ screenCenter,
+ setPosition,
+ setScale,
+ setRotation,
+ rotateToAngle,
+ screenToLocal,
+ localToScreen,
+ setTransform,
+ setScreenCenter,
+ }),
+ [
+ position,
+ scale,
+ rotation,
+ screenCenter,
+ rotateToAngle,
+ screenToLocal,
+ localToScreen,
+ setTransform,
+ ]
+ );
+
+ return (
+
+ {children}
+
+ );
+};
+
+// Custom hook for easy access to transform values
+export const useTransform = () => {
+ const context = useContext(TransformContext);
+ if (!context) {
+ throw new Error("useTransform must be used within a TransformProvider");
+ }
+ return context;
+};
diff --git a/src/pages/Route/route-preview/TravelPath.tsx b/src/pages/Route/route-preview/TravelPath.tsx
new file mode 100644
index 0000000..5102bcb
--- /dev/null
+++ b/src/pages/Route/route-preview/TravelPath.tsx
@@ -0,0 +1,34 @@
+import { Graphics } from "pixi.js";
+import { useCallback } from "react";
+import { PATH_COLOR, PATH_WIDTH } from "./Constants";
+import { coordinatesToLocal } from "./utils";
+
+interface TravelPathProps {
+ points: { x: number; y: number }[];
+}
+
+export function TravelPath({ points }: Readonly) {
+ const draw = useCallback(
+ (g: Graphics) => {
+ g.clear();
+ const coordStart = coordinatesToLocal(points[0].x, points[0].y);
+ g.moveTo(coordStart.x, coordStart.y);
+ for (let i = 1; i <= points.length - 1; i++) {
+ const coordinates = coordinatesToLocal(points[i].x, points[i].y);
+ g.lineTo(coordinates.x, coordinates.y);
+ }
+ g.stroke({
+ color: PATH_COLOR,
+ width: PATH_WIDTH,
+ });
+ },
+ [points]
+ );
+
+ if (points.length === 0) {
+ console.error("points is empty");
+ return null;
+ }
+
+ return ;
+}
diff --git a/src/pages/Route/route-preview/Widgets.tsx b/src/pages/Route/route-preview/Widgets.tsx
new file mode 100644
index 0000000..2c0d966
--- /dev/null
+++ b/src/pages/Route/route-preview/Widgets.tsx
@@ -0,0 +1,43 @@
+import { Stack, Typography } from "@mui/material";
+
+export function Widgets() {
+ return (
+
+
+
+ Станция
+
+
+
+
+ Погода
+
+
+
+ );
+}
diff --git a/src/pages/Route/route-preview/index.tsx b/src/pages/Route/route-preview/index.tsx
new file mode 100644
index 0000000..902b5c7
--- /dev/null
+++ b/src/pages/Route/route-preview/index.tsx
@@ -0,0 +1,176 @@
+import { useRef, useEffect, useState } from "react";
+
+import { Application, ApplicationRef, extend } from "@pixi/react";
+import {
+ Container,
+ Graphics,
+ Sprite,
+ Texture,
+ TilingSprite,
+ Text,
+} from "pixi.js";
+import { Stack } from "@mui/material";
+import { MapDataProvider, useMapData } from "./MapDataContext";
+import { TransformProvider, useTransform } from "./TransformContext";
+import { InfiniteCanvas } from "./InfiniteCanvas";
+import { Sight } from "./Sight";
+import { UP_SCALE } from "./Constants";
+import { Station } from "./Station";
+import { TravelPath } from "./TravelPath";
+import { LeftSidebar } from "./LeftSidebar";
+import { RightSidebar } from "./RightSidebar";
+import { Widgets } from "./Widgets";
+import { coordinatesToLocal } from "./utils";
+import { LanguageSwitcher } from "@widgets";
+import { languageStore } from "@shared";
+import { observer } from "mobx-react-lite";
+
+extend({
+ Container,
+ Graphics,
+ Sprite,
+ Texture,
+ TilingSprite,
+ Text,
+});
+
+export const RoutePreview = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export const RouteMap = observer(() => {
+ const { language } = languageStore;
+ const { setPosition, screenToLocal, setTransform, screenCenter } =
+ useTransform();
+ const { routeData, stationData, sightData, originalRouteData } = useMapData();
+ console.log(stationData);
+ const [points, setPoints] = useState<{ x: number; y: number }[]>([]);
+ const [isSetup, setIsSetup] = useState(false);
+
+ const parentRef = useRef(null);
+
+ useEffect(() => {
+ if (originalRouteData) {
+ const path = originalRouteData?.path;
+ const points =
+ path?.map(([x, y]: [number, number]) => ({
+ x: x * UP_SCALE,
+ y: y * UP_SCALE,
+ })) ?? [];
+ setPoints(points);
+ }
+ }, [originalRouteData]);
+
+ useEffect(() => {
+ if (isSetup || !screenCenter) {
+ return;
+ }
+
+ if (
+ originalRouteData?.center_latitude ===
+ originalRouteData?.center_longitude &&
+ originalRouteData?.center_latitude === 0
+ ) {
+ if (points.length > 0) {
+ let boundingBox = {
+ from: { x: Infinity, y: Infinity },
+ to: { x: -Infinity, y: -Infinity },
+ };
+ for (const point of points) {
+ boundingBox.from.x = Math.min(boundingBox.from.x, point.x);
+ boundingBox.from.y = Math.min(boundingBox.from.y, point.y);
+ boundingBox.to.x = Math.max(boundingBox.to.x, point.x);
+ boundingBox.to.y = Math.max(boundingBox.to.y, point.y);
+ }
+ const newCenter = {
+ x: -(boundingBox.from.x + boundingBox.to.x) / 2,
+ y: -(boundingBox.from.y + boundingBox.to.y) / 2,
+ };
+ setPosition(newCenter);
+ setIsSetup(true);
+ }
+ } else if (
+ originalRouteData?.center_latitude &&
+ originalRouteData?.center_longitude
+ ) {
+ const coordinates = coordinatesToLocal(
+ originalRouteData?.center_latitude,
+ originalRouteData?.center_longitude
+ );
+
+ setTransform(
+ coordinates.x,
+ coordinates.y,
+ originalRouteData?.rotate,
+ originalRouteData?.scale_min
+ );
+ setIsSetup(true);
+ }
+ }, [
+ points,
+ originalRouteData?.center_latitude,
+ originalRouteData?.center_longitude,
+ originalRouteData?.rotate,
+ isSetup,
+ screenCenter,
+ ]);
+
+ if (!routeData || !stationData || !sightData) {
+ console.error("routeData, stationData or sightData is null");
+ return Loading...
;
+ }
+
+ return (
+
+
+
+
+ {stationData[language].map((obj, index) => (
+
+ ))}
+
+ {
+ g.clear();
+ const localCenter = screenToLocal(0, 0);
+ g.circle(localCenter.x, localCenter.y, 10);
+ g.fill("#fff");
+ }}
+ />
+
+
+
+ );
+});
diff --git a/src/pages/Route/route-preview/types.ts b/src/pages/Route/route-preview/types.ts
new file mode 100644
index 0000000..6ced8be
--- /dev/null
+++ b/src/pages/Route/route-preview/types.ts
@@ -0,0 +1,69 @@
+export interface RouteData {
+ carrier: string;
+ carrier_id: number;
+ center_latitude: number;
+ center_longitude: number;
+ governor_appeal: number;
+ id: number;
+ path: [number, number][];
+ rotate: number;
+ route_direction: boolean;
+ route_number: string;
+ route_sys_number: string;
+ scale_max: number;
+ scale_min: number;
+}
+
+export interface StationTransferData {
+ bus: string;
+ metro_blue: string;
+ metro_green: string;
+ metro_orange: string;
+ metro_purple: string;
+ metro_red: string;
+ train: string;
+ tram: string;
+ trolleybus: string;
+}
+
+export interface StationData {
+ address: string;
+ city_id?: number;
+ description: string;
+ id: number;
+ latitude: number;
+ longitude: number;
+ name: string;
+ offset_x: number;
+ offset_y: number;
+ system_name: string;
+ transfers: StationTransferData;
+}
+
+export interface StationPatchData {
+ station_id: number;
+ offset_x: number;
+ offset_y: number;
+ transfers: StationTransferData;
+}
+
+export interface SightPatchData {
+ sight_id: number;
+ latitude: number;
+ longitude: number;
+}
+
+export interface SightData {
+ address: string;
+ city: string;
+ city_id: number;
+ id: number;
+ latitude: number;
+ left_article: number;
+ longitude: number;
+ name: string;
+ preview_media: number;
+ thumbnail: string; // uuid
+ watermark_lu: string; // uuid
+ watermark_rd: string; // uuid
+}
\ No newline at end of file
diff --git a/src/pages/Route/route-preview/utils.ts b/src/pages/Route/route-preview/utils.ts
new file mode 100644
index 0000000..fca59b8
--- /dev/null
+++ b/src/pages/Route/route-preview/utils.ts
@@ -0,0 +1,14 @@
+// approximation
+export function coordinatesToLocal(latitude: number, longitude: number) {
+ return {
+ x: longitude,
+ y: -latitude*2,
+ }
+}
+
+export function localToCoordinates(x: number, y: number) {
+ return {
+ longitude: x,
+ latitude: -y/2,
+ }
+}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index 3f35a87..c6a0530 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -24,7 +24,7 @@
resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.3.tgz"
integrity sha512-V42wFfx1ymFte+ecf6iXghnnP8kWTO+ZLXIyZq+1LAXHHvTZdVxicn4yiVYdYMGaCO3tmqub11AorKkv+iodqw==
-"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.26.10":
+"@babel/core@^7.26.10":
version "7.27.3"
resolved "https://registry.npmjs.org/@babel/core/-/core-7.27.3.tgz"
integrity sha512-hyrN8ivxfvJ4i0fIJuV4EOlV0WDMz5Ui4StRTgVaAvWeiRCilXgwVvxJKtFQ3TKtHgJscB2YiXKGNJuVwhQMtA==
@@ -173,6 +173,28 @@
resolved "https://registry.npmjs.org/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz"
integrity sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==
+"@emnapi/core@^1.4.3":
+ version "1.4.3"
+ resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.4.3.tgz#9ac52d2d5aea958f67e52c40a065f51de59b77d6"
+ integrity sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==
+ dependencies:
+ "@emnapi/wasi-threads" "1.0.2"
+ tslib "^2.4.0"
+
+"@emnapi/runtime@^1.4.3":
+ version "1.4.3"
+ resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.4.3.tgz#c0564665c80dc81c448adac23f9dfbed6c838f7d"
+ integrity sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==
+ dependencies:
+ tslib "^2.4.0"
+
+"@emnapi/wasi-threads@1.0.2", "@emnapi/wasi-threads@^1.0.2":
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/@emnapi/wasi-threads/-/wasi-threads-1.0.2.tgz#977f44f844eac7d6c138a415a123818c655f874c"
+ integrity sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==
+ dependencies:
+ tslib "^2.4.0"
+
"@emotion/babel-plugin@^11.13.5":
version "11.13.5"
resolved "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz"
@@ -218,7 +240,7 @@
resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz"
integrity sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==
-"@emotion/react@^11.0.0-rc.0", "@emotion/react@^11.14.0", "@emotion/react@^11.4.1", "@emotion/react@^11.5.0", "@emotion/react@^11.9.0":
+"@emotion/react@^11.14.0":
version "11.14.0"
resolved "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz"
integrity sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==
@@ -248,7 +270,7 @@
resolved "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz"
integrity sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==
-"@emotion/styled@^11.14.0", "@emotion/styled@^11.3.0", "@emotion/styled@^11.8.1":
+"@emotion/styled@^11.14.0":
version "11.14.0"
resolved "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.0.tgz"
integrity sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==
@@ -280,11 +302,131 @@
resolved "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz"
integrity sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==
+"@esbuild/aix-ppc64@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz#4e0f91776c2b340e75558f60552195f6fad09f18"
+ integrity sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==
+
+"@esbuild/android-arm64@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz#bc766407f1718923f6b8079c8c61bf86ac3a6a4f"
+ integrity sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==
+
+"@esbuild/android-arm@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.5.tgz#4290d6d3407bae3883ad2cded1081a234473ce26"
+ integrity sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==
+
+"@esbuild/android-x64@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.5.tgz#40c11d9cbca4f2406548c8a9895d321bc3b35eff"
+ integrity sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==
+
"@esbuild/darwin-arm64@0.25.5":
version "0.25.5"
resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz"
integrity sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==
+"@esbuild/darwin-x64@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz#e27a5d92a14886ef1d492fd50fc61a2d4d87e418"
+ integrity sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==
+
+"@esbuild/freebsd-arm64@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz#97cede59d638840ca104e605cdb9f1b118ba0b1c"
+ integrity sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==
+
+"@esbuild/freebsd-x64@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz#71c77812042a1a8190c3d581e140d15b876b9c6f"
+ integrity sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==
+
+"@esbuild/linux-arm64@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz#f7b7c8f97eff8ffd2e47f6c67eb5c9765f2181b8"
+ integrity sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==
+
+"@esbuild/linux-arm@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz#2a0be71b6cd8201fa559aea45598dffabc05d911"
+ integrity sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==
+
+"@esbuild/linux-ia32@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz#763414463cd9ea6fa1f96555d2762f9f84c61783"
+ integrity sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==
+
+"@esbuild/linux-loong64@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz#428cf2213ff786a502a52c96cf29d1fcf1eb8506"
+ integrity sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==
+
+"@esbuild/linux-mips64el@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz#5cbcc7fd841b4cd53358afd33527cd394e325d96"
+ integrity sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==
+
+"@esbuild/linux-ppc64@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz#0d954ab39ce4f5e50f00c4f8c4fd38f976c13ad9"
+ integrity sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==
+
+"@esbuild/linux-riscv64@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz#0e7dd30730505abd8088321e8497e94b547bfb1e"
+ integrity sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==
+
+"@esbuild/linux-s390x@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz#5669af81327a398a336d7e40e320b5bbd6e6e72d"
+ integrity sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==
+
+"@esbuild/linux-x64@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz#b2357dd153aa49038967ddc1ffd90c68a9d2a0d4"
+ integrity sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==
+
+"@esbuild/netbsd-arm64@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz#53b4dfb8fe1cee93777c9e366893bd3daa6ba63d"
+ integrity sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==
+
+"@esbuild/netbsd-x64@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz#a0206f6314ce7dc8713b7732703d0f58de1d1e79"
+ integrity sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==
+
+"@esbuild/openbsd-arm64@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz#2a796c87c44e8de78001d808c77d948a21ec22fd"
+ integrity sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==
+
+"@esbuild/openbsd-x64@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz#28d0cd8909b7fa3953af998f2b2ed34f576728f0"
+ integrity sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==
+
+"@esbuild/sunos-x64@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz#a28164f5b997e8247d407e36c90d3fd5ddbe0dc5"
+ integrity sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==
+
+"@esbuild/win32-arm64@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz#6eadbead38e8bd12f633a5190e45eff80e24007e"
+ integrity sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==
+
+"@esbuild/win32-ia32@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz#bab6288005482f9ed2adb9ded7e88eba9a62cc0d"
+ integrity sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==
+
+"@esbuild/win32-x64@0.25.5":
+ version "0.25.5"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz#7fc114af5f6563f19f73324b5d5ff36ece0803d1"
+ integrity sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==
+
"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.7.0":
version "4.7.0"
resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz"
@@ -333,7 +475,7 @@
minimatch "^3.1.2"
strip-json-comments "^3.1.1"
-"@eslint/js@^9.25.0", "@eslint/js@9.27.0":
+"@eslint/js@9.27.0", "@eslint/js@^9.25.0":
version "9.27.0"
resolved "https://registry.npmjs.org/@eslint/js/-/js-9.27.0.tgz"
integrity sha512-G5JD9Tu5HJEu4z2Uo4aHY2sLV64B7CDMXxFzqzjl3NKd6RVzSXNoE80jk7Y0lJkTTkjiIhBAqmlYwjuBY3tvpA==
@@ -453,7 +595,7 @@
dependencies:
"@babel/runtime" "^7.27.1"
-"@mui/material@^5.15.14 || ^6.0.0 || ^7.0.0", "@mui/material@^7.1.0", "@mui/material@^7.1.1":
+"@mui/material@^7.1.0":
version "7.1.1"
resolved "https://registry.npmjs.org/@mui/material/-/material-7.1.1.tgz"
integrity sha512-mTpdmdZCaHCGOH3SrYM41+XKvNL0iQfM9KlYgpSjgadXx/fEKhhvOktxm8++Xw6FFeOHoOiV+lzOI8X1rsv71A==
@@ -492,7 +634,7 @@
csstype "^3.1.3"
prop-types "^15.8.1"
-"@mui/system@^5.15.14 || ^6.0.0 || ^7.0.0", "@mui/system@^7.1.1":
+"@mui/system@^7.1.1":
version "7.1.1"
resolved "https://registry.npmjs.org/@mui/system/-/system-7.1.1.tgz"
integrity sha512-Kj1uhiqnj4Zo7PDjAOghtXJtNABunWvhcRU0O7RQJ7WOxeynoH6wXPcilphV8QTFtkKaip8EiNJRiCD+B3eROA==
@@ -546,6 +688,15 @@
"@babel/runtime" "^7.27.4"
"@mui/utils" "^7.1.1"
+"@napi-rs/wasm-runtime@^0.2.10":
+ version "0.2.11"
+ resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.11.tgz#192c1610e1625048089ab4e35bc0649ce478500e"
+ integrity sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA==
+ dependencies:
+ "@emnapi/core" "^1.4.3"
+ "@emnapi/runtime" "^1.4.3"
+ "@tybys/wasm-util" "^0.9.0"
+
"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz"
@@ -554,7 +705,7 @@
"@nodelib/fs.stat" "2.0.5"
run-parallel "^1.1.9"
-"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5":
+"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
version "2.0.5"
resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz"
integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
@@ -572,13 +723,26 @@
resolved "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.9.2.tgz"
integrity sha512-VgffxawQde93xKxT3qap3OH+meZf7VaSB5Sqd4Rqc+FP5alWbpOyan/7tRbOAvynjpG3GpdtAuGU/NdhQpmrog==
-"@photo-sphere-viewer/core@^5.13.2", "@photo-sphere-viewer/core@>=5.13.1":
+"@photo-sphere-viewer/core@^5.13.2":
version "5.13.2"
resolved "https://registry.npmjs.org/@photo-sphere-viewer/core/-/core-5.13.2.tgz"
integrity sha512-rL4Ey39Prx4Iyxt1f2tAqlXvqu4/ovXfUvIpLt540OpZJiFjWccs6qLywof9vuhBJ7PXHudHWCjRPce0W8kx8w==
dependencies:
three "^0.175.0"
+"@pixi/colord@^2.9.6":
+ version "2.9.6"
+ resolved "https://registry.yarnpkg.com/@pixi/colord/-/colord-2.9.6.tgz#7e4e7851480da6fd3cef4e331f008d60be7e1204"
+ integrity sha512-nezytU2pw587fQstUu1AsJZDVEynjskwOL+kibwcdxsMBFqPsFFNA7xl0ii/gXuDi6M0xj3mfRJj8pBSc2jCfA==
+
+"@pixi/react@^8.0.2":
+ version "8.0.2"
+ resolved "https://registry.yarnpkg.com/@pixi/react/-/react-8.0.2.tgz#d58288b2405cc4f40733297b9d55d016d74045bd"
+ integrity sha512-A42Bw/1YlxxCXhb+nDIgzPpACx5dOh7Yi+ZfBMlZ1sBB/qc7qyX9k7bdDtrnMqz8OofyF2FXg9gPw9MISFsQTA==
+ dependencies:
+ its-fine "^2.0.0"
+ react-reconciler "0.31.0"
+
"@popperjs/core@^2.11.8":
version "2.11.8"
resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz"
@@ -611,7 +775,7 @@
utility-types "^3.11.0"
zustand "^5.0.1"
-"@react-three/fiber@^9.0.0", "@react-three/fiber@^9.1.2":
+"@react-three/fiber@^9.1.2":
version "9.1.2"
resolved "https://registry.npmjs.org/@react-three/fiber/-/fiber-9.1.2.tgz"
integrity sha512-k8FR9yVHV9kIF3iuOD0ds5hVymXYXfgdKklqziBVod9ZEJ8uk05Zjw29J/omU3IKeUfLNAIHfxneN3TUYM4I2w==
@@ -634,11 +798,106 @@
resolved "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.9.tgz"
integrity sha512-e9MeMtVWo186sgvFFJOPGy7/d2j2mZhLJIdVW0C/xDluuOvymEATqz6zKsP0ZmXGzQtqlyjz5sC1sYQUoJG98w==
+"@rollup/rollup-android-arm-eabi@4.41.1":
+ version "4.41.1"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.41.1.tgz#f39f09f60d4a562de727c960d7b202a2cf797424"
+ integrity sha512-NELNvyEWZ6R9QMkiytB4/L4zSEaBC03KIXEghptLGLZWJ6VPrL63ooZQCOnlx36aQPGhzuOMwDerC1Eb2VmrLw==
+
+"@rollup/rollup-android-arm64@4.41.1":
+ version "4.41.1"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.41.1.tgz#d19af7e23760717f1d879d4ca3d2cd247742dff2"
+ integrity sha512-DXdQe1BJ6TK47ukAoZLehRHhfKnKg9BjnQYUu9gzhI8Mwa1d2fzxA1aw2JixHVl403bwp1+/o/NhhHtxWJBgEA==
+
"@rollup/rollup-darwin-arm64@4.41.1":
version "4.41.1"
resolved "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.41.1.tgz"
integrity sha512-5afxvwszzdulsU2w8JKWwY8/sJOLPzf0e1bFuvcW5h9zsEg+RQAojdW0ux2zyYAz7R8HvvzKCjLNJhVq965U7w==
+"@rollup/rollup-darwin-x64@4.41.1":
+ version "4.41.1"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.41.1.tgz#aa66d2ba1a25e609500e13bef06dc0e71cc0c0d4"
+ integrity sha512-egpJACny8QOdHNNMZKf8xY0Is6gIMz+tuqXlusxquWu3F833DcMwmGM7WlvCO9sB3OsPjdC4U0wHw5FabzCGZg==
+
+"@rollup/rollup-freebsd-arm64@4.41.1":
+ version "4.41.1"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.41.1.tgz#df10a7b6316a0ef1028c6ca71a081124c537e30d"
+ integrity sha512-DBVMZH5vbjgRk3r0OzgjS38z+atlupJ7xfKIDJdZZL6sM6wjfDNo64aowcLPKIx7LMQi8vybB56uh1Ftck/Atg==
+
+"@rollup/rollup-freebsd-x64@4.41.1":
+ version "4.41.1"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.41.1.tgz#a3fdce8a05e95b068cbcb46e4df5185e407d0c35"
+ integrity sha512-3FkydeohozEskBxNWEIbPfOE0aqQgB6ttTkJ159uWOFn42VLyfAiyD9UK5mhu+ItWzft60DycIN1Xdgiy8o/SA==
+
+"@rollup/rollup-linux-arm-gnueabihf@4.41.1":
+ version "4.41.1"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.41.1.tgz#49f766c55383bd0498014a9d76924348c2f3890c"
+ integrity sha512-wC53ZNDgt0pqx5xCAgNunkTzFE8GTgdZ9EwYGVcg+jEjJdZGtq9xPjDnFgfFozQI/Xm1mh+D9YlYtl+ueswNEg==
+
+"@rollup/rollup-linux-arm-musleabihf@4.41.1":
+ version "4.41.1"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.41.1.tgz#1d4d7d32fc557e17d52e1857817381ea365e2959"
+ integrity sha512-jwKCca1gbZkZLhLRtsrka5N8sFAaxrGz/7wRJ8Wwvq3jug7toO21vWlViihG85ei7uJTpzbXZRcORotE+xyrLA==
+
+"@rollup/rollup-linux-arm64-gnu@4.41.1":
+ version "4.41.1"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.41.1.tgz#f4fc317268441e9589edad3be8f62b6c03009bc1"
+ integrity sha512-g0UBcNknsmmNQ8V2d/zD2P7WWfJKU0F1nu0k5pW4rvdb+BIqMm8ToluW/eeRmxCared5dD76lS04uL4UaNgpNA==
+
+"@rollup/rollup-linux-arm64-musl@4.41.1":
+ version "4.41.1"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.41.1.tgz#63a1f1b0671cb17822dabae827fef0e443aebeb7"
+ integrity sha512-XZpeGB5TKEZWzIrj7sXr+BEaSgo/ma/kCgrZgL0oo5qdB1JlTzIYQKel/RmhT6vMAvOdM2teYlAaOGJpJ9lahg==
+
+"@rollup/rollup-linux-loongarch64-gnu@4.41.1":
+ version "4.41.1"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.41.1.tgz#c659b01cc6c0730b547571fc3973e1e955369f98"
+ integrity sha512-bkCfDJ4qzWfFRCNt5RVV4DOw6KEgFTUZi2r2RuYhGWC8WhCA8lCAJhDeAmrM/fdiAH54m0mA0Vk2FGRPyzI+tw==
+
+"@rollup/rollup-linux-powerpc64le-gnu@4.41.1":
+ version "4.41.1"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.41.1.tgz#612e746f9ad7e58480f964d65e0d6c3f4aae69a8"
+ integrity sha512-3mr3Xm+gvMX+/8EKogIZSIEF0WUu0HL9di+YWlJpO8CQBnoLAEL/roTCxuLncEdgcfJcvA4UMOf+2dnjl4Ut1A==
+
+"@rollup/rollup-linux-riscv64-gnu@4.41.1":
+ version "4.41.1"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.41.1.tgz#4610dbd1dcfbbae32fbc10c20ae7387acb31110c"
+ integrity sha512-3rwCIh6MQ1LGrvKJitQjZFuQnT2wxfU+ivhNBzmxXTXPllewOF7JR1s2vMX/tWtUYFgphygxjqMl76q4aMotGw==
+
+"@rollup/rollup-linux-riscv64-musl@4.41.1":
+ version "4.41.1"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.41.1.tgz#054911fab40dc83fafc21e470193c058108f19d8"
+ integrity sha512-LdIUOb3gvfmpkgFZuccNa2uYiqtgZAz3PTzjuM5bH3nvuy9ty6RGc/Q0+HDFrHrizJGVpjnTZ1yS5TNNjFlklw==
+
+"@rollup/rollup-linux-s390x-gnu@4.41.1":
+ version "4.41.1"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.41.1.tgz#98896eca8012547c7f04bd07eaa6896825f9e1a5"
+ integrity sha512-oIE6M8WC9ma6xYqjvPhzZYk6NbobIURvP/lEbh7FWplcMO6gn7MM2yHKA1eC/GvYwzNKK/1LYgqzdkZ8YFxR8g==
+
+"@rollup/rollup-linux-x64-gnu@4.41.1":
+ version "4.41.1"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.41.1.tgz#01cf56844a1e636ee80dfb364e72c2b7142ad896"
+ integrity sha512-cWBOvayNvA+SyeQMp79BHPK8ws6sHSsYnK5zDcsC3Hsxr1dgTABKjMnMslPq1DvZIp6uO7kIWhiGwaTdR4Og9A==
+
+"@rollup/rollup-linux-x64-musl@4.41.1":
+ version "4.41.1"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.41.1.tgz#e67c7531df6dff0b4c241101d4096617fbca87c3"
+ integrity sha512-y5CbN44M+pUCdGDlZFzGGBSKCA4A/J2ZH4edTYSSxFg7ce1Xt3GtydbVKWLlzL+INfFIZAEg1ZV6hh9+QQf9YQ==
+
+"@rollup/rollup-win32-arm64-msvc@4.41.1":
+ version "4.41.1"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.41.1.tgz#7eeada98444e580674de6989284e4baacd48ea65"
+ integrity sha512-lZkCxIrjlJlMt1dLO/FbpZbzt6J/A8p4DnqzSa4PWqPEUUUnzXLeki/iyPLfV0BmHItlYgHUqJe+3KiyydmiNQ==
+
+"@rollup/rollup-win32-ia32-msvc@4.41.1":
+ version "4.41.1"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.41.1.tgz#516c4b54f80587b4a390aaf4940b40870271d35d"
+ integrity sha512-+psFT9+pIh2iuGsxFYYa/LhS5MFKmuivRsx9iPJWNSGbh2XVEjk90fmpUEjCnILPEPJnikAU6SFDiEUyOv90Pg==
+
+"@rollup/rollup-win32-x64-msvc@4.41.1":
+ version "4.41.1"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.41.1.tgz#848f99b0d9936d92221bb6070baeff4db6947a30"
+ integrity sha512-Wq2zpapRYLfi4aKxf2Xff0tN+7slj2d4R87WEzqw7ZLsVvO5zwYCIuEGSZYiK41+GlwUo1HiR+GdkLEJnCKTCw==
+
"@tailwindcss/node@4.1.8":
version "4.1.8"
resolved "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.8.tgz"
@@ -652,11 +911,73 @@
source-map-js "^1.2.1"
tailwindcss "4.1.8"
+"@tailwindcss/oxide-android-arm64@4.1.8":
+ version "4.1.8"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.8.tgz#4cb4b464636fc7e3154a1bb7df38a828291b3e9a"
+ integrity sha512-Fbz7qni62uKYceWYvUjRqhGfZKwhZDQhlrJKGtnZfuNtHFqa8wmr+Wn74CTWERiW2hn3mN5gTpOoxWKk0jRxjg==
+
"@tailwindcss/oxide-darwin-arm64@4.1.8":
version "4.1.8"
resolved "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.8.tgz"
integrity sha512-RdRvedGsT0vwVVDztvyXhKpsU2ark/BjgG0huo4+2BluxdXo8NDgzl77qh0T1nUxmM11eXwR8jA39ibvSTbi7A==
+"@tailwindcss/oxide-darwin-x64@4.1.8":
+ version "4.1.8"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.8.tgz#d0f3fa4c3bde21a772e29e31c9739d91db79de12"
+ integrity sha512-t6PgxjEMLp5Ovf7uMb2OFmb3kqzVTPPakWpBIFzppk4JE4ix0yEtbtSjPbU8+PZETpaYMtXvss2Sdkx8Vs4XRw==
+
+"@tailwindcss/oxide-freebsd-x64@4.1.8":
+ version "4.1.8"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.8.tgz#545c94c941007ed1aa2e449465501b70d59cb3da"
+ integrity sha512-g8C8eGEyhHTqwPStSwZNSrOlyx0bhK/V/+zX0Y+n7DoRUzyS8eMbVshVOLJTDDC+Qn9IJnilYbIKzpB9n4aBsg==
+
+"@tailwindcss/oxide-linux-arm-gnueabihf@4.1.8":
+ version "4.1.8"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.8.tgz#e1bdbf63a179081669b8cd1c9523889774760eb9"
+ integrity sha512-Jmzr3FA4S2tHhaC6yCjac3rGf7hG9R6Gf2z9i9JFcuyy0u79HfQsh/thifbYTF2ic82KJovKKkIB6Z9TdNhCXQ==
+
+"@tailwindcss/oxide-linux-arm64-gnu@4.1.8":
+ version "4.1.8"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.8.tgz#8d28093bbd43bdae771a2dcca720e926baa57093"
+ integrity sha512-qq7jXtO1+UEtCmCeBBIRDrPFIVI4ilEQ97qgBGdwXAARrUqSn/L9fUrkb1XP/mvVtoVeR2bt/0L77xx53bPZ/Q==
+
+"@tailwindcss/oxide-linux-arm64-musl@4.1.8":
+ version "4.1.8"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.8.tgz#cc6cece814d813885ead9cd8b9d55aeb3db56c97"
+ integrity sha512-O6b8QesPbJCRshsNApsOIpzKt3ztG35gfX9tEf4arD7mwNinsoCKxkj8TgEE0YRjmjtO3r9FlJnT/ENd9EVefQ==
+
+"@tailwindcss/oxide-linux-x64-gnu@4.1.8":
+ version "4.1.8"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.8.tgz#4cac14fa71382574773fb7986d9f0681ad89e3de"
+ integrity sha512-32iEXX/pXwikshNOGnERAFwFSfiltmijMIAbUhnNyjFr3tmWmMJWQKU2vNcFX0DACSXJ3ZWcSkzNbaKTdngH6g==
+
+"@tailwindcss/oxide-linux-x64-musl@4.1.8":
+ version "4.1.8"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.8.tgz#e085f1ccbc8f97625773a6a3afc2a6f88edf59da"
+ integrity sha512-s+VSSD+TfZeMEsCaFaHTaY5YNj3Dri8rST09gMvYQKwPphacRG7wbuQ5ZJMIJXN/puxPcg/nU+ucvWguPpvBDg==
+
+"@tailwindcss/oxide-wasm32-wasi@4.1.8":
+ version "4.1.8"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.8.tgz#c5e19fffe67f25cabf12a357bba4e87128151ea0"
+ integrity sha512-CXBPVFkpDjM67sS1psWohZ6g/2/cd+cq56vPxK4JeawelxwK4YECgl9Y9TjkE2qfF+9/s1tHHJqrC4SS6cVvSg==
+ dependencies:
+ "@emnapi/core" "^1.4.3"
+ "@emnapi/runtime" "^1.4.3"
+ "@emnapi/wasi-threads" "^1.0.2"
+ "@napi-rs/wasm-runtime" "^0.2.10"
+ "@tybys/wasm-util" "^0.9.0"
+ tslib "^2.8.0"
+
+"@tailwindcss/oxide-win32-arm64-msvc@4.1.8":
+ version "4.1.8"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.8.tgz#77521f23f91604c587736927fd2cb526667b7344"
+ integrity sha512-7GmYk1n28teDHUjPlIx4Z6Z4hHEgvP5ZW2QS9ygnDAdI/myh3HTHjDqtSqgu1BpRoI4OiLx+fThAyA1JePoENA==
+
+"@tailwindcss/oxide-win32-x64-msvc@4.1.8":
+ version "4.1.8"
+ resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.8.tgz#55c876ab35f8779d1dceec61483cd9834d7365ac"
+ integrity sha512-fou+U20j+Jl0EHwK92spoWISON2OBnCazIc038Xj2TdweYV33ZRkS9nwqiUi2d/Wba5xg5UoHfvynnb/UB49cQ==
+
"@tailwindcss/oxide@4.1.8":
version "4.1.8"
resolved "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.8.tgz"
@@ -702,6 +1023,13 @@
resolved "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz"
integrity sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==
+"@tybys/wasm-util@^0.9.0":
+ version "0.9.0"
+ resolved "https://registry.yarnpkg.com/@tybys/wasm-util/-/wasm-util-0.9.0.tgz#3e75eb00604c8d6db470bf18c37b7d984a0e3355"
+ integrity sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==
+ dependencies:
+ tslib "^2.4.0"
+
"@types/babel__core@^7.20.5":
version "7.20.5"
resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz"
@@ -742,6 +1070,11 @@
dependencies:
"@types/tern" "*"
+"@types/css-font-loading-module@^0.0.12":
+ version "0.0.12"
+ resolved "https://registry.yarnpkg.com/@types/css-font-loading-module/-/css-font-loading-module-0.0.12.tgz#65494833928823f998fbe8e86312821875d80db5"
+ integrity sha512-x2tZZYkSxXqWvTDgveSynfjq/T2HyiZHXb00j/+gy19yp70PHCizM48XFdjBCWH7eHBD0R5i/pw9yMBP/BH5uA==
+
"@types/debug@^4.0.0":
version "4.1.12"
resolved "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz"
@@ -754,6 +1087,11 @@
resolved "https://registry.npmjs.org/@types/draco3d/-/draco3d-1.4.10.tgz"
integrity sha512-AX22jp8Y7wwaBgAixaSvkoG4M/+PlAcm3Qs4OW8yT9DM4xUpWKeFhLueTAyZF39pviAdcDdeJoACapiAceqNcw==
+"@types/earcut@^3.0.0":
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/@types/earcut/-/earcut-3.0.0.tgz#c21ab8372c47f8af1bec63cb36eecb6917b6c5b6"
+ integrity sha512-k/9fOUGO39yd2sCjrbAJvGDEQvRwRnQIZlBz43roGwUZo5SHAmyVvSFyaVVZkicRVCaDXPKlbxrUcBuJoSWunQ==
+
"@types/estree-jsx@^1.0.0":
version "1.0.5"
resolved "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz"
@@ -761,7 +1099,7 @@
dependencies:
"@types/estree" "*"
-"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.6", "@types/estree@1.0.7":
+"@types/estree@*", "@types/estree@1.0.7", "@types/estree@^1.0.0", "@types/estree@^1.0.6":
version "1.0.7"
resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz"
integrity sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==
@@ -795,7 +1133,7 @@
resolved "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz"
integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==
-"@types/node@^18.0.0 || ^20.0.0 || >=22.0.0", "@types/node@^22.15.24":
+"@types/node@^22.15.24":
version "22.15.24"
resolved "https://registry.npmjs.org/@types/node/-/node-22.15.24.tgz"
integrity sha512-w9CZGm9RDjzTh/D+hFwlBJ3ziUaVw7oufKA3vOFSOZlzmW9AkZnfjPb+DLnrV6qtgL/LNmP0/2zBNCFHL3F0ng==
@@ -837,7 +1175,7 @@
resolved "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz"
integrity sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==
-"@types/react@*", "@types/react@^17.0.0 || ^18.0.0 || ^19.0.0", "@types/react@^18.2.25 || ^19", "@types/react@^19.0.0", "@types/react@^19.1.2", "@types/react@>=16.8", "@types/react@>=18", "@types/react@>=18.0.0":
+"@types/react@^19.1.2":
version "19.1.6"
resolved "https://registry.npmjs.org/@types/react/-/react-19.1.6.tgz"
integrity sha512-JeG0rEWak0N6Itr6QUx+X60uQmN+5t3j9r/OVDtWzFXKaj6kD1BwJzOksD0FF6iWxZlbE1kB0q9vtnU2ekqa1Q==
@@ -856,7 +1194,7 @@
dependencies:
"@types/estree" "*"
-"@types/three@*", "@types/three@>=0.134.0":
+"@types/three@*":
version "0.177.0"
resolved "https://registry.npmjs.org/@types/three/-/three-0.177.0.tgz"
integrity sha512-/ZAkn4OLUijKQySNci47lFO+4JLE1TihEjsGWPUT+4jWqxtwOPPEwJV1C3k5MEx0mcBPCdkFjzRzDOnHEI1R+A==
@@ -904,7 +1242,7 @@
natural-compare "^1.4.0"
ts-api-utils "^2.1.0"
-"@typescript-eslint/parser@^8.33.0", "@typescript-eslint/parser@8.33.0":
+"@typescript-eslint/parser@8.33.0":
version "8.33.0"
resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.33.0.tgz"
integrity sha512-JaehZvf6m0yqYp34+RVnihBAChkqeH+tqqhS0GuX1qgPpwLvmTPheKEs6OeCK6hVJgXZHJ2vbjnC9j119auStQ==
@@ -932,7 +1270,7 @@
"@typescript-eslint/types" "8.33.0"
"@typescript-eslint/visitor-keys" "8.33.0"
-"@typescript-eslint/tsconfig-utils@^8.33.0", "@typescript-eslint/tsconfig-utils@8.33.0":
+"@typescript-eslint/tsconfig-utils@8.33.0", "@typescript-eslint/tsconfig-utils@^8.33.0":
version "8.33.0"
resolved "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.33.0.tgz"
integrity sha512-sTkETlbqhEoiFmGr1gsdq5HyVbSOF0145SYDJ/EQmXHtKViCaGvnyLqWFFHtEXoS0J1yU8Wyou2UGmgW88fEug==
@@ -947,7 +1285,7 @@
debug "^4.3.4"
ts-api-utils "^2.1.0"
-"@typescript-eslint/types@^8.33.0", "@typescript-eslint/types@8.33.0":
+"@typescript-eslint/types@8.33.0", "@typescript-eslint/types@^8.33.0":
version "8.33.0"
resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.0.tgz"
integrity sha512-DKuXOKpM5IDT1FA2g9x9x1Ug81YuKrzf4mYX8FAVSNu5Wo/LELHWQyM1pQaDkI42bX15PWl0vNPt1uGiIFUOpg==
@@ -1015,17 +1353,22 @@
"@types/babel__core" "^7.20.5"
react-refresh "^0.17.0"
-"@webgpu/types@*":
+"@webgpu/types@*", "@webgpu/types@^0.1.40":
version "0.1.61"
resolved "https://registry.npmjs.org/@webgpu/types/-/types-0.1.61.tgz"
integrity sha512-w2HbBvH+qO19SB5pJOJFKs533CdZqxl3fcGonqL321VHkW7W/iBo6H8bjDy6pr/+pbMwIu5dnuaAxH7NxBqUrQ==
+"@xmldom/xmldom@^0.8.10":
+ version "0.8.10"
+ resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz#a1337ca426aa61cef9fe15b5b28e340a72f6fa99"
+ integrity sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==
+
acorn-jsx@^5.3.2:
version "5.3.2"
resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz"
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
-"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.14.0:
+acorn@^8.14.0:
version "8.14.1"
resolved "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz"
integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==
@@ -1124,7 +1467,7 @@ braces@^3.0.3:
dependencies:
fill-range "^7.1.1"
-browserslist@^4.24.0, "browserslist@>= 4.21.0":
+browserslist@^4.24.0:
version "4.24.5"
resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.24.5.tgz"
integrity sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==
@@ -1378,12 +1721,12 @@ dunder-proto@^1.0.1:
es-errors "^1.3.0"
gopd "^1.2.0"
-earcut@^3.0.0:
+earcut@^3.0.0, earcut@^3.0.1:
version "3.0.1"
resolved "https://registry.npmjs.org/earcut/-/earcut-3.0.1.tgz"
integrity sha512-0l1/0gOjESMeQyYaK5IDiPNvFeu93Z/cO0TjZh9eZ1vyCtZnA7KMZ8rQggpsJHIbGSdrqYq9OhuveadOVHCshw==
-easymde@^2.20.0, "easymde@>= 2.0.0 < 3.0.0":
+easymde@^2.20.0:
version "2.20.0"
resolved "https://registry.npmjs.org/easymde/-/easymde-2.20.0.tgz"
integrity sha512-V1Z5f92TfR42Na852OWnIZMbM7zotWQYTddNaLYZFVKj7APBbyZ3FYJ27gBw2grMW3R6Qdv9J8n5Ij7XRSIgXQ==
@@ -1515,7 +1858,7 @@ eslint-visitor-keys@^4.2.0:
resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz"
integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==
-"eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^8.57.0 || ^9.0.0", eslint@^9.25.0, eslint@>=8.40:
+eslint@^9.25.0:
version "9.27.0"
resolved "https://registry.npmjs.org/eslint/-/eslint-9.27.0.tgz"
integrity sha512-ixRawFQuMB9DZ7fjU3iGGganFDp3+45bPOdaRurcFHSXO1e/sYwUX/FtQZpLZJR6SjMoJH8hR2pPEAfDyCoU2Q==
@@ -1767,6 +2110,13 @@ get-proto@^1.0.1:
dunder-proto "^1.0.1"
es-object-atoms "^1.0.0"
+gifuct-js@^2.1.2:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/gifuct-js/-/gifuct-js-2.1.2.tgz#06152437ba30ec914db8398bd838bd0fbc8a6ecd"
+ integrity sha512-rI2asw77u0mGgwhV3qA+OEgYqaDn5UNqgs+Bx0FGwSpuqfYn+Ir6RQY5ENNQ8SbIiG/m5gVa7CD5RriO4f4Lsg==
+ dependencies:
+ js-binary-schema-parser "^2.0.3"
+
glob-parent@^5.1.2:
version "5.1.2"
resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz"
@@ -2064,6 +2414,11 @@ isexe@^2.0.0:
resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz"
integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
+ismobilejs@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/ismobilejs/-/ismobilejs-1.1.1.tgz#c56ca0ae8e52b24ca0f22ba5ef3215a2ddbbaa0e"
+ integrity sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw==
+
its-fine@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/its-fine/-/its-fine-2.0.0.tgz"
@@ -2071,11 +2426,16 @@ its-fine@^2.0.0:
dependencies:
"@types/react-reconciler" "^0.28.9"
-jiti@*, jiti@^2.4.2, jiti@>=1.21.0:
+jiti@^2.4.2:
version "2.4.2"
resolved "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz"
integrity sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==
+js-binary-schema-parser@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/js-binary-schema-parser/-/js-binary-schema-parser-2.0.3.tgz#3d7848748e8586e63b34e8911b643f59cfb6396e"
+ integrity sha512-xezGJmOb4lk/M1ZZLTR/jaBHQ4gG/lqQnJqdIv4721DMggsa1bDVlHXNeHYogaIEHD9vCRv0fcL4hMA+Coarkg==
+
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
@@ -2150,7 +2510,52 @@ lightningcss-darwin-arm64@1.30.1:
resolved "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz"
integrity sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==
-lightningcss@^1.21.0, lightningcss@1.30.1:
+lightningcss-darwin-x64@1.30.1:
+ version "1.30.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz#e81105d3fd6330860c15fe860f64d39cff5fbd22"
+ integrity sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==
+
+lightningcss-freebsd-x64@1.30.1:
+ version "1.30.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz#a0e732031083ff9d625c5db021d09eb085af8be4"
+ integrity sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==
+
+lightningcss-linux-arm-gnueabihf@1.30.1:
+ version "1.30.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz#1f5ecca6095528ddb649f9304ba2560c72474908"
+ integrity sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==
+
+lightningcss-linux-arm64-gnu@1.30.1:
+ version "1.30.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz#eee7799726103bffff1e88993df726f6911ec009"
+ integrity sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==
+
+lightningcss-linux-arm64-musl@1.30.1:
+ version "1.30.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz#f2e4b53f42892feeef8f620cbb889f7c064a7dfe"
+ integrity sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==
+
+lightningcss-linux-x64-gnu@1.30.1:
+ version "1.30.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz#2fc7096224bc000ebb97eea94aea248c5b0eb157"
+ integrity sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==
+
+lightningcss-linux-x64-musl@1.30.1:
+ version "1.30.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz#66dca2b159fd819ea832c44895d07e5b31d75f26"
+ integrity sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==
+
+lightningcss-win32-arm64-msvc@1.30.1:
+ version "1.30.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz#7d8110a19d7c2d22bfdf2f2bb8be68e7d1b69039"
+ integrity sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==
+
+lightningcss-win32-x64-msvc@1.30.1:
+ version "1.30.1"
+ resolved "https://registry.yarnpkg.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz#fd7dd008ea98494b85d24b4bea016793f2e0e352"
+ integrity sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==
+
+lightningcss@1.30.1:
version "1.30.1"
resolved "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz"
integrity sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==
@@ -2613,7 +3018,7 @@ mobx-react-lite@^4.1.0:
dependencies:
use-sync-external-store "^1.4.0"
-mobx@^6.13.7, mobx@^6.9.0:
+mobx@^6.13.7:
version "6.13.7"
resolved "https://registry.npmjs.org/mobx/-/mobx-6.13.7.tgz"
integrity sha512-aChaVU/DO5aRPmk1GX8L+whocagUUpBQqoPtJk+cm7UOXUk87J4PeWCh6nNmTTIfEhiR9DI/+FnA8dln/hTK7g==
@@ -2720,6 +3125,11 @@ parse-json@^5.0.0:
json-parse-even-better-errors "^2.3.0"
lines-and-columns "^1.1.6"
+parse-svg-path@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/parse-svg-path/-/parse-svg-path-0.1.2.tgz#7a7ec0d1eb06fa5325c7d3e009b859a09b5d49eb"
+ integrity sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ==
+
parse5@^7.0.0:
version "7.3.0"
resolved "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz"
@@ -2772,11 +3182,27 @@ picomatch@^2.3.1:
resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
-"picomatch@^3 || ^4", picomatch@^4.0.2:
+picomatch@^4.0.2:
version "4.0.2"
resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz"
integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==
+pixi.js@^8.10.1:
+ version "8.10.1"
+ resolved "https://registry.yarnpkg.com/pixi.js/-/pixi.js-8.10.1.tgz#da7aca668fdb13c31b7eb4467a19ce5fa89db34e"
+ integrity sha512-wjKJXawhTUxuyKIuwE3jK05eBh5I4GKy+YrRVniURFRkK7pYEvRvnV41dEqz6owSXav/YMXdG5783YDJeamiow==
+ dependencies:
+ "@pixi/colord" "^2.9.6"
+ "@types/css-font-loading-module" "^0.0.12"
+ "@types/earcut" "^3.0.0"
+ "@webgpu/types" "^0.1.40"
+ "@xmldom/xmldom" "^0.8.10"
+ earcut "^3.0.1"
+ eventemitter3 "^5.0.1"
+ gifuct-js "^2.1.2"
+ ismobilejs "^1.1.1"
+ parse-svg-path "^0.1.2"
+
postcss-selector-parser@6.0.10:
version "6.0.10"
resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz"
@@ -2817,7 +3243,7 @@ promise-worker-transferable@^1.0.4:
is-promise "^2.1.0"
lie "^3.0.2"
-prop-types@^15.5.4, prop-types@^15.6.2, prop-types@^15.8.1:
+prop-types@^15.6.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@@ -2883,7 +3309,7 @@ react-colorful@^5.6.1:
resolved "https://registry.npmjs.org/react-colorful/-/react-colorful-5.6.1.tgz"
integrity sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==
-"react-dom@^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom@^18 || ^19", "react-dom@^18.0.0 || ^19.0.0", react-dom@^19, react-dom@^19.0.0, react-dom@^19.1.0, react-dom@>=16.0.0, react-dom@>=16.13, react-dom@>=16.6.0, react-dom@>=16.8.0, react-dom@>=16.8.2, react-dom@>=18:
+react-dom@^19.1.0:
version "19.1.0"
resolved "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz"
integrity sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==
@@ -2933,7 +3359,7 @@ react-photo-sphere-viewer@^6.2.3:
dependencies:
eventemitter3 "^5.0.1"
-react-reconciler@^0.31.0:
+react-reconciler@0.31.0, react-reconciler@^0.31.0:
version "0.31.0"
resolved "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.31.0.tgz"
integrity sha512-7Ob7Z+URmesIsIVRjnLoDGwBEG/tVitidU0nMsqX/eeJaLY89RISO/10ERe0MqmzuKUUB1rmY+h1itMbUHg9BQ==
@@ -2997,12 +3423,12 @@ react-use-measure@^2.1.7:
resolved "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.7.tgz"
integrity sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==
-"react@^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^16.8.0 || ^17 || ^18 || ^19", "react@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^17.0.0 || ^18.0.0 || ^19.0.0", "react@^18 || ^19", "react@^18.0 || ^19", "react@^18.0.0 || ^19.0.0", react@^19, react@^19.0.0, react@^19.1.0, "react@>= 16.8 || 18.0.0", "react@>= 16.8.0", react@>=16.0.0, react@>=16.13, react@>=16.6.0, react@>=16.8, react@>=16.8.0, react@>=16.8.2, react@>=17.0, react@>=18, react@>=18.0.0:
+react@^19.1.0:
version "19.1.0"
resolved "https://registry.npmjs.org/react/-/react-19.1.0.tgz"
integrity sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==
-redux@^5.0.0, redux@^5.0.1:
+redux@^5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz"
integrity sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==
@@ -3223,7 +3649,7 @@ suspend-react@^0.1.3:
resolved "https://registry.npmjs.org/suspend-react/-/suspend-react-0.1.3.tgz"
integrity sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ==
-tailwindcss@^4.1.8, "tailwindcss@>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1", tailwindcss@4.1.8:
+tailwindcss@4.1.8, tailwindcss@^4.1.8:
version "4.1.8"
resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.8.tgz"
integrity sha512-kjeW8gjdxasbmFKpVGrGd5T4i40mV5J2Rasw48QARfYeQ8YS9x02ON9SFWax3Qf616rt4Cp3nVNIj6Hd1mP3og==
@@ -3272,7 +3698,7 @@ three@^0.175.0:
resolved "https://registry.npmjs.org/three/-/three-0.175.0.tgz"
integrity sha512-nNE3pnTHxXN/Phw768u0Grr7W4+rumGg/H6PgeseNJojkJtmeHJfZWi41Gp2mpXl1pg1pf1zjwR4McM1jTqkpg==
-three@^0.177.0, "three@>= 0.159.0", three@>=0.125.0, three@>=0.126.1, three@>=0.128.0, three@>=0.134.0, three@>=0.137, three@>=0.156, three@>=0.159:
+three@^0.177.0:
version "0.177.0"
resolved "https://registry.npmjs.org/three/-/three-0.177.0.tgz"
integrity sha512-EiXv5/qWAaGI+Vz2A+JfavwYCMdGjxVsrn3oBwllUoqYeaBO75J63ZfyaQKoiLrqNHoTlUc6PFgMXnS0kI45zg==
@@ -3332,9 +3758,9 @@ ts-api-utils@^2.1.0:
resolved "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz"
integrity sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==
-tslib@^2.7.0:
+tslib@^2.4.0, tslib@^2.7.0, tslib@^2.8.0:
version "2.8.1"
- resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
tunnel-rat@^0.1.2:
@@ -3360,7 +3786,7 @@ typescript-eslint@^8.30.1:
"@typescript-eslint/parser" "8.33.0"
"@typescript-eslint/utils" "8.33.0"
-typescript@>=4.8.4, "typescript@>=4.8.4 <5.9.0", typescript@~5.8.3:
+typescript@~5.8.3:
version "5.8.3"
resolved "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz"
integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==
@@ -3441,7 +3867,7 @@ uri-js@^4.2.2:
dependencies:
punycode "^2.1.0"
-use-sync-external-store@^1.2.2, use-sync-external-store@^1.4.0, use-sync-external-store@^1.5.0, use-sync-external-store@>=1.2.0:
+use-sync-external-store@^1.2.2, use-sync-external-store@^1.4.0, use-sync-external-store@^1.5.0:
version "1.5.0"
resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz"
integrity sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==
@@ -3487,7 +3913,7 @@ vfile@^6.0.0:
"@types/unist" "^3.0.0"
vfile-message "^4.0.0"
-"vite@^4.2.0 || ^5.0.0 || ^6.0.0", "vite@^5.2.0 || ^6", vite@^6.3.5:
+vite@^6.3.5:
version "6.3.5"
resolved "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz"
integrity sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==
@@ -3553,11 +3979,6 @@ yaml@^1.10.0:
resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz"
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
-yaml@^2.4.2:
- version "2.8.0"
- resolved "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz"
- integrity sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==
-
yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz"