diff --git a/README.md b/README.md index 8707f36..b2e8892 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ @@ -12,13 +12,13 @@ ### _AI-Powered Traffic Optimization for Cleaner Cities_ -[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=for-the-badge)](https://opensource.org/licenses/MIT) -[![FIWARE](https://img.shields.io/badge/FIWARE-Orion--LD-002E67?style=for-the-badge&logo=fiware)](https://www.fiware.org/) -[![Docker](https://img.shields.io/badge/Docker-Ready-2496ED?style=for-the-badge&logo=docker&logoColor=white)](https://www.docker.com/) +License: MIT +FIWARE +Docker
-[**Documentation**](http://localhost:3000/GreenWave/) • [**Quick Start**](#-quick-start) • [**Architecture**](#-architecture) • [**Features**](#-features) +Documentation • [**Quick Start**](#getting-started) • [**Architecture**](#architecture) • [**Features**](#features) @@ -102,13 +102,13 @@ ### Prerequisites -| Requirement | Version | Download | -| :---------- | :------ | :------------------------------------------------- | -| **Docker** | 28.3.2+ | [Get Docker](https://www.docker.com/get-started/) | -| **Node.js** | 24.6.0+ | [Get Node.js](https://nodejs.org/en/download) | -| **SUMO** | 1.25.0+ | [Get SUMO](https://sumo.dlr.de/docs/Downloads.php) | +| Requirement | Version | Download | +| :---------- | :------ | :---------------------------------------------------------------------------- | +| **Docker** | 28.3.2+ | Get Docker | +| **Node.js** | 24.6.0+ | Get Node.js | +| **SUMO** | 1.25.0+ | Get SUMO | -> **Note:** If you want to run SUMO on your local machine, you need to download and install it from the [SUMO website](https://sumo.dlr.de/docs/Downloads.php). +> **Note:** If you want to run SUMO on your local machine, you need to download and install it from the SUMO website. ### 🏃‍♂️ Run the Application @@ -121,6 +121,12 @@ git clone https://github.com/sonmessia/GreenWave.git # Navigate to the project directory cd GreenWave +# Copy the environment variables +cp .env.example .env + +# Navigate to the project directory +cd src/backend + # Copy the environment variables cp .env.example .env ``` @@ -190,7 +196,7 @@ Once services are running, access them at:
-### **[Read Full Documentation](https://sonmessia.github.io/GreenWave)** +### Read Full Documentation Explore detailed tutorials, API references, architecture guides, and more! @@ -244,4 +250,4 @@ Help us keep GreenWave open and inclusive. Please read and follow our [Code of C This project is licensed under the terms of the [MIT](LICENSE) license. -

\ No newline at end of file +

diff --git a/docs/docs/installation.md b/docs/docs/installation.md index 2cf114e..5aadc08 100644 --- a/docs/docs/installation.md +++ b/docs/docs/installation.md @@ -45,6 +45,13 @@ cd GreenWave Copy the example configuration file to the official `.env` file: ```bash +# Copy the environment variables +cp .env.example .env + + # Change directory to backend +cd src/backend + +# Copy the environment variables cp .env.example .env ``` @@ -55,6 +62,7 @@ cp .env.example .env This is the simplest way to start the whole system: ```bash +# Run docker compose docker compose up -d ``` diff --git a/docs/docs/intro.md b/docs/docs/intro.md index 7f81b93..0495616 100644 --- a/docs/docs/intro.md +++ b/docs/docs/intro.md @@ -88,6 +88,13 @@ Run the following command to start all services (Context Broker, Backend, Fronte ```bash cp .env.example .env +# Change directory to backend +cd src/backend + +# Copy the environment variables +cp .env.example .env + +# Run docker compose docker compose up -d ``` diff --git a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_0.xml b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_0.xml index fbda692..646083a 100644 --- a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_0.xml +++ b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_0.xml @@ -1,6 +1,6 @@ - - - - diff --git a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_1.xml b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_1.xml index 7240710..7a83aec 100644 --- a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_1.xml +++ b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_1.xml @@ -1,6 +1,6 @@ - - - - diff --git a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_2.xml b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_2.xml index e98cab0..f46d4d8 100644 --- a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_2.xml +++ b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_2.xml @@ -1,6 +1,6 @@ - - - - diff --git a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_3.xml b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_3.xml index 7a5bc4b..7c0fcfb 100644 --- a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_3.xml +++ b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_3.xml @@ -1,6 +1,6 @@ - - - - diff --git a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_4.xml b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_4.xml index 4528af1..d0c4b12 100644 --- a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_4.xml +++ b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_4.xml @@ -1,6 +1,6 @@ - - - - diff --git a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_5.xml b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_5.xml index 627c823..14f488a 100644 --- a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_5.xml +++ b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1_5.xml @@ -1,6 +1,6 @@ - - - - diff --git a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1i_0.xml b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1i_0.xml index e7f3867..48cbb17 100644 --- a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1i_0.xml +++ b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1i_0.xml @@ -1,6 +1,6 @@ - - - - diff --git a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1i_1.xml b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1i_1.xml index 6348af9..9c5f7f4 100644 --- a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1i_1.xml +++ b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1i_1.xml @@ -1,6 +1,6 @@ - - - - diff --git a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1i_2.xml b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1i_2.xml index 070fcd9..b6bfa98 100644 --- a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1i_2.xml +++ b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1i_2.xml @@ -1,6 +1,6 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - diff --git a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1i_4.xml b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1i_4.xml index 3f5a5d8..c054194 100644 --- a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1i_4.xml +++ b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e1i_4.xml @@ -1,6 +1,6 @@ - - - - diff --git a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e2_0.xml b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e2_0.xml index 4625bdb..91991cd 100644 --- a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e2_0.xml +++ b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e2_0.xml @@ -1,6 +1,6 @@ - - - - diff --git a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e2_2.xml b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e2_2.xml index 9a2da83..d83476e 100644 --- a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e2_2.xml +++ b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/e2_2.xml @@ -1,6 +1,6 @@ - - - - diff --git a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/eed.xml b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/eed.xml index 37bd185..7849be2 100644 --- a/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/eed.xml +++ b/src/backend/app/sumo_rl/sumo_files/Nga4ThuDuc/eed.xml @@ -1,10 +1,3 @@ - - - + + diff --git a/src/backend/app/sumo_rl/sumo_files/current_scenario.txt b/src/backend/app/sumo_rl/sumo_files/current_scenario.txt index 3023eac..b9a8a0c 100644 --- a/src/backend/app/sumo_rl/sumo_files/current_scenario.txt +++ b/src/backend/app/sumo_rl/sumo_files/current_scenario.txt @@ -1 +1 @@ -QuangTrung \ No newline at end of file +Nga4ThuDuc \ No newline at end of file diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json index c0e3934..ed736b4 100644 --- a/src/frontend/package-lock.json +++ b/src/frontend/package-lock.json @@ -8,7 +8,6 @@ "name": "frontend", "version": "0.0.0", "dependencies": { - "@maptiler/sdk": "^3.8.0", "@reduxjs/toolkit": "^2.10.1", "@tailwindcss/vite": "^4.1.17", "@types/react-router-dom": "^5.3.3", @@ -17,32 +16,23 @@ "dotenv": "^17.2.3", "i18next": "^25.7.1", "i18next-browser-languagedetector": "^8.2.0", - "leaflet": "^1.9.4", "lucide-react": "^0.553.0", "react": "^19.2.0", "react-chartjs-2": "^5.3.1", "react-dom": "^19.2.0", "react-i18next": "^16.3.5", - "react-leaflet": "^5.0.0", "react-redux": "^9.2.0", "react-router-dom": "^7.9.6", "tailwindcss": "^4.1.17" }, "devDependencies": { - "@eslint/js": "^9.39.1", - "@types/leaflet": "^1.9.21", "@types/node": "^24.10.0", "@types/react": "^19.2.2", "@types/react-dom": "^19.2.2", "@vitejs/plugin-react-swc": "^4.2.1", - "eslint": "^9.39.1", - "eslint-config-prettier": "^10.1.8", - "eslint-plugin-react-hooks": "^5.2.0", - "eslint-plugin-react-refresh": "^0.4.24", "globals": "^16.5.0", "prettier": "^3.7.4", "typescript": "~5.9.3", - "typescript-eslint": "^8.46.3", "vite": "npm:rolldown-vite@7.2.2" } }, @@ -105,19 +95,6 @@ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/@eslint-community/regexpp": { "version": "4.12.2", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", @@ -128,53 +105,13 @@ "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@eslint/config-array": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", - "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.7", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/config-helpers": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, "node_modules/@eslint/eslintrc": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -199,6 +136,7 @@ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=18" }, @@ -219,82 +157,6 @@ "url": "https://eslint.org/donate" } }, - "node_modules/@eslint/object-schema": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0", - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", - "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.4.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -346,124 +208,6 @@ "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==", "license": "MIT" }, - "node_modules/@mapbox/geojson-rewind": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@mapbox/geojson-rewind/-/geojson-rewind-0.5.2.tgz", - "integrity": "sha512-tJaT+RbYGJYStt7wI3cq4Nl4SXxG8W7JDG5DMJu97V25RnbNg3QtQtf+KD+VLjNpWKYsRvXDNmNrBgEETr1ifA==", - "license": "ISC", - "dependencies": { - "get-stream": "^6.0.1", - "minimist": "^1.2.6" - }, - "bin": { - "geojson-rewind": "geojson-rewind" - } - }, - "node_modules/@mapbox/jsonlint-lines-primitives": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz", - "integrity": "sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@mapbox/point-geometry": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-1.1.0.tgz", - "integrity": "sha512-YGcBz1cg4ATXDCM/71L9xveh4dynfGmcLDqufR+nQQy3fKwsAZsWd/x4621/6uJaeB9mwOHE6hPeDgXz9uViUQ==", - "license": "ISC" - }, - "node_modules/@mapbox/tiny-sdf": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.0.7.tgz", - "integrity": "sha512-25gQLQMcpivjOSA40g3gO6qgiFPDpWRoMfd+G/GoppPIeP6JDaMMkMrEJnMZhKyyS6iKwVt5YKu02vCUyJM3Ug==", - "license": "BSD-2-Clause" - }, - "node_modules/@mapbox/unitbezier": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz", - "integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==", - "license": "BSD-2-Clause" - }, - "node_modules/@mapbox/vector-tile": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-2.0.4.tgz", - "integrity": "sha512-AkOLcbgGTdXScosBWwmmD7cDlvOjkg/DetGva26pIRiZPdeJYjYKarIlb4uxVzi6bwHO6EWH82eZ5Nuv4T5DUg==", - "license": "BSD-3-Clause", - "dependencies": { - "@mapbox/point-geometry": "~1.1.0", - "@types/geojson": "^7946.0.16", - "pbf": "^4.0.1" - } - }, - "node_modules/@mapbox/whoots-js": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz", - "integrity": "sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==", - "license": "ISC", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@maplibre/maplibre-gl-style-spec": { - "version": "23.3.0", - "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-23.3.0.tgz", - "integrity": "sha512-IGJtuBbaGzOUgODdBRg66p8stnwj9iDXkgbYKoYcNiiQmaez5WVRfXm4b03MCDwmZyX93csbfHFWEJJYHnn5oA==", - "license": "ISC", - "dependencies": { - "@mapbox/jsonlint-lines-primitives": "~2.0.2", - "@mapbox/unitbezier": "^0.0.1", - "json-stringify-pretty-compact": "^4.0.0", - "minimist": "^1.2.8", - "quickselect": "^3.0.0", - "rw": "^1.3.3", - "tinyqueue": "^3.0.0" - }, - "bin": { - "gl-style-format": "dist/gl-style-format.mjs", - "gl-style-migrate": "dist/gl-style-migrate.mjs", - "gl-style-validate": "dist/gl-style-validate.mjs" - } - }, - "node_modules/@maplibre/vt-pbf": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@maplibre/vt-pbf/-/vt-pbf-4.0.3.tgz", - "integrity": "sha512-YsW99BwnT+ukJRkseBcLuZHfITB4puJoxnqPVjo72rhW/TaawVYsgQHcqWLzTxqknttYoDpgyERzWSa/XrETdA==", - "license": "MIT", - "dependencies": { - "@mapbox/point-geometry": "^1.1.0", - "@mapbox/vector-tile": "^2.0.4", - "@types/geojson-vt": "3.2.5", - "@types/supercluster": "^7.1.3", - "geojson-vt": "^4.0.2", - "pbf": "^4.0.1", - "supercluster": "^8.0.1" - } - }, - "node_modules/@maptiler/client": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@maptiler/client/-/client-2.5.1.tgz", - "integrity": "sha512-2rveqohOu3xv16EX65rFUQF8fpPppefrGkvUEtZOx50EDHFxrhEVjKM0p95TuT0RLygxF/sw4vAqUFCBOnPbiw==", - "license": "BSD-3-Clause", - "dependencies": { - "quick-lru": "^7.0.0" - } - }, - "node_modules/@maptiler/sdk": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/@maptiler/sdk/-/sdk-3.8.0.tgz", - "integrity": "sha512-oXLlSyJhKADB1KTfxj5bhnRml3nrvBerhuuo1v+rDJKrUHqQpVPj6PS+z809D/+UB9ZwzzHOBeFZP3vYCK3U5g==", - "license": "BSD-3-Clause", - "dependencies": { - "@maplibre/maplibre-gl-style-spec": "~23.3.0", - "@maptiler/client": "~2.5.1", - "events": "^3.3.0", - "gl-matrix": "^3.4.3", - "js-base64": "^3.7.7", - "maplibre-gl": "~5.6.0", - "uuid": "^11.0.5" - } - }, "node_modules/@napi-rs/wasm-runtime": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.7.tgz", @@ -532,17 +276,6 @@ "url": "https://github.com/sponsors/Boshen" } }, - "node_modules/@react-leaflet/core": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-3.0.0.tgz", - "integrity": "sha512-3EWmekh4Nz+pGcr+xjf0KNyYfC3U2JjnkWsh0zcqaexYqmmB5ZhH37kz41JXGmKzpaMZCnPofBBm64i+YrEvGQ==", - "license": "Hippocratic-2.1", - "peerDependencies": { - "leaflet": "^1.9.0", - "react": "^19.0.0", - "react-dom": "^19.0.0" - } - }, "node_modules/@reduxjs/toolkit": { "version": "2.10.1", "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.10.1.tgz", @@ -569,440 +302,40 @@ } } }, - "node_modules/@rolldown/binding-android-arm64": { - "version": "1.0.0-beta.47", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-beta.47.tgz", - "integrity": "sha512-vPP9/MZzESh9QtmvQYojXP/midjgkkc1E4AdnPPAzQXo668ncHJcVLKjJKzoBdsQmaIvNjrMdsCwES8vTQHRQw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.0-beta.47", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-beta.47.tgz", - "integrity": "sha512-Lc3nrkxeaDVCVl8qR3qoxh6ltDZfkQ98j5vwIr5ALPkgjZtDK4BGCrrBoLpGVMg+csWcaqUbwbKwH5yvVa0oOw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.0-beta.47", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-beta.47.tgz", - "integrity": "sha512-eBYxQDwP0O33plqNVqOtUHqRiSYVneAknviM5XMawke3mwMuVlAsohtOqEjbCEl/Loi/FWdVeks5WkqAkzkYWQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.0-beta.47", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-beta.47.tgz", - "integrity": "sha512-Ns+kgp2+1Iq/44bY/Z30DETUSiHY7ZuqaOgD5bHVW++8vme9rdiWsN4yG4rRPXkdgzjvQ9TDHmZZKfY4/G11AA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.0-beta.47", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-beta.47.tgz", - "integrity": "sha512-4PecgWCJhTA2EFOlptYJiNyVP2MrVP4cWdndpOu3WmXqWqZUmSubhb4YUAIxAxnXATlGjC1WjxNPhV7ZllNgdA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.0-beta.47", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-beta.47.tgz", - "integrity": "sha512-CyIunZ6D9U9Xg94roQI1INt/bLkOpPsZjZZkiaAZ0r6uccQdICmC99M9RUPlMLw/qg4yEWLlQhG73W/mG437NA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.0-beta.47", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-beta.47.tgz", - "integrity": "sha512-doozc/Goe7qRCSnzfJbFINTHsMktqmZQmweull6hsZZ9sjNWQ6BWQnbvOlfZJe4xE5NxM1NhPnY5Giqnl3ZrYQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.0-beta.47", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-beta.47.tgz", - "integrity": "sha512-fodvSMf6Aqwa0wEUSTPewmmZOD44rc5Tpr5p9NkwQ6W1SSpUKzD3SwpJIgANDOhwiYhDuiIaYPGB7Ujkx1q0UQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.0-beta.47", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-beta.47.tgz", - "integrity": "sha512-Rxm5hYc0mGjwLh5sjlGmMygxAaV2gnsx7CNm2lsb47oyt5UQyPDZf3GP/ct8BEcwuikdqzsrrlIp8+kCSvMFNQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.0.0-beta.47", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-beta.47.tgz", - "integrity": "sha512-YakuVe+Gc87jjxazBL34hbr8RJpRuFBhun7NEqoChVDlH5FLhLXjAPHqZd990TVGVNkemourf817Z8u2fONS8w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.0-beta.47", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-beta.47.tgz", - "integrity": "sha512-ak2GvTFQz3UAOw8cuQq8pWE+TNygQB6O47rMhvevvTzETh7VkHRFtRUwJynX5hwzFvQMP6G0az5JrBGuwaMwYQ==", - "cpu": [ - "wasm32" - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@napi-rs/wasm-runtime": "^1.0.7" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.0-beta.47", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-beta.47.tgz", - "integrity": "sha512-o5BpmBnXU+Cj+9+ndMcdKjhZlPb79dVPBZnWwMnI4RlNSSq5yOvFZqvfPYbyacvnW03Na4n5XXQAPhu3RydZ0w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-win32-ia32-msvc": { - "version": "1.0.0-beta.47", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.0.0-beta.47.tgz", - "integrity": "sha512-FVOmfyYehNE92IfC9Kgs913UerDog2M1m+FADJypKz0gmRg3UyTt4o1cZMCAl7MiR89JpM9jegNO1nXuP1w1vw==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.0-beta.47", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-beta.47.tgz", - "integrity": "sha512-by/70F13IUE101Bat0oeH8miwWX5mhMFPk1yjCdxoTNHTyTdLgb0THNaebRM6AP7Kz+O3O2qx87sruYuF5UxHg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.47", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.47.tgz", - "integrity": "sha512-8QagwMH3kNCuzD8EWL8R2YPW5e4OrHNSAHRFDdmFqEwEaD/KcNKjVoumo+gP2vW5eKB2UPbM6vTYiGZX0ixLnw==", - "license": "MIT" - }, - "node_modules/@standard-schema/spec": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", - "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", - "license": "MIT" - }, - "node_modules/@standard-schema/utils": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", - "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", - "license": "MIT" - }, - "node_modules/@swc/core": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.1.tgz", - "integrity": "sha512-s9GN3M2jA32k+StvuS9uGe4ztf5KVGBdlJMMC6LR6Ah23Lq/CWKVcC3WeQi8qaAcLd+DiddoNCNMUWymLv+wWQ==", - "dev": true, - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "@swc/counter": "^0.1.3", - "@swc/types": "^0.1.25" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/swc" - }, - "optionalDependencies": { - "@swc/core-darwin-arm64": "1.15.1", - "@swc/core-darwin-x64": "1.15.1", - "@swc/core-linux-arm-gnueabihf": "1.15.1", - "@swc/core-linux-arm64-gnu": "1.15.1", - "@swc/core-linux-arm64-musl": "1.15.1", - "@swc/core-linux-x64-gnu": "1.15.1", - "@swc/core-linux-x64-musl": "1.15.1", - "@swc/core-win32-arm64-msvc": "1.15.1", - "@swc/core-win32-ia32-msvc": "1.15.1", - "@swc/core-win32-x64-msvc": "1.15.1" - }, - "peerDependencies": { - "@swc/helpers": ">=0.5.17" - }, - "peerDependenciesMeta": { - "@swc/helpers": { - "optional": true - } - } - }, - "node_modules/@swc/core-darwin-arm64": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.1.tgz", - "integrity": "sha512-vEPrVxegWIjKEz+1VCVuKRY89jhokhSmQ/YXBWLnmLj9cI08G61RTZJvdsIcjYUjjTu7NgZlYVK+b2y0fbh11g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-darwin-x64": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.1.tgz", - "integrity": "sha512-z9QguKxE3aldvwKHHDg5OlKehasbJBF1lacn5CnN6SlrHbdwokXHFA3nIoO3Bh1Tw7bCgFtdIR4jKlTTn3kBZA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.1.tgz", - "integrity": "sha512-yS2FHA8E4YeiPG9YeYk/6mKiCWuXR5RdYlCmtlGzKcjWbI4GXUVe7+p9C0M6myRt3zdj3M1knmJxk52MQA9EZQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.1.tgz", - "integrity": "sha512-IFrjDu7+5Y61jLsUqBVXlXutDoPBX10eEeNTjW6C1yzm+cSTE7ayiKXMIFri4gEZ4VpXS6MUgkwjxtDpIXTh+w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.1.tgz", - "integrity": "sha512-fKzP9mRQGbhc5QhJPIsqKNNX/jyWrZgBxmo3Nz1SPaepfCUc7RFmtcJQI5q8xAun3XabXjh90wqcY/OVyg2+Kg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.1.tgz", - "integrity": "sha512-ZLjMi138uTJxb+1wzo4cB8mIbJbAsSLWRNeHc1g1pMvkERPWOGlem+LEYkkzaFzCNv1J8aKcL653Vtw8INHQeg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-x64-musl": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.1.tgz", - "integrity": "sha512-jvSI1IdsIYey5kOITzyajjofXOOySVitmLxb45OPUjoNojql4sDojvlW5zoHXXFePdA6qAX4Y6KbzAOV3T3ctA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.1.tgz", - "integrity": "sha512-X/FcDtNrDdY9r4FcXHt9QxUqC/2FbQdvZobCKHlHe8vTSKhUHOilWl5EBtkFVfsEs4D5/yAri9e3bJbwyBhhBw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.1.tgz", - "integrity": "sha512-vfheiWBux8PpC87oy1cshcqzgH7alWYpnVq5jWe7xuVkjqjGGDbBUKuS84eJCdsWcVaB5EXIWLKt+11W3/BOwA==", + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0-beta.47", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-beta.47.tgz", + "integrity": "sha512-by/70F13IUE101Bat0oeH8miwWX5mhMFPk1yjCdxoTNHTyTdLgb0THNaebRM6AP7Kz+O3O2qx87sruYuF5UxHg==", "cpu": [ - "ia32" + "x64" ], - "dev": true, - "license": "Apache-2.0 AND MIT", + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=10" + "node": "^20.19.0 || >=22.12.0" } }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.47", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.47.tgz", + "integrity": "sha512-8QagwMH3kNCuzD8EWL8R2YPW5e4OrHNSAHRFDdmFqEwEaD/KcNKjVoumo+gP2vW5eKB2UPbM6vTYiGZX0ixLnw==", + "license": "MIT" + }, + "node_modules/@standard-schema/spec": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", + "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", + "license": "MIT" + }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "license": "MIT" + }, "node_modules/@swc/core-win32-x64-msvc": { "version": "1.15.1", "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.1.tgz", @@ -1020,23 +353,6 @@ "node": ">=10" } }, - "node_modules/@swc/counter": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", - "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/@swc/types": { - "version": "0.1.25", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.25.tgz", - "integrity": "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@swc/counter": "^0.1.3" - } - }, "node_modules/@tailwindcss/node": { "version": "4.1.17", "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.17.tgz", @@ -1075,195 +391,6 @@ "@tailwindcss/oxide-win32-x64-msvc": "4.1.17" } }, - "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.17", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.17.tgz", - "integrity": "sha512-BMqpkJHgOZ5z78qqiGE6ZIRExyaHyuxjgrJ6eBO5+hfrfGkuya0lYfw8fRHG77gdTjWkNWEEm+qeG2cDMxArLQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.17", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.17.tgz", - "integrity": "sha512-EquyumkQweUBNk1zGEU/wfZo2qkp/nQKRZM8bUYO0J+Lums5+wl2CcG1f9BgAjn/u9pJzdYddHWBiFXJTcxmOg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.17", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.17.tgz", - "integrity": "sha512-gdhEPLzke2Pog8s12oADwYu0IAw04Y2tlmgVzIN0+046ytcgx8uZmCzEg4VcQh+AHKiS7xaL8kGo/QTiNEGRog==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.17", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.17.tgz", - "integrity": "sha512-hxGS81KskMxML9DXsaXT1H0DyA+ZBIbyG/sSAjWNe2EDl7TkPOBI42GBV3u38itzGUOmFfCzk1iAjDXds8Oh0g==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.17", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.17.tgz", - "integrity": "sha512-k7jWk5E3ldAdw0cNglhjSgv501u7yrMf8oeZ0cElhxU6Y2o7f8yqelOp3fhf7evjIS6ujTI3U8pKUXV2I4iXHQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.17", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.17.tgz", - "integrity": "sha512-HVDOm/mxK6+TbARwdW17WrgDYEGzmoYayrCgmLEw7FxTPLcp/glBisuyWkFz/jb7ZfiAXAXUACfyItn+nTgsdQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.17", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.17.tgz", - "integrity": "sha512-HvZLfGr42i5anKtIeQzxdkw/wPqIbpeZqe7vd3V9vI3RQxe3xU1fLjss0TjyhxWcBaipk7NYwSrwTwK1hJARMg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.17", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.17.tgz", - "integrity": "sha512-M3XZuORCGB7VPOEDH+nzpJ21XPvK5PyjlkSFkFziNHGLc5d6g3di2McAAblmaSUNl8IOmzYwLx9NsE7bplNkwQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.17", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.17.tgz", - "integrity": "sha512-k7f+pf9eXLEey4pBlw+8dgfJHY4PZ5qOUFDyNf7SI6lHjQ9Zt7+NcscjpwdCEbYi6FI5c2KDTDWyf2iHcCSyyQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.1.17", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.17.tgz", - "integrity": "sha512-cEytGqSSoy7zK4JRWiTCx43FsKP/zGr0CsuMawhH67ONlH+T79VteQeJQRO/X7L0juEUA8ZyuYikcRBf0vsxhg==", - "bundleDependencies": [ - "@napi-rs/wasm-runtime", - "@emnapi/core", - "@emnapi/runtime", - "@tybys/wasm-util", - "@emnapi/wasi-threads", - "tslib" - ], - "cpu": [ - "wasm32" - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.6.0", - "@emnapi/runtime": "^1.6.0", - "@emnapi/wasi-threads": "^1.1.0", - "@napi-rs/wasm-runtime": "^1.0.7", - "@tybys/wasm-util": "^0.10.1", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.17", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.17.tgz", - "integrity": "sha512-JU5AHr7gKbZlOGvMdb4722/0aYbU+tN6lv1kONx0JK2cGsh7g148zVWLM0IKR3NeKLv+L90chBVYcJ8uJWbC9A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@tailwindcss/oxide-win32-x64-msvc": { "version": "4.1.17", "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.17.tgz", @@ -1309,22 +436,8 @@ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true, - "license": "MIT" - }, - "node_modules/@types/geojson": { - "version": "7946.0.16", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", - "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", - "license": "MIT" - }, - "node_modules/@types/geojson-vt": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/@types/geojson-vt/-/geojson-vt-3.2.5.tgz", - "integrity": "sha512-qDO7wqtprzlpe8FfQ//ClPV9xiuoh2nkIgiouIptON9w5jvD/fA4szvP9GBlDVdJ5dldAl0kX/sy3URbWwLx0g==", "license": "MIT", - "dependencies": { - "@types/geojson": "*" - } + "peer": true }, "node_modules/@types/history": { "version": "4.7.11", @@ -1337,17 +450,8 @@ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true, - "license": "MIT" - }, - "node_modules/@types/leaflet": { - "version": "1.9.21", - "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.21.tgz", - "integrity": "sha512-TbAd9DaPGSnzp6QvtYngntMZgcRk+igFELwR2N99XZn7RXUdKgsXMR+28bUO0rPsWp8MIu/f47luLIQuSLYv/w==", - "dev": true, "license": "MIT", - "dependencies": { - "@types/geojson": "*" - } + "peer": true }, "node_modules/@types/node": { "version": "24.10.1", @@ -1399,15 +503,6 @@ "@types/react-router": "*" } }, - "node_modules/@types/supercluster": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.3.tgz", - "integrity": "sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==", - "license": "MIT", - "dependencies": { - "@types/geojson": "*" - } - }, "node_modules/@types/use-sync-external-store": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", @@ -1695,6 +790,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -1708,6 +804,7 @@ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "license": "MIT", + "peer": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -1718,6 +815,7 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1735,6 +833,7 @@ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -1745,13 +844,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -1782,6 +874,7 @@ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1819,6 +912,7 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=6" } @@ -1829,6 +923,7 @@ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -1858,6 +953,7 @@ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -1870,7 +966,8 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/combined-stream": { "version": "1.0.8", @@ -1889,7 +986,8 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/cookie": { "version": "1.0.2", @@ -1906,6 +1004,7 @@ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -1944,7 +1043,8 @@ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/delayed-stream": { "version": "1.0.0", @@ -1955,15 +1055,6 @@ "node": ">=0.4.0" } }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, "node_modules/dotenv": { "version": "17.2.3", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", @@ -1990,12 +1081,6 @@ "node": ">= 0.4" } }, - "node_modules/earcut": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.2.tgz", - "integrity": "sha512-X7hshQbLyMJ/3RPhyObLARM2sNxxmRALLKx1+NVFFnQ9gKzmCrxm9+uLIAdBcvc8FNLpctqlQ2V6AE92Ol9UDQ==", - "license": "ISC" - }, "node_modules/enhanced-resolve": { "version": "5.18.3", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", @@ -2060,6 +1145,7 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, @@ -2073,6 +1159,7 @@ "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -2127,51 +1214,13 @@ } } }, - "node_modules/eslint-config-prettier": { - "version": "10.1.8", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", - "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", - "dev": true, - "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "funding": { - "url": "https://opencollective.com/eslint-config-prettier" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-plugin-react-hooks": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", - "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" - } - }, - "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.24.tgz", - "integrity": "sha512-nLHIW7TEq3aLrEYWpVaJ1dRgFR+wLDPN8e8FpYAql/bMV2oBEfC37K0gLEGgv9fy66juNShSMV8OkTqzltcG/w==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "eslint": ">=8.40" - } - }, "node_modules/eslint-scope": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -2183,25 +1232,13 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/espree": { "version": "10.4.0", "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", @@ -2220,6 +1257,7 @@ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "license": "BSD-3-Clause", + "peer": true, "dependencies": { "estraverse": "^5.1.0" }, @@ -2233,6 +1271,7 @@ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "estraverse": "^5.2.0" }, @@ -2246,6 +1285,7 @@ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "engines": { "node": ">=4.0" } @@ -2256,25 +1296,18 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/fast-glob": { "version": "3.3.3", @@ -2311,14 +1344,16 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/fastq": { "version": "1.19.1", @@ -2336,6 +1371,7 @@ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "flat-cache": "^4.0.0" }, @@ -2362,6 +1398,7 @@ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -2379,6 +1416,7 @@ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" @@ -2392,7 +1430,8 @@ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", "dev": true, - "license": "ISC" + "license": "ISC", + "peer": true }, "node_modules/follow-redirects": { "version": "1.15.11", @@ -2430,20 +1469,6 @@ "node": ">= 6" } }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -2453,12 +1478,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/geojson-vt": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-4.0.2.tgz", - "integrity": "sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A==", - "license": "ISC" - }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -2496,30 +1515,13 @@ "node": ">= 0.4" } }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gl-matrix": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.4.tgz", - "integrity": "sha512-latSnyDNt/8zYUB6VIJ6PCh2jBjJX6gnDsoCZ7LyW7GkqrD51EWwa9qCoGixj8YqBtETQK/xY7OmpTF8xz1DdQ==", - "license": "MIT" - }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "license": "ISC", + "peer": true, "dependencies": { "is-glob": "^4.0.3" }, @@ -2571,6 +1573,7 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=8" } @@ -2669,6 +1672,7 @@ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 4" } @@ -2689,6 +1693,7 @@ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -2706,6 +1711,7 @@ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=0.8.19" } @@ -2748,7 +1754,8 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true, - "license": "ISC" + "license": "ISC", + "peer": true }, "node_modules/jiti": { "version": "2.6.1", @@ -2759,18 +1766,13 @@ "jiti": "lib/jiti-cli.mjs" } }, - "node_modules/js-base64": { - "version": "3.7.8", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.8.tgz", - "integrity": "sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==", - "license": "BSD-3-Clause" - }, "node_modules/js-yaml": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "argparse": "^2.0.1" }, @@ -2783,33 +1785,24 @@ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true, - "license": "MIT" - }, - "node_modules/json-stringify-pretty-compact": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-4.0.0.tgz", - "integrity": "sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==", - "license": "MIT" - }, - "node_modules/kdbush": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz", - "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==", - "license": "ISC" + "license": "MIT", + "peer": true }, "node_modules/keyv": { "version": "4.5.4", @@ -2817,22 +1810,18 @@ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "json-buffer": "3.0.1" } }, - "node_modules/leaflet": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", - "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==", - "license": "BSD-2-Clause" - }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -2870,232 +1859,13 @@ "lightningcss-win32-x64-msvc": "1.30.2" } }, - "node_modules/lightningcss-android-arm64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", - "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", - "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", - "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", - "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", - "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", - "cpu": [ - "arm" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", - "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", - "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", - "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", - "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", - "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", - "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -3111,7 +1881,8 @@ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/lucide-react": { "version": "0.553.0", @@ -3131,43 +1902,6 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "node_modules/maplibre-gl": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-5.6.2.tgz", - "integrity": "sha512-SEqYThhUCFf6Lm0TckpgpKnto5u4JsdPYdFJb6g12VtuaFsm3nYdBO+fOmnUYddc8dXihgoGnuXvPPooUcRv5w==", - "license": "BSD-3-Clause", - "dependencies": { - "@mapbox/geojson-rewind": "^0.5.2", - "@mapbox/jsonlint-lines-primitives": "^2.0.2", - "@mapbox/point-geometry": "^1.1.0", - "@mapbox/tiny-sdf": "^2.0.7", - "@mapbox/unitbezier": "^0.0.1", - "@mapbox/vector-tile": "^2.0.4", - "@mapbox/whoots-js": "^3.1.0", - "@maplibre/maplibre-gl-style-spec": "^23.3.0", - "@maplibre/vt-pbf": "^4.0.3", - "@types/geojson": "^7946.0.16", - "@types/geojson-vt": "3.2.5", - "@types/supercluster": "^7.1.3", - "earcut": "^3.0.2", - "geojson-vt": "^4.0.2", - "gl-matrix": "^3.4.3", - "kdbush": "^4.0.2", - "murmurhash-js": "^1.0.0", - "pbf": "^4.0.1", - "potpack": "^2.1.0", - "quickselect": "^3.0.0", - "supercluster": "^8.0.1", - "tinyqueue": "^3.0.0" - }, - "engines": { - "node": ">=16.14.0", - "npm": ">=8.1.0" - }, - "funding": { - "url": "https://github.com/maplibre/maplibre-gl-js?sponsor=1" - } - }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -3228,6 +1962,7 @@ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", + "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -3235,15 +1970,6 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -3251,12 +1977,6 @@ "dev": true, "license": "MIT" }, - "node_modules/murmurhash-js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", - "integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==", - "license": "MIT" - }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -3288,6 +2008,7 @@ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -3306,6 +2027,7 @@ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "yocto-queue": "^0.1.0" }, @@ -3322,6 +2044,7 @@ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -3338,6 +2061,7 @@ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "callsites": "^3.0.0" }, @@ -3351,6 +2075,7 @@ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=8" } @@ -3361,22 +2086,11 @@ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=8" } }, - "node_modules/pbf": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pbf/-/pbf-4.0.1.tgz", - "integrity": "sha512-SuLdBvS42z33m8ejRbInMapQe8n0D3vN/Xd5fmWM3tufNgRQFBpaW2YVJxQZV4iPNqb0vEFvssMEo5w9c6BTIA==", - "license": "BSD-3-Clause", - "dependencies": { - "resolve-protobuf-schema": "^2.1.0" - }, - "bin": { - "pbf": "bin/pbf" - } - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -3424,18 +2138,13 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/potpack": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/potpack/-/potpack-2.1.0.tgz", - "integrity": "sha512-pcaShQc1Shq0y+E7GqJqvZj8DTthWV1KeHGdi0Z6IAin2Oi3JnLCOfwnCo84qc+HAp52wT9nK9H7FAJp5a44GQ==", - "license": "ISC" - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 0.8.0" } @@ -3456,12 +2165,6 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/protocol-buffers-schema": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", - "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==", - "license": "MIT" - }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -3474,6 +2177,7 @@ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=6" } @@ -3499,24 +2203,6 @@ ], "license": "MIT" }, - "node_modules/quick-lru": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-7.3.0.tgz", - "integrity": "sha512-k9lSsjl36EJdK7I06v7APZCbyGT2vMTsYSRX1Q2nbYmnkBqgUhRkAuzH08Ciotteu/PLJmIF2+tti7o3C/ts2g==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/quickselect": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz", - "integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==", - "license": "ISC" - }, "node_modules/react": { "version": "19.2.0", "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", @@ -3575,20 +2261,6 @@ } } }, - "node_modules/react-leaflet": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-5.0.0.tgz", - "integrity": "sha512-CWbTpr5vcHw5bt9i4zSlPEVQdTVcML390TjeDG0cK59z1ylexpqC6M1PJFjV8jD7CF+ACBFsLIDs6DRMoLEofw==", - "license": "Hippocratic-2.1", - "dependencies": { - "@react-leaflet/core": "^3.0.0" - }, - "peerDependencies": { - "leaflet": "^1.9.0", - "react": "^19.0.0", - "react-dom": "^19.0.0" - } - }, "node_modules/react-redux": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz", @@ -3677,19 +2349,11 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=4" } }, - "node_modules/resolve-protobuf-schema": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz", - "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==", - "license": "MIT", - "dependencies": { - "protocol-buffers-schema": "^3.3.1" - } - }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -3757,12 +2421,6 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/rw": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", - "license": "BSD-3-Clause" - }, "node_modules/scheduler": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", @@ -3794,6 +2452,7 @@ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -3807,6 +2466,7 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=8" } @@ -3826,6 +2486,7 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=8" }, @@ -3833,21 +2494,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/supercluster": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz", - "integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==", - "license": "ISC", - "dependencies": { - "kdbush": "^4.0.2" - } - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -3919,12 +2572,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/tinyqueue": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz", - "integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==", - "license": "ISC" - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -3964,6 +2611,7 @@ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "prelude-ls": "^1.2.1" }, @@ -3971,20 +2619,6 @@ "node": ">= 0.8.0" } }, - "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "devOptional": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, "node_modules/typescript-eslint": { "version": "8.46.4", "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.46.4.tgz", @@ -4022,6 +2656,7 @@ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "punycode": "^2.1.0" } @@ -4035,19 +2670,6 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, - "node_modules/uuid": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", - "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/esm/bin/uuid" - } - }, "node_modules/vite": { "name": "rolldown-vite", "version": "7.2.2", @@ -4168,6 +2790,7 @@ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "license": "ISC", + "peer": true, "dependencies": { "isexe": "^2.0.0" }, @@ -4184,6 +2807,7 @@ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -4194,6 +2818,7 @@ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, diff --git a/src/frontend/package.json b/src/frontend/package.json index bbfedff..2355333 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -6,12 +6,10 @@ "scripts": { "dev": "vite", "build": "tsc -b && vite build", - "lint": "eslint .", "preview": "vite preview", "format": "prettier --write ." }, "dependencies": { - "@maptiler/sdk": "^3.8.0", "@reduxjs/toolkit": "^2.10.1", "@tailwindcss/vite": "^4.1.17", "@types/react-router-dom": "^5.3.3", @@ -20,32 +18,23 @@ "dotenv": "^17.2.3", "i18next": "^25.7.1", "i18next-browser-languagedetector": "^8.2.0", - "leaflet": "^1.9.4", "lucide-react": "^0.553.0", "react": "^19.2.0", "react-chartjs-2": "^5.3.1", "react-dom": "^19.2.0", "react-i18next": "^16.3.5", - "react-leaflet": "^5.0.0", "react-redux": "^9.2.0", "react-router-dom": "^7.9.6", "tailwindcss": "^4.1.17" }, "devDependencies": { - "@eslint/js": "^9.39.1", - "@types/leaflet": "^1.9.21", "@types/node": "^24.10.0", "@types/react": "^19.2.2", "@types/react-dom": "^19.2.2", "@vitejs/plugin-react-swc": "^4.2.1", - "eslint": "^9.39.1", - "eslint-config-prettier": "^10.1.8", - "eslint-plugin-react-hooks": "^5.2.0", - "eslint-plugin-react-refresh": "^0.4.24", "globals": "^16.5.0", "prettier": "^3.7.4", "typescript": "~5.9.3", - "typescript-eslint": "^8.46.3", "vite": "npm:rolldown-vite@7.2.2" }, "overrides": { diff --git a/src/frontend/src/presentation/components/feature/area/AreaControlPanel.tsx b/src/frontend/src/presentation/components/feature/area/AreaControlPanel.tsx index 7bb5fc7..c2b332c 100644 --- a/src/frontend/src/presentation/components/feature/area/AreaControlPanel.tsx +++ b/src/frontend/src/presentation/components/feature/area/AreaControlPanel.tsx @@ -1,144 +1,124 @@ // Copyright (c) 2025 Green Wave Team -// +// // This software is released under the MIT License. // https://opensource.org/licenses/MIT -import React, { useState, useEffect, useCallback } from "react"; -import { useTranslation } from "react-i18next"; -import { useAppDispatch, useAppSelector } from "../../../../data/redux/hooks"; +import React, { useState, useEffect, useCallback } from 'react' +import { useTranslation } from 'react-i18next' +import { useAppDispatch, useAppSelector } from '../../../../data/redux/hooks' import { startSimulation, stopSimulation, fetchSumoStatus, performSimulationStep, -} from "../../../../data/redux/sumoSlice"; -import { SumoModelFactory } from "../../../../domain/models/SumoModels"; -import { Settings, MapPin } from "lucide-react"; -import { SumoStatusDisplay } from "../sumo/components/SumoStatusDisplay"; -import { SumoActionButtons } from "../sumo/components/SumoActionButtons"; +} from '../../../../data/redux/sumoSlice' +import { SumoModelFactory } from '../../../../domain/models/SumoModels' +import { Settings, MapPin } from 'lucide-react' +import { SumoStatusDisplay } from '../sumo/components/SumoStatusDisplay' +import { SumoActionButtons } from '../sumo/components/SumoActionButtons' -import { TRAFFIC_LOCATIONS } from "../../../../utils/trafficLocations"; +import { TRAFFIC_LOCATIONS } from '../../../../utils/trafficLocations' interface AreaControlPanelProps { - areaName: string; - onLog?: (message: string) => void; + areaName: string + onLog?: (message: string) => void } -export const AreaControlPanel: React.FC = ({ - areaName, - onLog, -}) => { - const { t } = useTranslation(["areaControl"]); - const dispatch = useAppDispatch(); - const { status, isLoading, isSimulationRunning, simulationState, error } = - useAppSelector((state) => state.sumo); +export const AreaControlPanel: React.FC = ({ areaName, onLog }) => { + const { t } = useTranslation(['areaControl']) + const dispatch = useAppDispatch() + const { status, isLoading, isSimulationRunning, simulationState } = useAppSelector( + (state) => state.sumo + ) // Find scenario ID based on areaName - const scenario = TRAFFIC_LOCATIONS.find( - (loc) => loc.nameKey === areaName - )?.id; + const scenario = TRAFFIC_LOCATIONS.find((loc) => loc.nameKey === areaName)?.id - const [useGUI, setUseGUI] = useState(false); - const [port] = useState(8813); - const [isStepping, setIsStepping] = useState(false); - const [autoStep, setAutoStep] = useState(false); + const [useGUI, setUseGUI] = useState(false) + const [port] = useState(8813) + const [isStepping, setIsStepping] = useState(false) + const [autoStep, setAutoStep] = useState(false) const handleStartSumo = async () => { if (!scenario) { - onLog?.(`❌ ${t("messages.noScenario", { area: areaName })}`); - return; + onLog?.(`❌ ${t('messages.noScenario', { area: areaName })}`) + return } try { - const config = SumoModelFactory.createConfiguration( - scenario, - useGUI, - port - ); - await dispatch(startSimulation(config)).unwrap(); - onLog?.(`✅ ${t("messages.connected", { area: areaName })}`); + const config = SumoModelFactory.createConfiguration(scenario, useGUI, port) + await dispatch(startSimulation(config)).unwrap() + onLog?.(`✅ ${t('messages.connected', { area: areaName })}`) } catch (error) { - onLog?.(`❌ ${t("messages.connectFailed", { error })}`); + onLog?.(`❌ ${t('messages.connectFailed', { error })}`) } - }; + } const handleStopSumo = async () => { try { - setAutoStep(false); - await dispatch(stopSimulation()).unwrap(); - onLog?.(`🛑 ${t("messages.disconnected")}`); + setAutoStep(false) + await dispatch(stopSimulation()).unwrap() + onLog?.(`🛑 ${t('messages.disconnected')}`) } catch (error) { - onLog?.(`❌ ${t("messages.disconnectFailed", { error })}`); + onLog?.(`❌ ${t('messages.disconnectFailed', { error })}`) } - }; + } const handleStepForward = useCallback(async () => { - if (!isSimulationRunning) return; - setIsStepping(true); + if (!isSimulationRunning) return + setIsStepping(true) try { - await dispatch(performSimulationStep()).unwrap(); - onLog?.( - `⏭️ Simulation step executed at time: ${ - simulationState?.simulationTime || "N/A" - }` - ); + await dispatch(performSimulationStep()).unwrap() + onLog?.(`⏭️ Simulation step executed at time: ${simulationState?.simulationTime || 'N/A'}`) } catch (error) { - onLog?.(`❌ Failed to execute step: ${error}`); + onLog?.(`❌ Failed to execute step: ${error}`) } finally { - setIsStepping(false); + setIsStepping(false) } - }, [dispatch, isSimulationRunning, onLog, simulationState?.simulationTime]); + }, [dispatch, isSimulationRunning, onLog, simulationState?.simulationTime]) const handleRefreshStatus = async () => { try { - await dispatch(fetchSumoStatus()).unwrap(); - onLog?.(`🔄 ${t("messages.statusUpdated")}`); + await dispatch(fetchSumoStatus()).unwrap() + onLog?.(`🔄 ${t('messages.statusUpdated')}`) } catch (error) { - onLog?.(`❌ ${t("messages.updateFailed", { error })}`); + onLog?.(`❌ ${t('messages.updateFailed', { error })}`) } - }; + } useEffect(() => { if (autoStep && isSimulationRunning && !isStepping) { const interval = setInterval(() => { - handleStepForward(); - }, 1000); - return () => clearInterval(interval); + handleStepForward() + }, 1000) + return () => clearInterval(interval) } - }, [autoStep, isSimulationRunning, isStepping, handleStepForward]); + }, [autoStep, isSimulationRunning, isStepping, handleStepForward]) // Determine effective status for display // If connected but scenario doesn't match, show as disconnected/mismatch - const isScenarioMatch = status.connected && status.scenario === scenario; + const isScenarioMatch = status.connected && status.scenario === scenario const displayStatus = isScenarioMatch ? status - : { ...status, connected: false, scenario: undefined }; // Or keep scenario undefined to show "Not running" + : { ...status, connected: false, scenario: undefined } // Or keep scenario undefined to show "Not running" - const displayState = isScenarioMatch ? simulationState : null; + const displayState = isScenarioMatch ? simulationState : null return (
-

- {t("title")} -

+

{t('title')}

- - {areaName} - + {areaName}
- +
@@ -168,5 +146,5 @@ export const AreaControlPanel: React.FC = ({ disabled={!scenario} />
- ); -}; + ) +} diff --git a/src/frontend/src/presentation/components/feature/dashboard/DeviceHealthPanel.tsx b/src/frontend/src/presentation/components/feature/dashboard/DeviceHealthPanel.tsx index 8da1472..2d16b3e 100644 --- a/src/frontend/src/presentation/components/feature/dashboard/DeviceHealthPanel.tsx +++ b/src/frontend/src/presentation/components/feature/dashboard/DeviceHealthPanel.tsx @@ -1,69 +1,122 @@ // Copyright (c) 2025 Green Wave Team -// +// // This software is released under the MIT License. // https://opensource.org/licenses/MIT -import React, { useEffect, useState } from "react"; -import { useTranslation } from "react-i18next"; -import { - Server, - Battery, - Wifi, - WifiOff, - CheckCircle, - Activity, -} from "lucide-react"; -import { deviceApi } from "../../../../api/deviceApi"; -import type { DeviceResponseDTO } from "../../../../data/dtos/DeviceDTOs"; +import React, { useEffect, useState } from 'react' +import { useTranslation } from 'react-i18next' +import { Server, Battery, Wifi, WifiOff, CheckCircle, Activity } from 'lucide-react' +import { deviceApi } from '../../../../api/deviceApi' +import type { DeviceResponseDTO } from '../../../../data/dtos/DeviceDTOs' export const DeviceHealthPanel: React.FC = () => { - const { t, i18n } = useTranslation(["devices"]); - const [devices, setDevices] = useState([]); - const [loading, setLoading] = useState(true); + const { t, i18n } = useTranslation(['devices']) + const [devices, setDevices] = useState([]) + const [loading, setLoading] = useState(true) const [stats, setStats] = useState({ total: 0, active: 0, inactive: 0, lowBattery: 0, - }); + }) useEffect(() => { const fetchDevices = async () => { try { - const response = await deviceApi.getAll({ limit: 100 }); - const allDevices = response.devices || []; - setDevices(allDevices); + const response = await deviceApi.getAll({ limit: 100 }) + const allDevices = response.devices || [] + setDevices(allDevices) - const active = allDevices.filter((d) => d.active_status).length; - const inactive = allDevices.length - active; + const active = allDevices.filter((d) => d.active_status).length + const inactive = allDevices.length - active // Mocking low battery check since it's not in the main DTO - const lowBattery = 0; + const lowBattery = 0 setStats({ total: allDevices.length, active, inactive, lowBattery, - }); + }) } catch (error) { - console.error("Failed to fetch devices", error); + console.error('Failed to fetch devices', error) + // Fallback to mock data on error or empty + const MOCK_DEVICES: DeviceResponseDTO[] = [ + { + id: '1', + device_name: 'Camera Ngã 4 Hàng Xanh', + device_type: 'Camera AI', + active_status: true, + location_desc: 'Cột đèn số 5, hướng về Quận 1', + status: 'active', + ip_address: '192.168.1.105', + serial_number: 'SN-CAM-001', + protocol: 'HTTP', + latitude: 10.85, + longitude: 106.77, + update_interval: 60, + created_at: new Date('2024-01-15').toISOString(), + updated_at: new Date().toISOString(), + }, + { + id: '2', + device_name: 'Trạm quan trắc không khí Quận 1', + device_type: 'Sensor', + active_status: true, + location_desc: 'Trụ sở UBND Quận 1', + status: 'active', + ip_address: '192.168.1.106', + serial_number: 'SN-SENS-001', + protocol: 'MQTT', + latitude: 10.776, + longitude: 106.701, + update_interval: 300, + created_at: new Date('2024-02-01').toISOString(), + updated_at: new Date().toISOString(), + }, + { + id: '3', + device_name: 'Đèn thông minh Ngã Tư Thủ Đức', + device_type: 'TrafficController', + active_status: false, + location_desc: 'Ngã Tư Thủ Đức', + status: 'maintenance', + ip_address: '192.168.1.107', + serial_number: 'SN-CTRL-001', + protocol: 'MQTT', + latitude: 10.851, + longitude: 106.769, + update_interval: 10, + created_at: new Date('2024-01-20').toISOString(), + updated_at: new Date().toISOString(), + }, + ] + + // If we failed or got empty, use mocks for demo + setDevices(MOCK_DEVICES) + setStats({ + total: MOCK_DEVICES.length, + active: MOCK_DEVICES.filter((d) => d.active_status).length, + inactive: MOCK_DEVICES.filter((d) => !d.active_status).length, + lowBattery: 1, // Mock value + }) } finally { - setLoading(false); + setLoading(false) } - }; + } - fetchDevices(); + fetchDevices() // Poll every 30s - const interval = setInterval(fetchDevices, 30000); - return () => clearInterval(interval); - }, []); + const interval = setInterval(fetchDevices, 30000) + return () => clearInterval(interval) + }, []) if (loading) { return (
- ); + ) } return ( @@ -71,10 +124,10 @@ export const DeviceHealthPanel: React.FC = () => {

- {t("healthTitle")} + {t('healthTitle')}

- {stats.total} {t("deviceCount")} + {stats.total} {t('deviceCount')}
@@ -84,7 +137,7 @@ export const DeviceHealthPanel: React.FC = () => {
- {t("status.active")} + {t('status.active')}
@@ -96,19 +149,17 @@ export const DeviceHealthPanel: React.FC = () => {
- {t("status.inactive")} + {t('status.inactive')}
- - {stats.inactive} - + {stats.inactive}
- {t("status.lowBattery")} + {t('status.lowBattery')}
@@ -128,8 +179,8 @@ export const DeviceHealthPanel: React.FC = () => {
{device.active_status ? ( @@ -143,8 +194,7 @@ export const DeviceHealthPanel: React.FC = () => { {device.device_name}

- {device.device_type} •{" "} - {device.location_desc || t("unknownLocation")} + {device.device_type} • {device.location_desc || t('unknownLocation')}

@@ -152,19 +202,19 @@ export const DeviceHealthPanel: React.FC = () => {
{device.status} {new Date(device.updated_at).toLocaleTimeString( - i18n.language === "en" ? "en-US" : "vi-VN", + i18n.language === 'en' ? 'en-US' : 'vi-VN', { - hour: "2-digit", - minute: "2-digit", + hour: '2-digit', + minute: '2-digit', } )} @@ -175,10 +225,10 @@ export const DeviceHealthPanel: React.FC = () => { {devices.length === 0 && (
-

{t("noDevices")}

+

{t('noDevices')}

)}
- ); -}; + ) +} diff --git a/src/frontend/src/presentation/components/feature/dashboard/NotificationPopover.tsx b/src/frontend/src/presentation/components/feature/dashboard/NotificationPopover.tsx index 8ba393f..6fc531e 100644 --- a/src/frontend/src/presentation/components/feature/dashboard/NotificationPopover.tsx +++ b/src/frontend/src/presentation/components/feature/dashboard/NotificationPopover.tsx @@ -19,7 +19,7 @@ export const NotificationPopover: React.FC = ({ onClearAll, }) => { const [isOpen, setIsOpen] = useState(false); - const unreadCount = notifications.filter((n) => !n.resolved).length; + const getIcon = (type: string) => { switch (type) { @@ -32,6 +32,35 @@ export const NotificationPopover: React.FC = ({ } }; + // Mock data for demo purposes if no notifications provided + const MOCK_NOTIFICATIONS: AlertLog[] = [ + { + id: "notif_mock_1", + timestamp: new Date().toISOString(), + type: "critical", + message: "Cảnh báo: Nồng độ PM2.5 vượt ngưỡng tại Ngã 4 Thủ Đức", + resolved: false, + }, + { + id: "notif_mock_2", + timestamp: new Date(Date.now() - 1800000).toISOString(), + type: "warning", + message: "Lưu lượng giao thông tăng cao tại Hàng Xanh", + resolved: false, + }, + { + id: "notif_mock_3", + timestamp: new Date(Date.now() - 3600000).toISOString(), + type: "info", + message: "Hệ thống đã tự động tối ưu hóa đèn tín hiệu", + resolved: true, + }, + ]; + + const displayNotifications = + notifications.length > 0 ? notifications : MOCK_NOTIFICATIONS; + const unreadCount = displayNotifications.filter((n) => !n.resolved).length; + return (
-

- Thông báo -

- {notifications.length > 0 && ( + + {displayNotifications.length > 0 && (
- {notifications.length === 0 ? ( + {displayNotifications.length === 0 ? (
Không có thông báo mới
) : (
- {notifications.map((notification) => ( + {displayNotifications.map((notification) => (
void; - onSubmit: (device: DeviceModel) => void; - editingDevice?: DeviceModel; + isOpen: boolean + onClose: () => void + onSubmit: (device: DeviceModel) => void + editingDevice?: DeviceModel } -type WizardStep = "type" | "connection" | "location" | "confirm"; -type ConnectionTestResult = "idle" | "testing" | "success" | "error"; +type WizardStep = 'type' | 'connection' | 'location' | 'confirm' +type ConnectionTestResult = 'idle' | 'testing' | 'success' | 'error' const getStepNumber = (step: WizardStep): number => { switch (step) { - case "type": - return 1; - case "connection": - return 2; - case "location": - return 3; - case "confirm": - return 4; + case 'type': + return 1 + case 'connection': + return 2 + case 'location': + return 3 + case 'confirm': + return 4 default: - return 1; + return 1 } -}; +} export const DeviceWizard: React.FC = ({ isOpen, @@ -54,157 +54,156 @@ export const DeviceWizard: React.FC = ({ onSubmit, editingDevice, }) => { - const { t } = useTranslation(["devices", "common"]); - const [currentStep, setCurrentStep] = useState("type"); + const { t } = useTranslation(['devices', 'common']) + const [currentStep, setCurrentStep] = useState('type') const deviceTypeOptions = useMemo( () => [ { type: DeviceType.TRAFFIC_CAM, - title: t("devices:types.trafficCam"), - description: t("devices:wizard.typeDescriptions.trafficCam"), + title: t('devices:types.trafficCam'), + description: t('devices:wizard.typeDescriptions.trafficCam'), icon: Camera, - color: "blue", + color: 'blue', protocol: ConnectionProtocol.RTSP, }, { type: DeviceType.AIR_QUALITY_SENSOR, - title: t("devices:types.airQualitySensor"), - description: t("devices:wizard.typeDescriptions.airQualitySensor"), + title: t('devices:types.airQualitySensor'), + description: t('devices:wizard.typeDescriptions.airQualitySensor'), icon: Wind, - color: "green", + color: 'green', protocol: ConnectionProtocol.MQTT, }, { type: DeviceType.SMART_LIGHT, - title: t("devices:types.smartLight"), - description: t("devices:wizard.typeDescriptions.smartLight"), + title: t('devices:types.smartLight'), + description: t('devices:wizard.typeDescriptions.smartLight'), icon: Cpu, - color: "purple", + color: 'purple', protocol: ConnectionProtocol.MQTT, }, { type: DeviceType.INDUCTIVE_LOOP, - title: t("devices:types.inductiveLoop"), - description: t("devices:wizard.typeDescriptions.inductiveLoop"), + title: t('devices:types.inductiveLoop'), + description: t('devices:wizard.typeDescriptions.inductiveLoop'), icon: Server, - color: "orange", + color: 'orange', protocol: ConnectionProtocol.MQTT, }, ], [t] - ); + ) const getStepTitle = (step: WizardStep): string => { switch (step) { - case "type": - return t("devices:wizard.steps.type"); - case "connection": - return t("devices:wizard.steps.connection"); - case "location": - return t("devices:wizard.steps.location"); - case "confirm": - return t("devices:wizard.steps.confirm"); + case 'type': + return t('devices:wizard.steps.type') + case 'connection': + return t('devices:wizard.steps.connection') + case 'location': + return t('devices:wizard.steps.location') + case 'confirm': + return t('devices:wizard.steps.confirm') default: - return ""; + return '' } - }; + } const [deviceData, setDeviceData] = useState>({ - name: "", + name: '', type: DeviceType.TRAFFIC_CAM, protocol: ConnectionProtocol.MQTT, - manufacturer: "", - serialNumber: "", + manufacturer: '', + serialNumber: '', location: { latitude: 0, longitude: 0 }, updateInterval: 30, isActive: true, - }); - const [connectionTest, setConnectionTest] = - useState("idle"); - const [testError, setTestError] = useState(""); + }) + const [connectionTest, setConnectionTest] = useState('idle') + const [testError, setTestError] = useState('') // Reset form khi mở modal useEffect(() => { if (isOpen) { if (editingDevice) { - setDeviceData(editingDevice); - setCurrentStep("confirm"); + setDeviceData(editingDevice) + setCurrentStep('confirm') } else { - resetForm(); + resetForm() } } - }, [isOpen, editingDevice]); + }, [isOpen, editingDevice]) const resetForm = () => { setDeviceData({ - name: "", + name: '', type: DeviceType.TRAFFIC_CAM, protocol: ConnectionProtocol.MQTT, - manufacturer: "", - serialNumber: "", + manufacturer: '', + serialNumber: '', location: { latitude: 0, longitude: 0 }, updateInterval: 30, isActive: true, - }); - setCurrentStep("type"); - setConnectionTest("idle"); - setTestError(""); - }; + }) + setCurrentStep('type') + setConnectionTest('idle') + setTestError('') + } const handleDeviceTypeSelect = (type: DeviceType) => { - const selectedType = deviceTypeOptions.find((opt) => opt.type === type); + const selectedType = deviceTypeOptions.find((opt) => opt.type === type) setDeviceData({ ...deviceData, type, protocol: selectedType?.protocol || ConnectionProtocol.MQTT, - }); - setCurrentStep("connection"); - }; + }) + setCurrentStep('connection') + } const handleConnectionTest = async () => { - setConnectionTest("testing"); - setTestError(""); + setConnectionTest('testing') + setTestError('') // Mock connection test - trong thực tế sẽ gọi API setTimeout(() => { - const isSuccess = Math.random() > 0.2; // 80% success rate for demo + const isSuccess = Math.random() > 0.2 // 80% success rate for demo if (isSuccess) { - setConnectionTest("success"); + setConnectionTest('success') } else { - setConnectionTest("error"); - setTestError(t("devices:wizard.messages.connectError")); + setConnectionTest('error') + setTestError(t('devices:wizard.messages.connectError')) } - }, 2000); - }; + }, 2000) + } const handleNext = () => { switch (currentStep) { - case "type": - if (deviceData.type) setCurrentStep("connection"); - break; - case "connection": - setCurrentStep("location"); - break; - case "location": - setCurrentStep("confirm"); - break; + case 'type': + if (deviceData.type) setCurrentStep('connection') + break + case 'connection': + setCurrentStep('location') + break + case 'location': + setCurrentStep('confirm') + break } - }; + } const handleBack = () => { switch (currentStep) { - case "connection": - setCurrentStep("type"); - break; - case "location": - setCurrentStep("connection"); - break; - case "confirm": - setCurrentStep("location"); - break; + case 'connection': + setCurrentStep('type') + break + case 'location': + setCurrentStep('connection') + break + case 'confirm': + setCurrentStep('location') + break } - }; + } const handleSubmit = () => { if (deviceData.type && deviceData.serialNumber && deviceData.location) { @@ -216,24 +215,22 @@ export const DeviceWizard: React.FC = ({ id: editingDevice?.id || Date.now().toString(), createdAt: editingDevice?.createdAt || new Date(), updatedAt: new Date(), - }); - onSubmit(newDevice); - onClose(); + }) + onSubmit(newDevice) + onClose() } - }; + } - if (!isOpen) return null; + if (!isOpen) return null return (
-
+
{/* Header */} -
+

- {editingDevice - ? t("devices:wizard.title.edit") - : t("devices:wizard.title.add")} + {editingDevice ? t('devices:wizard.title.edit') : t('devices:wizard.title.add')}

- ); + ) })}
)} {/* Step 2: Connection Configuration */} - {currentStep === "connection" && ( + {currentStep === 'connection' && (

- {t("devices:wizard.stepTitles.connection")} + {t('devices:wizard.stepTitles.connection')}

{/* General Information */}

- {t("devices:wizard.labels.generalInfo")} + {t('devices:wizard.labels.generalInfo')}

- setDeviceData({ ...deviceData, name: e.target.value }) - } + value={deviceData.name || ''} + onChange={(e) => setDeviceData({ ...deviceData, name: e.target.value })} className="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-greenwave-primary-light" - placeholder={t("devices:wizard.placeholders.name")} + placeholder={t('devices:wizard.placeholders.name')} />
setDeviceData({ ...deviceData, @@ -364,16 +361,16 @@ export const DeviceWizard: React.FC = ({ }) } className="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-greenwave-primary-light" - placeholder={t("devices:wizard.placeholders.serial")} + placeholder={t('devices:wizard.placeholders.serial')} />
setDeviceData({ ...deviceData, @@ -381,14 +378,12 @@ export const DeviceWizard: React.FC = ({ }) } className="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-greenwave-primary-light" - placeholder={t( - "devices:wizard.placeholders.manufacturer" - )} + placeholder={t('devices:wizard.placeholders.manufacturer')} />
@@ -415,35 +408,33 @@ export const DeviceWizard: React.FC = ({ {deviceData.protocol === ConnectionProtocol.MQTT && (

- {t("devices:wizard.labels.mqttConfig")} + {t('devices:wizard.labels.mqttConfig')}

setDeviceData({ ...deviceData, mqttConfig: { - topicSubscribe: "", + topicSubscribe: '', ...deviceData.mqttConfig, brokerUrl: e.target.value, }, }) } className="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-greenwave-primary-light" - placeholder={t( - "devices:wizard.placeholders.brokerUrl" - )} + placeholder={t('devices:wizard.placeholders.brokerUrl')} />
= ({ setDeviceData({ ...deviceData, mqttConfig: { - topicSubscribe: "", + topicSubscribe: '', ...deviceData.mqttConfig, port: parseInt(e.target.value), }, @@ -463,11 +454,11 @@ export const DeviceWizard: React.FC = ({
setDeviceData({ ...deviceData, @@ -478,32 +469,28 @@ export const DeviceWizard: React.FC = ({ }) } className="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-greenwave-primary-light" - placeholder={t( - "devices:wizard.placeholders.topicSubscribe" - )} + placeholder={t('devices:wizard.placeholders.topicSubscribe')} />
setDeviceData({ ...deviceData, mqttConfig: { - topicSubscribe: "", + topicSubscribe: '', ...deviceData.mqttConfig, topicPublish: e.target.value, }, }) } className="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-greenwave-primary-light" - placeholder={t( - "devices:wizard.placeholders.topicPublish" - )} + placeholder={t('devices:wizard.placeholders.topicPublish')} />
@@ -513,12 +500,12 @@ export const DeviceWizard: React.FC = ({ {deviceData.protocol === ConnectionProtocol.RTSP && (

- {t("devices:wizard.labels.rtspConfig")} + {t('devices:wizard.labels.rtspConfig')}

= ({ }) } className="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-greenwave-primary-light" - placeholder={t( - "devices:wizard.placeholders.ipAddress" - )} + placeholder={t('devices:wizard.placeholders.ipAddress')} />
setDeviceData({ ...deviceData, httpConfig: { ...deviceData.httpConfig, rtspUrl: e.target.value, - ipAddress: deviceData.httpConfig?.ipAddress || "", + ipAddress: deviceData.httpConfig?.ipAddress || '', }, }) } className="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-greenwave-primary-light" - placeholder={t("devices:wizard.placeholders.rtspUrl")} + placeholder={t('devices:wizard.placeholders.rtspUrl')} />
@@ -568,51 +553,43 @@ export const DeviceWizard: React.FC = ({

- {t("devices:wizard.labels.connectionTest")} + {t('devices:wizard.labels.connectionTest')}

- {t("devices:wizard.labels.testDescription")} + {t('devices:wizard.labels.testDescription')}

- {connectionTest === "success" && ( + {connectionTest === 'success' && (
- ✓ {t("devices:wizard.messages.connectSuccess")} + ✓ {t('devices:wizard.messages.connectSuccess')}
)} - {connectionTest === "error" && testError && ( + {connectionTest === 'error' && testError && (
✗ {testError}
@@ -623,21 +600,21 @@ export const DeviceWizard: React.FC = ({ )} {/* Step 3: Location */} - {currentStep === "location" && ( + {currentStep === 'location' && (

- {t("devices:wizard.stepTitles.location")} + {t('devices:wizard.stepTitles.location')}

- {t("devices:wizard.labels.enterCoordinates")} + {t('devices:wizard.labels.enterCoordinates')}

= ({
= ({