diff --git a/package-lock.json b/package-lock.json
index cb1c3f0..006c228 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,12 +10,14 @@
"dependencies": {
"@emotion/react": "^11.8.2",
"@emotion/styled": "^11.8.1",
+ "@esbuild/win32-x64": "^0.25.3",
"@hello-pangea/dnd": "^18.0.1",
"@mui/icons-material": "^6.1.6",
"@mui/lab": "^6.0.0-beta.14",
"@mui/material": "^6.1.7",
"@mui/x-data-grid": "^7.22.2",
"@photo-sphere-viewer/core": "^5.13.2",
+ "@pixi/react": "^8.0.0-beta.25",
"@react-three/drei": "^10.0.6",
"@react-three/fiber": "^9.1.2",
"@refinedev/cli": "^2.16.21",
@@ -38,6 +40,7 @@
"jwt-decode": "^4.0.0",
"mobx": "^6.13.7",
"mobx-react-lite": "^4.1.0",
+ "pixi.js": "^8.2.6",
"react": "19.0.0",
"react-beautiful-dnd": "^13.1.1",
"react-dom": "19.0.0",
@@ -937,6 +940,54 @@
"integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==",
"license": "MIT"
},
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
+ "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
+ "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
+ "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/@esbuild/darwin-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
@@ -954,6 +1005,292 @@
"node": ">=12"
}
},
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
+ "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
+ "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
+ "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
+ "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
+ "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
+ "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
+ "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
+ "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
+ "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
+ "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
+ "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
+ "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
+ "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
+ "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
+ "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
+ "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
+ "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.3.tgz",
+ "integrity": "sha512-ICgUR+kPimx0vvRzf+N/7L7tVSQeE3BYY+NhHRHXS1kBuPO7z2+7ea2HbhDyZdTephgvNvKrlDDKUexuCVBVvg==",
+ "cpu": [
+ "x64"
+ ],
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/@eslint-community/eslint-utils": {
"version": "4.6.1",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.6.1.tgz",
@@ -1998,6 +2335,35 @@
"three": "^0.175.0"
}
},
+ "node_modules/@pixi/colord": {
+ "version": "2.9.6",
+ "resolved": "https://registry.npmjs.org/@pixi/colord/-/colord-2.9.6.tgz",
+ "integrity": "sha512-nezytU2pw587fQstUu1AsJZDVEynjskwOL+kibwcdxsMBFqPsFFNA7xl0ii/gXuDi6M0xj3mfRJj8pBSc2jCfA=="
+ },
+ "node_modules/@pixi/react": {
+ "version": "8.0.0-beta.25",
+ "resolved": "https://registry.npmjs.org/@pixi/react/-/react-8.0.0-beta.25.tgz",
+ "integrity": "sha512-nXZbWj6nBHoOhlN1hKjKCeSPWPcv4BGBe8Em8B2V/QrSiihKI4C2vaxvV6Q1udLGsLnv4Hv9EBVa0Ixe0QAdiQ==",
+ "dependencies": {
+ "its-fine": "^1.2.5",
+ "react-reconciler": "0.31.0"
+ },
+ "peerDependencies": {
+ "pixi.js": "^8.2.6",
+ "react": ">=19.0.0"
+ }
+ },
+ "node_modules/@pixi/react/node_modules/its-fine": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/its-fine/-/its-fine-1.2.5.tgz",
+ "integrity": "sha512-fXtDA0X0t0eBYAGLVM5YsgJGsJ5jEmqZEPrGbzdf5awjv0xE7nqv3TVnvtUF060Tkes15DbDAKW/I48vsb6SyA==",
+ "dependencies": {
+ "@types/react-reconciler": "^0.28.0"
+ },
+ "peerDependencies": {
+ "react": ">=18.0"
+ }
+ },
"node_modules/@pkgjs/parseargs": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@@ -3262,6 +3628,11 @@
"@types/tern": "*"
}
},
+ "node_modules/@types/css-font-loading-module": {
+ "version": "0.0.12",
+ "resolved": "https://registry.npmjs.org/@types/css-font-loading-module/-/css-font-loading-module-0.0.12.tgz",
+ "integrity": "sha512-x2tZZYkSxXqWvTDgveSynfjq/T2HyiZHXb00j/+gy19yp70PHCizM48XFdjBCWH7eHBD0R5i/pw9yMBP/BH5uA=="
+ },
"node_modules/@types/d3-color": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-2.0.6.tgz",
@@ -3318,6 +3689,11 @@
"integrity": "sha512-AX22jp8Y7wwaBgAixaSvkoG4M/+PlAcm3Qs4OW8yT9DM4xUpWKeFhLueTAyZF39pviAdcDdeJoACapiAceqNcw==",
"license": "MIT"
},
+ "node_modules/@types/earcut": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@types/earcut/-/earcut-2.1.4.tgz",
+ "integrity": "sha512-qp3m9PPz4gULB9MhjGID7wpo3gJ4bTGXm7ltNDsmOvsPduTeHp8wSW9YckBj3mljeOh4F0m2z/0JKAALRKbmLQ=="
+ },
"node_modules/@types/estree": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
@@ -3886,6 +4262,14 @@
"integrity": "sha512-8B/tdfRFKdrnejqmvq95ogp8tf52oZ51p3f4QD5m5Paey/qlX4Rhhy5Y8tgFMi7Ms70HzcMMw3EQjH/jdhTwlA==",
"license": "BSD-3-Clause"
},
+ "node_modules/@xmldom/xmldom": {
+ "version": "0.8.10",
+ "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
+ "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
"node_modules/accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@@ -5418,6 +5802,11 @@
"node": ">= 0.4"
}
},
+ "node_modules/earcut": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz",
+ "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ=="
+ },
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
@@ -5610,6 +5999,22 @@
"@esbuild/win32-x64": "0.18.20"
}
},
+ "node_modules/esbuild/node_modules/@esbuild/win32-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
+ "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
@@ -7410,6 +7815,11 @@
"node": ">=16"
}
},
+ "node_modules/ismobilejs": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ismobilejs/-/ismobilejs-1.1.1.tgz",
+ "integrity": "sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw=="
+ },
"node_modules/isobject": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
@@ -9887,6 +10297,11 @@
"integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==",
"license": "MIT"
},
+ "node_modules/parse-svg-path": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz",
+ "integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ=="
+ },
"node_modules/parse5": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
@@ -10017,6 +10432,22 @@
"node": ">= 6"
}
},
+ "node_modules/pixi.js": {
+ "version": "8.2.6",
+ "resolved": "https://registry.npmjs.org/pixi.js/-/pixi.js-8.2.6.tgz",
+ "integrity": "sha512-CNfr7CmjIEWJ06e3TBrXBKFpcTPMGUaFdtP4RlMOgNOTkDD6+Bhm728I/EkGAo2vsOVO1YwNFsuORQyD3MngZg==",
+ "dependencies": {
+ "@pixi/colord": "^2.9.6",
+ "@types/css-font-loading-module": "^0.0.12",
+ "@types/earcut": "^2.1.4",
+ "@webgpu/types": "^0.1.40",
+ "@xmldom/xmldom": "^0.8.10",
+ "earcut": "^2.2.4",
+ "eventemitter3": "^5.0.1",
+ "ismobilejs": "^1.1.1",
+ "parse-svg-path": "^0.1.2"
+ }
+ },
"node_modules/pkg-dir": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
@@ -12477,7 +12908,6 @@
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-4.3.0.tgz",
"integrity": "sha512-Jy9qLB2/PyWklpYy0xk0UU3TlU0t2UMpJXZvf+hWII1lAmRHrOUKi11Uw8N3rxoNk7atZNYO3pR3vI1f7oi+6w==",
- "license": "MIT",
"dependencies": {
"@rollup/pluginutils": "^5.1.3",
"@svgr/core": "^8.1.0",
diff --git a/package.json b/package.json
index b6b5a6d..0728d8a 100644
--- a/package.json
+++ b/package.json
@@ -6,12 +6,14 @@
"dependencies": {
"@emotion/react": "^11.8.2",
"@emotion/styled": "^11.8.1",
+ "@esbuild/win32-x64": "^0.25.3",
"@hello-pangea/dnd": "^18.0.1",
"@mui/icons-material": "^6.1.6",
"@mui/lab": "^6.0.0-beta.14",
"@mui/material": "^6.1.7",
"@mui/x-data-grid": "^7.22.2",
"@photo-sphere-viewer/core": "^5.13.2",
+ "@pixi/react": "^8.0.0-beta.25",
"@react-three/drei": "^10.0.6",
"@react-three/fiber": "^9.1.2",
"@refinedev/cli": "^2.16.21",
@@ -34,6 +36,7 @@
"jwt-decode": "^4.0.0",
"mobx": "^6.13.7",
"mobx-react-lite": "^4.1.0",
+ "pixi.js": "^8.2.6",
"react": "19.0.0",
"react-beautiful-dnd": "^13.1.1",
"react-dom": "19.0.0",
diff --git a/public/Emblem.svg b/public/Emblem.svg
new file mode 100644
index 0000000..724f0ee
--- /dev/null
+++ b/public/Emblem.svg
@@ -0,0 +1,373 @@
+
diff --git a/public/GET.png b/public/GET.png
new file mode 100644
index 0000000..d224f3f
Binary files /dev/null and b/public/GET.png differ
diff --git a/public/SightIcon.png b/public/SightIcon.png
new file mode 100644
index 0000000..02e8adb
Binary files /dev/null and b/public/SightIcon.png differ
diff --git a/src/App.tsx b/src/App.tsx
index bb67e71..684b53f 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -58,6 +58,7 @@ import {
VehicleShow,
} from "./pages/vehicle";
import { RouteList, RouteCreate, RouteEdit, RouteShow } from "./pages/route";
+import { RoutePreview } from "./pages/route-preview";
import { UserList, UserCreate, UserEdit, UserShow } from "./pages/user";
import {
@@ -201,6 +202,15 @@ function App() {
icon: ,
},
},
+ {
+ name: "route-preview",
+ list: "/route",
+ show: "/route/:id/station",
+ meta: {
+ hide: true,
+ stations: "route/:id/station"
+ },
+ },
{
name: "user",
list: "/user",
@@ -223,6 +233,10 @@ function App() {
>
+
+ } />
+
+
{
+ 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, applicationRef, getCenter } = useTransform();
+ const { routeData, originalRouteData } = useMapData();
+
+ 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 handlePointerDown = (e: FederatedMouseEvent) => {
+ setIsDragging(true);
+ setStartPosition({
+ x: position.x,
+ y: position.y
+ });
+ setStartMousePosition({
+ x: e.globalX,
+ y: e.globalY
+ });
+ setStartRotation(rotation);
+ e.stopPropagation();
+ };
+
+
+ useEffect(() => {
+ setRotation((originalRouteData?.rotate ?? 0) * Math.PI / 180);
+ }, [originalRouteData?.rotate]);
+ // Get canvas element and its dimensions/position
+ const handlePointerMove = (e: FederatedMouseEvent) => {
+ if (!isDragging) return;
+
+ if (e.shiftKey) {
+ const center = getCenter();
+ 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 {
+ setPosition({
+ x: startPosition.x - startMousePosition.x + e.globalX,
+ y: startPosition.y - startMousePosition.y + e.globalY
+ });
+ }
+ e.stopPropagation();
+ };
+
+ // Handle mouse up
+ const handlePointerUp = (e: FederatedMouseEvent) => {
+ setIsDragging(false);
+ e.stopPropagation();
+ };
+ // Handle mouse wheel for zooming
+ const handleWheel = (e: FederatedWheelEvent) => {
+ e.stopPropagation();
+
+ // 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)/20;
+ const scaleMax = (routeData?.scale_max ?? 20)/20;
+
+ let zoomFactor = e.deltaY > 0 ? 0.9 : 1.1; // Zoom out/in
+ //const newScale = scale * zoomFactor;
+ const newScale = Math.max(scaleMin, Math.min(scaleMax, scale * zoomFactor));
+ zoomFactor = newScale / scale;
+
+ if (scale === newScale) {
+ return;
+ }
+
+ // Update position to zoom towards mouse cursor
+ setPosition({
+ x: position.x + mouseX * (1 - zoomFactor),
+ y: position.y + mouseY * (1 - zoomFactor)
+ });
+
+ setScale(newScale);
+ };
+
+
+ return (
+
+ {applicationRef?.current && (
+ {
+ const canvas = applicationRef.current!.getCanvas();
+ 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}
+
+ {
+ g.clear();
+ const center = getCenter();
+ g.circle(center.x, center.y, 1);
+ g.fill("#fff");
+ }}
+ />
+
+ );
+}
\ No newline at end of file
diff --git a/src/pages/route-preview/LeftSidebar.tsx b/src/pages/route-preview/LeftSidebar.tsx
new file mode 100644
index 0000000..49c02ff
--- /dev/null
+++ b/src/pages/route-preview/LeftSidebar.tsx
@@ -0,0 +1,33 @@
+import { Stack, Typography, Button } from "@mui/material";
+
+export function LeftSidebar() {
+ return (
+
+
+
+
+ При поддержке Правительства
+ Санкт-Петербурга
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #ВсемПоПути
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/pages/route-preview/MapDataContext.tsx b/src/pages/route-preview/MapDataContext.tsx
new file mode 100644
index 0000000..b8ea2ee
--- /dev/null
+++ b/src/pages/route-preview/MapDataContext.tsx
@@ -0,0 +1,187 @@
+import { useCustom, useShow, useApiUrl } from "@refinedev/core";
+import { useParams } from "react-router";
+import { createContext, ReactNode, useContext, useEffect, useMemo, useState } from "react";
+import { RouteData, SightData, StationData, StationPatchData } from "./types";
+import { axiosInstance } from "../../providers/data";
+
+
+
+const MapDataContext = createContext<{
+ originalRouteData?: RouteData,
+ originalStationData?: StationData[],
+ originalSightData?: SightData[],
+ routeData?: RouteData,
+ stationData?: StationData[],
+ 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,
+ saveChanges: () => void,
+}>({
+ originalRouteData: undefined,
+ originalStationData: undefined,
+ originalSightData: undefined,
+ routeData: undefined,
+ stationData: undefined,
+ sightData: undefined,
+
+ isRouteLoading: true,
+ isStationLoading: true,
+ isSightLoading: true,
+ setScaleRange: () => {},
+ setMapRotation: () => {},
+ setMapCenter: () => {},
+ setStationOffset: () => {},
+ saveChanges: () => {},
+});
+
+export function MapDataProvider({ children }: Readonly<{ children: ReactNode }>) {
+ const { id: routeId } = useParams<{ id: string }>();
+ const apiUrl = useApiUrl();
+
+ const [originalRouteData, setOriginalRouteData] = useState();
+ const [originalStationData, setOriginalStationData] = useState();
+ const [originalSightData, setOriginalSightData] = useState();
+
+ const [routeData, setRouteData] = useState();
+ const [stationData, setStationData] = useState();
+ const [sightData, setSightData] = useState();
+
+ const [routeChanges, setRouteChanges] = useState({} as RouteData);
+ const [stationChanges, setStationChanges] = useState([]);
+ const [sightChanges, setSightChanges] = useState([]);
+
+
+ const { data: routeQuery, isLoading: isRouteLoading } = useCustom({
+ url: `${apiUrl}/route/${routeId}`,
+ method: 'get',
+ });
+ const { data: stationQuery, isLoading: isStationLoading } = useCustom({
+ url: `${apiUrl}/route/${routeId}/station`,
+ method: 'get',
+ });
+ const { data: sightQuery, isLoading: isSightLoading } = useCustom({
+ url: `${apiUrl}/route/${routeId}/sight`,
+ method: 'get',
+ });
+ useEffect(() => {
+ // if not undefined, set original data
+ if(routeQuery?.data) setOriginalRouteData(routeQuery.data as RouteData);
+ if(stationQuery?.data) setOriginalStationData(stationQuery.data as StationData[]);
+ if(sightQuery?.data) setOriginalSightData(sightQuery.data as SightData[]);
+ console.log("queries", routeQuery, stationQuery, sightQuery);
+ }, [routeQuery, stationQuery, sightQuery]);
+
+ useEffect(() => {
+ // combine changes with original data
+ if(originalRouteData) setRouteData({...originalRouteData, ...routeChanges});
+ if(originalStationData) setStationData(originalStationData);
+ if(originalSightData) setSightData(originalSightData);
+ }, [
+ originalRouteData, originalStationData, originalSightData,
+ routeChanges, stationChanges, sightChanges
+ ]);
+
+ useEffect(() => {
+ console.log("data", routeData, stationData, sightData);
+ }, [routeData, stationData, sightData]);
+
+ 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() {
+ console.log("saveChanges", routeData);
+ const response = await axiosInstance.patch(`/route/${routeId}`, routeData);
+ saveStationChanges();
+ }
+
+ async function saveStationChanges() {
+ console.log("saveStationChanges", stationChanges);
+ for(const station of stationChanges) {
+ const response = await axiosInstance.patch(`/route/${routeId}/station`, station);
+ console.log("response", response);
+ }
+ }
+
+ 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?.find((station) => station.id === stationId);
+ if(foundStation) {
+ return [...prev, {
+ station_id: stationId,
+ offset_x: x, offset_y: y,
+ transfers: foundStation.transfers
+ }];
+ }
+ return prev;
+ }
+ });
+ }
+
+ useEffect(() => {
+ console.log("stationChanges", stationChanges);
+ }, [stationChanges]);
+
+ const value = useMemo(() => ({
+ originalRouteData: originalRouteData,
+ originalStationData: originalStationData,
+ originalSightData: originalSightData,
+ routeData: routeData,
+ stationData: stationData,
+ sightData: sightData,
+ isRouteLoading,
+ isStationLoading,
+ isSightLoading,
+ setScaleRange,
+ setMapRotation,
+ setMapCenter,
+ saveChanges,
+ setStationOffset,
+ }), [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;
+};
\ No newline at end of file
diff --git a/src/pages/route-preview/RightSidebar.tsx b/src/pages/route-preview/RightSidebar.tsx
new file mode 100644
index 0000000..e4b7334
--- /dev/null
+++ b/src/pages/route-preview/RightSidebar.tsx
@@ -0,0 +1,188 @@
+import { Button, Stack, TextField, Typography } from "@mui/material";
+import { useMapData } from "./MapDataContext";
+import { useEffect, useState } from "react";
+import { useTransform } from "./TransformContext";
+
+export function RightSidebar() {
+ const { routeData, setScaleRange, saveChanges, originalRouteData, setMapRotation, setMapCenter } = useMapData();
+ const { rotation, setRotation, position, screenToLocal, getCenter, localToScreen, rotateToAngle, panToCoordinates } = 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 = getCenter();
+ const localCenter = screenToLocal(center.x, center.y);
+ setLocalCenter(localCenter);
+ }, [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}) {
+ panToCoordinates(x, y, rotation);
+ }
+
+ if(!routeData) {
+ console.error("routeData is null");
+ return null;
+ }
+
+ return (
+
+
+ Детали о достопримечательностях
+
+
+
+ setMinScale(Number(e.target.value))}
+ style={{backgroundColor: "#222", borderRadius: 4}}
+ sx={{
+ '& .MuiInputLabel-root.Mui-focused': {
+ color: "#fff"
+ }
+ }}
+ slotProps={{
+ input: {
+ min: 0.1
+ }
+ }}
+ />
+ setMaxScale(Number(e.target.value))}
+ style={{backgroundColor: "#222", borderRadius: 4}}
+ sx={{
+ '& .MuiInputLabel-root.Mui-focused': {
+ 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.Mui-focused': {
+ 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.Mui-focused': {
+ 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.Mui-focused': {
+ color: "#fff"
+ }
+ }}
+ />
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/pages/route-preview/Sight.tsx b/src/pages/route-preview/Sight.tsx
new file mode 100644
index 0000000..d873cb0
--- /dev/null
+++ b/src/pages/route-preview/Sight.tsx
@@ -0,0 +1,114 @@
+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";
+
+
+interface SightProps {
+ sight: SightData;
+ id: number;
+}
+
+export function Sight({
+ sight, id
+}: Readonly) {
+ const { rotation, scale } = useTransform();
+
+ const [position, setPosition] = useState({ x: 0, y: 0 });
+ 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;
+ const dy = (e.globalY - startMousePosition.y) / 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);
+ 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;
+ }
+
+
+ return (
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/pages/route-preview/Station.tsx b/src/pages/route-preview/Station.tsx
new file mode 100644
index 0000000..cd7aa4d
--- /dev/null
+++ b/src/pages/route-preview/Station.tsx
@@ -0,0 +1,103 @@
+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, useState } from "react";
+import { StationData } from "./types";
+import { useMapData } from "./MapDataContext";
+
+interface StationProps {
+ station: StationData;
+}
+
+export function Station({
+ station
+}: Readonly) {
+ const draw = useCallback((g: Graphics) => {
+ g.clear();
+ g.circle(station.latitude * UP_SCALE, station.longitude * UP_SCALE, STATION_RADIUS);
+ g.fill({color: PATH_COLOR});
+ g.stroke({color: BACKGROUND_COLOR, width: STATION_OUTLINE_WIDTH});
+ }, []);
+
+ return (
+
+
+
+
+ );
+}
+
+export function StationLabel({
+ station
+}: Readonly) {
+ 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) / scale;
+ const dy = (e.globalY - startMousePosition.y) / 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);
+ setStationOffset(station.id, newPosition.x, newPosition.y);
+ e.stopPropagation();
+ };
+
+ const handlePointerUp = (e: FederatedMouseEvent) => {
+ setIsDragging(false);
+ e.stopPropagation();
+ };
+
+ return (
+
+
+
+ );
+}
diff --git a/src/pages/route-preview/TransformContext.tsx b/src/pages/route-preview/TransformContext.tsx
new file mode 100644
index 0000000..cf91baf
--- /dev/null
+++ b/src/pages/route-preview/TransformContext.tsx
@@ -0,0 +1,161 @@
+import { createContext, ReactNode, RefObject, useContext, useEffect, useMemo, useRef, useState } from "react";
+import {
+ ApplicationRef
+} from '@pixi/react';
+import { UP_SCALE } from "./Constants";
+
+
+const TransformContext = createContext<{
+ position: { x: number, y: number },
+ scale: number,
+ rotation: number,
+ applicationRef: RefObject | null,
+
+ 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 },
+ getCenter: () => { x: number, y: number },
+ rotateToAngle: (to: number, fromPosition?: {x: number, y: number}) => void,
+ panToCoordinates: (latitude: number, longitude: number, rotation?: number) => void
+}>({
+ position: { x: 0, y: 0 },
+ scale: 1,
+ rotation: 0,
+ applicationRef: null,
+
+ setPosition: () => {},
+ setScale: () => {},
+ setRotation: () => {},
+ screenToLocal: () => ({ x: 0, y: 0 }),
+ localToScreen: () => ({ x: 0, y: 0 }),
+ getCenter: () => ({ x: 0, y: 0 }),
+ rotateToAngle: () => {},
+ panToCoordinates: () => {}
+});
+
+// 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 applicationRef = useRef(null);
+
+ function screenToLocal(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
+ };
+ }
+
+ // Inverse of screenToLocal
+ function localToScreen(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
+ };
+ }
+
+ function getCenter() {
+ const canvas = applicationRef?.current?.getCanvas();
+ const canvasRect = canvas?.getBoundingClientRect();
+ const canvasLeft = canvasRect?.left ?? 0;
+ const canvasTop = canvasRect?.top ?? 0;
+
+ const centerX = window.innerWidth / 2 - canvasLeft;
+ const centerY = window.innerHeight / 2 - canvasTop;
+ return {x: centerX, y: centerY};
+ }
+
+ function rotateToAngle(to: number, fromPosition?: {x: number, y: number}) {
+ setRotation(to);
+ console.log(to, fromPosition);
+ const rotationDiff = to - rotation;
+ console.log("rotationDiff", rotationDiff);
+
+ const center = getCenter();
+ const cosDelta = Math.cos(rotationDiff);
+ const sinDelta = Math.sin(rotationDiff);
+
+ fromPosition ??= position;
+
+ setPosition({
+ x: center.x * (1 - cosDelta) + fromPosition.x * cosDelta + (center.y - fromPosition.y) * sinDelta,
+ y: center.y * (1 - cosDelta) + fromPosition.y * cosDelta + (fromPosition.x - center.x) * sinDelta
+ });
+ }
+
+ function panToCoordinates(latitude: number, longitude: number, rotation?: number) {
+ const center = getCenter();
+ const newPosition = {
+ x: -latitude * UP_SCALE,
+ y: -longitude * UP_SCALE
+ };
+ rotation ??= 0;
+
+ const cos = Math.cos(rotation);
+ const sin = Math.sin(rotation);
+
+ // Translate point relative to center, rotate, then translate back
+ const dx = newPosition.x;
+ const dy = newPosition.y;
+ newPosition.x = (dx * cos - dy * sin) + center.x;
+ newPosition.y = (dx * sin + dy * cos) + center.y;
+
+
+ setPosition(newPosition);
+ }
+
+ const value = useMemo(() => ({
+ position,
+ scale,
+ rotation,
+ applicationRef,
+ getCenter,
+ setPosition,
+ setScale,
+ setRotation,
+ rotateToAngle,
+ panToCoordinates,
+ screenToLocal,
+ localToScreen
+ }), [position, scale, rotation, applicationRef]);
+
+ 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;
+};
\ No newline at end of file
diff --git a/src/pages/route-preview/TravelPath.tsx b/src/pages/route-preview/TravelPath.tsx
new file mode 100644
index 0000000..2213e11
--- /dev/null
+++ b/src/pages/route-preview/TravelPath.tsx
@@ -0,0 +1,36 @@
+import { Graphics } from "pixi.js";
+import { useCallback } from "react";
+import { PATH_COLOR, PATH_WIDTH } from "./Constants";
+
+
+interface TravelPathProps {
+ points: {x: number, y: number}[];
+}
+
+export function TravelPath({
+ points
+}: Readonly) {
+
+ const draw = useCallback((g: Graphics) => {
+ g.clear();
+ g.moveTo(points[0].x, points[0].y);
+ for (let i = 1; i < points.length - 1; i++) {
+ g.lineTo(points[i].x, points[i].y);
+ }
+ g.stroke({
+ color: PATH_COLOR,
+ width: PATH_WIDTH
+ });
+ }, [points]);
+
+ if(points.length === 0) {
+ console.error("points is empty");
+ return null;
+ }
+
+ return (
+
+ );
+}
\ No newline at end of file
diff --git a/src/pages/route-preview/Widgets.tsx b/src/pages/route-preview/Widgets.tsx
new file mode 100644
index 0000000..f9182cc
--- /dev/null
+++ b/src/pages/route-preview/Widgets.tsx
@@ -0,0 +1,31 @@
+import { Stack, Typography } from "@mui/material";
+
+export function Widgets() {
+ return (
+
+
+ Станция
+
+
+ Погода
+
+
+ )
+}
diff --git a/src/pages/route-preview/index.tsx b/src/pages/route-preview/index.tsx
new file mode 100644
index 0000000..29f7c60
--- /dev/null
+++ b/src/pages/route-preview/index.tsx
@@ -0,0 +1,137 @@
+import { useRef, useEffect, useState } from "react";
+
+import {
+ Application,
+ 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";
+
+extend({
+ Container,
+ Graphics,
+ Sprite,
+ Texture,
+ TilingSprite,
+ Text
+});
+
+export const RoutePreview = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+
+export function RouteMap() {
+ const { applicationRef, setPosition, screenToLocal, panToCoordinates } = useTransform();
+ const {
+ routeData, stationData, sightData, originalRouteData
+ } = useMapData();
+ const [points, setPoints] = useState<{x: number, y: number}[]>([]);
+
+ 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 (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);
+ }
+ } else if (
+ originalRouteData?.center_latitude &&
+ originalRouteData?.center_longitude
+ ) {
+ panToCoordinates(
+ originalRouteData?.center_latitude,
+ originalRouteData?.center_longitude,
+ originalRouteData?.rotate * Math.PI / 180
+ );
+ }
+ }, [points, originalRouteData?.center_latitude, originalRouteData?.center_longitude, originalRouteData?.rotate]);
+
+ if (!routeData || !stationData || !sightData) {
+ console.error("routeData, stationData or sightData is null");
+ return Loading...
;
+ }
+
+
+ return (
+
+
+
+
+ {stationData?.map((obj) => (
+
+ ))}
+ {sightData?.map((obj, index) => (
+
+ ))}
+
+ {
+ g.clear();
+ const localCenter = screenToLocal(0,0);
+ g.circle(localCenter.x, localCenter.y, 10);
+ g.fill("#fff");
+ }}
+ />
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/src/pages/route-preview/types.ts b/src/pages/route-preview/types.ts
new file mode 100644
index 0000000..6311136
--- /dev/null
+++ b/src/pages/route-preview/types.ts
@@ -0,0 +1,63 @@
+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 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/show.tsx b/src/pages/route/show.tsx
index 6355843..d9b47da 100644
--- a/src/pages/route/show.tsx
+++ b/src/pages/route/show.tsx
@@ -1,4 +1,4 @@
-import { Stack, Typography, Box } from "@mui/material";
+import { Stack, Typography, Box, Button } from "@mui/material";
import { useShow } from "@refinedev/core";
import { Show, TextFieldComponent as TextField } from "@refinedev/mui";
import { LinkedItems } from "../../components/LinkedItems";
@@ -8,11 +8,14 @@ import {
stationFields,
vehicleFields,
} from "./types";
+import { useNavigate, useParams } from "react-router";
export const RouteShow = () => {
const { query } = useShow({});
const { data, isLoading } = query;
const record = data?.data;
+ const { id } = useParams();
+ const navigate = useNavigate();
const fields = [
{ label: "Перевозчик", data: "carrier" },
@@ -87,6 +90,17 @@ export const RouteShow = () => {
/>
>
)}
+
+
+
+
+
);
diff --git a/yarn.lock b/yarn.lock
index 2d18a64..d0ffb3d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -453,114 +453,14 @@
resolved "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz"
integrity sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==
-"@esbuild/android-arm64@0.18.20":
- version "0.18.20"
- resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622"
- integrity sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==
-
-"@esbuild/android-arm@0.18.20":
- version "0.18.20"
- resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz#fedb265bc3a589c84cc11f810804f234947c3682"
- integrity sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==
-
-"@esbuild/android-x64@0.18.20":
- version "0.18.20"
- resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz#35cf419c4cfc8babe8893d296cd990e9e9f756f2"
- integrity sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==
-
-"@esbuild/darwin-arm64@0.18.20":
- version "0.18.20"
- resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz"
- integrity sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==
-
-"@esbuild/darwin-x64@0.18.20":
- version "0.18.20"
- resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz#d70d5790d8bf475556b67d0f8b7c5bdff053d85d"
- integrity sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==
-
-"@esbuild/freebsd-arm64@0.18.20":
- version "0.18.20"
- resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz#98755cd12707f93f210e2494d6a4b51b96977f54"
- integrity sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==
-
-"@esbuild/freebsd-x64@0.18.20":
- version "0.18.20"
- resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz#c1eb2bff03915f87c29cece4c1a7fa1f423b066e"
- integrity sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==
-
-"@esbuild/linux-arm64@0.18.20":
- version "0.18.20"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz#bad4238bd8f4fc25b5a021280c770ab5fc3a02a0"
- integrity sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==
-
-"@esbuild/linux-arm@0.18.20":
- version "0.18.20"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz#3e617c61f33508a27150ee417543c8ab5acc73b0"
- integrity sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==
-
-"@esbuild/linux-ia32@0.18.20":
- version "0.18.20"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz#699391cccba9aee6019b7f9892eb99219f1570a7"
- integrity sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==
-
-"@esbuild/linux-loong64@0.18.20":
- version "0.18.20"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz#e6fccb7aac178dd2ffb9860465ac89d7f23b977d"
- integrity sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==
-
-"@esbuild/linux-mips64el@0.18.20":
- version "0.18.20"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz#eeff3a937de9c2310de30622a957ad1bd9183231"
- integrity sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==
-
-"@esbuild/linux-ppc64@0.18.20":
- version "0.18.20"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz#2f7156bde20b01527993e6881435ad79ba9599fb"
- integrity sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==
-
-"@esbuild/linux-riscv64@0.18.20":
- version "0.18.20"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz#6628389f210123d8b4743045af8caa7d4ddfc7a6"
- integrity sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==
-
-"@esbuild/linux-s390x@0.18.20":
- version "0.18.20"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz#255e81fb289b101026131858ab99fba63dcf0071"
- integrity sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==
-
-"@esbuild/linux-x64@0.18.20":
- version "0.18.20"
- resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz#c7690b3417af318a9b6f96df3031a8865176d338"
- integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==
-
-"@esbuild/netbsd-x64@0.18.20":
- version "0.18.20"
- resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz#30e8cd8a3dded63975e2df2438ca109601ebe0d1"
- integrity sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==
-
-"@esbuild/openbsd-x64@0.18.20":
- version "0.18.20"
- resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz#7812af31b205055874c8082ea9cf9ab0da6217ae"
- integrity sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==
-
-"@esbuild/sunos-x64@0.18.20":
- version "0.18.20"
- resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz#d5c275c3b4e73c9b0ecd38d1ca62c020f887ab9d"
- integrity sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==
-
-"@esbuild/win32-arm64@0.18.20":
- version "0.18.20"
- resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz#73bc7f5a9f8a77805f357fab97f290d0e4820ac9"
- integrity sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==
-
-"@esbuild/win32-ia32@0.18.20":
- version "0.18.20"
- resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz#ec93cbf0ef1085cc12e71e0d661d20569ff42102"
- integrity sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==
+"@esbuild/win32-x64@^0.25.3":
+ version "0.25.3"
+ resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.3.tgz"
+ integrity sha512-ICgUR+kPimx0vvRzf+N/7L7tVSQeE3BYY+NhHRHXS1kBuPO7z2+7ea2HbhDyZdTephgvNvKrlDDKUexuCVBVvg==
"@esbuild/win32-x64@0.18.20":
version "0.18.20"
- resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz#786c5f41f043b07afb1af37683d7c33668858f6d"
+ resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz"
integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==
"@eslint-community/eslint-utils@^4.2.0":
@@ -851,7 +751,14 @@
csstype "^3.1.3"
prop-types "^15.8.1"
-"@mui/types@^7.2.14", "@mui/types@^7.4.1":
+"@mui/types@^7.2.14":
+ version "7.4.1"
+ resolved "https://registry.npmjs.org/@mui/types/-/types-7.4.1.tgz"
+ integrity sha512-gUL8IIAI52CRXP/MixT1tJKt3SI6tVv4U/9soFsTtAsHzaJQptZ42ffdHZV3niX1ei0aUgMvOxBBN0KYqdG39g==
+ dependencies:
+ "@babel/runtime" "^7.27.0"
+
+"@mui/types@^7.4.1":
version "7.4.1"
resolved "https://registry.npmjs.org/@mui/types/-/types-7.4.1.tgz"
integrity sha512-gUL8IIAI52CRXP/MixT1tJKt3SI6tVv4U/9soFsTtAsHzaJQptZ42ffdHZV3niX1ei0aUgMvOxBBN0KYqdG39g==
@@ -916,7 +823,7 @@
"@nodelib/fs.stat" "2.0.5"
run-parallel "^1.1.9"
-"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
+"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5":
version "2.0.5"
resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz"
integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
@@ -971,6 +878,19 @@
dependencies:
three "^0.175.0"
+"@pixi/colord@^2.9.6":
+ version "2.9.6"
+ resolved "https://registry.npmjs.org/@pixi/colord/-/colord-2.9.6.tgz"
+ integrity sha512-nezytU2pw587fQstUu1AsJZDVEynjskwOL+kibwcdxsMBFqPsFFNA7xl0ii/gXuDi6M0xj3mfRJj8pBSc2jCfA==
+
+"@pixi/react@^8.0.0-beta.25":
+ version "8.0.0-beta.25"
+ resolved "https://registry.npmjs.org/@pixi/react/-/react-8.0.0-beta.25.tgz"
+ integrity sha512-nXZbWj6nBHoOhlN1hKjKCeSPWPcv4BGBe8Em8B2V/QrSiihKI4C2vaxvV6Q1udLGsLnv4Hv9EBVa0Ixe0QAdiQ==
+ dependencies:
+ its-fine "^1.2.5"
+ react-reconciler "0.31.0"
+
"@pkgjs/parseargs@^0.11.0":
version "0.11.0"
resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz"
@@ -1409,6 +1329,11 @@
dependencies:
"@types/tern" "*"
+"@types/css-font-loading-module@^0.0.12":
+ version "0.0.12"
+ resolved "https://registry.npmjs.org/@types/css-font-loading-module/-/css-font-loading-module-0.0.12.tgz"
+ integrity sha512-x2tZZYkSxXqWvTDgveSynfjq/T2HyiZHXb00j/+gy19yp70PHCizM48XFdjBCWH7eHBD0R5i/pw9yMBP/BH5uA==
+
"@types/d3-color@^2":
version "2.0.6"
resolved "https://registry.npmjs.org/@types/d3-color/-/d3-color-2.0.6.tgz"
@@ -1460,6 +1385,11 @@
resolved "https://registry.npmjs.org/@types/draco3d/-/draco3d-1.4.10.tgz"
integrity sha512-AX22jp8Y7wwaBgAixaSvkoG4M/+PlAcm3Qs4OW8yT9DM4xUpWKeFhLueTAyZF39pviAdcDdeJoACapiAceqNcw==
+"@types/earcut@^2.1.4":
+ version "2.1.4"
+ resolved "https://registry.npmjs.org/@types/earcut/-/earcut-2.1.4.tgz"
+ integrity sha512-qp3m9PPz4gULB9MhjGID7wpo3gJ4bTGXm7ltNDsmOvsPduTeHp8wSW9YckBj3mljeOh4F0m2z/0JKAALRKbmLQ==
+
"@types/estree-jsx@^1.0.0":
version "1.0.5"
resolved "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz"
@@ -1581,7 +1511,7 @@
resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.6.tgz"
integrity sha512-nf22//wEbKXusP6E9pfOCDwFdHAX4u172eaJI4YkDRQEZiorm6KfYnSC2SWLDMVWUOWPERmJnN0ujeAfTBLvrw==
-"@types/react-reconciler@^0.28.9":
+"@types/react-reconciler@^0.28.0", "@types/react-reconciler@^0.28.9":
version "0.28.9"
resolved "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.9.tgz"
integrity sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg==
@@ -1611,7 +1541,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@16 || 17 || 18 || 19":
+"@types/react@*":
version "19.1.2"
resolved "https://registry.npmjs.org/@types/react/-/react-19.1.2.tgz"
integrity sha512-oxLPMytKchWGbnQM9O7D67uPa9paTNxO7jVoNMXgkkErULBPhPARCfkKL9ytcIJJRGjbsVwW4ugJzyFFvm/Tiw==
@@ -1626,6 +1556,13 @@
"@types/prop-types" "*"
csstype "^3.0.2"
+"@types/react@16 || 17 || 18 || 19":
+ version "19.1.2"
+ resolved "https://registry.npmjs.org/@types/react/-/react-19.1.2.tgz"
+ integrity sha512-oxLPMytKchWGbnQM9O7D67uPa9paTNxO7jVoNMXgkkErULBPhPARCfkKL9ytcIJJRGjbsVwW4ugJzyFFvm/Tiw==
+ dependencies:
+ csstype "^3.0.2"
+
"@types/semver@^7.3.12":
version "7.7.0"
resolved "https://registry.npmjs.org/@types/semver/-/semver-7.7.0.tgz"
@@ -1660,7 +1597,12 @@
resolved "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz"
integrity sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==
-"@types/unist@^2", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3":
+"@types/unist@^2", "@types/unist@^2.0.0", "@types/unist@^2.0.3":
+ version "2.0.11"
+ resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz"
+ integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==
+
+"@types/unist@^2.0.2":
version "2.0.11"
resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz"
integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==
@@ -1787,11 +1729,16 @@
"@types/babel__core" "^7.20.5"
react-refresh "^0.17.0"
-"@webgpu/types@*":
+"@webgpu/types@*", "@webgpu/types@^0.1.40":
version "0.1.60"
resolved "https://registry.npmjs.org/@webgpu/types/-/types-0.1.60.tgz"
integrity sha512-8B/tdfRFKdrnejqmvq95ogp8tf52oZ51p3f4QD5m5Paey/qlX4Rhhy5Y8tgFMi7Ms70HzcMMw3EQjH/jdhTwlA==
+"@xmldom/xmldom@^0.8.10":
+ version "0.8.10"
+ resolved "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz"
+ integrity sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==
+
accepts@~1.3.8:
version "1.3.8"
resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz"
@@ -2000,7 +1947,7 @@ bl@^4.1.0:
inherits "^2.0.4"
readable-stream "^3.4.0"
-body-parser@1.20.3, body-parser@^1.20.2:
+body-parser@^1.20.2, body-parser@1.20.3:
version "1.20.3"
resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz"
integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==
@@ -2281,7 +2228,12 @@ clone@^1.0.2:
resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz"
integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==
-clsx@^1.1.0, clsx@^1.1.1:
+clsx@^1.1.0:
+ version "1.2.1"
+ resolved "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz"
+ integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
+
+clsx@^1.1.1:
version "1.2.1"
resolved "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz"
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
@@ -2395,16 +2347,16 @@ cookie-signature@1.0.6:
resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz"
integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==
-cookie@0.7.1:
- version "0.7.1"
- resolved "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz"
- integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==
-
cookie@^1.0.1:
version "1.0.2"
resolved "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz"
integrity sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==
+cookie@0.7.1:
+ version "0.7.1"
+ resolved "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz"
+ integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==
+
cosmiconfig@^7.0.0:
version "7.1.0"
resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz"
@@ -2454,13 +2406,6 @@ csstype@^3.0.2, csstype@^3.1.3:
resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz"
integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
-"d3-array@2.5.0 - 3":
- version "3.2.4"
- resolved "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz"
- integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==
- dependencies:
- internmap "1 - 2"
-
d3-array@^2.5.0:
version "2.12.1"
resolved "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz"
@@ -2468,6 +2413,13 @@ d3-array@^2.5.0:
dependencies:
internmap "^1.0.0"
+"d3-array@2.5.0 - 3":
+ version "3.2.4"
+ resolved "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz"
+ integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==
+ dependencies:
+ internmap "1 - 2"
+
"d3-color@1 - 2":
version "2.0.0"
resolved "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz"
@@ -2512,7 +2464,7 @@ d3-geo@^3.1.1:
dependencies:
d3-color "1 - 2"
-d3-selection@2, d3-selection@^2.0.0:
+d3-selection@^2.0.0, d3-selection@2:
version "2.0.0"
resolved "https://registry.npmjs.org/d3-selection/-/d3-selection-2.0.0.tgz"
integrity sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA==
@@ -2556,13 +2508,6 @@ debounce-fn@^4.0.0:
dependencies:
mimic-fn "^3.0.0"
-debug@2.6.9:
- version "2.6.9"
- resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz"
- integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
- dependencies:
- ms "2.0.0"
-
debug@^4.0.0, debug@^4.1.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.6:
version "4.4.0"
resolved "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz"
@@ -2570,6 +2515,13 @@ debug@^4.0.0, debug@^4.1.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3
dependencies:
ms "^2.1.3"
+debug@2.6.9:
+ version "2.6.9"
+ resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz"
+ integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
+ dependencies:
+ ms "2.0.0"
+
decamelize@^5.0.0:
version "5.0.1"
resolved "https://registry.npmjs.org/decamelize/-/decamelize-5.0.1.tgz"
@@ -2734,6 +2686,11 @@ dunder-proto@^1.0.1:
es-errors "^1.3.0"
gopd "^1.2.0"
+earcut@^2.2.4:
+ version "2.2.4"
+ resolved "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz"
+ integrity sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==
+
eastasianwidth@^0.2.0:
version "0.2.0"
resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz"
@@ -3325,11 +3282,6 @@ fs.realpath@^1.0.0:
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
-fsevents@~2.3.2:
- version "2.3.3"
- resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz"
- integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
-
function-bind@^1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz"
@@ -3625,7 +3577,7 @@ i18next@^24.2.2:
dependencies:
"@babel/runtime" "^7.26.10"
-iconv-lite@0.4.24, iconv-lite@^0.4.24:
+iconv-lite@^0.4.24, iconv-lite@0.4.24:
version "0.4.24"
resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz"
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
@@ -3668,7 +3620,7 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
-inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4:
+inherits@^2.0.3, inherits@^2.0.4, inherits@2, inherits@2.0.4:
version "2.0.4"
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@@ -3720,16 +3672,16 @@ inquirer@^8.2.5:
through "^2.3.6"
wrap-ansi "^6.0.1"
-"internmap@1 - 2":
- version "2.0.3"
- resolved "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz"
- integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==
-
internmap@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz"
integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==
+"internmap@1 - 2":
+ version "2.0.3"
+ resolved "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz"
+ integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==
+
intl-messageformat@10.7.16:
version "10.7.16"
resolved "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.16.tgz"
@@ -3897,11 +3849,23 @@ isexe@^3.1.1:
resolved "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz"
integrity sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==
+ismobilejs@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.npmjs.org/ismobilejs/-/ismobilejs-1.1.1.tgz"
+ integrity sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw==
+
isobject@^3.0.1:
version "3.0.1"
resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz"
integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==
+its-fine@^1.2.5:
+ version "1.2.5"
+ resolved "https://registry.npmjs.org/its-fine/-/its-fine-1.2.5.tgz"
+ integrity sha512-fXtDA0X0t0eBYAGLVM5YsgJGsJ5jEmqZEPrGbzdf5awjv0xE7nqv3TVnvtUF060Tkes15DbDAKW/I48vsb6SyA==
+ dependencies:
+ "@types/react-reconciler" "^0.28.0"
+
its-fine@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/its-fine/-/its-fine-2.0.0.tgz"
@@ -3928,7 +3892,15 @@ js-cookie@^3.0.5:
resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
-js-yaml@^3.13.0, js-yaml@^3.13.1:
+js-yaml@^3.13.0:
+ version "3.14.1"
+ resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz"
+ integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==
+ dependencies:
+ argparse "^1.0.7"
+ esprima "^4.0.0"
+
+js-yaml@^3.13.1:
version "3.14.1"
resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz"
integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==
@@ -4796,16 +4768,16 @@ mobx@^6.13.7:
resolved "https://registry.npmjs.org/mobx/-/mobx-6.13.7.tgz"
integrity sha512-aChaVU/DO5aRPmk1GX8L+whocagUUpBQqoPtJk+cm7UOXUk87J4PeWCh6nNmTTIfEhiR9DI/+FnA8dln/hTK7g==
+ms@^2.1.3, ms@2.1.3:
+ version "2.1.3"
+ resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz"
+ integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
+
ms@2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"
integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==
-ms@2.1.3, ms@^2.1.3:
- version "2.1.3"
- resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz"
- integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
-
mute-stream@0.0.8:
version "0.0.8"
resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz"
@@ -5108,6 +5080,11 @@ parse-srcset@^1.0.2:
resolved "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz"
integrity sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==
+parse-svg-path@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz"
+ integrity sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ==
+
parse5-htmlparser2-tree-adapter@^6.0.0:
version "6.0.1"
resolved "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz"
@@ -5198,6 +5175,21 @@ pirates@^4.0.6:
resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz"
integrity sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==
+pixi.js@^8.2.6:
+ version "8.2.6"
+ resolved "https://registry.npmjs.org/pixi.js/-/pixi.js-8.2.6.tgz"
+ integrity sha512-CNfr7CmjIEWJ06e3TBrXBKFpcTPMGUaFdtP4RlMOgNOTkDD6+Bhm728I/EkGAo2vsOVO1YwNFsuORQyD3MngZg==
+ dependencies:
+ "@pixi/colord" "^2.9.6"
+ "@types/css-font-loading-module" "^0.0.12"
+ "@types/earcut" "^2.1.4"
+ "@webgpu/types" "^0.1.40"
+ "@xmldom/xmldom" "^0.8.10"
+ earcut "^2.2.4"
+ eventemitter3 "^5.0.1"
+ ismobilejs "^1.1.1"
+ parse-svg-path "^0.1.2"
+
pkg-dir@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz"
@@ -5323,13 +5315,6 @@ punycode@^2.1.0:
resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz"
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
-qs@6.13.0:
- version "6.13.0"
- resolved "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz"
- integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==
- dependencies:
- side-channel "^1.0.6"
-
qs@^6.10.1:
version "6.14.0"
resolved "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz"
@@ -5337,6 +5322,13 @@ qs@^6.10.1:
dependencies:
side-channel "^1.1.0"
+qs@6.13.0:
+ version "6.13.0"
+ resolved "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz"
+ integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==
+ dependencies:
+ side-channel "^1.0.6"
+
query-string@^7.1.1:
version "7.1.3"
resolved "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz"
@@ -5385,13 +5377,6 @@ react-beautiful-dnd@^13.1.1:
redux "^4.0.4"
use-memo-one "^1.1.1"
-react-dom@19.0.0:
- version "19.0.0"
- resolved "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz"
- integrity sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==
- dependencies:
- scheduler "^0.25.0"
-
react-dom@^18.0.0:
version "18.3.1"
resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz"
@@ -5400,6 +5385,13 @@ react-dom@^18.0.0:
loose-envify "^1.1.0"
scheduler "^0.23.2"
+react-dom@19.0.0:
+ version "19.0.0"
+ resolved "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz"
+ integrity sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==
+ dependencies:
+ scheduler "^0.25.0"
+
react-draggable@^4.4.6:
version "4.4.6"
resolved "https://registry.npmjs.org/react-draggable/-/react-draggable-4.4.6.tgz"
@@ -5444,12 +5436,22 @@ react-intl@^7.1.10:
intl-messageformat "10.7.16"
tslib "^2.8.0"
-react-is@^16.13.1, react-is@^16.7.0:
+react-is@^16.13.1:
version "16.13.1"
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
-react-is@^17.0.0, react-is@^17.0.2:
+react-is@^16.7.0:
+ version "16.13.1"
+ resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
+ integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
+
+react-is@^17.0.0:
+ version "17.0.2"
+ resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz"
+ integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
+
+react-is@^17.0.2:
version "17.0.2"
resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
@@ -5510,7 +5512,7 @@ react-reconciler@^0.29.0:
loose-envify "^1.1.0"
scheduler "^0.23.2"
-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==
@@ -5595,11 +5597,6 @@ react-virtual@^2.8.2:
dependencies:
"@reach/observe-rect" "^1.1.0"
-react@19.0.0:
- version "19.0.0"
- resolved "https://registry.npmjs.org/react/-/react-19.0.0.tgz"
- integrity sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==
-
react@^18.0.0:
version "18.3.1"
resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz"
@@ -5607,6 +5604,11 @@ react@^18.0.0:
dependencies:
loose-envify "^1.1.0"
+react@19.0.0:
+ version "19.0.0"
+ resolved "https://registry.npmjs.org/react/-/react-19.0.0.tgz"
+ integrity sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==
+
readable-stream@^3.4.0:
version "3.6.2"
resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz"
@@ -5791,7 +5793,7 @@ rxjs@^7.5.4, rxjs@^7.5.5:
dependencies:
tslib "^2.1.0"
-safe-buffer@5.2.1, safe-buffer@~5.2.0:
+safe-buffer@~5.2.0, safe-buffer@5.2.1:
version "5.2.1"
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
@@ -5840,19 +5842,17 @@ semver-diff@^3.1.1:
dependencies:
semver "^6.3.0"
-semver@7.5.2:
- version "7.5.2"
- resolved "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz"
- integrity sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==
- dependencies:
- lru-cache "^6.0.0"
-
semver@^5.6.0:
version "5.7.2"
resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz"
integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==
-semver@^6.3.0, semver@^6.3.1:
+semver@^6.3.0:
+ version "6.3.1"
+ resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz"
+ integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
+
+semver@^6.3.1:
version "6.3.1"
resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz"
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
@@ -5862,6 +5862,13 @@ semver@^7.1.1, semver@^7.3.5, semver@^7.3.7, semver@^7.5.3:
resolved "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz"
integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==
+semver@7.5.2:
+ version "7.5.2"
+ resolved "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz"
+ integrity sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==
+ dependencies:
+ lru-cache "^6.0.0"
+
send@0.19.0:
version "0.19.0"
resolved "https://registry.npmjs.org/send/-/send-0.19.0.tgz"
@@ -6087,6 +6094,13 @@ strict-uri-encode@^2.0.0:
resolved "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz"
integrity sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==
+string_decoder@^1.1.1:
+ version "1.3.0"
+ resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz"
+ integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
+ dependencies:
+ safe-buffer "~5.2.0"
+
"string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3"
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
@@ -6114,13 +6128,6 @@ string-width@^5.0.1, string-width@^5.1.2:
emoji-regex "^9.2.2"
strip-ansi "^7.0.1"
-string_decoder@^1.1.1:
- version "1.3.0"
- resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz"
- integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
- dependencies:
- safe-buffer "~5.2.0"
-
stringify-entities@^4.0.0:
version "4.0.4"
resolved "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz"
@@ -6177,13 +6184,6 @@ style-to-js@^1.0.0:
dependencies:
style-to-object "1.0.8"
-style-to-object@1.0.8:
- version "1.0.8"
- resolved "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz"
- integrity sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==
- dependencies:
- inline-style-parser "0.2.4"
-
style-to-object@^0.3.0:
version "0.3.0"
resolved "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz"
@@ -6191,6 +6191,13 @@ style-to-object@^0.3.0:
dependencies:
inline-style-parser "0.1.1"
+style-to-object@1.0.8:
+ version "1.0.8"
+ resolved "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz"
+ integrity sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==
+ dependencies:
+ inline-style-parser "0.2.4"
+
stylis@4.2.0:
version "4.2.0"
resolved "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz"
@@ -6559,7 +6566,7 @@ universalify@^2.0.0:
resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz"
integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==
-unpipe@1.0.0, unpipe@~1.0.0:
+unpipe@~1.0.0, unpipe@1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz"
integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==