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 ( + + + logo + + При поддержке Правительства + Санкт-Петербурга + + + + + + + + + + + logo + + + #ВсемПоПути + + + + ); +} \ 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==