From b7116a1e6f578851290af7e8d6c99381d5220c8a Mon Sep 17 00:00:00 2001 From: ISA Date: Sat, 10 Aug 2024 10:32:37 +0200 Subject: [PATCH] polylines tooltip content --- .babelrc | 3 + .env.local | 45 +- .gitignore | 1 + .prettierrc | 3 + .vscode/settings.json | 1 + Jenkinsfile | 81 +- MapTypC.aspx.txt | 47 + Wiki.md | 2 +- __mocks__/leaflet.js | 23 + __tests__/unit/components/DataSheet.test.js | 82 + .../unit/components/MapComponent.test.js | 89 + .../gisPolylines/icons/CircleIcon.test.js | 40 + .../gisPolylines/icons/EndIcon.test.js | 24 + .../gisPolylines/icons/StartIcon.test.js | 41 + __tests__/unit/hooks/useLineData.test.js | 42 + __tests__/unit/pois/AddPoiModalWindow.test.js | 86 + .../unit/pois/AddPoiModalWindowPopup.test.js | 77 + .../pois/AddPoiModalWindowWrapper.test.js | 75 + __tests__/unit/pois/PoiUpdateModal.test.js | 117 + .../unit/pois/PoiUpdateModalWindow.test.js | 57 + .../unit/pois/PoiUpdateModalWrapper.test.js | 79 + __tests__/unit/pois/PoiUtils.test.js | 111 + __tests__/unit/utils/mapUtils.test.js | 6 + babel.config.js | 3 + components/DataSheet.js | 65 +- components/MapComponent.js | 2953 +----- components/VersionInfoModal.js | 30 + components/gisPolylines/icons/CircleIcon.js | 12 + components/gisPolylines/icons/EndIcon.js | 11 + components/gisPolylines/icons/StartIcon.js | 17 + .../gisPolylines/icons/SupportPointIcons.js | 27 + components/imports.js | 160 + components/pois/AddPoiModalWindow.js | 145 + components/pois/AddPoiModalWindowPopup.js | 24 + components/pois/AddPoiModalWindowWrapper.js | 30 + components/pois/PoiUpdateModal.js | 213 + components/pois/PoiUpdateModalWindow.js | 9 + components/pois/PoiUpdateModalWrapper.js | 26 + components/pois/PoiUtils.js | 52 + components/useMapContextMenu.js | 77 + config/config.js | 74 +- config/layers.js | 17 + config/settings.js | 5 + config/urls.js | 45 + hooks/talasMarkersLayer.js | 47 + hooks/useCiscoRouterMarkersLayer.js | 49 + hooks/useDauzMarkersLayer.js | 45 + hooks/useEciMarkersLayer.js | 47 + hooks/useFetchPoiData.js | 25 + hooks/useGmaMarkersLayer.js | 63 + hooks/useGsmModemMarkersLayer.js | 47 + hooks/useLayerVisibility.js | 24 + hooks/useLineData - Kopie.js | 64 + hooks/useLineData - stationname.js | 93 + hooks/useLineData.js | 152 + hooks/useMapComponentState.js | 28 + hooks/useMarkerLayers.js | 26 + hooks/useMessstellenMarkersLayer.js | 37 + hooks/useOtdrMarkersLayer.js | 45 + hooks/usePoiTypData.js | 26 + hooks/useSiemensMarkersLayer.js | 49 + hooks/useSmsfunkmodemMarkersLayer.js | 54 + hooks/useSonstigeMarkersLayer.js | 45 + hooks/useTalasMarkers.js | 102 + hooks/useTalasiclMarkersLayer.js | 45 + hooks/useUlafMarkersLayer.js | 76 + hooks/useWagoMarkersLayer.js | 49 + hooks/useWdmMarkersLayer.js | 45 + jest.config.js | 11 + jest.setup.js | 3 + package-lock.json | 8507 +++++++++++++++-- package.json | 43 +- pages/_app.js | 3 +- pages/api back30/[...path].js | 20 + pages/api back30/get-talasIP.js | 20 + pages/api back30/gis-proxy.js | 34 + pages/api back30/linesColorApi.js | 64 + pages/api back30/rights.js | 29 + pages/api back30/talas5/area.js | 40 + pages/api back30/talas5/location_device.js | 39 + .../webserviceMap/GisStationsMeasurements.js | 116 + .../GisStationsStaticDistrict.js | 281 + .../GisStationsStatusDistrict.js | 100 + .../talas5/webserviceMap/GisSystemStatic.js | 273 + .../gisStationsMeasurementsSQL.js | 70 + .../talas_v5_DB/gisLines/readGisLines.js | 37 + .../gisLines/updateLineCoordinates.js | 61 + .../talas_v5_DB/locationDevice/getDeviceId.js | 40 + .../locationDevice/locationDeviceNameById.js | 46 + .../locationDevice/locationDevices.js | 35 + .../talas_v5_DB/poiTyp/readPoiTyp.js | 33 + .../talas_v5_DB/pois/addLocation.js | 38 + .../api back30/talas_v5_DB/pois/deletePoi.js | 45 + .../api back30/talas_v5_DB/pois/getPoiById.js | 42 + .../api back30/talas_v5_DB/pois/poi-icons.js | 42 + .../talas_v5_DB/pois/readLocations.js | 42 + .../talas_v5_DB/pois/updateLocation.js | 39 + .../api back30/talas_v5_DB/pois/updatePoi.js | 46 + .../api back30/talas_v5_DB/priorityConfig.js | 40 + pages/api/[...path].js | 7 +- pages/api/gis-proxy.js | 34 + pages/api/linesColorApi.js | 23 +- pages/api/talas5/area.js | 29 +- pages/api/talas5/location_device.js | 64 +- .../GisStationsStatusDistrict.js | 46 +- .../gisStationsMeasurementsSQL.js | 48 +- .../api/talas_v5_DB/gisLines/readGisLines.js | 37 +- .../gisLines/updateLineCoordinates.js | 82 +- .../talas_v5_DB/locationDevice/getDeviceId.js | 41 +- .../locationDevice/locationDeviceNameById.js | 47 +- .../locationDevice/locationDevices.js | 37 +- pages/api/talas_v5_DB/poiTyp/readPoiTyp.js | 44 +- pages/api/talas_v5_DB/pois/addLocation.js | 39 +- pages/api/talas_v5_DB/pois/deletePoi.js | 37 +- pages/api/talas_v5_DB/pois/getPoiById.js | 63 +- pages/api/talas_v5_DB/pois/poi-icons.js | 48 +- pages/api/talas_v5_DB/pois/readLocations.js | 55 +- pages/api/talas_v5_DB/pois/updateLocation.js | 47 +- pages/api/talas_v5_DB/pois/updatePoi.js | 58 +- pages/api/talas_v5_DB/priorityConfig.js | 48 +- .../station/getStationNameByIdLD.js | 31 + pages/index.js | 40 +- .../img/icons/gisLines/add-support-point.svg | 4 + .../icons/gisLines/remove-support-point.svg | 4 + services/apiService.js | 129 + services/fetchData.js | 62 + setupTests.js | 2 + store/atoms/gisSystemState.js | 2 +- store/atoms/poiDeviceNameState.js | 7 + store/atoms/poiLayerVisibleState.js | 8 + styles/global.css | 13 + tailwind.config.js | 3 +- tree_included.ps1 | 42 + utils/contextMenuUtils.js | 33 + utils/geometryUtils.js | 19 + utils/handlePoiSelect.js | 39 + utils/mapFeatures.js | 272 + utils/mapInitialization.js | 75 + utils/mapUtils.js | 110 + utils/markerUtils.js | 199 + utils/openInSameWindow.js | 10 + utils/zoomAndCenterUtils.js | 45 + 142 files changed, 14451 insertions(+), 4281 deletions(-) create mode 100644 .babelrc create mode 100644 .prettierrc create mode 100644 .vscode/settings.json create mode 100644 MapTypC.aspx.txt create mode 100644 __mocks__/leaflet.js create mode 100644 __tests__/unit/components/DataSheet.test.js create mode 100644 __tests__/unit/components/MapComponent.test.js create mode 100644 __tests__/unit/components/gisPolylines/icons/CircleIcon.test.js create mode 100644 __tests__/unit/components/gisPolylines/icons/EndIcon.test.js create mode 100644 __tests__/unit/components/gisPolylines/icons/StartIcon.test.js create mode 100644 __tests__/unit/hooks/useLineData.test.js create mode 100644 __tests__/unit/pois/AddPoiModalWindow.test.js create mode 100644 __tests__/unit/pois/AddPoiModalWindowPopup.test.js create mode 100644 __tests__/unit/pois/AddPoiModalWindowWrapper.test.js create mode 100644 __tests__/unit/pois/PoiUpdateModal.test.js create mode 100644 __tests__/unit/pois/PoiUpdateModalWindow.test.js create mode 100644 __tests__/unit/pois/PoiUpdateModalWrapper.test.js create mode 100644 __tests__/unit/pois/PoiUtils.test.js create mode 100644 __tests__/unit/utils/mapUtils.test.js create mode 100644 babel.config.js create mode 100644 components/VersionInfoModal.js create mode 100644 components/gisPolylines/icons/CircleIcon.js create mode 100644 components/gisPolylines/icons/EndIcon.js create mode 100644 components/gisPolylines/icons/StartIcon.js create mode 100644 components/gisPolylines/icons/SupportPointIcons.js create mode 100644 components/imports.js create mode 100644 components/pois/AddPoiModalWindow.js create mode 100644 components/pois/AddPoiModalWindowPopup.js create mode 100644 components/pois/AddPoiModalWindowWrapper.js create mode 100644 components/pois/PoiUpdateModal.js create mode 100644 components/pois/PoiUpdateModalWindow.js create mode 100644 components/pois/PoiUpdateModalWrapper.js create mode 100644 components/pois/PoiUtils.js create mode 100644 components/useMapContextMenu.js create mode 100644 config/layers.js create mode 100644 config/settings.js create mode 100644 config/urls.js create mode 100644 hooks/talasMarkersLayer.js create mode 100644 hooks/useCiscoRouterMarkersLayer.js create mode 100644 hooks/useDauzMarkersLayer.js create mode 100644 hooks/useEciMarkersLayer.js create mode 100644 hooks/useFetchPoiData.js create mode 100644 hooks/useGmaMarkersLayer.js create mode 100644 hooks/useGsmModemMarkersLayer.js create mode 100644 hooks/useLayerVisibility.js create mode 100644 hooks/useLineData - Kopie.js create mode 100644 hooks/useLineData - stationname.js create mode 100644 hooks/useLineData.js create mode 100644 hooks/useMapComponentState.js create mode 100644 hooks/useMarkerLayers.js create mode 100644 hooks/useMessstellenMarkersLayer.js create mode 100644 hooks/useOtdrMarkersLayer.js create mode 100644 hooks/usePoiTypData.js create mode 100644 hooks/useSiemensMarkersLayer.js create mode 100644 hooks/useSmsfunkmodemMarkersLayer.js create mode 100644 hooks/useSonstigeMarkersLayer.js create mode 100644 hooks/useTalasMarkers.js create mode 100644 hooks/useTalasiclMarkersLayer.js create mode 100644 hooks/useUlafMarkersLayer.js create mode 100644 hooks/useWagoMarkersLayer.js create mode 100644 hooks/useWdmMarkersLayer.js create mode 100644 jest.config.js create mode 100644 jest.setup.js create mode 100644 pages/api back30/[...path].js create mode 100644 pages/api back30/get-talasIP.js create mode 100644 pages/api back30/gis-proxy.js create mode 100644 pages/api back30/linesColorApi.js create mode 100644 pages/api back30/rights.js create mode 100644 pages/api back30/talas5/area.js create mode 100644 pages/api back30/talas5/location_device.js create mode 100644 pages/api back30/talas5/webserviceMap/GisStationsMeasurements.js create mode 100644 pages/api back30/talas5/webserviceMap/GisStationsStaticDistrict.js create mode 100644 pages/api back30/talas5/webserviceMap/GisStationsStatusDistrict.js create mode 100644 pages/api back30/talas5/webserviceMap/GisSystemStatic.js create mode 100644 pages/api back30/talas5/webserviceMap/gisStationsMeasurementsSQL.js create mode 100644 pages/api back30/talas_v5_DB/gisLines/readGisLines.js create mode 100644 pages/api back30/talas_v5_DB/gisLines/updateLineCoordinates.js create mode 100644 pages/api back30/talas_v5_DB/locationDevice/getDeviceId.js create mode 100644 pages/api back30/talas_v5_DB/locationDevice/locationDeviceNameById.js create mode 100644 pages/api back30/talas_v5_DB/locationDevice/locationDevices.js create mode 100644 pages/api back30/talas_v5_DB/poiTyp/readPoiTyp.js create mode 100644 pages/api back30/talas_v5_DB/pois/addLocation.js create mode 100644 pages/api back30/talas_v5_DB/pois/deletePoi.js create mode 100644 pages/api back30/talas_v5_DB/pois/getPoiById.js create mode 100644 pages/api back30/talas_v5_DB/pois/poi-icons.js create mode 100644 pages/api back30/talas_v5_DB/pois/readLocations.js create mode 100644 pages/api back30/talas_v5_DB/pois/updateLocation.js create mode 100644 pages/api back30/talas_v5_DB/pois/updatePoi.js create mode 100644 pages/api back30/talas_v5_DB/priorityConfig.js create mode 100644 pages/api/gis-proxy.js create mode 100644 pages/api/talas_v5_DB/station/getStationNameByIdLD.js create mode 100644 public/img/icons/gisLines/add-support-point.svg create mode 100644 public/img/icons/gisLines/remove-support-point.svg create mode 100644 services/apiService.js create mode 100644 services/fetchData.js create mode 100644 setupTests.js create mode 100644 store/atoms/poiDeviceNameState.js create mode 100644 store/atoms/poiLayerVisibleState.js create mode 100644 tree_included.ps1 create mode 100644 utils/contextMenuUtils.js create mode 100644 utils/geometryUtils.js create mode 100644 utils/handlePoiSelect.js create mode 100644 utils/mapFeatures.js create mode 100644 utils/mapInitialization.js create mode 100644 utils/mapUtils.js create mode 100644 utils/markerUtils.js create mode 100644 utils/openInSameWindow.js create mode 100644 utils/zoomAndCenterUtils.js diff --git a/.babelrc b/.babelrc new file mode 100644 index 000000000..2b7bafa5f --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["@babel/preset-env", "@babel/preset-react"] +} diff --git a/.env.local b/.env.local index cb14642ed..018676da7 100644 --- a/.env.local +++ b/.env.local @@ -1,10 +1,45 @@ +#.env.local +#je nach dem Mysql Server, ob localhost freigegeben ist oder die IP Adresse des Servers, manchmal die beide und manchmal nur eine -DB_HOST=localhost -#DB_HOST=192.168.10.58 -#DB_HOST=10.10.0.13 +#DB_HOST=10.10.0.30 +#DB_USER=root +#DB_PASSWORD="root#$" +#DB_NAME=talas_v5 +#DB_PORT=3306 + + +######################### + +#NEXT_PUBLIC_BASE_URL="http://10.10.0.30/talas5/devices/" +#NEXT_PUBLIC_SERVER_URL="http://10.10.0.30" +#NEXT_PUBLIC_PROXY_TARGET="http://10.10.0.30" +#NEXT_PUBLIC_ONLINE_TILE_LAYER="http://10.10.0.30:3000/mapTiles/{z}/{x}/{y}.png" +######################### + + +#DB_HOST=10.10.0.70 +#DB_USER=root +#DB_PASSWORD="root#$" +#DB_NAME=talas_v5 +#DB_PORT=3306 + + +######################### + +#NEXT_PUBLIC_BASE_URL="http://10.10.0.70/talas5/devices/" +#NEXT_PUBLIC_SERVER_URL="http://10.10.0.70" +#NEXT_PUBLIC_PROXY_TARGET="http://10.10.0.70" +#NEXT_PUBLIC_ONLINE_TILE_LAYER="http://10.10.0.13:3000/mapTiles/{z}/{x}/{y}.png" +######################### + +DB_HOST=192.168.10.167 DB_USER=root DB_PASSWORD="root#$" DB_NAME=talas_v5 DB_PORT=3306 -######################### Kontetmenü -> Station in tab öffnen -#BASE_URL=http://10.10.0.13/talas5/devices/ \ No newline at end of file +######################### +#URLs für den Client (clientseitig) +NEXT_PUBLIC_BASE_URL="http://192.168.10.167/talas5/devices/" +NEXT_PUBLIC_SERVER_URL="http://192.168.10.167" +NEXT_PUBLIC_PROXY_TARGET="http://192.168.10.167" +NEXT_PUBLIC_ONLINE_TILE_LAYER="http://192.168.10.14:3000/mapTiles/{z}/{x}/{y}.png" diff --git a/.gitignore b/.gitignore index be30aedd7..cba64b18b 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ trace # Ignore specific Next.js build files pages-manifest.json +nodeMap für 13 am 16.07.2024.zip diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..0b2f36155 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +{ + "printWidth": 250 +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1 @@ +{} diff --git a/Jenkinsfile b/Jenkinsfile index 3294a62ae..5633ee135 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,96 +1,37 @@ pipeline { agent any - environment { - NODE_ENV = 'production' - } - - tools { - nodejs 'nodejs' // Ensure this matches the name defined in Jenkins - } - stages { - stage('Checkout') { + stage('Checkout SCM') { steps { - script { - try { - // Code aus dem Repository holen - git branch: 'develop', url: 'http://172.19.0.2:3000/Ismail/NodeMap.git' - } catch (Exception e) { - error "Branch 'develop' exists nicht im Repository" - } - } + checkout([$class: 'GitSCM', branches: [[name: '**']], + doGenerateSubmoduleConfigurations: false, + extensions: [], + userRemoteConfigs: [[url: 'http://172.20.0.2:3000/Ismail/NodeMap', credentialsId: 'd378f013-2f24-417b-9afd-33df5d410ab8']]]) } } - stage('Check Node.js Version') { steps { script { - sh 'node --version' + def nodeVersion = sh(script: 'node --version', returnStdout: true).trim() + echo "Node.js version: ${nodeVersion}" } } } - stage('Install Dependencies') { steps { script { - try { - // Install dependencies - sh 'npm install' - } catch (Exception e) { - error "Dependency Installation failed: ${e.message}" - } + sh 'npm install' } } } - - stage('Build') { + stage('Run Unit Tests') { steps { script { - try { - // Build the project - sh 'npm run build' - } catch (Exception e) { - error "Build failed: ${e.message}" - } + sh 'npm test' } } } - - stage('Test') { - steps { - script { - try { - // Run tests - sh 'npm test' - } catch (Exception e) { - error "Tests failed: ${e.message}" - } - } - } - } - - stage('Deploy') { - steps { - script { - try { - // Add your deployment steps here - // For example: sh 'npm run deploy' - echo 'Deployment steps go here' - } catch (Exception e) { - error "Deployment failed: ${e.message}" - } - } - } - } - } - - post { - success { - echo 'Build, tests, and deployment were successful!' - } - failure { - echo 'Build, tests, or deployment failed.' - } + // Weitere Stages ... } } diff --git a/MapTypC.aspx.txt b/MapTypC.aspx.txt new file mode 100644 index 000000000..2fe1ad5a2 --- /dev/null +++ b/MapTypC.aspx.txt @@ -0,0 +1,47 @@ +<%@ Page Title="" Language="C#" MasterPageFile="~/Standard.Master" AutoEventWireup="true" CodeBehind="MapTypC.aspx.cs" Inherits="TALAS_V5.MessagesMap.MapTypC" %> +<%@ Register assembly="DevExpress.Web.v19.2, Version=19.2.6.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" namespace="DevExpress.Web" tagprefix="dx" %> + + + + + + + + + +
+ +
+ + + +
\ No newline at end of file diff --git a/Wiki.md b/Wiki.md index 8b157b905..49c6ae9aa 100644 --- a/Wiki.md +++ b/Wiki.md @@ -146,7 +146,7 @@ Bei Problemen während der Weiterentwicklung könnte es hilfreich sein, die Seit - **DataSheet.js**: Verantwortlich für die Anzeige und Interaktion mit den Layer- und Stationsauswahlen. Ermöglicht das Aktivieren/Deaktivieren von Layern und zeigt Informationen zu geografischen Punkten. - **MapComponent.js**: Kernkomponente für die Darstellung der Karte. Beinhaltet Logik für das Hinzufügen von Layern, Zoom-Funktionen und andere interaktive Elemente. - **PoiUpdateModal.js**:Komponente zum Aktualisieren(update) und löschen von Pois. -- **ShowAddStationPopup.js**:Komponente zum hinzufügen von Pois. +- **AddPoiModalWindow.js**:Komponente zum hinzufügen von Pois. ### /public diff --git a/__mocks__/leaflet.js b/__mocks__/leaflet.js new file mode 100644 index 000000000..2ef6e4a0a --- /dev/null +++ b/__mocks__/leaflet.js @@ -0,0 +1,23 @@ +// __mocks__/leaflet.js +const L = { + divIcon: jest.fn(() => new L.DivIcon()), + DivIcon: function () { + this.options = { + className: "custom-start-icon", + html: ` + + + + + `, + iconSize: [18, 18], + iconAnchor: [9, 10], + }; + }, +}; + +L.DivIcon.prototype = { + constructor: L.DivIcon, +}; + +module.exports = L; diff --git a/__tests__/unit/components/DataSheet.test.js b/__tests__/unit/components/DataSheet.test.js new file mode 100644 index 000000000..f390de883 --- /dev/null +++ b/__tests__/unit/components/DataSheet.test.js @@ -0,0 +1,82 @@ +// __tests__/components/DataSheet.test.js +import React from "react"; +import { render, screen, waitFor } from "@testing-library/react"; +import "@testing-library/jest-dom"; +import userEvent from "@testing-library/user-event"; +import DataSheet from "../../components/DataSheet"; +import { RecoilRoot } from "recoil"; +import * as Recoil from "recoil"; +import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil"; +import { gisStationsStaticDistrictState } from "../../store/atoms/gisStationState"; +import { gisSystemStaticState } from "../../store/atoms/gisSystemState"; +import { mapLayersState } from "../../store/atoms/mapLayersState"; +import { selectedAreaState } from "../../store/atoms/selectedAreaState"; +import { zoomTriggerState } from "../../store/atoms/zoomTriggerState"; +import { poiLayerVisibleState } from "../../store/atoms/poiLayerVisibleState"; + +// Stelle sicher, dass alle notwendigen Atome korrekt gemockt sind +jest.mock("../../store/atoms/gisStationState", () => ({ + gisStationState: { + subscribe: jest.fn(), + getSnapshot: jest.fn(() => []), // Mocked return value + }, +})); + +jest.mock("../../store/atoms/gisSystemState", () => ({ + gisSystemStaticState: { + subscribe: jest.fn(), + getSnapshot: jest.fn(() => []), // Mocked return value + }, +})); + +describe("DataSheet Component", () => { + //-------------------------------------------------------------------------------- + it("renders the basic fields and initial station/system listings", async () => { + render( + + + + ); + + // Waiting for asynchronous tasks to complete + await waitFor(() => { + // Check if the specific elements are present after data processing + expect(screen.getByRole("combobox")).toBeInTheDocument(); + expect(screen.getByLabelText("POIs")).toBeInTheDocument(); + expect(screen.getByRole("option", { name: "Station wählen" })).toBeInTheDocument(); + }); + + // Optionally print out the full DOM for debugging + screen.debug(); + }); + //-------------------------------------------------------------------------------- + test("should open dropdown on click", async () => { + render( + + + + ); + const combobox = screen.getByRole("combobox"); + userEvent.click(combobox); + // Überprüfe, ob die Dropdown-Optionen angezeigt werden + expect(screen.getByRole("option", { name: "Station wählen" })).toBeInTheDocument(); + }); + + //-------------------------------------------------------------------------------- + test("should toggle checkbox", async () => { + render( + + + + ); + const checkbox = screen.getByLabelText("POIs"); + // Stelle sicher, dass die Checkbox nicht angekreuzt ist + expect(checkbox).not.toBeChecked(); + // Klicke auf die Checkbox + userEvent.click(checkbox); + // Jetzt sollte sie angekreuzt sein + expect(checkbox).toBeChecked(); + }); + + //-------------------------------------------------------------------------------- +}); diff --git a/__tests__/unit/components/MapComponent.test.js b/__tests__/unit/components/MapComponent.test.js new file mode 100644 index 000000000..ea9be1af6 --- /dev/null +++ b/__tests__/unit/components/MapComponent.test.js @@ -0,0 +1,89 @@ +// __tests__/MapComponent.test.js + +// Ein einfacher Testfall, der sicherstellt, dass die Addition korrekt ist +test("simple addition", () => { + const a = 1; + const b = 2; + const c = a + b; + expect(c).toBe(3); // Überprüft, ob c gleich 3 ist +}); + +//import L from "leaflet"; +//import { checkOverlappingMarkers } from "../utils/mapUtils"; // Passe den Pfad entsprechend an + +/* describe("checkOverlappingMarkers", () => { + let map; + + beforeEach(() => { + // Erstelle eine neue Leaflet-Karte für jeden Test + map = L.map(document.createElement("div")); + }); + + it("should group markers by coordinates and add plus icons for overlapping markers", () => { + // Erstelle einige Beispielmarker + const markers = [ + L.marker([51.505, -0.09]), + L.marker([51.505, -0.09]), + L.marker([51.51, -0.1]), + ]; + + const plusIcon = L.divIcon({ className: "plus-icon" }); + + // Rufe die Funktion auf + checkOverlappingMarkers(map, markers, plusIcon); + + // Überprüfe, dass die Marker zu Gruppen hinzugefügt wurden + const overlappingGroups = map._layers; + expect(Object.keys(overlappingGroups).length).toBeGreaterThan(0); + + // Überprüfe, dass die Plus-Marker hinzugefügt wurden + const plusMarkers = Object.values(overlappingGroups).filter( + (layer) => + layer.options.icon && + layer.options.icon.options.className === "plus-icon" + ); + expect(plusMarkers.length).toBeGreaterThan(0); + }); + + it("should handle non-array markers argument gracefully", () => { + const plusIcon = L.divIcon({ className: "plus-icon" }); + + // Rufe die Funktion mit einem ungültigen Argument auf + checkOverlappingMarkers(map, null, plusIcon); + + // Stelle sicher, dass keine Marker hinzugefügt wurden + const layers = map._layers; + expect(Object.keys(layers).length).toBe(0); + }); + + it("should not add plus markers if there are no overlaps", () => { + // Erstelle einige Beispielmarker + const markers = [ + L.marker([51.505, -0.09]), + L.marker([51.51, -0.1]), + L.marker([51.52, -0.12]), + ]; + + const plusIcon = L.divIcon({ className: "plus-icon" }); + + // Rufe die Funktion auf + checkOverlappingMarkers(map, markers, plusIcon); + + // Überprüfe, dass keine Plus-Marker hinzugefügt wurden + const plusMarkers = Object.values(map._layers).filter( + (layer) => + layer.options.icon && + layer.options.icon.options.className === "plus-icon" + ); + expect(plusMarkers.length).toBe(0); + }); +}); */ +/* +In diesem Test: + +Wird eine neue Leaflet-Karte vor jedem Test erstellt. +checkOverlappingMarkers wird aufgerufen, um zu überprüfen, ob die Funktion die Marker richtig gruppiert und Plus-Icons für überlappende Marker hinzufügt. +Der Test überprüft auch, ob die Funktion ungültige Argumente (wie null für Marker) korrekt behandelt. +Es wird sichergestellt, dass keine Plus-Marker hinzugefügt werden, wenn keine Überlappungen vorliegen. +Stelle sicher, dass du die Pfade und Importe entsprechend deiner Projektstruktur anpasst. +*/ diff --git a/__tests__/unit/components/gisPolylines/icons/CircleIcon.test.js b/__tests__/unit/components/gisPolylines/icons/CircleIcon.test.js new file mode 100644 index 000000000..efc9e485e --- /dev/null +++ b/__tests__/unit/components/gisPolylines/icons/CircleIcon.test.js @@ -0,0 +1,40 @@ +// __tests__/components/gisPolylines/icons/CircleIcon.test.js +jest.mock("leaflet", () => { + const actualLeaflet = jest.requireActual("leaflet"); + return { + ...actualLeaflet, + DivIcon: jest.fn().mockImplementation((options) => ({ + ...options, + options, + _leaflet_id: Math.random(), + })), + }; +}); + +import L from "leaflet"; +import CircleIcon from "../../../components/gisPolylines/icons/CircleIcon"; + +describe("CircleIcon", () => { + test("should be a Leaflet divIcon with correct properties", () => { + // console.log("CircleIcon options:", CircleIcon.options); + expect(CircleIcon).toEqual( + expect.objectContaining({ + options: expect.objectContaining({ + className: "custom-circle-icon leaflet-marker-icon", + html: '
', + iconSize: [25, 25], + iconAnchor: [5, 5], + }), + }) + ); + expect(CircleIcon.options.className).toContain("custom-circle-icon"); + expect(CircleIcon.options.html).toContain(" { + const actualLeaflet = jest.requireActual("leaflet"); + return { + ...actualLeaflet, + DivIcon: jest.fn().mockImplementation((options) => ({ + ...options, + options, + _leaflet_id: Math.random(), + })), + }; +}); + +import L from "leaflet"; +import EndIcon from "../../../../components/gisPolylines/icons/EndIcon"; +//console.log("console log EndIcon: ", EndIcon); +describe("endIcon", () => { + test("should be a custom-end-icon with correct HTML and styles", () => { + expect(EndIcon.options.className).toBe("custom-end-icon"); + expect(EndIcon.options.html).toBe("
"); + expect(EndIcon.options.iconSize).toEqual([14, 14]); + expect(EndIcon.options.iconAnchor).toEqual([7, 7]); + }); +}); diff --git a/__tests__/unit/components/gisPolylines/icons/StartIcon.test.js b/__tests__/unit/components/gisPolylines/icons/StartIcon.test.js new file mode 100644 index 000000000..2769119ea --- /dev/null +++ b/__tests__/unit/components/gisPolylines/icons/StartIcon.test.js @@ -0,0 +1,41 @@ +// __tests__/components/gisPolylines/icons/StartIcon.test.js +jest.mock("leaflet", () => { + const actualLeaflet = jest.requireActual("leaflet"); + return { + ...actualLeaflet, + DivIcon: jest.fn().mockImplementation((options) => ({ + ...options, + options, + _leaflet_id: Math.random(), + _createIcon: jest.fn(), + _createImg: jest.fn(), + _getIconUrl: jest.fn(), + _initHooks: [], + _initHooksCalled: true, + _setIconStyles: jest.fn(), + callInitHooks: jest.fn(), + createIcon: jest.fn(), + createShadow: jest.fn(), + initialize: jest.fn(), + })), + }; +}); + +import L from "leaflet"; +import StartIcon from "../../../../../components/gisPolylines/icons/StartIcon"; + +describe("StartIcon", () => { + test("should be a Leaflet divIcon with correct properties", () => { + //console.log("StartIcon options:", StartIcon.options); + expect(StartIcon).toEqual( + expect.objectContaining({ + options: expect.objectContaining({ + className: "custom-start-icon", + html: expect.stringContaining(" { + if (url === mockUrl) { + return Promise.resolve({ + json: () => Promise.resolve(mockData1), + }); + } else { + return Promise.resolve({ + json: () => Promise.resolve(mockData2), + }); + } +}); + +describe("useLineData", () => { + test("should fetch line data and set line colors and tooltip contents", async () => { + const setLineStatusData = jest.fn(); + + const { result } = renderHook(() => useLineData(mockUrl, setLineStatusData)); + + await waitFor( + () => { + expect(setLineStatusData).toHaveBeenCalledWith(expect.any(Array)); + expect(result.current).toEqual( + expect.objectContaining({ + lineColors: expect.any(Object), + tooltipContents: expect.any(Object), + }) + ); + }, + { timeout: 5000 } // Increase the timeout to 5000ms + ); + }); +}); diff --git a/__tests__/unit/pois/AddPoiModalWindow.test.js b/__tests__/unit/pois/AddPoiModalWindow.test.js new file mode 100644 index 000000000..5a95b654f --- /dev/null +++ b/__tests__/unit/pois/AddPoiModalWindow.test.js @@ -0,0 +1,86 @@ +// __tests__/components/pois/AddPoiModalWindow.test.js + +import React from "react"; +import { render, screen, fireEvent, waitFor, act } from "@testing-library/react"; +import "@testing-library/jest-dom"; +import AddPoiModalWindow from "../../../components/pois/AddPoiModalWindow"; +import { RecoilRoot } from "recoil"; + +// Mock für die fetch-Funktion +global.fetch = jest.fn((url) => { + if (url === "/api/talas_v5_DB/poiTyp/readPoiTyp") { + return Promise.resolve({ + json: () => Promise.resolve([{ idPoiTyp: "1", name: "Type1" }]), + }); + } else if (url === "/api/talas5/location_device") { + return Promise.resolve({ + json: () => Promise.resolve([{ idLD: "1", name: "Device1" }]), + }); + } else if (url === "/api/talas_v5_DB/pois/addLocation") { + return Promise.resolve({ ok: true }); + } +}); + +describe("AddPoiModalWindow", () => { + const mockOnClose = jest.fn(); + const mockMap = { + closePopup: jest.fn(), + }; + const mockLatLng = { lat: 52.52, lng: 13.405 }; + + // Mock window.location.reload + beforeAll(() => { + Object.defineProperty(window, "location", { + value: { + ...window.location, + reload: jest.fn(), + }, + writable: true, + }); + }); + + beforeEach(() => { + fetch.mockClear(); + window.location.reload.mockClear(); // Clear the mock before each test + }); + + test("renders correctly and allows form submission", async () => { + await act(async () => { + render( + + + + ); + }); + + // Überprüfen, ob die Formularelemente gerendert werden + expect(screen.getByLabelText(/Name/i)).toBeInTheDocument(); + expect(screen.getByLabelText(/Gerät/i)).toBeInTheDocument(); + expect(screen.getByLabelText(/Typ/i)).toBeInTheDocument(); + expect(screen.getByText(/Lat/i)).toHaveTextContent(`Lat : ${mockLatLng.lat.toFixed(5)}`); + expect(screen.getByText(/Lng/i)).toHaveTextContent(`Lng : ${mockLatLng.lng.toFixed(5)}`); + + // Simulieren der Eingabe in das Namensfeld + fireEvent.change(screen.getByLabelText(/Name/i), { target: { value: "New POI" } }); + expect(screen.getByLabelText(/Name/i)).toHaveValue("New POI"); + + // Simulieren der Auswahl eines Geräts + fireEvent.change(screen.getByLabelText(/Gerät/i), { target: { value: "Device1" } }); + expect(screen.getByLabelText(/Gerät/i)).toHaveValue("Device1"); + + // Simulieren der Auswahl eines Typs + fireEvent.change(screen.getByLabelText(/Typ/i), { target: { value: "1" } }); + expect(screen.getByLabelText(/Typ/i)).toHaveValue("1"); + + // Simulieren des Formulareingabeverfahrens + fireEvent.submit(screen.getByRole("button", { name: /POI hinzufügen/i })); + + // Warten auf die Formulareinreichung und Überprüfen der Ergebnisse + await waitFor(() => { + expect(mockOnClose).toHaveBeenCalled(); + expect(mockMap.closePopup).toHaveBeenCalled(); + expect(fetch).toHaveBeenCalledWith("/api/talas_v5_DB/pois/addLocation", expect.any(Object)); + expect(window.location.reload).toHaveBeenCalled(); // Verify that reload was called + }); + }); +}); diff --git a/__tests__/unit/pois/AddPoiModalWindowPopup.test.js b/__tests__/unit/pois/AddPoiModalWindowPopup.test.js new file mode 100644 index 000000000..e55327219 --- /dev/null +++ b/__tests__/unit/pois/AddPoiModalWindowPopup.test.js @@ -0,0 +1,77 @@ +// __tests__/components/pois/AddPoiModalWindowPopup.test.js + +import React from "react"; +import { render, screen, fireEvent } from "@testing-library/react"; +import "@testing-library/jest-dom"; +import AddPoiModalWindowPopup from "../../../components/pois/AddPoiModalWindowPopup"; + +// Mock the AddPoiModalWindow component +jest.mock("../../../components/pois/AddPoiModalWindow", () => ({ onClose, onSubmit, latlng }) => ( +
+ + +
+ Coordinates: {latlng.lat}, {latlng.lng} +
+
+)); + +describe("AddPoiModalWindowPopup", () => { + const closePopupMock = jest.fn(); + const handleAddStationMock = jest.fn(); + const popupCoordinatesMock = { lat: 52.52, lng: 13.405 }; + + // Suppress console.log for the duration of these tests + beforeAll(() => { + jest.spyOn(console, "log").mockImplementation(() => {}); + }); + + // Restore console.log after all tests + afterAll(() => { + console.log.mockRestore(); + }); + + beforeEach(() => { + closePopupMock.mockClear(); + handleAddStationMock.mockClear(); + }); + + test("renders the popup when showPopup is true", () => { + render(); + + expect(screen.getByTestId("add-poi-modal-window")).toBeInTheDocument(); + expect(screen.getByText("Coordinates: 52.52, 13.405")).toBeInTheDocument(); + }); + + test("does not render the popup when showPopup is false", () => { + render(); + + expect(screen.queryByTestId("add-poi-modal-window")).not.toBeInTheDocument(); + }); + + test("closes the popup when the top right close button is clicked", () => { + render(); + + // Use the aria-label to uniquely identify the close button in the outer component + const closeButton = screen.getByRole("button", { name: "Close" }); + + // Click the button with aria-label "Close" + fireEvent.click(closeButton); + expect(closePopupMock).toHaveBeenCalledTimes(1); + }); + + test("submits the form when the submit button is clicked", () => { + render(); + + fireEvent.click(screen.getByText("Submit")); + expect(handleAddStationMock).toHaveBeenCalledTimes(1); // This should now pass + }); + + test('clicking the "Close Modal" button inside AddPoiModalWindow should not close the popup', () => { + render(); + + // Click the "Close Modal" button inside the mock + fireEvent.click(screen.getByText("Close Modal")); + expect(closePopupMock).toHaveBeenCalledTimes(0); // Should not call the popup close + }); +}); diff --git a/__tests__/unit/pois/AddPoiModalWindowWrapper.test.js b/__tests__/unit/pois/AddPoiModalWindowWrapper.test.js new file mode 100644 index 000000000..c8fddf41b --- /dev/null +++ b/__tests__/unit/pois/AddPoiModalWindowWrapper.test.js @@ -0,0 +1,75 @@ +// __tests__/components/pois/AddPoiModalWindowWrapper.test.js + +import React from "react"; +import { render, screen, fireEvent } from "@testing-library/react"; +import "@testing-library/jest-dom"; +import AddPoiModalWindowWrapper from "../../../components/pois/AddPoiModalWindowWrapper"; + +// Mock the AddPoiModalWindow component to avoid testing its internal implementation here +jest.mock("../../../components/pois/AddPoiModalWindow", () => ({ onClose, onSubmit, latlng }) => ( +
+ + +
+ Mocked Coordinates: {latlng.lat}, {latlng.lng} +
+
+)); + +describe("AddPoiModalWindowWrapper", () => { + const onCloseMock = jest.fn(); + const handleAddStationMock = jest.fn(); + const latlngMock = { lat: 52.52, lng: 13.405 }; + + beforeEach(() => { + onCloseMock.mockClear(); + handleAddStationMock.mockClear(); + }); + + test("renders the modal when 'show' is true", () => { + render(); + + // Check if the modal and its contents are in the document + expect(screen.getByTestId("add-poi-modal-window")).toBeInTheDocument(); + expect(screen.getByText("Mocked Coordinates: 52.52, 13.405")).toBeInTheDocument(); + }); + + test("does not render the modal when 'show' is false", () => { + render(); + + // Check if the modal is not in the document + expect(screen.queryByTestId("add-poi-modal-window")).not.toBeInTheDocument(); + }); + + test("calls onClose when the close button is clicked", () => { + render(); + + // Click the close button + fireEvent.click(screen.getByRole("button", { name: "Close" })); + expect(onCloseMock).toHaveBeenCalledTimes(1); + }); + + test("calls onClose when the background is clicked", () => { + render(); + + // Click the background overlay + fireEvent.click(screen.getByTestId("modal-overlay")); + expect(onCloseMock).toHaveBeenCalledTimes(1); + }); + + test("does not call onClose when the modal content is clicked", () => { + render(); + + // Click the modal content + fireEvent.click(screen.getByRole("dialog")); + expect(onCloseMock).toHaveBeenCalledTimes(0); + }); + + test("calls handleAddStation when the submit button is clicked", () => { + render(); + + // Click the submit button + fireEvent.click(screen.getByText("Mocked Submit")); + expect(handleAddStationMock).toHaveBeenCalledTimes(1); + }); +}); diff --git a/__tests__/unit/pois/PoiUpdateModal.test.js b/__tests__/unit/pois/PoiUpdateModal.test.js new file mode 100644 index 000000000..b99db4dfd --- /dev/null +++ b/__tests__/unit/pois/PoiUpdateModal.test.js @@ -0,0 +1,117 @@ +// __tests__/components/pois/PoiUpdateModal.test.js + +import React from "react"; +import { render, screen, fireEvent, waitFor, act } from "@testing-library/react"; +import "@testing-library/jest-dom"; +import PoiUpdateModal from "../../../components/pois/PoiUpdateModal"; +import { useRecoilValue } from "recoil"; +import { selectedPoiState, currentPoiState } from "../../../store/atoms/poiState"; + +// Mock the recoil states +jest.mock("recoil"); + +describe("PoiUpdateModal", () => { + const mockOnClose = jest.fn(); + const mockOnSubmit = jest.fn(); + const poiDataMock = { + idPoi: "123", + name: "Test POI", + description: "Test Description", + idPoiTyp: "1", + idLD: "2", + }; + + const selectedPoiMock = { + idPoi: "123", + typ: "Type1", + }; + + const currentPoiMock = { + idLD: "2", + }; + + beforeEach(() => { + useRecoilValue.mockImplementation((state) => { + if (state === selectedPoiState) return selectedPoiMock; + if (state === currentPoiState) return currentPoiMock; + }); + + mockOnClose.mockClear(); + mockOnSubmit.mockClear(); + + global.fetch = jest.fn((url) => { + if (url === "/api/talas_v5_DB/poiTyp/readPoiTyp") { + return Promise.resolve({ + json: () => Promise.resolve([{ idPoiTyp: "1", name: "Type1" }]), + }); + } else if (url === "/api/talas_v5_DB/locationDevice/locationDevices") { + return Promise.resolve({ + json: () => Promise.resolve([{ id: "2", name: "Device1" }]), + }); + } else if (url.startsWith("/api/talas_v5_DB/locationDevice/getDeviceId")) { + return Promise.resolve({ + json: () => Promise.resolve({ idLD: "2", name: "Device1" }), + }); + } else if (url.startsWith("/api/talas_v5_DB/pois/deletePoi")) { + return Promise.resolve({ ok: true }); + } else if (url === "/api/talas_v5_DB/pois/updatePoi") { + return Promise.resolve({ ok: true }); + } + }); + + global.alert = jest.fn(); // Mock alert + delete window.location; + window.location = { reload: jest.fn() }; // Mock location.reload + }); + + test("renders modal with correct data", async () => { + await act(async () => { + render(); + }); + + expect(screen.getByDisplayValue("Test Description")).toBeInTheDocument(); + expect(screen.getByDisplayValue("Device1")).toBeInTheDocument(); + expect(screen.getByDisplayValue("Type1")).toBeInTheDocument(); + }); + + test("handles POI update submission", async () => { + await act(async () => { + render(); + }); + + fireEvent.change(screen.getByLabelText("Beschreibung:"), { target: { value: "Updated Description" } }); + fireEvent.click(screen.getByText("POI aktualisieren")); + + await waitFor(() => { + expect(global.fetch).toHaveBeenCalledWith("/api/talas_v5_DB/pois/updatePoi", expect.any(Object)); + expect(mockOnClose).toHaveBeenCalledTimes(1); + }); + }); + + test("handles POI deletion", async () => { + window.confirm = jest.fn().mockImplementation(() => true); // Mock confirm dialog to always accept + + await act(async () => { + render(); + }); + + fireEvent.click(screen.getByText("POI löschen")); + + await waitFor(() => { + expect(global.fetch).toHaveBeenCalledWith(expect.stringContaining("/api/talas_v5_DB/pois/deletePoi"), { method: "DELETE" }); + expect(mockOnClose).toHaveBeenCalledTimes(1); + expect(window.location.reload).toHaveBeenCalledTimes(1); + expect(global.alert).toHaveBeenCalledWith("POI wurde erfolgreich gelöscht."); + }); + }); + + test("closes the modal when the close button is clicked", async () => { + await act(async () => { + render(); + }); + + fireEvent.click(screen.getByLabelText("Close")); + + expect(mockOnClose).toHaveBeenCalledTimes(1); + }); +}); diff --git a/__tests__/unit/pois/PoiUpdateModalWindow.test.js b/__tests__/unit/pois/PoiUpdateModalWindow.test.js new file mode 100644 index 000000000..8ad912330 --- /dev/null +++ b/__tests__/unit/pois/PoiUpdateModalWindow.test.js @@ -0,0 +1,57 @@ +// __tests__/components/pois/PoiUpdateModalWindow.test.js + +import React from "react"; +import { render, screen } from "@testing-library/react"; +import "@testing-library/jest-dom"; +import PoiUpdateModalWindow from "../../../components/pois/PoiUpdateModalWindow"; +import PoiUpdateModal from "../../../components/pois/PoiUpdateModal"; + +// Mock the PoiUpdateModal component to avoid testing its internal implementation here +jest.mock("../../../components/pois/PoiUpdateModal", () => ({ onClose, poiData, onSubmit, latlng }) => ( +
+ +
POI Data: {poiData ? poiData.name : "No Data"}
+
LatLng: {latlng ? `${latlng.lat}, ${latlng.lng}` : "No Coordinates"}
+
+)); + +describe("PoiUpdateModalWindow", () => { + const closePoiUpdateModalMock = jest.fn(); + const currentPoiDataMock = { + idPoi: "123", + name: "Test POI", + description: "Test Description", + idPoiTyp: "1", + idLD: "2", + }; + + const popupCoordinatesMock = { lat: 52.52, lng: 13.405 }; + + beforeEach(() => { + closePoiUpdateModalMock.mockClear(); + }); + + test("renders PoiUpdateModal when showPoiUpdateModal is true", () => { + render(); + + // Check if the modal and its contents are in the document + expect(screen.getByTestId("poi-update-modal")).toBeInTheDocument(); + expect(screen.getByText("POI Data: Test POI")).toBeInTheDocument(); + expect(screen.getByText("LatLng: 52.52, 13.405")).toBeInTheDocument(); + }); + + test("does not render PoiUpdateModal when showPoiUpdateModal is false", () => { + render(); + + // Check if the modal is not in the document + expect(screen.queryByTestId("poi-update-modal")).not.toBeInTheDocument(); + }); + + test("calls closePoiUpdateModal when the close button is clicked", () => { + render(); + + // Click the close button + screen.getByText("Close").click(); + expect(closePoiUpdateModalMock).toHaveBeenCalledTimes(1); + }); +}); diff --git a/__tests__/unit/pois/PoiUpdateModalWrapper.test.js b/__tests__/unit/pois/PoiUpdateModalWrapper.test.js new file mode 100644 index 000000000..034550342 --- /dev/null +++ b/__tests__/unit/pois/PoiUpdateModalWrapper.test.js @@ -0,0 +1,79 @@ +// __tests__/components/pois/PoiUpdateModalWrapper.test.js + +import React from "react"; +import { render, screen, fireEvent, act } from "@testing-library/react"; +import "@testing-library/jest-dom"; +import PoiUpdateModalWrapper from "../../../components/pois/PoiUpdateModalWrapper"; +import { useRecoilValue, useSetRecoilState } from "recoil"; +import { currentPoiState, selectedPoiState } from "../../../store/atoms/poiState"; +import { poiReadFromDbTriggerAtom } from "../../../store/atoms/poiReadFromDbTriggerAtom"; + +// Mock Recoil hooks +jest.mock("recoil"); + +describe("PoiUpdateModalWrapper", () => { + const mockOnClose = jest.fn(); + const currentPoiMock = { + idPoi: "123", + name: "Test POI", + description: "Test Description", + idPoiTyp: "1", + idLD: "2", + }; + const latlngMock = { lat: 52.52, lng: 13.405 }; + + beforeEach(() => { + // Mock the recoil values + useRecoilValue.mockImplementation((atom) => { + if (atom === currentPoiState) return currentPoiMock; + if (atom === poiReadFromDbTriggerAtom) return 0; + }); + useSetRecoilState.mockImplementation(() => jest.fn()); + + mockOnClose.mockClear(); + + // Mock global fetch + global.fetch = jest.fn((url) => + Promise.resolve({ + json: () => { + if (url.includes("getDeviceIdById")) { + return Promise.resolve({ idLD: "2", name: "Device1" }); + } + if (url.includes("readPoiTyp")) { + return Promise.resolve([{ idPoiTyp: "1", name: "Type1" }]); + } + if (url.includes("locationDevices")) { + return Promise.resolve([{ id: "2", name: "Device1" }]); + } + return Promise.resolve({}); + }, + }) + ); + }); + + test("renders PoiUpdateModal when 'show' is true", async () => { + await act(async () => { + render(); + }); + + // Check if the modal and its contents are in the document + expect(screen.getByDisplayValue("Test Description")).toBeInTheDocument(); + }); + + test("does not render PoiUpdateModal when 'show' is false", () => { + render(); + + // Check if the modal is not in the document + expect(screen.queryByDisplayValue("Test POI")).not.toBeInTheDocument(); + }); + + test("calls onClose when the modal close button is clicked", async () => { + await act(async () => { + render(); + }); + + // Simulate closing the modal + fireEvent.click(screen.getByLabelText("Close")); + expect(mockOnClose).toHaveBeenCalledTimes(1); + }); +}); diff --git a/__tests__/unit/pois/PoiUtils.test.js b/__tests__/unit/pois/PoiUtils.test.js new file mode 100644 index 000000000..85bafff99 --- /dev/null +++ b/__tests__/unit/pois/PoiUtils.test.js @@ -0,0 +1,111 @@ +// __tests__/components/pois/PoiUtils.test.js + +import { createPoiMarkers, addMarkersToMap, updateLocationInDatabase } from "../../../components/pois/PoiUtils"; + +// Mock Leaflet +jest.mock("leaflet", () => { + const Leaflet = { + marker: jest.fn((latlng, options) => ({ + addTo: jest.fn(), + on: jest.fn(), + options: options, + getLatLng: jest.fn(() => ({ + lat: latlng[0], + lng: latlng[1], + })), + })), + icon: jest.fn((options) => options), + }; + return Leaflet; +}); + +describe("PoiUtils", () => { + describe("createPoiMarkers", () => { + it("should create markers with correct coordinates and icon", () => { + const poiData = [ + { idPoi: "1", latitude: 52.52, longitude: 13.405 }, + { idPoi: "2", latitude: 48.8566, longitude: 2.3522 }, + ]; + const iconPath = "path/to/icon.png"; + const markers = createPoiMarkers(poiData, iconPath); + + expect(markers).toHaveLength(2); + + markers.forEach((marker, index) => { + expect(marker.options.icon.iconUrl).toBe(iconPath); + expect(marker.options.icon.iconSize).toEqual([25, 41]); + expect(marker.options.id).toBe(poiData[index].idPoi); + }); + }); + }); + + describe("addMarkersToMap", () => { + it("should add markers to map and bind events", () => { + const mockMap = {}; + const mockLayerGroup = { addLayer: jest.fn() }; + const mockMarker = { + addTo: jest.fn(), + on: jest.fn(), + }; + + const markers = [mockMarker, mockMarker]; + + addMarkersToMap(markers, mockMap, mockLayerGroup); + + markers.forEach((marker) => { + expect(marker.addTo).toHaveBeenCalledWith(mockLayerGroup); + expect(marker.on).toHaveBeenCalledWith("mouseover", expect.any(Function)); + expect(marker.on).toHaveBeenCalledWith("mouseout", expect.any(Function)); + expect(marker.on).toHaveBeenCalledWith("dragend", expect.any(Function)); + }); + }); + }); + + describe("updateLocationInDatabase", () => { + beforeEach(() => { + global.fetch = jest.fn(() => + Promise.resolve({ + ok: true, + json: () => Promise.resolve({}), + }) + ); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it("should call fetch with correct parameters", async () => { + const id = "1"; + const newLatitude = 52.52; + const newLongitude = 13.405; + + await updateLocationInDatabase(id, newLatitude, newLongitude); + + expect(fetch).toHaveBeenCalledWith("/api/talas_v5_DB/pois/updateLocation", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + id, + latitude: newLatitude, + longitude: newLongitude, + }), + }); + }); + + it("should log error when fetch response is not ok", async () => { + console.error = jest.fn(); + + global.fetch = jest.fn(() => + Promise.resolve({ + ok: false, + json: () => Promise.resolve({}), + }) + ); + + await updateLocationInDatabase("1", 52.52, 13.405); + + expect(console.error).toHaveBeenCalledWith("Fehler beim Aktualisieren der Position"); + }); + }); +}); diff --git a/__tests__/unit/utils/mapUtils.test.js b/__tests__/unit/utils/mapUtils.test.js new file mode 100644 index 000000000..b72a59f6f --- /dev/null +++ b/__tests__/unit/utils/mapUtils.test.js @@ -0,0 +1,6 @@ +// __tests__/utils/mapUtils.test.js +describe("Dummy test suite", () => { + test("dummy test", () => { + expect(true).toBe(true); + }); +}); diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 000000000..e8ca8aa71 --- /dev/null +++ b/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: ["@babel/preset-env", "@babel/preset-react"], +}; diff --git a/components/DataSheet.js b/components/DataSheet.js index b3181a7d5..baa9cf9cf 100644 --- a/components/DataSheet.js +++ b/components/DataSheet.js @@ -1,3 +1,4 @@ +// components/DataSheet.js import React, { useEffect, useState } from "react"; import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil"; import { gisStationsStaticDistrictState } from "../store/atoms/gisStationState"; @@ -5,18 +6,15 @@ import { gisSystemStaticState } from "../store/atoms/gisSystemState"; import { mapLayersState } from "../store/atoms/mapLayersState"; import { selectedAreaState } from "../store/atoms/selectedAreaState"; import { zoomTriggerState } from "../store/atoms/zoomTriggerState"; -import { poiLayerVisibleState } from "../store/atoms/poiLayerVisible"; +import { poiLayerVisibleState } from "../store/atoms/poiLayerVisibleState"; function DataSheet() { const [poiVisible, setPoiVisible] = useRecoilState(poiLayerVisibleState); const setSelectedArea = useSetRecoilState(selectedAreaState); - const [mapLayersVisibility, setMapLayersVisibility] = - useRecoilState(mapLayersState); + const [mapLayersVisibility, setMapLayersVisibility] = useRecoilState(mapLayersState); const [stationListing, setStationListing] = useState([]); const [systemListing, setSystemListing] = useState([]); - const GisStationsStaticDistrict = useRecoilValue( - gisStationsStaticDistrictState - ); + const GisStationsStaticDistrict = useRecoilValue(gisStationsStaticDistrictState); const GisSystemStatic = useRecoilValue(gisSystemStaticState); const setZoomTrigger = useSetRecoilState(zoomTriggerState); @@ -24,30 +22,31 @@ function DataSheet() { const selectedIndex = event.target.options.selectedIndex; const areaName = event.target.options[selectedIndex].text; setSelectedArea(areaName); - console.log("Area selected oder areaName in DataSheet.js:", areaName); }; useEffect(() => { - const allowedSystems = new Set( - GisSystemStatic.filter((system) => system.Allow === 1).map( - (system) => system.IdSystem - ) - ); + console.log("GisStationsStaticDistrict:", GisStationsStaticDistrict); + console.log("GisSystemStatic:", GisSystemStatic); + const allowedSystems = new Set(GisSystemStatic.filter((system) => system.Allow === 1).map((system) => system.IdSystem)); + console.log("allowedSystems:", allowedSystems); + const seenNames = new Set(); const filteredAreas = GisStationsStaticDistrict.filter((item) => { - const isUnique = - !seenNames.has(item.Area_Name) && allowedSystems.has(item.System); + const isUnique = !seenNames.has(item.Area_Name) && allowedSystems.has(item.System); if (isUnique) { seenNames.add(item.Area_Name); } return isUnique; }); + setStationListing( filteredAreas.map((area, index) => ({ id: index + 1, name: area.Area_Name, })) ); + //console.log("filteredAreas:", filteredAreas); + const seenSystemNames = new Set(); const filteredSystems = GisSystemStatic.filter((item) => { const formattedName = item.Name.replace(/[\s\-]+/g, ""); @@ -57,6 +56,7 @@ function DataSheet() { } return isUnique; }); + setSystemListing( filteredSystems.map((system, index) => ({ id: index + 1, @@ -64,19 +64,21 @@ function DataSheet() { })) ); }, [GisStationsStaticDistrict, GisSystemStatic]); + //}, []); + //----------------------------------------- + //----------------------------------------- const handleCheckboxChange = (name, event) => { const { checked } = event.target; - console.log(`Checkbox ${name} checked state:`, checked); setMapLayersVisibility((prev) => { const newState = { ...prev, [name]: checked, }; - console.log(`New mapLayersVisibility state:`, newState); return newState; }); + console.log("mapLayersVisibility:", mapLayersVisibility); }; const handleIconClick = () => { @@ -85,16 +87,14 @@ function DataSheet() { }; return ( -
+
- Expand + Expand
{systemListing.map((system) => ( - handleCheckboxChange(system.name, e)} - /> - + handleCheckboxChange(system.name, e)} id={`system-${system.id}`} /> +
))} @@ -128,12 +121,12 @@ function DataSheet() { onChange={(e) => { const checked = e.target.checked; setPoiVisible(checked); - console.log( - `POIs sind jetzt ${checked ? "sichtbar" : "nicht sichtbar"}.` - ); }} + id="poi-checkbox" /> - +
diff --git a/components/MapComponent.js b/components/MapComponent.js index 3424be481..803b72d1c 100644 --- a/components/MapComponent.js +++ b/components/MapComponent.js @@ -1,265 +1,149 @@ // components/MapComponent.js -//Kommentar für Jenkins Test 23 - -import React, { +import { + React, useEffect, useRef, useState, - useMemo, - useCallback, - use, -} from "react"; -import { MapContainer, TileLayer, Polyline, LayerGroup } from "react-leaflet"; - -import L, { marker } from "leaflet"; -import "leaflet/dist/leaflet.css"; -import "leaflet-contextmenu/dist/leaflet.contextmenu.css"; -import "leaflet-contextmenu"; -import * as config from "../config/config.js"; -import dynamic from "next/dynamic"; -import "leaflet.smooth_marker_bouncing"; -import OverlappingMarkerSpiderfier from "overlapping-marker-spiderfier-leaflet"; -import DataSheet from "./DataSheet.js"; -import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil"; -import { gisStationsStaticDistrictState } from "../store/atoms/gisStationState.js"; -import { gisSystemStaticState } from "../store/atoms/gisSystemState.js"; -import { mapLayersState } from "../store/atoms/mapLayersState.js"; -import { selectedAreaState } from "../store/atoms/selectedAreaState.js"; -import { zoomTriggerState } from "../store/atoms/zoomTriggerState.js"; -import { poiTypState } from "../store/atoms/poiTypState.js"; -import ShowAddStationPopup from "./ShowAddStationPopup"; -import { poiReadFromDbTriggerAtom } from "../store/atoms/poiReadFromDbTriggerAtom"; -import { InformationCircleIcon } from "@heroicons/react/20/solid"; // oder 'outline' -import PoiUpdateModal from "./PoiUpdateModal.js"; -import { selectedPoiState } from "../store/atoms/poiState.js"; -import { currentPoiState } from "../store/atoms/currentPoiState"; -import { ToastContainer, toast } from "react-toastify"; -import "react-toastify/dist/ReactToastify.css"; -import { mapIdState, userIdState } from "../store/atoms/urlParameterState"; -import { set } from "lodash"; -import { poiLayerVisibleState } from "../store/atoms/poiLayerVisible"; -import { data } from "autoprefixer"; -import plusRoundIcon from "./PlusRoundIcon.js"; - -//--------------------------------------------------------------------- -//-------------------- MapComponent ----------------------------------- + L, + config, + urls, + OverlappingMarkerSpiderfier, + DataSheet, + useRecoilState, + useRecoilValue, + useSetRecoilState, + gisStationsStaticDistrictState, + gisSystemStaticState, + mapLayersState, + selectedAreaState, + zoomTriggerState, + AddPoiModalWindow, + poiReadFromDbTriggerAtom, + InformationCircleIcon, + PoiUpdateModal, + selectedPoiState, + currentPoiState, + ToastContainer, + toast, + mapIdState, + userIdState, + poiLayerVisibleState, + plusRoundIcon, + createAndSetMarkers, + restoreMapSettings, + checkOverlappingMarkers, + fetchGisStatusStations, + fetchPoiData, + fetchUserRights, + MAP_VERSION, + layers, + initializeMap, + addItemsToMapContextMenu, + useGmaMarkersLayer, + useTalasMarkersLayer, + useEciMarkersLayer, + useGsmModemMarkersLayer, + useCiscoRouterMarkersLayer, + useWagoMarkersLayer, + useSiemensMarkersLayer, + useOtdrMarkersLayer, + useWdmMarkersLayer, + useMessstellenMarkersLayer, + useTalasiclMarkersLayer, + useDauzMarkersLayer, + useSmsfunkmodemMarkersLayer, + useUlafMarkersLayer, + useSonstigeMarkersLayer, + fetchGisStationsStaticDistrict, + fetchGisStationsStatusDistrict, + fetchGisStationsMeasurements, + fetchGisSystemStatic, + setupPolylines, + setupMarkers, + VersionInfoModal, + useFetchPoiData, + usePoiTypData, + useLayerVisibility, + useLineData, +} from "./imports.js"; +import { useMapComponentState } from "../hooks/useMapComponentState"; const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { + const { deviceName, setDeviceName } = useMapComponentState(); + const { poiTypData, isPoiTypLoaded } = usePoiTypData("/api/talas_v5_DB/poiTyp/readPoiTyp"); + //const [deviceName, setDeviceName] = useState(""); + const [locationDeviceData, setLocationDeviceData] = useState([]); const [priorityConfig, setPriorityConfig] = useState([]); - - const fetchPriorityConfig = async () => { - try { - const response = await fetch("/api/talas_v5_DB/priorityConfig"); - const data = await response.json(); - console.log("Prioritätskonfiguration:", data); - setPriorityConfig(data); - } catch (error) { - console.error("Fehler beim Laden der Prioritätskonfiguration:", error); - } - }; - - useEffect(() => { - fetchPriorityConfig(); - }, []); - - useEffect(() => { - console.log("Aktualisierte Prioritätskonfiguration:", priorityConfig); - }, [priorityConfig]); - //--------------------------------------------------------------------- - const fetchGisStatusStations = async (idMap, idUser) => { - try { - const response = await fetch( - `/api/talas5/webserviceMap/GisStationsStatusDistrict?idMap=${idMap}&idUser=${idUser}` - ); - if (!response.ok) { - throw new Error(`Error: ${response.statusText}`); - } - const data = await response.json(); - console.log("GisStatusStations:", data); - return data; - } catch (error) { - console.error("Fehler beim Abrufen der Daten:", error); - } - }; - - useEffect(() => { - fetchGisStatusStations(12, 484); // Beispielaufruf mit idMap = 10 und idUser = 484 - }, []); - - //--------------------------------------------------------------------- - /* - path.includes("critical") || // Priorität 1 - path.includes("major") || // Priorität 2 - path.includes("minor") || // Priorität 3 - path.includes("system") // Priorität 4 - */ - /* const priorityColors = { - 1: "#ba0000", // High priority, red, critical - 2: "#ed7b00", // Medium priority orange major - 3: "#d1ca00", // priority minor senfgelb - 4: "#8602ab", // priority system Violett - // 5: "#298a00", // normal priority green - }; */ const [menuItemAdded, setMenuItemAdded] = useState(false); - const poiLayerVisible = useRecoilValue(poiLayerVisibleState); - - const [contextMenuItems, setContextMenuItems] = useState([]); const [isRightsLoaded, setIsRightsLoaded] = useState(false); const [hasRights, setHasRights] = useState(false); const [mapId, setMapId] = useRecoilState(mapIdState); const [userId, setUserId] = useRecoilState(userIdState); - - const [showAddStationPopup, setShowAddStationPopup] = useState(false); + const [AddPoiModalWindowState, setAddPoiModalWindowState] = useState(false); const [userRights, setUserRights] = useState(null); const setSelectedPoi = useSetRecoilState(selectedPoiState); - const openPoiUpdateModal = () => setShowPoiUpdateModal(true); - const closePoiUpdateModal = () => setShowPoiUpdateModal(false); const [showPoiUpdateModal, setShowPoiUpdateModal] = useState(false); const [currentPoiData, setCurrentPoiData] = useState(null); const setCurrentPoi = useSetRecoilState(currentPoiState); - const currentPoi = useRecoilValue(currentPoiState); - const handlePoiSelect = (poiData) => { - setSelectedPoi(poiData); // poiData should be the data of the selected POI - // Open the modal or any other logic - }; - - useEffect(() => { - const params = new URL(window.location.href).searchParams; - setMapId(params.get("m")); - setUserId(params.get("u")); - }, [setMapId, setUserId]); - useEffect(() => { - fetchUserRights().then(() => { - setIsRightsLoaded(true); - }); - }, []); // Lade die Berechtigungen beim Initialisieren der Komponente - - const handleEditPoi = (marker) => { - // Prüfung, ob der Benutzer die notwendigen Rechte hat - if (!userRights || !userRights.includes(56)) { - toast.error("Benutzer hat keine Berechtigung zum Bearbeiten.", { - position: "top-center", - autoClose: 5000, - hideProgressBar: false, - closeOnClick: true, - pauseOnHover: true, - draggable: true, - progress: undefined, - }); - console.log("Benutzer hat keine Berechtigung zum Bearbeiten."); - return; // Beendet die Funktion frühzeitig, wenn keine Berechtigung vorliegt - } - - //console.log("Selected Marker ID (idPoi):", marker.options.idPoi); - //console.log("Selected Marker Description:", marker.options.description); - - setCurrentPoiData({ - idPoi: marker.options.id, - name: marker.options.name, - description: marker.options.description, - }); - //console.log("POI-Daten1:", currentPoiData); - - fetchPoiData(marker.options.id); - - setShowPoiUpdateModal(true); - }; - - const fetchPoiData = async (idPoi) => { - const response = await fetch( - `/api/talas_v5_DB/pois/getPoiById?idPoi=${idPoi}` - ); - if (!response.ok) { - console.error("Fehler beim Abrufen der POI-Daten"); - return; - } - const data = await response.json(); - setCurrentPoiData({ - idPoi, - name: data.name, - description: data.description, - }); - //console.log("POI-Daten2:", currentPoiData); - setShowPoiUpdateModal(true); - }; - const [showVersionInfoModal, setShowVersionInfoModal] = useState(false); const zoomTrigger = useRecoilValue(zoomTriggerState); - const offlineTileLayer = "/mapTiles/{z}/{x}/{y}.png"; - //const onlineTileLayer = "/mapTiles/{z}/{x}/{y}.png"; - //const onlineTileLayer = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"; - const onlineTileLayer = "http://10.10.0.13:3000/mapTiles/{z}/{x}/{y}.png"; //Talas_v5 Server - //const onlineTileLayer = "http://192.168.10.14:3000/mapTiles/{z}/{x}/{y}.png"; //Talas_v5 Server - // Create map layers - const TALAS = new L.layerGroup(); - const ECI = new L.layerGroup(); - const ULAF = new L.layerGroup(); - const GSMModem = new L.layerGroup(); - const CiscoRouter = new L.layerGroup(); - const WAGO = new L.layerGroup(); - const Siemens = new L.layerGroup(); - const OTDR = new L.layerGroup(); - const WDM = new L.layerGroup(); - const GMA = new L.layerGroup(); - const Sonstige = new L.layerGroup(); - const TALASICL = new L.layerGroup(); - const lineLayer = new L.LayerGroup(); - const [gisSystemStaticLoaded, setGisSystemStaticLoaded] = useState(false); - - const baseUrl = "http://10.10.0.13/talas5/devices/"; // für Station öffnen in neuer tab und gleicher tab, im localhost gab es keine Probleme mit der Frame - //const baseUrl = "http://localhost:3000/talas5/devices/"; - //const baseUrl = "http://192.168.10.14/talas5/devices/"; - const [isPoiTypLoaded, setIsPoiTypLoaded] = useState(false); const [poiTypMap, setPoiTypMap] = useState(new Map()); const [showPopup, setShowPopup] = useState(false); - const [popupCoordinates, setPopupCoordinates] = useState({ - lat: 52.52, - lng: 13.405, - }); // Beispielkoordinaten - const openPopup = () => setShowPopup(true); - const closePopup = () => setShowPopup(false); - - const handleAddStation = (stationData) => { - // Station-Daten speichern oder API-Aufruf durchführen - //console.log("Neue Station:", userRights.includes(56)); - - //console.log("Neue Station:", stationData); - setShowAddStationPopup(false); - closePopup(); // Schließt das Popup nach dem Hinzufügen - }; - // Beispiel zum Öffnen des Popups mit bestimmten Koordinaten - const openAddStationPopupWithCoordinates = (lat, lng) => { - setPopupCoordinates({ lat, lng }); - setShowPopup(true); - }; - const poiReadTrigger = useRecoilValue(poiReadFromDbTriggerAtom); - const [poiTypData, setPoiTypData] = useState(poiTypState); // Recoil State verwenden const poiLayerRef = useRef(null); // Referenz auf die Layer-Gruppe für Datenbank-Marker const mapRef = useRef(null); // Referenz auf das DIV-Element der Karte const [map, setMap] = useState(null); // Zustand der Karteninstanz const [oms, setOms] = useState(null); // State für OMS-Instanz - const [online, setOnline] = useState(navigator.onLine); // Zustand der Internetverbindung - const [GisStationsStaticDistrict, setGisStationsStaticDistrict] = - useRecoilState(gisStationsStaticDistrictState); - const [GisStationsStatusDistrict, setGisStationsStatusDistrict] = useState( - [] - ); // Zustand für Statusdaten + const [GisStationsStaticDistrict, setGisStationsStaticDistrict] = useRecoilState(gisStationsStaticDistrictState); + const [GisStationsStatusDistrict, setGisStationsStatusDistrict] = useState([]); // Zustand für Statusdaten const [GisStationsMeasurements, setGisStationsMeasurements] = useState([]); // Zustand für Messdaten - const [GisSystemStatic, setGisSystemStatic] = - useRecoilState(gisSystemStaticState); // Zustand für Systemdaten - const [DataIcons, setDataIcons] = useState([]); // Zustand für Icon-Daten - + const [GisSystemStatic, setGisSystemStatic] = useRecoilState(gisSystemStaticState); // Zustand für Systemdaten // Konstanten für die URLs - const mapGisStationsStaticDistrictUrl = - config.mapGisStationsStaticDistrictUrl; - const mapGisStationsStatusDistrictUrl = - config.mapGisStationsStatusDistrictUrl; + const mapGisStationsStaticDistrictUrl = config.mapGisStationsStaticDistrictUrl; + const mapGisStationsStatusDistrictUrl = config.mapGisStationsStatusDistrictUrl; const mapGisStationsMeasurementsUrl = config.mapGisStationsMeasurementsUrl; const mapGisSystemStaticUrl = config.mapGisSystemStaticUrl; - const mapDataIconUrl = config.mapDataIconUrl; const webserviceGisLinesStatusUrl = config.webserviceGisLinesStatusUrl; + //console.log("priorityConfig in MapComponent1: ", priorityConfig); + const talasMarkers = useTalasMarkersLayer(map, oms, GisSystemStatic, priorityConfig); // Use the new custom hook + const eciMarkers = useEciMarkersLayer(map, eciMarkers, oms, layers.MAP_LAYERS.ECI); + const gsmModemMarkers = useGsmModemMarkersLayer(map, oms, GisSystemStatic, priorityConfig); // Use the new custom hook + const ciscoRouterMarkers = useCiscoRouterMarkersLayer(map, oms, GisSystemStatic, priorityConfig); // Use the new custom hook + const wagoMarkers = useWagoMarkersLayer(map, oms, GisSystemStatic, priorityConfig); + const siemensMarkers = useSiemensMarkersLayer(map, oms, GisSystemStatic, priorityConfig); + const otdrMarkers = useOtdrMarkersLayer(map, oms, GisSystemStatic, priorityConfig); // Use the new custom hook + const wdmMarkers = useWdmMarkersLayer(map, oms, GisSystemStatic, priorityConfig); // Use the new custom hook + const messstellenMarkers = useMessstellenMarkersLayer(map, oms, GisSystemStatic, priorityConfig); // Use the new custom hook + const talasiclMarkers = useTalasiclMarkersLayer(map, oms, GisSystemStatic, priorityConfig); + const dauzMarkers = useDauzMarkersLayer(map, oms, GisSystemStatic, priorityConfig); // Use the new custom hook + const smsfunkmodemMarkers = useSmsfunkmodemMarkersLayer(map, oms, GisSystemStatic, priorityConfig); // Use the new custom hook + const ulafMarkers = useUlafMarkersLayer(map, oms, GisSystemStatic, priorityConfig); + const sonstigeMarkers = useSonstigeMarkersLayer(map, oms, GisSystemStatic, priorityConfig); // Use the new custom hook + const [gmaMarkers, setGmaMarkers] = useState([]); //--------------------station.System === 11 alle sind untetschiedlich Nummern + const [lineStatusData, setLineStatusData] = useState([]); + const [linesData, setLinesData] = useState([]); + const mapLayersVisibility = useRecoilValue(mapLayersState); + const selectedArea = useRecoilValue(selectedAreaState); + const poiData = useFetchPoiData("/api/talas_v5_DB/pois/poi-icons"); + const [linePositions, setLinePositions] = useState([]); + const { lineColors, tooltipContents } = useLineData(webserviceGisLinesStatusUrl, setLineStatusData); + const [polylines, setPolylines] = useState([]); + const [markers, setMarkers] = useState([]); + const closePopup = () => setShowPopup(false); + const [newPoint, setNewPoint] = useState(null); + const [newCoords, setNewCoords] = useState(null); + const [tempMarker, setTempMarker] = useState(null); + + const [popupCoordinates, setPopupCoordinates] = useState({ + lat: 52.52, + lng: 13.405, + }); + + const handleAddStation = (stationData) => { + setAddPoiModalWindowState(false); + closePopup(); // Schließt das Popup nach dem Hinzufügen + }; const openVersionInfoModal = () => { setShowVersionInfoModal(true); @@ -268,821 +152,113 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { const closeVersionInfoModal = () => { setShowVersionInfoModal(false); }; - // Funktion zum Aktualisieren der Position in der Datenbank - const updateLocationInDatabase = async (id, newLatitude, newLongitude) => { - const response = await fetch("/api/talas_v5_DB/pois/updateLocation", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - id, - latitude: newLatitude, - longitude: newLongitude, - }), - }); - if (response.ok) { - //schreib die neue Kooridnaten in die Console - //akuellisiere die Position in der Datenbank mit den neuen Koordinaten mit updateLocation mit SQL Anweisung UPDATE - } else { - console.error("Fehler beim Aktualisieren der Position"); - } - }; - //--------------------------------------------- + const [currentZoom, setCurrentZoom] = useState(() => { + const storedZoom = localStorage.getItem("mapZoom"); + return storedZoom ? parseInt(storedZoom, 10) : 12; + }); - //---------------------------------------------------- - //-----Kontextmenu---------------- - function addContextMenuToMarker(marker) { - marker.unbindContextMenu(); // Entferne das Kontextmenü, um Duplikate zu vermeiden - - marker.bindContextMenu({ - contextmenu: true, - contextmenuWidth: 140, - contextmenuItems: [ - /* { - text: "Station öffnen (Tab)", - icon: "/img/screen_new.png", - callback: (e) => openInNewTab(e, marker), - }, - { - text: "Station öffnen", - icon: "/img/screen_same.png", - callback: (e) => openInSameWindow(e, marker), - }, */ - ], - }); - } - // Funktion zum Öffnen in einem neuen Tab - function openInNewTab(e, marker) { - if (marker && marker.options && marker.options.link) { - //console.log("Marker data:", baseUrl + marker.options.link); - window.open(baseUrl + marker.options.link, "_blank"); - } else { - console.error("Fehler: Marker hat keine gültige 'link' Eigenschaft"); - } - } - - // Funktion zum Öffnen im gleichen Fenster - function openInSameWindow(e, marker) { - if (marker && marker.options && marker.options.link) { - //console.log("Marker data:", baseUrl + marker.options.link); - window.location.href = baseUrl + marker.options.link; - } else { - console.error("Fehler: Marker hat keine gültige 'link' Eigenschaft"); - } - } - - const zoomIn = (e) => { - initMap.flyTo(e.latlng, 12); - //console.log("ZoomIn koordinaten in MapComponent", e.latlng); - }; - - const zoomOut = (e) => { - fly(); - }; - const centerHere = (e) => { - initMap.panTo(e.latlng); - }; - - // Funktion zum Anzeigen der Koordinaten - const showCoordinates = (e) => { - alert( - "Breitengrad: " + - e.latlng.lat.toFixed(5) + - "\nLängengrad: " + - e.latlng.lng.toFixed(5) - ); - }; - const showData = (e) => {}; - const showTalas = (e) => { - map.addLayer(TALAS); - loadData(); - }; - const hideTalas = (e) => { - map.removeLayer(TALAS); - loadData(); - }; - const showGSM = (e) => { - map.addLayer(GMA); - loadData(); - }; - const hideGSM = (e) => { - map.removeLayer(GMA); - loadData(); - }; - - // Kontextmenü Callback für "POI hinzufügen" - /* const addStationCallback = useCallback( - (event, hasRights) => { - console.log("Kontextmenü-Callback für 'POI hinzufügen' aufgerufen"); - console.log(event); - console.log("Benutzerrechte zum Zeitpunkt des Aufrufs:", hasRights); - - if (hasRights) { - setPopupCoordinates(event.latlng); - setShowPopup(true); - } else { - toast.error("Benutzer hat keine Berechtigung zum Hinzufügen.", { - position: "top-center", - autoClose: 5000, - hideProgressBar: false, - closeOnClick: true, - pauseOnHover: true, - draggable: true, - progress: undefined, - }); - console.log("Benutzer hat keine Berechtigung zum Hinzufügen."); - } - }, - [hasRights, isRightsLoaded] - ); // Keine Abhängigkeiten, da `hasRights` als Parameter übergeben wird */ - const addStationCallback = useCallback( - (event) => { - //console.log("Benutzerrechte zum Zeitpunkt des Aufrufs:", hasRights); - if (hasRights) { - setPopupCoordinates(event.latlng); - setShowPopup(true); - } else { - toast.error("Benutzer hat keine Berechtigung zum Hinzufügen.", { - position: "top-center", - autoClose: 5000, - hideProgressBar: false, - closeOnClick: true, - pauseOnHover: true, - draggable: true, - progress: undefined, - }); - console.error("Benutzer hat keine Berechtigung zum Hinzufügen."); - } - }, - [hasRights] - ); // Abhängigkeit zu hasRights hinzufügen - - //-----Kontextmenu----ende------------ - //-------------------------------------------------------------------------------- - - // Verwende useMemo, um die Kontextmenü-Items nur zu initialisieren, wenn notwendig - /* const contextMenuItems = useMemo( - () => [ - { - text: "Station öffnen (Tab)", - icon: "/img/screen_new.png", - callback: (e) => { - const clickedMarker = e.relatedTarget; // Zugriff auf den Marker, der das Event ausgelöst hat - openInNewTab(e, clickedMarker); - }, - }, - { - text: "Station öffnen", - icon: "/img/screen_same.png", - //callback: (e) => openInSameWindow(e, marker), - callback: (e) => { - const clickedMarker = e.relatedTarget; // Zugriff auf den Marker, der das Event ausgelöst hat - openInSameWindow(e, clickedMarker); - }, - }, - "-", // Divider - { - text: "POI hinzufügen", - icon: "img/add_station.png", - className: "background-red", - callback: (event) => addStationCallback(event, hasRights), - }, - - { - text: "Koordinaten anzeigen", - icon: "img/not_listed_location.png", - callback: showCoordinates, - }, - "-", // Divider - { text: "Reinzoomen", icon: "img/zoom_in.png", callback: zoomIn }, - { text: "Rauszoomen", icon: "img/zoom_out.png", callback: zoomOut }, - { - text: "Hier zentrieren", - icon: "img/center_focus.png", - callback: centerHere, - }, - ], - [hasRights] - ); */ - /* useEffect(() => { - if (hasRights) { - setContextMenuItems([ - { - text: "POI hinzufügen test", - icon: "img/add_station.png", - className: "background-red", - callback: (event) => addStationCallback(event), - }, - // Weitere Menüpunkte... - ]); - } - }, [isRightsLoaded, hasRights]); - */ - //---------------------------------------------------------------------------------- - //------------------------------------------ */ - const layerNames = { - "GSM Modem": "GSMMODEM", - "Cisco Router": "CiscoRouter", - "TALAS ICL": "TALASICL", - "SMS-Funkmodem": "GSMModem", - }; - //------------------------------------------ */ - function fly(stationValue) { - var x = 51.41321407879154; - var y = 7.739617925303934; - var zoom = 7; - - initMap.flyTo([x, y], zoom); - } - //------------------------------------------ - //------------------------------------------ - // Funktionen zur Überwachung der Internetverbindung - const checkInternet = () => { - fetch("https://tile.openstreetmap.org/1/1/1.png", { method: "HEAD" }) - .then((response) => setOnline(response.ok)) - .catch(() => setOnline(false)); - }; - let initMap = []; - //------------------------------------------ - //------------------------------------------ - function parsePoint(pointString) { - const match = pointString.match( - /POINT\s*\((\d+(\.\d+)?)\s+(\d+(\.\d+)?)\)/ - ); - if (match) { - return { - longitude: parseFloat(match[1]), - latitude: parseFloat(match[3]), // Achtung: Index 3 für die zweite Koordinate, wegen der Gruppe (\.\d+)? - }; - } else { - // Handle the error or return a default/fallback value - console.error("Invalid POINT format:", pointString); - return null; // Oder eine sinnvolle Standardantwort - } - } - //---------------------------------- - //------------------------------------------ - - function parsePoint(position) { - const [longitude, latitude] = position.slice(6, -1).split(" "); - return { latitude: parseFloat(latitude), longitude: parseFloat(longitude) }; - } - //----------------------------------------------------------------- - // TALAS Marker hinzufügen - //----------------------------------------------------------------- - // Reihenfolge nach API sortiert mit der Attribute "System" - const [talasVisible, setTalasVisible] = useRecoilState(mapLayersState); - const [eciVisible, setEciVisible] = useRecoilState(mapLayersState); - const [gsmModemVisible, setGsmModemVisible] = useRecoilState(mapLayersState); - const [ciscoRouterVisible, setCiscoRouterVisible] = - useRecoilState(mapLayersState); - const [wagoVisible, setWagoVisible] = useRecoilState(mapLayersState); - const [siemensVisible, setSiemensVisible] = useRecoilState(mapLayersState); - const [otdrVisible, setOtdrVisible] = useRecoilState(mapLayersState); - const [wdmVisible, setWdmVisible] = useRecoilState(mapLayersState); - const [gmaVisible, setGmaVisible] = useRecoilState(mapLayersState); - const [messstellenVisible, setMessstellenVisible] = - useRecoilState(mapLayersState); - const [talasiclVisible, setTalasiclVisible] = useRecoilState(mapLayersState); - const [dauzVisible, setDauzVisible] = useRecoilState(mapLayersState); - const [smsfunkmodemVisible, setSmsfunkmodemVisible] = - useRecoilState(mapLayersState); - const [sonstigeVisible, setSonstigeVisible] = useRecoilState(mapLayersState); - const [ulafVisible, setUlafVisible] = useRecoilState(mapLayersState); - - const [talasMarkers, setTalasMarkers] = useState([]); //----------------station.System === 1 - const [eciMarkers, setEciMarkers] = useState([]); //--------------------station.System === 2 - const [gsmModemMarkers, setGsmModemMarkers] = useState([]); //----------station.System === 5 - const [ciscoRouterMarkers, setCiscoRouterMarkers] = useState([]); //----station.System === 6 - const [wagoMarkers, setWagoMarkers] = useState([]); //------------------station.System === 7 - const [siemensMarkers, setSiemensMarkers] = useState([]); //------------station.System === 8 - const [otdrMarkers, setOtdrMarkers] = useState([]); //------------------station.System === 9 - const [wdmMarkers, setWdmMarkers] = useState([]); //--------------------station.System === 10 - const [gmaMarkers, setGmaMarkers] = useState([]); //--------------------station.System === 11 - const [messstellenMarkers, setMessstellenMarkers] = useState([]); //----station.System === 13 - const [talasiclMarkers, setTalasiclMarkers] = useState([]); //----------station.System === 100 - const [dauzMarkers, setDauzMarkers] = useState([]); //------------------station.System === 110 - const [smsfunkmodemMarkers, setSmsfunkmodemMarkers] = useState([]); //--station.System === 111 - const [sonstigeMarkers, setSonstigeMarkers] = useState([]); //----------station.System === 200 - const [ulafMarkers, setUlafMarkers] = useState([]); //------------------ no exist - //-------------------------------------------------------------------------------- - const determinePriority = (iconPath) => { - for (let priority of priorityConfig) { - if (iconPath.includes(priority.name.toLowerCase())) { - return priority.level; - } - } - return 5; // Default priority (lowest) - }; - /* function determinePriority(iconPath) { - if (iconPath.includes("critical")) return 1; // Highest priority - if (iconPath.includes("critical")) { - console.log( - "iconPath.includes('critical'):", - iconPath.includes("critical") - ); - } - - if (iconPath.includes("major")) return 2; - if (iconPath.includes("minor")) { - console.log("iconPath.includes('minor'):", iconPath.includes("minor")); - } - if (iconPath.includes("minor")) return 3; - if (iconPath.includes("system")) { - console.log("iconPath.includes('system'):", iconPath.includes("system")); - } - if (iconPath.includes("system")) return 4; - if (iconPath.includes("system")) { - console.log("iconPath.includes('system'):", iconPath.includes("system")); - } - return 5; // Default priority (lowest) - } */ - // Daten von einer externen Quelle laden - const createAndSetMarkers = async (systemId, setMarkersFunction) => { + const [currentCenter, setCurrentCenter] = useState(() => { + const storedCenter = localStorage.getItem("mapCenter"); try { - const response1 = await fetch(config.mapGisStationsStaticDistrictUrl); - const jsonResponse = await response1.json(); - const response2 = await fetch(config.mapGisStationsStatusDistrictUrl); - const statusResponse = await response2.json(); + return storedCenter ? JSON.parse(storedCenter) : [53.111111, 8.4625]; + } catch (e) { + console.error("Error parsing stored map center:", e); + return [53.111111, 8.4625]; + } + }); - const getIdSystemAndAllowValueMap = new Map( - GisSystemStatic.map((system) => [system.IdSystem, system.Allow]) - ); - //console.log("getIdSystemAndAllowValueMap:", getIdSystemAndAllowValueMap); + useEffect(() => { + fetchGisStatusStations(12, 484); // Beispielaufruf mit idMap = 10 und idUser = 484 + }, []); - if (jsonResponse.Points && statusResponse.Statis) { - const statisMap = new Map( - statusResponse.Statis.map((s) => [s.IdLD, s]) - ); - let markersData = jsonResponse.Points.filter( - (station) => - station.System === systemId && - getIdSystemAndAllowValueMap.get(station.System) === 1 - ).map((station) => { - const statis = statisMap.get(station.IdLD); - const iconPath = statis - ? `img/icons/${statis.Na}-marker-icon-${station.Icon}.png` - : `img/icons/marker-icon-${station.Icon}.png`; + useEffect(() => { + const params = new URL(window.location.href).searchParams; + setMapId(params.get("m")); + setUserId(params.get("u")); + }, [setMapId, setUserId]); - const priority = determinePriority(iconPath); - const zIndexOffset = 100 * (5 - priority); // Adjusted for simplicity and positive values + useEffect(() => { + if (map && poiLayerRef.current && isPoiTypLoaded && !menuItemAdded && isRightsLoaded) { + //console.log("Überprüfung der Berechtigung vor addItemsToMapContextMenu: ", hasRights); + addItemsToMapContextMenu(hasRights); + } + }, [ + map, + poiLayerRef, + isPoiTypLoaded, + menuItemAdded, // Hinzufügen zu den Abhängigkeiten, um den Effekt korrekt zu steuern + hasRights, // Sicherstellen, dass hasRights berücksichtigt wird + isRightsLoaded, // Überprüfung, ob die Rechte geladen sind + ]); - /* console.log( - `Icon Path: ${iconPath}, Priority: ${priority}, zIndexOffset: ${zIndexOffset}` - ); */ + useEffect(() => { + const fetchAndSetUserRights = async () => { + const rights = await fetchUserRights(); + setUserRights(rights); + setIsRightsLoaded(true); + setHasRights(rights && rights.includes(56)); // Prüfen, ob Benutzer die Rechte hat + }; - const marker = L.marker([station.X, station.Y], { - icon: L.icon({ - iconUrl: iconPath, - iconSize: [25, 41], - iconAnchor: [12, 41], - popupAnchor: [1, -34], - }), - areaName: station.Area_Name, // Stelle sicher, dass dieser Bereich gesetzt wird - link: station.Link, - zIndexOffset: zIndexOffset, - bounceOnAdd: !!statis, - }); + fetchAndSetUserRights(); + }, []); - if (statis) { - marker.on("add", () => marker.bounce(3)); + useGmaMarkersLayer(map, gmaMarkers, GisStationsMeasurements, layers.MAP_LAYERS.GMA, oms); // Verwende den ausgelagerten Hook + + useEffect(() => { + const fetchAllData = async () => { + try { + // Fetch GIS Stations Static District + await fetchGisStationsStaticDistrict(mapGisStationsStaticDistrictUrl, setGisStationsStaticDistrict); + + // Fetch GIS Stations Status District + await fetchGisStationsStatusDistrict(mapGisStationsStatusDistrictUrl, setGisStationsStatusDistrict); + + // Fetch GIS Stations Measurements + await fetchGisStationsMeasurements(mapGisStationsMeasurementsUrl, setGisStationsMeasurements); + + // Fetch GIS System Static + await fetchGisSystemStatic(mapGisSystemStaticUrl, setGisSystemStatic, setGisSystemStaticLoaded); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + fetchAllData(); + }, []); + //-------------------------------------------------------- + useEffect(() => { + const endpoint = "/api/talas_v5_DB/gisLines/readGisLines"; + //const endpoint = "http://localhost/talas5/ClientData/WebServiceMap.asmx/GisLinesStatus?idMap=10"; + fetch(endpoint) + .then((response) => { + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + return response.json(); + }) + .then((data) => { + const newLinePositions = data.map((item) => { + //console.log("item.idLD", item.idLD); + //console.log("item.idModul", item.idModul); + + if (item.points && Array.isArray(item.points)) { + return { + coordinates: item.points.map((point) => [point.x, point.y]), + idModul: item.idModul, + idLD: item.idLD, + }; + } else { + throw new Error("Points missing or not an array"); } - - const statusInfo = statusResponse.Statis.filter( - (status) => status.IdLD === station.IdLD - ) - .reverse() - .map( - (status) => ` -
-
- ${status.Me} (${status.Na}) -
- ` - ) - .join(""); - - marker.bindPopup(` -
- ${station.LD_Name} - ${station.Device}
- ${station.Area_Short} (${station.Area_Name})
- ${station.Location_Short} (${station.Location_Name}) -
${statusInfo}
-
- `); - return marker; }); - - setMarkersFunction(markersData); - } - } catch (error) { - console.error("Error fetching data: ", error); - } - }; - //-------------------------------------------------------------------------------- - - const mapLayersVisibility = useRecoilValue(mapLayersState); - /* - const handleCheckboxChange = (name, event) => { - const { checked } = event.target; - const internalName = layerNames[name] || name; // Nutzt den internen Namen, wenn vorhanden, sonst den originalen Namen - - setMapLayersVisibility((prev) => { - return { - ...prev, - [internalName]: checked, - }; - }); - }; */ - - //------------------------------------------ - //------------------------------------------ */ - const selectedArea = useRecoilValue(selectedAreaState); - const setSelectedArea = useSetRecoilState(selectedAreaState); - - // Combine all markers into a single array - const allMarkers = [ - ...talasMarkers, - ...eciMarkers, - ...gsmModemMarkers, - ...ciscoRouterMarkers, - ...wagoMarkers, - ...siemensMarkers, - ...otdrMarkers, - ...wdmMarkers, - ...gmaMarkers, - ...messstellenMarkers, - ...talasiclMarkers, - ...dauzMarkers, - ...smsfunkmodemMarkers, - ...sonstigeMarkers, - ...ulafMarkers, - ]; - - // Function to find a marker by areaName across all groups - const findMyMarker = (areaName) => { - return allMarkers.find((marker) => marker.options.areaName === areaName); - }; - //-------------------------------------------------------------- - //--------------------------------------------------------- - // Now update checkOverlappingMarkers to check if oms is initialized - function checkOverlappingMarkers(map, markers, plusIcon) { - // Ensure markers is always an array - if (!Array.isArray(markers)) { - //console.error("The `markers` argument is not an array:", markers); - return; - } - - const overlappingGroups = {}; - - // Group markers by coordinates as strings - markers.forEach((marker) => { - const latlngStr = marker.getLatLng().toString(); - if (overlappingGroups[latlngStr]) { - overlappingGroups[latlngStr].push(marker); - } else { - overlappingGroups[latlngStr] = [marker]; - } - }); - - // Add plus markers at coordinates where overlaps occur - for (const coords in overlappingGroups) { - if (overlappingGroups[coords].length > 1) { - const latLng = L.latLng(coords.match(/[-.\d]+/g).map(Number)); - const plusMarker = L.marker(latLng, { icon: plusIcon }); - plusMarker.addTo(map); - - //console.log("Adding plus icon marker at", latLng); - } - } - } - //--------------------------------------------------------- - const handleMarkerClick = (markerData) => { - // Setze die aktuellen Daten im State, um sie im Formular vorzubelegen - setCurrentMarkerData(markerData); - setShowEditModal(true); - }; - // In der Marker-Erstellungsfunktion - //--------------------------------------------------------- - //----------------------------------------------------------- - // Funktion um die Benutzerrechte zu überprüfen - // serverIP 10.10.0.13 idMap=10 idUser=485 - //const serverURL = "http://10.10.0.13"; - - const url = new URL(window.location.href); - const hostname = url.hostname; // Gibt den Hostnamen (IP oder Domain) zurück - const port = url.port; // Gibt den Port zurück, leer wenn Standardport verwendet wird - const protocol = url.protocol; // "http:" oder "https:" - //const serverURL = `${protocol}//${hostname}`; - const serverURL = "http://10.10.0.13"; // weil ich keine API habe, ansonsten serverURL ist localhost(IP-Adresse) für GisSystemStatic für die Benutzerrechte - //const serverURL = "http://localhost:3000"; // weil ich keine API habe, ansonsten serverURL ist localhost(IP-Adresse) für GisSystemStatic für die Benutzerrechte - - const params = new URL(window.location.href).searchParams; - //const serverURL = `${protocol}//${hostname}${port ? `:${port}` : ""}`; - - const c = params.get("m"); // Beispielwert für idMap - const user = params.get("u"); // Beispielwert für idUser - //console.log("serverURL:", serverURL); - const fetchUserRights = async () => { - try { - const response = await fetch( - `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic?idMap=${c}&idUser=${user}` - //`${serverURL}/api/talas5/webserviceMap/GisSystemStatic?idMap=${c}&idUser=${user}` //Berechtigung zum hinzufügen von POIs in der Karte - //`${serverURL}/api/rights?idMap=${c}&idUser=${user}` - ); - const data = await response.json(); - //console.log("Benutzerrechte:", data); - const rightsArray = data.Rights; // Nehmen an, dass 'Rights' das Array von Rechten ist - - // Speichert die IDs der Rechte in einem Array - const userRightsIds = rightsArray.map((right) => right.IdRight); - setUserRights(userRightsIds); // Speichert die Rechte in den Zustand - - //console.log("Benutzerrechte:", rightsArray); - //console.log("Benutzerrechte IDs:", userRightsIds); - //console.log("Benutzerrechte in if :", userRightsIds.includes(56)); - setHasRights(userRightsIds.includes(56)); - } catch (error) { - console.error("Fehler beim Abrufen der Benutzerrechte", error); - } - }; - useEffect(() => { - //console.log("Aktualisierter Status von hasRights: ", hasRights); - }, [hasRights]); // Dieser Effekt läuft jedes Mal, wenn sich `hasRights` ändert. - - // Überprüfen der Benutzerrechte beim Initialisieren der Komponente - useEffect(() => { - fetchUserRights(); - }, []); - - // Anzeigen von Modals basierend auf Benutzerrechten - useEffect(() => { - if (userRights !== 56) { - setShowPoiUpdateModal(false); - setShowAddStationPopup(false); - } - }, [userRights]); - //----------------------------------------------------------- - //--------------------------------------------------------- - useEffect(() => { - //console.log("useEffect current Data:", currentPoiData); - }, [currentPoiData]); - //--------------------------------------------------------- - //------------------------------------------ - // API-Daten laden für GisStationsStaticDistrict - //http://10.10.0.13/talas5/ClientData/WebServiceMap.asmx/GisStationsStaticDistrict?idMap=10&idUser=485 - useEffect(() => { - const fetchData = async () => { - try { - const response = await fetch(mapGisStationsStaticDistrictUrl); - const jsonResponse = await response.json(); - - // Prüfen, ob die Antwort das erwartete Format hat und Daten enthält - if (jsonResponse && jsonResponse.Points) { - setGisStationsStaticDistrict(jsonResponse.Points); // Direkter Zugriff auf 'Points' - } else { - console.error( - 'Erwartete Daten im "Points"-Array nicht gefunden', - jsonResponse - ); - setGisStationsStaticDistrict([]); - } - } catch (error) { - console.error("Fehler beim Laden der Daten 1: ", error); - setGisStationsStaticDistrict([]); - } - }; - - fetchData(); - }, []); // Dependency-Array ist leer, um den Effekt nur beim Mount auszuführen - - //GisStationsStaticDistrict Daten laden - useEffect(() => { - const fetchData = async () => { - try { - const response = await fetch(mapGisStationsStaticDistrictUrl); - const jsonResponse = await response.json(); - - // Prüfen, ob die Antwort das erwartete Format hat und Daten enthält - if (jsonResponse && jsonResponse.Points) { - setGisStationsStaticDistrict(jsonResponse.Points); // Direkter Zugriff auf 'Points' - } else { - console.error( - 'Erwartete Daten im "Points"-Array nicht gefunden', - jsonResponse - ); - setGisStationsStaticDistrict([]); - } - } catch (error) { - console.error("Fehler beim Laden der Daten 1: ", error); - setGisStationsStaticDistrict([]); - } - }; - - fetchData(); - }, []); // Dependency-Array ist leer, um den Effekt nur beim Mount auszuführen - //------------------------------------------ - //GisStationsStatusDistrict Daten laden - useEffect(() => { - const fetchData = async () => { - try { - const response = await fetch(mapGisStationsStatusDistrictUrl); - const jsonResponse = await response.json(); - - // Prüfen, ob die Antwort das erwartete Format hat und Daten enthält - if (jsonResponse && jsonResponse.Statis) { - setGisStationsStatusDistrict(jsonResponse.Statis); // Direkter Zugriff auf 'Statis' - } else { - console.error( - 'Erwartete Daten im "Statis"-Array nicht gefunden', - jsonResponse - ); - setGisStationsStatusDistrict([]); - } - } catch (error) { - console.error("Fehler beim Laden der Daten 2: ", error); - setGisStationsStatusDistrict([]); - } - }; - - fetchData(); - }, []); // Dependency-Array ist leer, um den Effekt nur beim Mount auszuführen - //------------------------------------------ - //GisStationsMeasurements Daten laden - - useEffect(() => { - const fetchData = async () => { - try { - const response = await fetch(mapGisStationsMeasurementsUrl); - const jsonResponse = await response.json(); - - // Prüfen, ob die Antwort das erwartete Format hat und Daten enthält - if (jsonResponse && jsonResponse.Statis) { - setGisStationsMeasurements(jsonResponse.Statis); // Direkter Zugriff auf 'Statis' - } else { - console.error( - 'Erwartete Daten im "Statis"-Array nicht gefunden', - - jsonResponse - ); - setGisStationsMeasurements([]); - } - } catch (error) { - console.error("Fehler beim Laden der Daten 3: ", error); - setGisStationsMeasurements([]); - } - }; - - fetchData(); - }, []); // Dependency-Array ist leer, um den Effekt nur beim Mount auszuführen - //------------------------------------------ - - //GisSystemStatic Daten laden - useEffect(() => { - const fetchData = async () => { - try { - const response = await fetch(mapGisSystemStaticUrl); - const jsonResponse = await response.json(); - - if (jsonResponse && jsonResponse.Systems) { - setGisSystemStatic(jsonResponse.Systems); - setGisSystemStaticLoaded(true); // Setze den Zustand auf geladen - } else { - console.error( - 'Erwartete Daten im "Systems"-Array nicht gefunden', - jsonResponse - ); - setGisSystemStatic([]); - } - } catch (error) { - console.error("Fehler beim Laden der Daten 4: ", error); - setGisSystemStatic([]); - } - }; - - fetchData(); - }, []); - //------------------------------------------ - - useEffect(() => { - if (typeof window !== "undefined") { - //console.log("Window height from config:", config.windowHeight); - } - }, []); - - // Initialisierung der karte und hinzuügen der Layers - useEffect(() => { - if (mapRef.current && !map) { - initMap = L.map(mapRef.current, { - center: [53.111111, 8.4625], - zoom: 8, - layers: [ - TALAS, - ECI, - ULAF, - GSMModem, - CiscoRouter, - WAGO, - Siemens, - OTDR, - WDM, - GMA, - Sonstige, - TALASICL, - ], - minZoom: 5, // Minimale Zoomstufe - maxZoom: 15, // Maximale Zoomstufe - zoomControl: false, - contextmenu: true, - contextmenuItems: [ - { - text: "Station öffnen (Tab)", - icon: "/img/screen_new.png", - callback: (e) => { - const clickedMarker = e.relatedTarget; // Zugriff auf den Marker, der das Event ausgelöst hat - openInNewTab(e, clickedMarker); - }, - }, - "-", // Divider - - { - text: "Koordinaten anzeigen", - icon: "img/not_listed_location.png", - callback: showCoordinates, - }, - "-", // Divider - { text: "Reinzoomen", icon: "img/zoom_in.png", callback: zoomIn }, - { text: "Rauszoomen", icon: "img/zoom_out.png", callback: zoomOut }, - { - text: "Hier zentrieren", - icon: "img/center_focus.png", - callback: centerHere, - }, - "-", // Divider - ], + setLinePositions(newLinePositions); + }) + .catch((error) => { + console.error("Error fetching data:", error.message); }); - - L.tileLayer(online ? onlineTileLayer : offlineTileLayer, { - attribution: - '© OpenStreetMap contributors', - }).addTo(initMap); - - const overlappingMarkerSpiderfier = - new window.OverlappingMarkerSpiderfier(initMap, { - nearbyDistance: 20, - }); - - setMap(initMap); - setOms(overlappingMarkerSpiderfier); - - initMap.on("zoomend", function () { - // Überprüfen, ob der aktuelle Zoom außerhalb der Grenzen liegt - if (initMap.getZoom() > 15) { - initMap.setZoom(15); - } else if (initMap.getZoom() < 5) { - initMap.setZoom(5); - } - }); - - // Nach der Initialisierung der Map und Setzen im State kannst du Funktionen aufrufen, die `map` benötigen. - initMap.whenReady(() => { - console.log("Karte ist jetzt bereit und initialisiert."); - // Rufe hier Funktionen auf, die eine initialisierte Karte benötigen. - }); - } - //console.log("trigger in MapComponent.js:", poiReadTrigger); - }, [mapRef, map, poiReadTrigger, contextMenuItems]); // Prüfe die Abhängigkeiten sorgfältig - - // poiTyp Daten hinzufügen - //------------------------------------------ - // Funktion zum Abrufen der poiTyp Daten - - useEffect(() => { - const fetchPoiTypData = async () => { - try { - const response = await fetch("/api/talas_v5_DB/poiTyp/readPoiTyp"); - const data = await response.json(); - setPoiTypData(data); // Daten im Recoil State speichern - } catch (error) { - console.error("Fehler beim Abrufen der poiTyp Daten:", error); - } - }; - /* console.log( - "trigger in MapComponent.js in fetchPoiTypData:", - poiReadTrigger - ); */ - fetchPoiTypData(); }, []); - - // Effekt zum Loggen der poiTypData, wenn sie sich ändern - useEffect(() => { - //console.log("poiTypData aktualisiert:", poiTypData); - }, [poiTypData]); - - //--------------------------------------- - - // Funktion, um die name und idPoiTyp von `poiTyp` MySQL DB Tabelle in einer Map zu speichern + //-------------------------------------------- useEffect(() => { const fetchPoiTypData = async () => { try { @@ -1091,133 +267,11 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { const map = new Map(); data.forEach((item) => map.set(item.idPoiTyp, item.name)); setPoiTypMap(map); - setIsPoiTypLoaded(true); // Daten wurden erfolgreich geladen - //console.log("poiTypMap:", map); - const poiTypName = poiTypMap.get(0) || "Unbekannt"; - //console.log("poiTypName:", poiTypName); } catch (error) { - console.error("Fehler beim Abrufen der poiTyp-Daten:", error); + console.error("Fehler beim Abrufen der poiTyp-Daten-1:", error); } }; - - fetchPoiTypData(); - }, []); - //------------------------------------------ - let dbLayer = null; - useEffect(() => { - if (map) { - // Schicht für Datenbank-Marker, sicherstellen, dass map nicht null ist - dbLayer = new L.LayerGroup().addTo(map); - - // Fügen Sie Ihre Marker hier innerhalb dieser useEffect hinzu, da map nicht null ist - - return () => { - // Bereinigung, entfernt dbLayer, wenn die Komponente unmountet - dbLayer.remove(); - }; - } - }, [map]); - - //------------------------------------------ - - useEffect(() => { - // Initialisierung der dbLayer, wenn die Karte verfügbar ist - if (map && !poiLayerRef.current) { - poiLayerRef.current = new L.LayerGroup().addTo(map); - } - - return () => { - if (map && poiLayerRef.current) { - // Entfernen der dbLayer bei Unmount - map.removeLayer(poiLayerRef.current); - poiLayerRef.current = new L.LayerGroup().addTo(map); - } - locations.forEach((location) => { - // Fügen Sie hier die Logik hinzu, um Marker zu erstellen und zu konfigurieren - }); - }; - //console.log("trigger in MapComponent.js:", poiReadTrigger); - }, [map, locations, poiReadTrigger]); // Dieser Effekt läuft nur, wenn sich `map` ändert - //------------------------------------------ - function editPoi(marker) { - // Zugriff auf die Markerdaten - const markerId = marker.options.id; - //console.log("Bearbeiten des POI mit ID:", markerId); - - // Hier könnte ein Modal mit Formular geöffnet werden - // Beispiel: openEditModal(markerId); - } - - //------------------------------------------ - - const fetchDeviceNameById = async (idLD) => { - try { - const response = await fetch( - `/api/talas_v5_DB/locationDevice/locationDeviceNameById?idLD=${idLD}` - ); - const data = await response.json(); - if (response.ok) { - return data.name; - } else { - throw new Error(data.error || "Gerät nicht gefunden"); - } - } catch (error) { - console.error( - "Fehler beim Abrufen des Gerätenamens in MapComponent.js:", - error - ); - return "Unbekannt"; - } - }; - //-------------------------------------------------- - /* useEffect(() => { - fetchUserRights().then(() => { - setIsRightsLoaded(true); // Stellen Sie sicher, dass Sie diesen Status verwenden, um die Initialisierung zu kontrollieren. - }); -}, []); */ - - /* useEffect(() => { - if (map && !map.contextmenu) { - map.contextmenu = new L.Control.ContextMenu({ - contextmenu: true, - contextmenuWidth: 140, - contextmenuItems: [], // Starten mit einem leeren Array oder initialen Einträgen - }).addTo(map); - } - }, [map]); */ - - const addItemsToMapContextMenu = () => { - if (!menuItemAdded) { - //console.log("contextMenuItems hasRights:", hasRights); - - map.contextmenu.addItem({ - text: "POI hinzufügen", - icon: "img/add_station.png", - className: "background-red", - callback: (event) => addStationCallback(event, hasRights), - }); - - setMenuItemAdded(true); // Menüpunkt wurde hinzugefült, Zustand aktualisieren - } - }; - - useEffect(() => { - if (map && poiLayerRef.current && isPoiTypLoaded && !menuItemAdded) { - addItemsToMapContextMenu(); - } - }, [ - map, - poiLayerRef, - isPoiTypLoaded, - menuItemAdded, // Hinzufügen zu den Abhängigkeiten, um den Effekt korrekt zu steuern - ]); - //------------------------------------------ - - // poiLayerRef(poiDbLayer) POI hinzufügen - //-------------------------------------------- - const [poiData, setPoiData] = useState([]); - - useEffect(() => { + //-------------------------------------------- const fetchPoiData = async () => { try { const response = await fetch("/api/talas_v5_DB/pois/poi-icons"); @@ -1225,842 +279,85 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { throw new Error("Network response was not ok"); } const data = await response.json(); - setPoiData(data); - //console.log("poiData data:", data); - //console.log("poiData icons:", poiData); } catch (error) { - console.error("Fehler beim Abrufen der poiData:", error); + console.error("Fehler beim Abrufen der poiData-2:", error); } }; + //-------------------------------------------- + fetchPoiTypData(); fetchPoiData(); }, []); + + useEffect(() => { + if (map) { + const dbLayer = new L.LayerGroup().addTo(map); // Define dbLayer here + + return () => { + dbLayer.remove(); + }; + } + }, [map]); + + useEffect(() => { + if (map && !poiLayerRef.current) { + poiLayerRef.current = new L.LayerGroup().addTo(map); + } + + return () => { + if (map && poiLayerRef.current) { + map.removeLayer(poiLayerRef.current); + poiLayerRef.current = new L.LayerGroup().addTo(map); + } + locations.forEach((location) => {}); + }; + //console.log("trigger in MapComponent.js:", poiReadTrigger); + }, [map, locations, poiReadTrigger]); + //-------------------------------------------- useEffect(() => { if (poiData.length === 0) return; - try { - if (map && poiLayerRef.current && isPoiTypLoaded) { - map.removeLayer(poiLayerRef.current); - poiLayerRef.current = new L.LayerGroup().addTo(map); - - locations.forEach(async (location) => { - try { - const { latitude, longitude } = parsePoint(location.position); - const poiTypName = poiTypMap.get(location.idPoiTyp) || "Unbekannt"; - const deviceName = await fetchDeviceNameById(location.idLD); - //console.log("deviceName:", deviceName); // Das ist in Modal POI hinzufügen - - const canDrag = userRights ? userRights.includes(56) : false; - const matchingIcon = poiData.find( - (poi) => poi.idPoi === location.idPoi - ); - const iconUrl = matchingIcon - ? `/img/icons/pois/${matchingIcon.path}` - : "/img/icons/pois/default-icon.png"; - - const marker = L.marker([latitude, longitude], { - icon: L.icon({ - iconUrl: iconUrl, - iconSize: [25, 41], - iconAnchor: [12, 41], - popupAnchor: [1, -34], - }), - draggable: canDrag, - id: location.idPoi, - }).bindContextMenu({ - contextmenu: true, - contextmenuWidth: 140, - contextmenuItems: [ - { - text: "POI Bearbeiten", - icon: "/img/poi-edit.png", - callback: () => handleEditPoi(marker), - }, - ], - }); - - marker.bindPopup(` -
- ${location.description || "Unbekannt"}
- ${deviceName}
- ${poiTypName}
-
- `); - - marker.on("mouseover", function () { - this.openPopup(); - handlePoiSelect({ - id: location.idPoi, - deviceId: location.idLD, - typ: poiTypName, - description: location.description, - }); - setCurrentPoi(location); - }); - - marker.on("mouseout", function () { - this.closePopup(); - }); - - marker.on("dragend", (e) => { - if (canDrag) { - const newLat = e.target.getLatLng().lat; - const newLng = e.target.getLatLng().lng; - const markerId = e.target.options.id; - updateLocationInDatabase(markerId, newLat, newLng).then(() => { - onLocationUpdate(markerId, newLat, newLng); - }); - } else { - console.error("Drag operation not allowed"); - } - }); - - if (poiLayerVisible) { - marker.addTo(poiLayerRef.current); - } - } catch (innerError) { - console.error("Error processing a location:", innerError); - } - }); - } - } catch (error) { - console.error("Error in useEffect:", error); - } - }, [ - map, - locations, - onLocationUpdate, - poiReadTrigger, - isPoiTypLoaded, - userRights, - poiLayerVisible, - poiData, // Add poiData as a dependency - ]); + setupMarkers(map, locations, poiData, poiTypMap, userRights, poiLayerRef, setSelectedPoi, setLocationDeviceData, setDeviceName, setCurrentPoi, poiLayerVisible, fetchPoiData, toast, setShowPoiUpdateModal, setCurrentPoiData); + }, [map, locations, onLocationUpdate, poiReadTrigger, isPoiTypLoaded, userRights, poiLayerVisible, poiData, poiTypMap]); //--------------------------------------------- - - //------------------------------------------------------------------------------- + //console.log("priorityConfig in MapComponent2: ", priorityConfig); useEffect(() => { if (gisSystemStaticLoaded && map) { - createAndSetMarkers(1, setTalasMarkers); // TALAS-System - createAndSetMarkers(2, setEciMarkers); // ECI-System - createAndSetMarkers(5, setGsmModemMarkers); // GSM-Modem-System - createAndSetMarkers(6, setCiscoRouterMarkers); // Cisco-Router-System - createAndSetMarkers(7, setWagoMarkers); // WAGO-System - createAndSetMarkers(8, setSiemensMarkers); // Siemens-System - createAndSetMarkers(9, setOtdrMarkers); // OTDR-System - createAndSetMarkers(10, setWdmMarkers); // WDM-System - createAndSetMarkers(11, setGmaMarkers); // GMA-System - createAndSetMarkers(13, setMessstellenMarkers); // Messstellen-System - createAndSetMarkers(100, setTalasiclMarkers); // TALASICL-System - createAndSetMarkers(110, setDauzMarkers); // DAUZ-System - createAndSetMarkers(111, setSmsfunkmodemMarkers); // SMS-Funkmodem-System - createAndSetMarkers(200, setSonstigeMarkers); // Sonstige-System - createAndSetMarkers(0, setUlafMarkers); // ULAF-System + createAndSetMarkers(1, GisSystemStatic, priorityConfig); // TALAS-System + createAndSetMarkers(2, GisSystemStatic, priorityConfig); // ECI-System + createAndSetMarkers(5, GisSystemStatic, priorityConfig); // GSM-Modem-System + createAndSetMarkers(6, GisSystemStatic, priorityConfig); // Cisco-Router-System + createAndSetMarkers(7, GisSystemStatic, priorityConfig); // WAGO-System + createAndSetMarkers(8, GisSystemStatic, priorityConfig); // Siemens-System + createAndSetMarkers(9, GisSystemStatic, priorityConfig); // OTDR-System + createAndSetMarkers(10, GisSystemStatic, priorityConfig); // WDM-System + createAndSetMarkers(11, setGmaMarkers, GisSystemStatic, priorityConfig); // GMA-System + createAndSetMarkers(13, GisSystemStatic, priorityConfig); // Messstellen-System + createAndSetMarkers(100, GisSystemStatic, priorityConfig); // TALASICL-System + createAndSetMarkers(110, GisSystemStatic, priorityConfig); // DAUZ-System + createAndSetMarkers(111, GisSystemStatic, priorityConfig); // SMS-Funkmodem-System + createAndSetMarkers(200, GisSystemStatic, priorityConfig); // Sonstige-System + createAndSetMarkers(0, GisSystemStatic, priorityConfig); // ULAF-System } - }, [gisSystemStaticLoaded, map]); - //-------------------------------------------------------------------------------- - useEffect(() => { - if (map && talasMarkers.length) { - talasMarkers.forEach((marker) => { - marker.addTo(map); - oms.addMarker(marker); - - // Popup beim Überfahren mit der Maus öffnen und schließen - marker.on("mouseover", function () { - this.openPopup(); - }); - marker.on("mouseout", function () { - this.closePopup(); - }); - - addContextMenuToMarker(marker); - }); - map.addLayer(TALAS); - //console.log("map", map); - //console.log("oms", oms); - //disable map contextmenu - map.options.contextmenu = false; - map.options.contextmenuItems = []; - - oms.map.options.contextmenu = false; - oms.map.options.contextmenuItems = []; - - // Call the function here - checkOverlappingMarkers(oms, map, plusRoundIcon); - } - }, [map, talasMarkers]); // Abhängigkeiten auf `map` und `talasMarkers` beschränken - - //------------------------------------------- - //-------------------------------------------------------------------------------- - useEffect(() => { - if (map && eciMarkers.length) { - eciMarkers.forEach((marker) => { - marker.addTo(map); - oms.addMarker(marker); - - // Popup beim Überfahren mit der Maus öffnen und schließen - marker.on("mouseover", function () { - this.openPopup(); - }); - marker.on("mouseout", function () { - this.closePopup(); - }); - addContextMenuToMarker(marker); - }); - map.addLayer(ECI); - } - }, [map, eciMarkers]); - - //console.log("eciMarkers", eciMarkers); - //------------------------------------------- - //-------------------------------------------------------------------------------- - useEffect(() => { - if (map && gsmModemMarkers.length) { - gsmModemMarkers.forEach((marker) => { - marker.addTo(map); - oms.addMarker(marker); - - // Popup beim Überfahren mit der Maus öffnen und schließen - marker.on("mouseover", function () { - this.openPopup(); - }); - marker.on("mouseout", function () { - this.closePopup(); - }); - addContextMenuToMarker(marker); - }); - map.addLayer(GSMModem); - } - }, [map, gsmModemMarkers]); - - //console.log("gsmModemMarkers", gsmModemMarkers); - //------------------------------------------- - //-------------------------------------------------------------------------------- - useEffect(() => { - if (map && ciscoRouterMarkers.length) { - ciscoRouterMarkers.forEach((marker) => { - marker.addTo(map); - oms.addMarker(marker); - - // Popup beim Überfahren mit der Maus öffnen und schließen - marker.on("mouseover", function () { - this.openPopup(); - }); - marker.on("mouseout", function () { - this.closePopup(); - }); - addContextMenuToMarker(marker); - }); - map.addLayer(CiscoRouter); - } - }, [map, ciscoRouterMarkers]); - - //console.log("ciscoRouterMarkers", ciscoRouterMarkers); - //------------------------------------------- - //-------------------------------------------------------------------------------- - useEffect(() => { - if (map && wagoMarkers.length) { - wagoMarkers.forEach((marker) => { - marker.addTo(map); - oms.addMarker(marker); - - // Popup beim Überfahren mit der Maus öffnen und schließen - marker.on("mouseover", function () { - this.openPopup(); - }); - marker.on("mouseout", function () { - this.closePopup(); - }); - addContextMenuToMarker(marker); - }); - map.addLayer(WAGO); - - //toggleLayer(mapLayersVisibility.WAGO); - } - // }, [map, wagoMarkers, mapLayersVisibility.WAGO]); - }, [map, wagoMarkers]); - //console.log("wagoMarkers", wagoMarkers); - //------------------------------------------- - //-------------------------------------------------------------------------------- - useEffect(() => { - if (map && siemensMarkers.length) { - siemensMarkers.forEach((marker) => { - marker.addTo(map); - oms.addMarker(marker); - - // Popup beim Überfahren mit der Maus öffnen und schließen - marker.on("mouseover", function () { - this.openPopup(); - }); - marker.on("mouseout", function () { - this.closePopup(); - }); - addContextMenuToMarker(marker); - }); - map.addLayer(Siemens); - } - }, [map, siemensMarkers]); - - //console.log("siemensMarkers", siemensMarkers); - //------------------------------------------- - //-------------------------------------------------------------------------------- - useEffect(() => { - if (map && otdrMarkers.length) { - otdrMarkers.forEach((marker) => { - marker.addTo(map); - oms.addMarker(marker); - - // Popup beim Überfahren mit der Maus öffnen und schließen - marker.on("mouseover", function () { - this.openPopup(); - }); - marker.on("mouseout", function () { - this.closePopup(); - }); - addContextMenuToMarker(marker); - }); - map.addLayer(OTDR); - } - }, [map, otdrMarkers]); - - //console.log("otdrMarkers", otdrMarkers); - //------------------------------------------- - //-------------------------------------------------------------------------------- - useEffect(() => { - if (map && wdmMarkers.length) { - wdmMarkers.forEach((marker) => { - marker.addTo(map); - oms.addMarker(marker); - - // Popup beim Überfahren mit der Maus öffnen und schließen - marker.on("mouseover", function () { - this.openPopup(); - }); - marker.on("mouseout", function () { - this.closePopup(); - }); - addContextMenuToMarker(marker); - }); - map.addLayer(WDM); - } - }, [map, wdmMarkers]); - - //console.log("wdmMarkers", wdmMarkers); - //------------------------------------------- - //-------------------------------------------------------------------------------- - useEffect(() => { - if (map && gmaMarkers.length) { - // Filtern des Arrays um nur "GMA" Messungen zu erhalten - const gmaMeasurements = GisStationsMeasurements.filter( - (m) => m.Gr === "GMA" - ); - let area_name = ""; - let measurements = {}; - - gmaMeasurements.forEach((m) => { - //console.log(`Messung: ${m.Area_Name}, Na: ${m.Na}, Wert: ${m.Val}`); - area_name = m.Area_Name; // Dies überschreibt area_name mit dem letzten Area_Name im Array - measurements[m.Na] = m.Val; // Speichert den Wert von Val unter dem Code Na in einem Objekt - }); - - // Zugriff auf die Werte über die Codes - let measurementLT = measurements["LT"]; - let measurementFTP = measurements["FTP"]; - let measurementGT = measurements["GT"]; - let measurementRLF = measurements["RLF"]; - - /* console.log( - "area_name", - area_name, - "------measurementLT", - measurements.LT, - "-------measurementFBT", - measurements.FBT, - "------measurementGT", - measurements.GT, - "------measurementRLF", - measurements.RLF - ); - console.log("measurements", measurements); */ - gmaMarkers.forEach((marker) => { - marker.addTo(map); - oms.addMarker(marker); - - // Tooltip beim Überfahren mit der Maus anzeigen - marker.bindTooltip( - ` -
-
- ${area_name} -
-
- LT : ${measurements.LT} °C -
-
- FBT : ${measurements.FBT} °C -
-
- GT : ${measurements.GT === "nicht ermittelbar" ? measurements.GT : `${measurements.GT} °C`} -
-
- RLF : ${measurements.RLF} % -
-
- `, - { - permanent: true, // Tooltip wird ständig angezeigt - direction: "auto", // Automatische Ausrichtung - offset: [20, 0], // Offset-Werte - } - ); - - // Popup beim Überfahren mit der Maus öffnen und schließen - marker.on("mouseover", function () { - this.openPopup(); - }); - marker.on("mouseout", function () { - this.closePopup(); - }); - addContextMenuToMarker(marker); - }); - map.addLayer(GMA); - } - }, [map, gmaMarkers]); // Abhängigkeiten auf `map` und `gmaMarkers` beschränken - - //console.log("gmaMarkers", gmaMarkers); - - //------------------------------------------- - //-------------------------------------------------------------------------------- - useEffect(() => { - if (map && messstellenMarkers.length) { - messstellenMarkers.forEach((marker) => { - marker.addTo(map); - oms.addMarker(marker); - - // Popup beim Überfahren mit der Maus öffnen und schließen - marker.on("mouseover", function () { - this.openPopup(); - }); - marker.on("mouseout", function () { - this.closePopup(); - }); - addContextMenuToMarker(marker); - }); - map.addLayer(GMA); - } - }, [map, messstellenMarkers]); - - //console.log("messstellenMarkers", messstellenMarkers); - //------------------------------------------- - //-------------------------------------------------------------------------------- - useEffect(() => { - if (map && talasiclMarkers.length) { - talasiclMarkers.forEach((marker) => { - marker.addTo(map); - oms.addMarker(marker); - - // Popup beim Überfahren mit der Maus öffnen und schließen - marker.on("mouseover", function () { - this.openPopup(); - }); - marker.on("mouseout", function () { - this.closePopup(); - }); - addContextMenuToMarker(marker); - }); - map.addLayer(TALASICL); - } - }, [map, talasiclMarkers]); - - //console.log("talasiclMarkers", talasiclMarkers); - //------------------------------------------- - //-------------------------------------------------------------------------------- - useEffect(() => { - if (map && dauzMarkers.length) { - dauzMarkers.forEach((marker) => { - marker.addTo(map); - oms.addMarker(marker); - - // Popup beim Überfahren mit der Maus öffnen und schließen - marker.on("mouseover", function () { - this.openPopup(); - }); - marker.on("mouseout", function () { - this.closePopup(); - }); - addContextMenuToMarker(marker); - }); - } - }, [map, dauzMarkers]); - - //console.log("dauzMarkers", dauzMarkers); - //------------------------------------------- - //-------------------------------------------------------------------------------- - useEffect(() => { - if (map && smsfunkmodemMarkers.length) { - smsfunkmodemMarkers.forEach((marker) => { - marker.addTo(map); - oms.addMarker(marker); - - // Popup beim Überfahren mit der Maus öffnen und schließen - marker.on("mouseover", function () { - this.openPopup(); - }); - marker.on("mouseout", function () { - this.closePopup(); - }); - addContextMenuToMarker(marker); - }); - } - }, [map, smsfunkmodemMarkers]); - - //console.log("smsfunkmodemMarkers", smsfunkmodemMarkers); - //------------------------------------------- - //-------------------------------------------------------------------------------- - useEffect(() => { - if (map && ulafMarkers.length) { - ulafMarkers.forEach((marker) => { - marker.addTo(map); - oms.addMarker(marker); - - // Popup beim Überfahren mit der Maus öffnen und schließen - marker.on("mouseover", function () { - this.openPopup(); - }); - marker.on("mouseout", function () { - this.closePopup(); - }); - addContextMenuToMarker(marker); - }); - } - }, [map, ulafMarkers]); - - //console.log("ulafMarkers", ulafMarkers); - //------------------------------------------- - //-------------------------------------------------------------------------------- - useEffect(() => { - if (map && sonstigeMarkers.length) { - sonstigeMarkers.forEach((marker) => { - marker.addTo(map); - oms.addMarker(marker); - - // Popup beim Überfahren mit der Maus öffnen und schließen - marker.on("mouseover", function () { - this.openPopup(); - }); - marker.on("mouseout", function () { - this.closePopup(); - }); - addContextMenuToMarker(marker); - }); - } - }, [map, sonstigeMarkers]); - - //console.log("sonstige", sonstigeMarkers); - //------------------------------------------- - - // Funktion zum Ein- und Ausblenden der TALAS-Marker basierend auf dem Zustand von mapLayersVisibility.TALAS - - useEffect(() => { - if (!map || !talasMarkers) return; - /* const someLineCoordinatesforTalas = [ - [53.111111, 8.4625], - [53.111111, 8.4625], - [53.111111, 8.4625], - [53.111111, 8.4625], - ]; */ - const toggleLayer = (isVisible) => { - if (isVisible) { - talasMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added - //console.log("talasMarkers", talasMarkers); - //console.log("talasMarkers.color", talasMarkers.color); - //talasMarkers.forEach((marker) => map.removeLayer(marker)); - /* console.log("talasMarkers linePositions ", linePositions); - const polyline = L.polyline(someLineCoordinatesforTalas, { - color: "green", - }).addTo( - //Linien-Farbe /Farbe für die Strecke zwischen den Markern - TALAS - ); */ - } else { - talasMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually - } - }; - - // Apply visibility state to the TALAS layer - toggleLayer(mapLayersVisibility.TALAS); - }, [map, talasMarkers, mapLayersVisibility.TALAS]); - - //------------------------------------------ */ - // Funktion zum Ein- und Ausblenden der ECI-Marker basierend auf dem Zustand von mapLayersVisibility.ECI - - useEffect(() => { - if (!map || !eciMarkers) return; - const toggleLayer = (isVisible) => { - if (isVisible) { - eciMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added - } else { - eciMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually - } - }; - // Apply visibility state to the ECI layer - toggleLayer(mapLayersVisibility.ECI); - }, [map, eciMarkers, mapLayersVisibility.ECI]); - - //------------------------------------------ */ - // Funktion zum Ein- und Ausblenden der ULAF-Marker basierend auf dem Zustand von mapLayersVisibility.ULAF - - useEffect(() => { - if (!map || !ulafMarkers) return; - const toggleLayer = (isVisible) => { - if (isVisible) { - ulafMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added - } else { - ulafMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually - } - }; - // Apply visibility - toggleLayer(mapLayersVisibility.ULAF); - }, [map, ulafMarkers, mapLayersVisibility.ULAF]); - - //------------------------------------------ */ - //------------------------------------------ */ - // Funktion zum Ein- und Ausblenden der GSMModem-Marker basierend auf dem Zustand von mapLayersVisibility.GSMModem - - useEffect(() => { - if (!map || !gsmModemMarkers) return; - const toggleLayer = (isVisible) => { - if (isVisible) { - gsmModemMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added - } else { - gsmModemMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually - } - }; - // Apply visibility - toggleLayer(mapLayersVisibility.GSMModem); - }, [map, gsmModemMarkers, mapLayersVisibility.GSMModem]); - - //------------------------------------------ */ - - // Funktion zum Ein- und Ausblenden der CiscoRouter-Marker basierend auf dem Zustand von mapLayersVisibility.CiscoRouter - - useEffect(() => { - if (!map || !ciscoRouterMarkers) return; - const toggleLayer = (isVisible) => { - if (isVisible) { - ciscoRouterMarkers.forEach((marker) => marker.addTo(map)); - } else { - ciscoRouterMarkers.forEach((marker) => map.removeLayer(marker)); - } - }; - // Nutzt die Map, um den internen Namen zu bekommen - const internalName = layerNames["Cisco Router"] || "CiscoRouter"; - toggleLayer(mapLayersVisibility[internalName]); - //console.log("internalName Cisco Router: ", internalName); - }, [map, ciscoRouterMarkers, mapLayersVisibility]); - - //------------------------------------------ */ - //------------------------------------------ */ - // Funktion zum Ein- und Ausblenden der WAGO-Marker basierend auf dem Zustand von mapLayersVisibility.WAGO - - useEffect(() => { - if (!map || !wagoMarkers) return; - const toggleLayer = (isVisible) => { - if (isVisible) { - wagoMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added - } else { - wagoMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually - } - }; - // Apply visibility - toggleLayer(mapLayersVisibility.WAGO); - }, [map, wagoMarkers, mapLayersVisibility.WAGO]); - - //------------------------------------------ */ - //------------------------------------------ */ - // Funktion zum Ein- und Ausblenden der Siemens-Marker basierend auf dem Zustand von mapLayersVisibility.Siemens - - useEffect(() => { - if (!map || !siemensMarkers) return; - const toggleLayer = (isVisible) => { - if (isVisible) { - siemensMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added - } else { - siemensMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually - } - }; - // Apply visibility - toggleLayer(mapLayersVisibility.Siemens); - }, [map, siemensMarkers, mapLayersVisibility.Siemens]); - - //------------------------------------------ */ - //------------------------------------------ */ - // Funktion zum Ein- und Ausblenden der OTDR-Marker basierend auf dem Zustand von mapLayersVisibility.OTDR - - useEffect(() => { - if (!map || !otdrMarkers) return; - const toggleLayer = (isVisible) => { - if (isVisible) { - otdrMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added - } else { - otdrMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually - } - }; - // Apply visibility - toggleLayer(mapLayersVisibility.OTDR); - }, [map, otdrMarkers, mapLayersVisibility.OTDR]); - - //------------------------------------------ */ - //------------------------------------------ */ - // Funktion zum Ein- und Ausblenden der WDM-Marker basierend auf dem Zustand von mapLayersVisibility.WDM - - useEffect(() => { - if (!map || !wdmMarkers) return; - const toggleLayer = (isVisible) => { - if (isVisible) { - wdmMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added - } else { - wdmMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually - } - }; - // Apply visibility - toggleLayer(mapLayersVisibility.WDM); - }, [map, wdmMarkers, mapLayersVisibility.WDM]); - - //------------------------------------------ */ - // Funktion zum Ein- und Ausblenden der GMA-Marker basierend auf dem Zustand von mapLayersVisibility.GMA - - useEffect(() => { - if (!map || !gmaMarkers) return; - - const toggleLayer = (isVisible) => { - if (isVisible) { - gmaMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added - } else { - gmaMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually - } - }; - - // Apply visibility - toggleLayer(mapLayersVisibility.GMA); - }, [map, gmaMarkers, mapLayersVisibility.GMA]); - - //------------------------------------------ */ - //------------------------------------------ */ - // Funktion zum Ein- und Ausblenden der Sonstige-Marker basierend auf dem Zustand von mapLayersVisibility.Sonstige - - useEffect(() => { - if (!map || !sonstigeMarkers) return; - const toggleLayer = (isVisible) => { - if (isVisible) { - sonstigeMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added - } else { - sonstigeMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually - } - }; - // Apply visibility - toggleLayer(mapLayersVisibility.Sonstige); - }, [map, sonstigeMarkers, mapLayersVisibility.Sonstige]); - - //------------------------------------------ */ - //------------------------------------------ */ - // Funktion zum Ein- und Ausblenden der TALASICL-Marker basierend auf dem Zustand von mapLayersVisibility.TALASICL - - useEffect(() => { - if (!map || !talasiclMarkers) return; - //console.log("talasiclMarkers", talasiclMarkers); - const toggleLayer = (isVisible) => { - if (isVisible) { - talasiclMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added - } else { - talasiclMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually - } - }; - - // Verwendung der Map, um den internen Namen zu bekommen, und Fallback auf "TALASICL", falls nicht gefunden - const internalName = - layerNames["TALAS ICL"] || "TALASICL || talasiclMarkers "; - toggleLayer(mapLayersVisibility[internalName]); - //console.log("internalName for TALAS ICL in MapComponent: ", internalName); - }, [map, talasiclMarkers, mapLayersVisibility]); - - //------------------------------------------ */ - //------------------------------------------ */ - // Funktion zum Ein- und Ausblenden der DAUZ-Marker basierend auf dem Zustand von mapLayersVisibility.DAUZ - - useEffect(() => { - if (!map || !dauzMarkers) return; - const toggleLayer = (isVisible) => { - if (isVisible) { - dauzMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added - } else { - dauzMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually - } - }; - // Apply visibility - toggleLayer(mapLayersVisibility.DAUZ); - }, [map, dauzMarkers, mapLayersVisibility.DAUZ]); - - //------------------------------------------ */ - //------------------------------------------ */ - // Funktion zum Ein- und Ausblenden der SMSFunkmodem-Marker basierend auf dem Zustand von mapLayersVisibility.SMSFunkmodem - - useEffect(() => { - if (!map || !smsfunkmodemMarkers) return; - const toggleLayer = (isVisible) => { - if (isVisible) { - smsfunkmodemMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added - } else { - smsfunkmodemMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually - } - }; - // Apply visibility - toggleLayer(mapLayersVisibility.SMSFunkmodem); - }, [map, smsfunkmodemMarkers, mapLayersVisibility.SMSFunkmodem]); - - //------------------------------------------ */ - //------------------------------------------ */ - // Funktion zum Ein- und Ausblenden der Messstellen-Marker basierend auf dem Zustand von mapLayersVisibility.Messstellen - - useEffect(() => { - if (!map || !messstellenMarkers) return; - const toggleLayer = (isVisible) => { - if (isVisible) { - messstellenMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added - } else { - messstellenMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually - } - }; - // Apply visibility - toggleLayer(mapLayersVisibility.Messstellen); - }, [map, messstellenMarkers, mapLayersVisibility.Messstellen]); - - //------------------------------------------ */ - - // Effect to handle navigation to selected area - /* useEffect(() => { - if (selectedArea && map) { - const marker = findMyMarker(selectedArea); - if (marker) { - map.flyTo(marker.getLatLng(), 14); // Adjust zoom level as needed - } - } - }, [selectedArea, map, allMarkers]); // Include allMarkers in the dependencies */ - - useEffect(() => { - if (selectedArea && map) { - const marker = findMyMarker(selectedArea); - if (marker) { - map.flyTo(marker.getLatLng(), 14); - map.once("moveend", () => { - setSelectedArea("Station wählen"); - }); - } - } - }, [selectedArea, map]); - //------------------------------------------ + }, [gisSystemStaticLoaded, map, GisSystemStatic, priorityConfig]); + + useLayerVisibility(map, talasMarkers, mapLayersVisibility, "TALAS"); + useLayerVisibility(map, eciMarkers, mapLayersVisibility, "ECI"); + useLayerVisibility(map, gsmModemMarkers, mapLayersVisibility, "GSMModem"); + useLayerVisibility(map, ciscoRouterMarkers, mapLayersVisibility, "CiscoRouter"); + useLayerVisibility(map, wagoMarkers, mapLayersVisibility, "WAGO"); + useLayerVisibility(map, siemensMarkers, mapLayersVisibility, "Siemens"); + useLayerVisibility(map, otdrMarkers, mapLayersVisibility, "OTDR"); + useLayerVisibility(map, wdmMarkers, mapLayersVisibility, "WDM"); + useLayerVisibility(map, gmaMarkers, mapLayersVisibility, "GMA"); + useLayerVisibility(map, sonstigeMarkers, mapLayersVisibility, "Sonstige"); + useLayerVisibility(map, talasiclMarkers, mapLayersVisibility, "TALASICL"); + useLayerVisibility(map, dauzMarkers, mapLayersVisibility, "DAUZ"); + useLayerVisibility(map, smsfunkmodemMarkers, mapLayersVisibility, "SMSFunkmodem"); + useLayerVisibility(map, messstellenMarkers, mapLayersVisibility, "Messstellen"); + useLayerVisibility(map, ulafMarkers, mapLayersVisibility, "ULAF"); useEffect(() => { if (map) { @@ -2072,22 +369,12 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { map.flyTo([x, y], zoom); } else { console.error("Map object is not ready or does not have flyTo method"); - } // Ihre bereits existierende Funktion, die Zoom-Out ausführt + } } }, [map, zoomTrigger]); - //--------------------------------------------------------- - /* useEffect(() => { - //console.log("Aktualisierung in MapComponent.js:", poiReadTrigger); - // Logik zur Aktualisierung der Map hier hinzufügen - // Beispiel: Daten neu laden oder aktualisieren - }, [poiReadTrigger]); */ - //--------------------------------------------------------- - - //--------------------------------------------------------- useEffect(() => { if (map) { - // Combine all markers from different layers const allMarkers = [ ...talasMarkers, ...eciMarkers, @@ -2106,593 +393,153 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { ...ulafMarkers, ]; - // Call the function to check for overlaps and add plus icons checkOverlappingMarkers(map, allMarkers, plusRoundIcon); } - }, [ - map, - talasMarkers, - eciMarkers, - gsmModemMarkers, - ciscoRouterMarkers, - wagoMarkers, - siemensMarkers, - otdrMarkers, - wdmMarkers, - gmaMarkers, - messstellenMarkers, - talasiclMarkers, - dauzMarkers, - smsfunkmodemMarkers, - sonstigeMarkers, - ulafMarkers, - ]); - //--------------------------------------------------------- - //LINESTRING (53.151257 8.190471,53.161601 8.129359,53.19802 8.092366,53.244065 8.014003,53.252539 7.954265) - const [linePositions, setLinePositions] = useState([]); - // ------------Linien zeichnen---------------- - useEffect(() => { - const endpoint = "/api/talas_v5_DB/gisLines/readGisLines"; - fetch(endpoint) - .then((response) => { - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - return response.json(); - }) - .then((data) => { - const newLinePositions = data.map((item) => { - if (item.points && Array.isArray(item.points)) { - return { - coordinates: item.points.map((point) => [point.x, point.y]), - idModul: item.idModul, - idLD: item.idLD, - }; - } else { - throw new Error("Points missing or not an array"); - } - }); - setLinePositions(newLinePositions); - }) - .catch((error) => { - console.error("Error fetching data:", error.message); - }); - }, []); - //--------------------------- Linien färben ------------------------------ - const [lineColors, setLineColors] = useState({}); - const [tooltipContents, setTooltipContents] = useState({}); - const [polylines, setPolylines] = useState([]); - const [markers, setMarkers] = useState([]); - - // API-Aufruf, um Farben der Linien abzurufen + }, [map, talasMarkers, eciMarkers, gsmModemMarkers, ciscoRouterMarkers, wagoMarkers, siemensMarkers, otdrMarkers, wdmMarkers, gmaMarkers, messstellenMarkers, talasiclMarkers, dauzMarkers, smsfunkmodemMarkers, sonstigeMarkers, ulafMarkers]); useEffect(() => { const fetchData = async () => { try { const response1 = await fetch(webserviceGisLinesStatusUrl); const data1 = await response1.json(); - const response2 = await fetch("/api/talas_v5_DB/gisLines/readGisLines"); - const data2 = await response2.json(); - - const colorsByModule = {}; - const newTooltipContents = {}; - - data1.Statis.forEach((stat) => { - const matchingLine = data2.find( - (item) => item.idLD === stat.IdLD && item.idModul === stat.Modul - ); - if (matchingLine) { - colorsByModule[matchingLine.idModul] = stat.PrioColor; - newTooltipContents[matchingLine.idModul] = ` -
- ${stat.ModulName || "Unknown"} -
- ${stat.ModulTyp || "N/A"} -
-
- - ${stat.Message || "N/A"} -
- (${stat.PrioName || "N/A"}) -
-
- `; - - /* newTooltipContents[matchingLine.idModul] = ` -
- ${stat.ModulName || "Unknown"} -
- ${stat.ModulTyp || "N/A"} -
-
- - ${stat.Message || "N/A"} -
- (${stat.PrioName || "N/A"}) -
-
- `; */ - } - }); - - setLineColors(colorsByModule); - setTooltipContents(newTooltipContents); - } catch (error) { - console.error("Error fetching data:", error); - } - }; - - fetchData(); - }, []); - - // Überwachen des lineColors Zustandes - useEffect(() => { - //console.log("Aktualisierte lineColors", lineColors); - }, [lineColors]); - - //--------------------------------------------------------- - // Custom circle icon for draggable markers - const circleIcon = L.divIcon({ - className: "custom-div-icon", - html: "
", - iconSize: [25, 25], - iconAnchor: [5, 5], - }); - const startIcon = L.divIcon({ - className: "custom-start-icon", - html: "
", // Rot für den Startpunkt - iconSize: [25, 25], - iconAnchor: [5, 5], - }); - - const endIcon = L.divIcon({ - className: "custom-end-icon", - html: "
", // Blau für den Endpunkt - iconSize: [25, 25], - iconAnchor: [5, 5], - }); - //----------------------- Update lines---------------------------------- - const [lineStatusData, setLineStatusData] = useState([]); - const [linesData, setLinesData] = useState([]); - - useEffect(() => { - const fetchData = async () => { - try { - const response1 = await fetch(webserviceGisLinesStatusUrl); - const data1 = await response1.json(); - setLineStatusData(data1.Statis); + //console.log("data1.Statis", data1.Statis); + const reversedData = data1.Statis.reverse(); + setLineStatusData(reversedData); const response2 = await fetch("/api/talas_v5_DB/gisLines/readGisLines"); const data2 = await response2.json(); const colorsByModule = {}; - data1.Statis.forEach((stat) => { - const matchingLine = data2.find( - (item) => item.idLD === stat.IdLD && item.idModul === stat.Modul - ); + reversedData.forEach((stat) => { + const matchingLine = data2.find((item) => item.idLD === stat.IdLD && item.idModul === stat.Modul); if (matchingLine) { colorsByModule[matchingLine.idModul] = stat.PrioColor; - console.log("Übereinstimmung gefunden für: ", stat); + //console.log("Übereinstimmung gefunden für: ", stat); setLinesData(matchingLine); } }); - setLineColors(colorsByModule); + //setLineColors(colorsByModule); } catch (error) { console.error("Error fetching data:", error); } }; fetchData(); }, []); - //--------------------------------------------------------- - useEffect(() => { - console.log("lineStatusData", lineStatusData); - console.log("lineData:", linesData); - }, [lineStatusData, linesData]); - //--------------------------------------------------------- - const [newPoint, setNewPoint] = useState(null); - const [newCoords, setNewCoords] = useState(null); - const [tempMarker, setTempMarker] = useState(null); useEffect(() => { if (!map) return; - // Entfernen alter Marker und Polylines markers.forEach((marker) => marker.remove()); polylines.forEach((polyline) => polyline.remove()); - const newMarkers = []; - const newPolylines = []; - - linePositions.forEach((lineData, lineIndex) => { - const lineMarkers = []; - lineData.coordinates.forEach((coord, index) => { - let icon = circleIcon; // Standard-Icon für mittlere Punkte - if (index === 0) { - icon = startIcon; // Start-Icon für den ersten Punkt - } else if (index === lineData.coordinates.length - 1) { - icon = endIcon; // End-Icon für den letzten Punkt - } - - const marker = L.marker(coord, { - icon: icon, - draggable: true, - contextmenu: true, - contextmenuInheritItems: false, - contextmenuItems: [], // Starte mit einem leeren Menü - }).addTo(map); - - marker.on("dragend", () => { - const newCoords = marker.getLatLng(); - setNewCoords(newCoords); // Aktualisieren Sie den Zustand - const newCoordinates = [...lineData.coordinates]; - newCoordinates[index] = [newCoords.lat, newCoords.lng]; - - const updatedPolyline = L.polyline(newCoordinates, { - color: lineColors[lineData.idModul] || "#000000", - }).addTo(map); - - updatedPolyline.bindTooltip( - tooltipContents[lineData.idModul] || "Standard-Tooltip-Inhalt", - { - permanent: false, - direction: "auto", - } - ); - - updatedPolyline.on("mouseover", () => { - updatedPolyline.setStyle({ weight: 10 }); - updatedPolyline.bringToFront(); - }); - updatedPolyline.on("mouseout", () => { - updatedPolyline.setStyle({ weight: 5 }); - }); - - newPolylines[lineIndex].remove(); - newPolylines[lineIndex] = updatedPolyline; - lineData.coordinates = newCoordinates; - - const requestData = { - idModul: lineData.idModul, - idLD: lineData.idLD, - newCoordinates, - }; - - console.log("Sending to API:", requestData); - // API-Aufruf, um die neuen Koordinaten zu speichern - fetch("/api/talas_v5_DB/gisLines/updateLineCoordinates", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(requestData), - }) - .then((response) => { - if (!response.ok) { - return response.json().then((data) => { - throw new Error(data.error || "Unbekannter Fehler"); - }); - } - return response.json(); - }) - .then((data) => { - console.log("Koordinaten erfolgreich aktualisiert:", data); - }) - .catch((error) => { - console.error( - "Fehler beim Aktualisieren der Koordinaten:", - error.message - ); - }); - }); - - // Füge die Option zum Entfernen nur hinzu, wenn der Benutzer mit der Maus über dem Marker ist - marker.on("mouseover", function () { - this.bindContextMenu({ - contextmenuItems: [ - { - text: "Marker entfernen", - callback: () => { - const newCoords = marker.getLatLng(); - const newCoordinates = [...lineData.coordinates]; - newCoordinates[index] = [newCoords.lat, newCoords.lng]; - - removeMarker(marker, lineData); - newPolylines[lineIndex].remove(); - lineData.coordinates = newCoordinates; - }, - }, - ], - }); - }); - - // Entferne die Option, wenn der Benutzer den Mausbereich des Markers verlässt - marker.on("mouseout", function () { - this.unbindContextMenu(); - }); - - lineMarkers.push(marker); - }); - - const polyline = L.polyline(lineData.coordinates, { - color: lineColors[lineData.idModul] || "#000000", - contextmenu: true, - contextmenuItems: [ - { - text: "Marker hier hinzufügen", - callback: (e) => { - if (tempMarker) { - tempMarker.remove(); // Entfernen des Platzhalter-Icons - } - //------------ - const newPoint = e.latlng; - setNewPoint(newPoint); // Aktualisieren Sie den Zustand - const closestPoints = findClosestPoints( - lineData.coordinates, - newPoint - ); - insertNewMarker(closestPoints, newPoint, lineData, map); - redrawPolyline(lineData); - }, - }, - ], - }).addTo(map); - - polyline.on("mouseover", (e) => { - // Optional: Visualisiere, dass die Linie interaktiv ist - polyline.setStyle({ color: "blue", weight: 10 }); - }); - - polyline.on("mouseout", (e) => { - // Setze die ursprüngliche Farbe zurück - polyline.setStyle({ color: lineColors[lineData.idModul] || "#000000" }); - }); - - polyline.bindTooltip( - tooltipContents[lineData.idModul] || "Standard-Tooltip-Inhalt", - { - permanent: false, - direction: "auto", - } - ); - - newPolylines.push(polyline); - newMarkers.push(...lineMarkers); - }); + const { markers: newMarkers, polylines: newPolylines } = setupPolylines(map, linePositions, lineColors, tooltipContents, setNewCoords, tempMarker); setMarkers(newMarkers); setPolylines(newPolylines); - }, [ - map, - linePositions, - lineColors, - tooltipContents, - newPoint, - newCoords, - tempMarker, - ]); + }, [map, linePositions, lineColors, tooltipContents, newPoint, newCoords, tempMarker]); - //--------------------------------------------------------- - //-------------------------Funktionen-------------------------------- - - function addMarkerAt(e, lineData) { - const newCoord = [e.latlng.lat, e.latlng.lng]; - lineData.coordinates.push(newCoord); // neuen Punkt hinzufügen - drawPolyline(lineData); // Polylinie neu zeichnen - - const marker = L.marker(newCoord, { draggable: true }).addTo(map); - marker.on("drag", (event) => { - updateMarkerPosition(event.target.getLatLng(), lineData, marker); - }); - } - - function drawPolyline(lineData) { - if (lineData.polyline) map.removeLayer(lineData.polyline); - lineData.polyline = L.polyline(lineData.coordinates, { - color: "red", - }).addTo(map); - } - - function removeMarker(marker, lineData) { - const index = lineData.coordinates.findIndex((coord) => - L.latLng(coord[0], coord[1]).equals(marker.getLatLng()) - ); - if (index !== -1) { - lineData.coordinates.splice(index, 1); // Entferne die Koordinaten des Markers - redrawPolyline(lineData); // Neuzeichnen der Polylinie - marker.remove(); // Entferne den Marker von der Karte - saveLineData(lineData); // Speichern der neuen Linienkoordinaten + useEffect(() => { + if (map) { + restoreMapSettings(map); } - } + }, [map]); - function redrawPolyline(lineData) { - const polyline = L.polyline(lineData.coordinates, { - color: lineColors[lineData.idModul] || "#000000", - }).addTo(map); + useEffect(() => { + if (map) { + const handleMapMoveEnd = (event) => { + const newCenter = map.getCenter(); + const newZoom = map.getZoom(); - polyline.bindTooltip( - tooltipContents[lineData.idModul] || "Standard-Tooltip-Inhalt", - { - permanent: false, - direction: "auto", + setCurrentCenter([newCenter.lat, newCenter.lng]); + setCurrentZoom(newZoom); + + localStorage.setItem("mapCenter", JSON.stringify([newCenter.lat, newCenter.lng])); + localStorage.setItem("mapZoom", newZoom); + }; + + map.on("moveend", handleMapMoveEnd); + map.on("zoomend", handleMapMoveEnd); + + return () => { + map.off("moveend", handleMapMoveEnd); + map.off("zoomend", handleMapMoveEnd); + }; + } + }, [map]); + + useEffect(() => { + if (selectedArea && map) { + const station = GisStationsStaticDistrict.find((s) => s.Area_Name === selectedArea); + if (station) { + map.flyTo([station.X, station.Y], 14); } - ); + } + }, [selectedArea, map, GisStationsStaticDistrict]); - polyline.on("mouseover", () => { - polyline.setStyle({ weight: 10 }); - polyline.bringToFront(); - }); - polyline.on("mouseout", () => { - polyline.setStyle({ weight: 5 }); - }); - } + useEffect(() => { + if (zoomTrigger && map) { + map.flyTo([51.41321407879154, 7.739617925303934], 7); + } + }, [zoomTrigger, map]); - function saveLineData(lineData) { - fetch("/api/talas_v5_DB/gisLines/updateLineCoordinates", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - idModul: lineData.idModul, - idLD: lineData.idLD, - newCoordinates: lineData.coordinates, - }), - }) - .then((response) => { - if (!response.ok) { - throw new Error("Fehler beim Speichern der Linienänderungen"); + useEffect(() => { + if (mapRef.current && !map) { + initializeMap(mapRef, setMap, setOms, setMenuItemAdded, addItemsToMapContextMenu, hasRights); + } + }, [mapRef, map, hasRights, addItemsToMapContextMenu]); + + useEffect(() => { + if (map && poiLayerRef.current && isPoiTypLoaded && !menuItemAdded && isRightsLoaded) { + addItemsToMapContextMenu(map, menuItemAdded, setMenuItemAdded, hasRights, setShowPopup, setPopupCoordinates); + } + }, [map, poiLayerRef, isPoiTypLoaded, menuItemAdded, hasRights, isRightsLoaded]); + //-------------------------------------------- + // rote Marker ganz oben wenn überlappen sind + useEffect(() => { + const fetchPriorityConfig = async () => { + try { + const res = await fetch("/api/talas_v5_DB/priorityConfig"); + if (!res.ok) { + throw new Error(`HTTP error! status: ${res.status}`); } - return response.json(); - }) - .then((data) => { - console.log("Linienänderungen gespeichert:", data); - }) - .catch((error) => { - console.error("Fehler beim Speichern der Linienänderungen:", error); - }); - } - - function insertNewMarker(closestPoints, newPoint, lineData, map) { - const newMarker = L.marker(newPoint, { - icon: circleIcon, - draggable: true, - }).addTo(map); - lineData.coordinates.splice(closestPoints[2], 0, [ - newPoint.lat, - newPoint.lng, - ]); - - // Hier direkt speichern nach Einfügen - saveLineData(lineData); - - redrawPolyline(lineData); - - // Event-Listener für das Verschieben des Markers hinzufügen - newMarker.on("dragend", () => { - updateMarkerPosition(newMarker.getLatLng(), lineData, newMarker); - saveLineData(lineData); // Speichern der neuen Koordinaten nach dem Verschieben - }); - } - - function updateMarkerPosition(newLatLng, lineData, marker) { - const index = lineData.coordinates.findIndex((coord) => - L.latLng(coord[0], coord[1]).equals(marker.getLatLng()) - ); - if (index !== -1) { - lineData.coordinates[index] = [newLatLng.lat, newLatLng.lng]; - redrawPolyline(lineData); - saveLineData(lineData); // Speichern der neuen Koordinaten nach dem Verschieben - } - } - - function findClosestPoints(coordinates, newPoint) { - let minDist = Infinity; - let closestPair = []; - for (let i = 1; i < coordinates.length; i++) { - const dist = L.LineUtil.pointToSegmentDistance( - map.latLngToLayerPoint(newPoint), - map.latLngToLayerPoint(coordinates[i - 1]), - map.latLngToLayerPoint(coordinates[i]) - ); - if (dist < minDist) { - minDist = dist; - closestPair = [coordinates[i - 1], coordinates[i], i]; + const data = await res.json(); + setPriorityConfig(data); + } catch (error) { + console.error("Failed to load priority configuration:", error); } - } - return closestPair; - } + }; - //--------------------------------------------------------- - //--------------------------------------------------------- + fetchPriorityConfig(); + }, []); + //-------------------------------------------- + /* useEffect(() => { + if (!map) return; + + markers.forEach((marker) => marker.remove()); + polylines.forEach((polyline) => polyline.remove()); + + const { markers: newMarkers, polylines: newPolylines } = setupPolylines(map, linePositions, lineColors, tooltipContents, setNewCoords, tempMarker, currentZoom, currentCenter); + + setMarkers(newMarkers); + setPolylines(newPolylines); + }, [map, linePositions, lineColors, tooltipContents, newPoint, newCoords, tempMarker, currentZoom, currentCenter]); // Ensure currentZoom and currentCenter are included in the dependency array */ + //-------------------------------------------- return ( <> -
- {/* Zeigt das Popup-Fenster nur, wenn `showPopup` wahr ist */} - {showPoiUpdateModal && ( -
-
e.stopPropagation()} // Verhindert das Schließen innerhalb des Fensters - > - {/* Schließen-Button oben rechts */} - +
{showPoiUpdateModal && setShowPoiUpdateModal(false)} poiData={currentPoiData} onSubmit={() => {}} latlng={popupCoordinates} />}
- {/* Formular-Komponente zum Hinzufügen einer Station */} - setShowPoiUpdateModal(false)} - poiData={currentPoiData} - onSubmit={handleAddStation} - latlng={popupCoordinates} - /> -
-
- )} -
- - {/* Rest of your component */}
- {/* Zeigt das Popup-Fenster nur, wenn `showPopup` wahr ist */} {showPopup && ( -
-
e.stopPropagation()} // Verhindert das Schließen innerhalb des Fensters - > - {/* Schließen-Button oben rechts */} - - - {/* Formular-Komponente zum Hinzufügen einer Station */} - +
)} @@ -2700,75 +547,23 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { -
+
- - {" "} - TALAS.Map{" "} - - + TALAS.Map
- Version 1.0.0 + Version {MAP_VERSION}
- {showVersionInfoModal && ( -
-
-
- TALAS V5 Logo -
-

- Littwin Systemtechnik GmbH & Co. KG -

-

- Bürgermeister-Brötje Str. 28 -

-

- D-26180 Rastede -

-
- T: +49 4402 9725 77-0 -
-
- E: kontakt@littwin-systemtechnik.de -
-
-

- TALAS.Map Version 1.0.0 -

- -
-
- )} + ); }; diff --git a/components/VersionInfoModal.js b/components/VersionInfoModal.js new file mode 100644 index 000000000..30fd4d824 --- /dev/null +++ b/components/VersionInfoModal.js @@ -0,0 +1,30 @@ +// components/VersionInfoModal.js +import React from "react"; + +const VersionInfoModal = ({ showVersionInfoModal, closeVersionInfoModal, MAP_VERSION }) => { + return ( + <> + {showVersionInfoModal && ( +
+
+
+ TALAS V5 Logo +
+

Littwin Systemtechnik GmbH & Co. KG

+

Bürgermeister-Brötje Str. 28

+

D-26180 Rastede

+
T: +49 4402 9725 77-0
+
E: kontakt@littwin-systemtechnik.de
+
+

TALAS.Map Version {MAP_VERSION}

+ +
+
+ )} + + ); +}; + +export default VersionInfoModal; diff --git a/components/gisPolylines/icons/CircleIcon.js b/components/gisPolylines/icons/CircleIcon.js new file mode 100644 index 000000000..c4a17e6ea --- /dev/null +++ b/components/gisPolylines/icons/CircleIcon.js @@ -0,0 +1,12 @@ +// /components/gisPolylines/icons/CircleIcon.js +import L from "leaflet"; +import "leaflet/dist/leaflet.css"; + +const CircleIcon = new L.DivIcon({ + className: "custom-circle-icon leaflet-marker-icon", + html: '
', + iconSize: [25, 25], + iconAnchor: [5, 5], +}); + +export default CircleIcon; diff --git a/components/gisPolylines/icons/EndIcon.js b/components/gisPolylines/icons/EndIcon.js new file mode 100644 index 000000000..151fe745c --- /dev/null +++ b/components/gisPolylines/icons/EndIcon.js @@ -0,0 +1,11 @@ +// /components/gisPolylines/icons/EndIcon.js +// Viereck als End-Icon für die Route +import L from "leaflet"; +const EndIcon = L.divIcon({ + className: "custom-end-icon", + html: "
", // Graues Viereck + iconSize: [14, 14], + iconAnchor: [7, 7], // Mittelpunkt des Vierecks als Anker +}); + +export default EndIcon; diff --git a/components/gisPolylines/icons/StartIcon.js b/components/gisPolylines/icons/StartIcon.js new file mode 100644 index 000000000..cd2677d72 --- /dev/null +++ b/components/gisPolylines/icons/StartIcon.js @@ -0,0 +1,17 @@ +// /components/gisPolylines/icons/StartIcon.js +//Custom triangle icon for draggable markers +import L from "leaflet"; + +const StartIcon = L.divIcon({ + className: "custom-start-icon", + html: ` + + + + + `, // Schwarzes Dreieck innerhalb eines grauen Dreiecks + iconSize: [18, 18], + iconAnchor: [9, 10], +}); + +export default StartIcon; diff --git a/components/gisPolylines/icons/SupportPointIcons.js b/components/gisPolylines/icons/SupportPointIcons.js new file mode 100644 index 000000000..d312e4a9a --- /dev/null +++ b/components/gisPolylines/icons/SupportPointIcons.js @@ -0,0 +1,27 @@ +// komponents/gisPolylines/icons/SupportPointIcons +import L from "leaflet"; +import "leaflet/dist/leaflet.css"; + +// Icon für Stützpunkt hinzufügen +export const AddSupportPointIcon = L.divIcon({ + className: "custom-add-support-point-icon", + html: ` +
+
+
+
+ `, + iconSize: [24, 24], + iconAnchor: [12, 12], +}); + +// Icon für Stützpunkt entfernen +export const RemoveSupportPointIcon = L.divIcon({ + className: "custom-remove-support-point-icon", + html: ` +
+
-
+
+ `, + iconSize: [24, 24], + iconAnchor: [12, 12], +}); diff --git a/components/imports.js b/components/imports.js new file mode 100644 index 000000000..eb0fd565b --- /dev/null +++ b/components/imports.js @@ -0,0 +1,160 @@ +// imports.js +import React, { useEffect, useRef, useState, useCallback } from "react"; +import L, { marker } from "leaflet"; +import "leaflet/dist/leaflet.css"; +import "leaflet-contextmenu/dist/leaflet.contextmenu.css"; +import "leaflet-contextmenu"; +import * as config from "../config/config.js"; +import * as urls from "../config/urls.js"; +import "leaflet.smooth_marker_bouncing"; +import OverlappingMarkerSpiderfier from "overlapping-marker-spiderfier-leaflet"; +import DataSheet from "./DataSheet.js"; +import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil"; +import { gisStationsStaticDistrictState } from "../store/atoms/gisStationState.js"; +import { gisSystemStaticState } from "../store/atoms/gisSystemState.js"; +import { mapLayersState } from "../store/atoms/mapLayersState.js"; +import { selectedAreaState } from "../store/atoms/selectedAreaState.js"; +import { zoomTriggerState } from "../store/atoms/zoomTriggerState.js"; +import { poiTypState } from "../store/atoms/poiTypState.js"; +import AddPoiModalWindow from "./pois/AddPoiModalWindow.js"; +import { poiReadFromDbTriggerAtom } from "../store/atoms/poiReadFromDbTriggerAtom.js"; +import { InformationCircleIcon } from "@heroicons/react/20/solid"; // oder 'outline' +import PoiUpdateModal from "./pois/PoiUpdateModal.js"; +import { selectedPoiState } from "../store/atoms/poiState.js"; +import { currentPoiState } from "../store/atoms/currentPoiState.js"; +import { ToastContainer, toast } from "react-toastify"; +import "react-toastify/dist/ReactToastify.css"; +import { mapIdState, userIdState } from "../store/atoms/urlParameterState.js"; +import { poiLayerVisibleState } from "../store/atoms/poiLayerVisibleState.js"; +import plusRoundIcon from "./PlusRoundIcon.js"; +import { parsePoint, findClosestPoints } from "../utils/geometryUtils.js"; +import { insertNewMarker, removeMarker, createAndSetMarkers, handleEditPoi } from "../utils/markerUtils.js"; +import { redrawPolyline, restoreMapSettings, checkOverlappingMarkers } from "../utils/mapUtils.js"; +import circleIcon from "./gisPolylines/icons/CircleIcon.js"; +import startIcon from "./gisPolylines/icons/StartIcon.js"; +import endIcon from "./gisPolylines/icons/EndIcon.js"; +import { fetchGisStatusStations, fetchPriorityConfig, fetchPoiData, updateLocationInDatabase, fetchUserRights, fetchDeviceNameById } from "../services/apiService.js"; +import { addContextMenuToMarker } from "../utils/contextMenuUtils.js"; +import { MAP_VERSION } from "../config/settings.js"; +import * as layers from "../config/layers.js"; +import { zoomIn, zoomOut, centerHere } from "../utils/zoomAndCenterUtils.js"; +import { initializeMap } from "../utils/mapInitialization.js"; +import { addItemsToMapContextMenu } from "./useMapContextMenu.js"; +import useGmaMarkersLayer from "../hooks/useGmaMarkersLayer.js"; // Import the custom hook +import useTalasMarkersLayer from "../hooks/talasMarkersLayer.js"; // Import the custom hook +import useEciMarkersLayer from "../hooks/useEciMarkersLayer.js"; +import useGsmModemMarkersLayer from "../hooks/useGsmModemMarkersLayer.js"; +import useCiscoRouterMarkersLayer from "../hooks/useCiscoRouterMarkersLayer.js"; +import useWagoMarkersLayer from "../hooks/useWagoMarkersLayer.js"; +import useSiemensMarkersLayer from "../hooks/useSiemensMarkersLayer.js"; +import useOtdrMarkersLayer from "../hooks/useOtdrMarkersLayer.js"; +import useWdmMarkersLayer from "../hooks/useWdmMarkersLayer.js"; +import useMessstellenMarkersLayer from "../hooks/useMessstellenMarkersLayer.js"; +import useTalasiclMarkersLayer from "../hooks/useTalasiclMarkersLayer.js"; +import useDauzMarkersLayer from "../hooks/useDauzMarkersLayer.js"; +import useSmsfunkmodemMarkersLayer from "../hooks/useSmsfunkmodemMarkersLayer.js"; +import useUlafMarkersLayer from "../hooks/useUlafMarkersLayer.js"; +import useSonstigeMarkersLayer from "../hooks/useSonstigeMarkersLayer.js"; +import handlePoiSelect from "../utils/handlePoiSelect.js"; +import { fetchGisStationsStaticDistrict, fetchGisStationsStatusDistrict, fetchGisStationsMeasurements, fetchGisSystemStatic } from "../services/fetchData.js"; +import { setupPolylines, setupMarkers } from "../utils/mapFeatures.js"; // Import the functions +import VersionInfoModal from "./VersionInfoModal.js"; +//-------------------------------------------- +import PoiUpdateModalWrapper from "./pois/PoiUpdateModalWrapper"; +import AddPoiModalWindowWrapper from "./pois/AddPoiModalWindowWrapper"; +import useFetchPoiData from "../hooks/useFetchPoiData"; +import usePoiTypData from "../hooks/usePoiTypData"; +import useMarkerLayers from "../hooks/useMarkerLayers"; +import useLayerVisibility from "../hooks/useLayerVisibility"; +import useLineData from "../hooks/useLineData.js"; + +export { + React, + useEffect, + useRef, + useState, + useCallback, + L, + marker, + config, + urls, + OverlappingMarkerSpiderfier, + DataSheet, + useRecoilState, + useRecoilValue, + useSetRecoilState, + gisStationsStaticDistrictState, + gisSystemStaticState, + mapLayersState, + selectedAreaState, + zoomTriggerState, + poiTypState, + AddPoiModalWindow, + poiReadFromDbTriggerAtom, + InformationCircleIcon, + PoiUpdateModal, + selectedPoiState, + currentPoiState, + ToastContainer, + toast, + mapIdState, + userIdState, + poiLayerVisibleState, + plusRoundIcon, + parsePoint, + findClosestPoints, + insertNewMarker, + removeMarker, + createAndSetMarkers, + handleEditPoi, + redrawPolyline, + restoreMapSettings, + checkOverlappingMarkers, + circleIcon, + startIcon, + endIcon, + fetchGisStatusStations, + fetchPriorityConfig, + fetchPoiData, + updateLocationInDatabase, + fetchUserRights, + fetchDeviceNameById, + addContextMenuToMarker, + MAP_VERSION, + layers, + zoomIn, + zoomOut, + centerHere, + initializeMap, + addItemsToMapContextMenu, + useGmaMarkersLayer, + useTalasMarkersLayer, + useEciMarkersLayer, + useGsmModemMarkersLayer, + useCiscoRouterMarkersLayer, + useWagoMarkersLayer, + useSiemensMarkersLayer, + useOtdrMarkersLayer, + useWdmMarkersLayer, + useMessstellenMarkersLayer, + useTalasiclMarkersLayer, + useDauzMarkersLayer, + useSmsfunkmodemMarkersLayer, + useUlafMarkersLayer, + useSonstigeMarkersLayer, + handlePoiSelect, + fetchGisStationsStaticDistrict, + fetchGisStationsStatusDistrict, + fetchGisStationsMeasurements, + fetchGisSystemStatic, + setupPolylines, + setupMarkers, + VersionInfoModal, + PoiUpdateModalWrapper, + AddPoiModalWindowWrapper, + useFetchPoiData, + usePoiTypData, + useMarkerLayers, + useLayerVisibility, + useLineData, +}; diff --git a/components/pois/AddPoiModalWindow.js b/components/pois/AddPoiModalWindow.js new file mode 100644 index 000000000..56677bf79 --- /dev/null +++ b/components/pois/AddPoiModalWindow.js @@ -0,0 +1,145 @@ +// components/pois/AddPoiModalWindow.js +import React, { useState, useEffect, use } from "react"; +import ReactDOM from "react-dom"; +import { useRecoilValue, useRecoilState, useSetRecoilState } from "recoil"; +import { readPoiMarkersStore } from "../../store/selectors/readPoiMarkersStore"; +import { poiReadFromDbTriggerAtom } from "../../store/atoms/poiReadFromDbTriggerAtom"; + +const AddPoiModalWindow = ({ onClose, map, latlng }) => { + const [poiTypData, setpoiTypData] = useState(); // Recoil State verwenden + const [name, setName] = useState(""); + const [poiTypeId, setPoiTypeId] = useState(""); // Initialize as string + const [poiTypeName, setPoiTypeName] = useState(""); // Initialize as string + const [latitude] = useState(latlng.lat.toFixed(5)); + const [longitude] = useState(latlng.lng.toFixed(5)); + const setLoadData = useSetRecoilState(readPoiMarkersStore); + const setTrigger = useSetRecoilState(poiReadFromDbTriggerAtom); + const [locationDeviceData, setLocationDeviceData] = useState([]); + const [deviceName, setDeviceName] = useState(""); + //------------------------------------------------------------------------------------------ + useEffect(() => { + const fetchInitialData = async () => { + try { + const [poiTypResponse, locationDeviceResponse] = await Promise.all([fetch("/api/talas_v5_DB/poiTyp/readPoiTyp"), fetch("/api/talas5/location_device")]); + + const poiTypData = await poiTypResponse.json(); + setpoiTypData(poiTypData); + + if (poiTypData.length > 0) { + setPoiTypeId(poiTypData[0].idPoiTyp); // Set initial poiTypeId to the id of the first poiType + if (poiTypData[1]) { + setPoiTypeName(poiTypData[1].name); + } + } + + const locationDeviceData = await locationDeviceResponse.json(); + setLocationDeviceData(locationDeviceData); + + if (locationDeviceData.length > 0) { + setDeviceName(locationDeviceData[0].name); // Set initial device name + } + } catch (error) { + console.error("Fehler beim Abrufen der Daten:", error); + } + }; + + fetchInitialData(); + }, []); + + //------------------------------------------------------------------------------------------ + //-----------------handleSubmit------------------- + const handleSubmit = async (event) => { + event.preventDefault(); + const formData = { + name, + poiTypeId, + latitude, + longitude, + idLD: locationDeviceData.find((device) => device.name === deviceName).idLD, + }; + + const response = await fetch("/api/talas_v5_DB/pois/addLocation", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(formData), + }); + + if (response.ok) { + setTrigger((trigger) => { + //console.log("Aktueller Trigger-Wert:", trigger); // Vorheriger Wert + const newTrigger = trigger + 1; + //console.log("Neuer Trigger-Wert:", newTrigger); // Aktualisierter Wert + onClose(); + return newTrigger; + }); + + // Browser aktualisieren + window.location.reload(); + } else { + console.error("Fehler beim Hinzufügen des POI"); + } + + if (map && typeof map.closePopup === "function") { + map.closePopup(); + } + }; + + //-----------------handleSubmit------------------- + + return ( +
+
+ + setName(e.target.value)} placeholder="Name der Station" className="block p-2 w-full border-2 border-gray-200 rounded-md text-sm" /> +
+ + {/* {locationDeviceData.----------------------------------------------*/} +
+ + +
+ {/* {locationDeviceData.----------------------------------------------*/} +
+ + +
+
+
+ +
+
+ +
+
+ + +
+ ); +}; + +export default AddPoiModalWindow; diff --git a/components/pois/AddPoiModalWindowPopup.js b/components/pois/AddPoiModalWindowPopup.js new file mode 100644 index 000000000..f535a5c33 --- /dev/null +++ b/components/pois/AddPoiModalWindowPopup.js @@ -0,0 +1,24 @@ +// components/pois/AddPoiModalWindowPopup.js +import React from "react"; +import AddPoiModalWindow from "./AddPoiModalWindow.js"; + +const AddPoiModalWindowPopup = ({ showPopup, closePopup, handleAddStation, popupCoordinates }) => { + return ( + <> + {showPopup && ( +
+
e.stopPropagation()}> + + +
+
+ )} + + ); +}; + +export default AddPoiModalWindowPopup; diff --git a/components/pois/AddPoiModalWindowWrapper.js b/components/pois/AddPoiModalWindowWrapper.js new file mode 100644 index 000000000..1ac3402bd --- /dev/null +++ b/components/pois/AddPoiModalWindowWrapper.js @@ -0,0 +1,30 @@ +// components/pois/AddPoiModalWindowWrapper.js +import React from "react"; +import AddPoiModalWindow from "./AddPoiModalWindow"; + +const AddPoiModalWindowWrapper = ({ show, onClose, latlng, handleAddStation }) => { + return ( + show && ( +
+
e.stopPropagation()} + role="dialog" // Hinzugefügt, um das Dialog-Element zu identifizieren + > + + +
+
+ ) + ); +}; + +export default AddPoiModalWindowWrapper; diff --git a/components/pois/PoiUpdateModal.js b/components/pois/PoiUpdateModal.js new file mode 100644 index 000000000..30b1452b0 --- /dev/null +++ b/components/pois/PoiUpdateModal.js @@ -0,0 +1,213 @@ +// components/pois/poiUpdateModal.js + +import React, { useState, useEffect } from "react"; +import { useRecoilValue } from "recoil"; +import { selectedPoiState } from "../../store/atoms/poiState"; +import { currentPoiState } from "../../store/atoms/currentPoiState"; + +const PoiUpdateModal = ({ onClose, poiData, onSubmit }) => { + const currentPoi = useRecoilValue(currentPoiState); + const selectedPoi = useRecoilValue(selectedPoiState); + const [poiId, setPoiId] = useState(poiData ? poiData.idPoi : ""); + const [name, setName] = useState(poiData ? poiData.name : ""); + const [poiTypData, setPoiTypData] = useState([]); + const [poiTypeId, setPoiTypeId] = useState(""); + const [locationDeviceData, setLocationDeviceData] = useState([]); + const [deviceName, setDeviceName] = useState(""); + const [idLD, setIdLD] = useState(poiData ? poiData.idLD : ""); + + const [description, setDescription] = useState(poiData ? poiData.description : ""); + + useEffect(() => { + if (poiData) { + //console.log("Initial poiData:", poiData); + setPoiId(poiData.idPoi); + setName(poiData.name); + setPoiTypeId(poiData.idPoiTyp); + setIdLD(poiData.idLD); + setDescription(poiData.description); + setDeviceName(poiData.idLD); + //console.log("Loaded POI Data for editing:", poiData); + } + }, [poiData]); + + useEffect(() => { + const fetchDeviceId = async () => { + if (poiData && poiData.idLD) { + try { + const response = await fetch(`/api/talas_v5_DB/locationDevice/getDeviceIdById?idLD=${poiData.idLD}`); + const data = await response.json(); + if (data) setDeviceName(data.name); + } catch (error) { + console.error("Fehler beim Abrufen der Geräteinformation in PoiUpdateModel.js: ", error); + } + } + }; + + fetchDeviceId(); + }, [poiData]); + + const handleDeletePoi = async () => { + if (confirm("Sind Sie sicher, dass Sie diesen POI löschen möchten?")) { + try { + const response = await fetch(`/api/talas_v5_DB/pois/deletePoi?id=${poiId}`, { + method: "DELETE", + }); + if (response.ok) { + alert("POI wurde erfolgreich gelöscht."); + onClose(); + window.location.reload(); + } else { + throw new Error("Fehler beim Löschen des POI."); + } + } catch (error) { + console.error("Fehler beim Löschen des POI:", error); + alert("Fehler beim Löschen des POI."); + } + } + }; + + useEffect(() => { + const fetchPoiTypData = async () => { + try { + const response = await fetch("/api/talas_v5_DB/poiTyp/readPoiTyp"); + const data = await response.json(); + setPoiTypData(data); + if (selectedPoi && data) { + const matchingType = data.find((pt) => pt.name === selectedPoi.typ); + if (matchingType) { + setPoiTypeId(matchingType.idPoiTyp); + } + } + } catch (error) { + console.error("Fehler beim Abrufen der poiTyp Daten:", error); + } + }; + fetchPoiTypData(); + }, [selectedPoi]); + + useEffect(() => { + const fetchData = async () => { + try { + // const response = await fetch("/api/talas_v5/location_device"); //"/api/talas_v5_DB/locationDevice/location_device" + const response = await fetch("/api/talas_v5_DB/locationDevice/locationDevices"); + const data = await response.json(); + setLocationDeviceData(data); + if (poiData && poiData.idLD) { + const selectedDevice = data.find((device) => device.id === poiData.idLD); + setDeviceName(selectedDevice ? selectedDevice.id : data[0].id); + //console.log("Selected Device in poiUpdate:", selectedDevice); + } + } catch (error) { + console.error("Fehler beim Abrufen der Standort- und Gerätedaten:", error); + } + }; + fetchData(); + }, []); + + useEffect(() => { + fetch("/api/talas_v5_DB/locationDevice/locationDevices") + .then((response) => response.json()) + .then((data) => { + setLocationDeviceData(data); + const currentDevice = data.find((device) => device.idLD === currentPoi.idLD); + if (currentDevice) { + setDeviceName(currentDevice.name); + //console.log("Current Device name in poiUpdate:", currentDevice.name); + } + }) + .catch((error) => { + console.error("Fehler beim Abrufen der Gerätedaten:", error); + setLocationDeviceData([]); + }); + }, [poiData?.idLD, currentPoi]); + + const handleSubmit = async (event) => { + event.preventDefault(); + const idLDResponse = await fetch(`/api/talas_v5_DB/locationDevice/getDeviceId?deviceName=${encodeURIComponent(deviceName)}`); + const idLDData = await idLDResponse.json(); + const idLD = idLDData.idLD; + try { + const response = await fetch("/api/talas_v5_DB/pois/updatePoi", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + idPoi: poiId, + name: name, + description: description, + idPoiTyp: poiTypeId, + idLD: idLD, + }), + }); + + if (response.ok) { + onClose(); + window.location.reload(); + } else { + const errorResponse = await response.json(); + throw new Error(errorResponse.error || "Fehler beim Aktualisieren des POI."); + } + } catch (error) { + console.error("Fehler beim Aktualisieren des POI:", error); + alert("Fehler beim Aktualisieren des POI."); + } + }; + + return ( +
+
e.stopPropagation()}> + +
+
+ + setDescription(e.target.value)} placeholder="Beschreibung der Station" className="block p-2 w-full border-2 border-gray-200 rounded-md text-sm" /> +
+ +
+ + +
+ +
+ + +
+ + + + +
+
+
+ ); +}; + +export default PoiUpdateModal; diff --git a/components/pois/PoiUpdateModalWindow.js b/components/pois/PoiUpdateModalWindow.js new file mode 100644 index 000000000..9badee70a --- /dev/null +++ b/components/pois/PoiUpdateModalWindow.js @@ -0,0 +1,9 @@ +// components/pois/PoiUpdateModalWindow.js +import React from "react"; +import PoiUpdateModal from "./PoiUpdateModal.js"; + +const PoiUpdateModalWindow = ({ showPoiUpdateModal, closePoiUpdateModal, currentPoiData, popupCoordinates }) => { + return <>{showPoiUpdateModal && {}} latlng={popupCoordinates} />}; +}; + +export default PoiUpdateModalWindow; diff --git a/components/pois/PoiUpdateModalWrapper.js b/components/pois/PoiUpdateModalWrapper.js new file mode 100644 index 000000000..92debdc41 --- /dev/null +++ b/components/pois/PoiUpdateModalWrapper.js @@ -0,0 +1,26 @@ +// components/pois/PoiUpdateModalWrapper.js +import React, { useState } from "react"; +import PoiUpdateModal from "./PoiUpdateModal"; +import { useRecoilValue, useSetRecoilState } from "recoil"; +import { currentPoiState, selectedPoiState } from "../../store/atoms/poiState"; +import { poiReadFromDbTriggerAtom } from "../../store/atoms/poiReadFromDbTriggerAtom"; + +const PoiUpdateModalWrapper = ({ show, onClose, latlng }) => { + const setSelectedPoi = useSetRecoilState(selectedPoiState); + const setCurrentPoi = useSetRecoilState(currentPoiState); + const currentPoi = useRecoilValue(currentPoiState); + const poiReadTrigger = useRecoilValue(poiReadFromDbTriggerAtom); + + return ( + show && ( + {}} // Add your submit logic here + latlng={latlng} + /> + ) + ); +}; + +export default PoiUpdateModalWrapper; diff --git a/components/pois/PoiUtils.js b/components/pois/PoiUtils.js new file mode 100644 index 000000000..003145249 --- /dev/null +++ b/components/pois/PoiUtils.js @@ -0,0 +1,52 @@ +// components/pois/PoiUtils.js +import L from "leaflet"; + +// Funktion, um POI Markers zu erstellen +export const createPoiMarkers = (poiData, iconPath) => { + return poiData.map((location) => { + return L.marker([location.latitude, location.longitude], { + icon: L.icon({ + iconUrl: iconPath, + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + draggable: true, + }), + id: location.idPoi, + }); + }); +}; + +// Funktion zum Hinzufügen von Markern zur Karte und zum Umgang mit Events +export const addMarkersToMap = (markers, map, layerGroup) => { + markers.forEach((marker) => { + marker.addTo(layerGroup); + marker.on("mouseover", () => marker.openPopup()); + marker.on("mouseout", () => marker.closePopup()); + marker.on("dragend", (e) => { + const newLat = e.target.getLatLng().lat; + const newLng = e.target.getLatLng().lng; + const markerId = e.target.options.id; + updateLocationInDatabase(markerId, newLat, newLng); + }); + }); +}; + +// Funktion zum Aktualisieren der Standorte in der Datenbank +export const updateLocationInDatabase = async (id, newLatitude, newLongitude) => { + const response = await fetch("/api/talas_v5_DB/pois/updateLocation", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + id, + latitude: newLatitude, + longitude: newLongitude, + }), + }); + + if (!response.ok) { + console.error("Fehler beim Aktualisieren der Position"); + } +}; + +// Weitere Funktionen können hier hinzugefügt werden diff --git a/components/useMapContextMenu.js b/components/useMapContextMenu.js new file mode 100644 index 000000000..13fe8a6a9 --- /dev/null +++ b/components/useMapContextMenu.js @@ -0,0 +1,77 @@ +// /components/useMapContextMenu.js +import { toast } from "react-toastify"; +import { zoomIn, zoomOut, centerHere } from "../utils/zoomAndCenterUtils"; // Assuming these are imported correctly + +const zoomInCallback = (e, map) => { + zoomIn(e, map); +}; + +const zoomOutCallback = (map) => { + zoomOut(map); +}; + +const centerHereCallback = (e, map) => { + centerHere(e, map); +}; +// Funktion zum Anzeigen der Koordinaten +const showCoordinates = (e) => { + alert("Breitengrad: " + e.latlng.lat.toFixed(5) + "\nLängengrad: " + e.latlng.lng.toFixed(5)); +}; +// Kontextmenü Callback für "POI hinzufügen" +const addStationCallback = (event, hasRights, setShowPopup, setPopupCoordinates) => { + if (hasRights) { + setPopupCoordinates(event.latlng); + setShowPopup(true); + } else { + toast.error("Benutzer hat keine Berechtigung zum Hinzufügen.", { + position: "top-center", + autoClose: 5000, + hideProgressBar: false, + closeOnClick: true, + pauseOnHover: true, + draggable: true, + progress: undefined, + }); + } +}; + +export const addItemsToMapContextMenu = (map, menuItemAdded, setMenuItemAdded, hasRights, setShowPopup, setPopupCoordinates) => { + if (!menuItemAdded && map && map.contextmenu) { + map.contextmenu.addItem({ + text: "Koordinaten anzeigen", + icon: "img/not_listed_location.png", + callback: showCoordinates, + }); + + map.contextmenu.addItem({ separator: true }); + + map.contextmenu.addItem({ + text: "Reinzoomen", + icon: "img/zoom_in.png", + callback: (e) => zoomInCallback(e, map), + }); + + map.contextmenu.addItem({ + text: "Rauszoomen", + icon: "img/zoom_out.png", + callback: () => zoomOutCallback(map), + }); + + map.contextmenu.addItem({ + text: "Hier zentrieren", + icon: "img/center_focus.png", + callback: (e) => centerHereCallback(e, map), + }); + + map.contextmenu.addItem({ separator: true }); + + map.contextmenu.addItem({ + text: "POI hinzufügen", + icon: "img/add_station.png", + className: "background-red", + callback: (event) => addStationCallback(event, hasRights, setShowPopup, setPopupCoordinates), + }); + + setMenuItemAdded(true); + } +}; diff --git a/config/config.js b/config/config.js index 832a135b8..d65aaa16a 100644 --- a/config/config.js +++ b/config/config.js @@ -1,18 +1,21 @@ -// Definieren der grundlegenden Umgebungseinstellungen und Konfigurationen der Karte +// /config/config.js +import * as urls from "../config/urls.js"; +// Definieren der grundlegenden Umgebungseinstellungen und Konfigurationen der Karte const mapVersion = "0.5.3"; // Die Version der verwendeten Karte const standardSideMenu = true; // Einstellung, ob ein standardmäßiges Seitenmenü verwendet wird const fullSideMenu = false; // Einstellung, ob ein vollständiges Seitenmenü verwendet wird -const serverURL = "/api"; // Die Basis-URL des Servers, von dem Daten bezogen werden - +//const serverURL = "/api"; // Die Basis-URL des Servers, von dem Daten bezogen werden +//const serverURL = "http://10.10.0.13"; +//const serverURL = "http://10.10.0.70"; +const serverURL = process.env.NEXT_PUBLIC_SERVER_URL; +if (!serverURL) { + throw new Error("Die Umgebungsvariable NEXT_PUBLIC_SERVER_URL ist nicht gesetzt!"); +} +console.log("serverURL in config:", serverURL); // Initialisieren von Variablen, die später im Browserkontext gesetzt werden -let windowHeight, url_string, url, c, user; +let windowHeight, url_string, url, idMap, idUser; //Online Daten -let mapGisStationsStaticDistrictUrl, - mapGisStationsStatusDistrictUrl, - mapGisStationsMeasurementsUrl, - mapGisSystemStaticUrl, - mapDataIconUrl, - webserviceGisLinesStatusUrl; +let mapGisStationsStaticDistrictUrl, mapGisStationsStatusDistrictUrl, mapGisStationsMeasurementsUrl, mapGisSystemStaticUrl, mapDataIconUrl, webserviceGisLinesStatusUrl; // Prüfen, ob das Code im Browser ausgeführt wird if (typeof window !== "undefined") { @@ -20,28 +23,31 @@ if (typeof window !== "undefined") { windowHeight = window.innerHeight; // Die Höhe des Browserfensters url_string = window.location.href; // Die vollständige URL als String url = new URL(url_string); // Die URL als URL-Objekt, um Teile der URL einfacher zu handhaben - c = url.searchParams.get("m"); // Ein Parameter aus der URL, Standardwert ist '10' - user = url.searchParams.get("u"); // Ein weiterer Parameter aus der URL, Standardwert ist '484 admin zu testen von Stationen ausblenden und einblenden in der Card' + console.log("URL in config:", url); + console.log("URL origin in config:", url.origin); //http://localhost:3000 + idMap = url.searchParams.get("m"); // Ein Parameter aus der URL, Standardwert ist '10' + idUser = url.searchParams.get("u"); // Ein weiterer Parameter aus der URL, Standardwert ist '484 admin zu testen von Stationen ausblenden und einblenden in der Card' - console.log(`Parameter 'idMap' : ${c}`); - console.log(`Parameter 'idUser': ${user}`); - - console.log(`Parameter 'idMap' : ${c}`); - console.log(`Parameter 'idUser': ${user}`); + console.log(`Parameter 'idMap' : ${idMap}`); + console.log(`Parameter 'idUser': ${idUser}`); // Konstruktion von URLs, die auf spezifische Ressourcen auf dem Server zeigen //http://localhost:3000/?m=10&u=485 //-----------------Von WebService------------------------------------------------ - mapGisStationsStaticDistrictUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisStationsStaticDistrict?idMap=${c}&idUser=${user}`; //idMap: 10, idUser: 484 - mapGisStationsStatusDistrictUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisStationsStatusDistrict?idMap=${c}&idUser=${user}`; - mapGisStationsMeasurementsUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisStationsMeasurements?idMap=${c}`; - mapGisSystemStaticUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic?idMap=${c}&idUser=${user}`; + mapGisStationsStaticDistrictUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisStationsStaticDistrict?idMap=${idMap}&idUser=${idUser}`; //idMap: 10, idUser: 484 + mapGisStationsStatusDistrictUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisStationsStatusDistrict?idMap=${idMap}&idUser=${idUser}`; + mapGisStationsMeasurementsUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisStationsMeasurements?idMap=${idMap}`; + mapGisSystemStaticUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic?idMap=${idMap}&idUser=${idUser}`; mapDataIconUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GetIconsStatic`; - //webserviceGisLinesStatusUrl = `http://10.10.0.13/talas5/ClientData/WebServiceMap.asmx/GisLinesStatus?idMap=${c}`; - webserviceGisLinesStatusUrl = `http://localhost:3000/api/linesColorApi`; - //webserviceGisLinesStatusUrl = `http://192.168.10.14/talas5/ClientData/WebServiceMap.asmx/GisLinesStatus?idMap=${c}`; + //webserviceGisLinesStatusUrl = `http://10.10.0.13/talas5/ClientData/WebServiceMap.asmx/GisLinesStatus?idMap=${idMap}`; + //webserviceGisLinesStatusUrl = `http://localhost:3000/api/linesColorApi`; + //webserviceGisLinesStatusUrl = `http://localhost:3000/api/linesColorApi`; + //webserviceGisLinesStatusUrl = `${"serverURL"}:3000/api/linesColorApi`; + // webserviceGisLinesStatusUrl = `http://localhost:3000/api/linesColorApi`; + //webserviceGisLinesStatusUrl = `http://192.168.10.14/talas5/ClientData/WebServiceMap.asmx/GisLinesStatus?idMap=${idMap}`; + webserviceGisLinesStatusUrl = `${serverURL}/talas5/ClientData/WebServiceMap.asmx/GisLinesStatus?idMap=${idMap}`; //http://10.10.0.13/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic?idMap=12&idUser=484 @@ -51,11 +57,11 @@ if (typeof window !== "undefined") { mapGisSystemStaticUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic`; mapDataIconUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GetIconsStatic`; */ - /* mapGisStationsStaticDistrictUrl = `${serverURL}/api/talas5/webserviceMap/GisStationsStaticDistrict?idMap=${c}&idUser=${user}`; - mapGisStationsStatusDistrictUrl = `${serverURL}/api/talas5/webserviceMap/GisStationsStatusDistrict?idMap=${c}&idUser=${user}`; - mapGisStationsMeasurementsUrl = `${serverURL}/api/talas5/webserviceMap/GisStationsMeasurements?idMap=${c}`; - mapGisStationsMeasurementsUrl = `${serverURL}/api/talas5/webserviceMap/gisStationsMeasurementsSQL?idMap=${c}`; - mapGisSystemStaticUrl = `${serverURL}/api/talas5/webserviceMap/GisSystemStatic?idMap=${c}&idUser=${user}`; + /* mapGisStationsStaticDistrictUrl = `${serverURL}/api/talas5/webserviceMap/GisStationsStaticDistrict?idMap=${idMap}&idUser=${idUser}`; + mapGisStationsStatusDistrictUrl = `${serverURL}/api/talas5/webserviceMap/GisStationsStatusDistrict?idMap=${idMap}&idUser=${idUser}`; + mapGisStationsMeasurementsUrl = `${serverURL}/api/talas5/webserviceMap/GisStationsMeasurements?idMap=${idMap}`; + mapGisStationsMeasurementsUrl = `${serverURL}/api/talas5/webserviceMap/gisStationsMeasurementsSQL?idMap=${idMap}`; + mapGisSystemStaticUrl = `${serverURL}/api/talas5/webserviceMap/GisSystemStatic?idMap=${idMap}&idUser=${idUser}`; mapDataIconUrl = `${serverURL}/api/talas5/webserviceMap/GetIconsStatic`; */ } @@ -68,8 +74,8 @@ export { windowHeight, url_string, url, - c, - user, + idMap, + idUser, mapGisStationsStaticDistrictUrl, mapGisStationsStatusDistrictUrl, mapGisStationsMeasurementsUrl, @@ -77,3 +83,9 @@ export { mapDataIconUrl, webserviceGisLinesStatusUrl, }; + +/* +Access to fetch at 'http://localhost:3000/api/linesColorApi' from origin 'http://10.10.0.13:3000' has been blocked by CORS policy: + No 'Access-Control-Allow-Origin' header is present on the requested resource. + If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. + */ diff --git a/config/layers.js b/config/layers.js new file mode 100644 index 000000000..30c0ebde7 --- /dev/null +++ b/config/layers.js @@ -0,0 +1,17 @@ +import L from "leaflet"; + +export const MAP_LAYERS = { + TALAS: new L.layerGroup(), + ECI: new L.layerGroup(), + ULAF: new L.layerGroup(), + GSMModem: new L.layerGroup(), + CiscoRouter: new L.layerGroup(), + WAGO: new L.layerGroup(), + Siemens: new L.layerGroup(), + OTDR: new L.layerGroup(), + WDM: new L.layerGroup(), + GMA: new L.layerGroup(), + Sonstige: new L.layerGroup(), + TALASICL: new L.layerGroup(), + lineLayer: new L.LayerGroup(), +}; diff --git a/config/settings.js b/config/settings.js new file mode 100644 index 000000000..36391cc2b --- /dev/null +++ b/config/settings.js @@ -0,0 +1,5 @@ +// /config/settings.js +// Definieren der grundlegenden Umgebungseinstellungen und Konfigurationen der Karte +export const MAP_VERSION = "1.0.0"; +//export const STANDARD_SIDE_MENU = true; +//export const FULL_SIDE_MENU = false; diff --git a/config/urls.js b/config/urls.js new file mode 100644 index 000000000..207d02eff --- /dev/null +++ b/config/urls.js @@ -0,0 +1,45 @@ +// /config/urls.js + +export const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL; //Station in Tab öffnen +export const SERVER_URL = process.env.NEXT_PUBLIC_SERVER_URL; //Die Konstante ist in MapComponent.js und useLineData.js verwendet +export const PROXY_TARGET = process.env.NEXT_PUBLIC_PROXY_TARGET; // damit nodejs auf Port 3000 auf dem Server Talas5 auf Port 80 aufgerufen kann, ansonsten gibt CORS Fehler +export const ONLINE_TILE_LAYER = process.env.NEXT_PUBLIC_ONLINE_TILE_LAYER; //Map von Talas_v5 Server +//----------------------------------- +//export const ONLINE_TILE_LAYER = "http://10.10.0.13:3000/mapTiles/{z}/{x}/{y}.png"; //Map von Talas_v5 Server +// export const PROXY_TARGET = "http://10.10.0.70"; // damit nodejs auf Port 3000 auf dem Server Talas5 auf Port 80 aufgerufen kann, ansonsten gibt CORS Fehler +// export const SERVER_URL = "http://10.10.0.70"; //Die Konstante ist in MapComponent.js und useLineData.js verwendet +// export const BASE_URL = "http://10.10.0.70/talas5/devices/"; //Station in Tab öffnen +// //----------------------------------- +/* export const ONLINE_TILE_LAYER = "http://192.168.10.14:3000/mapTiles/{z}/{x}/{y}.png"; //Map von Talas_v5 Server +export const PROXY_TARGET = "http://192.168.10.167"; // damit nodejs auf Port 3000 auf dem Server Talas5 auf Port 80 aufgerufen kann, ansonsten gibt CORS Fehler +export const SERVER_URL = "http://192.168.10.167"; //Die Konstante ist in MapComponent.js und useLineData.js verwendet +export const BASE_URL = "http://192.168.10.167/talas5/devices/"; //Station in Tab öffnen */ +//----------------------------------- +// export const ONLINE_TILE_LAYER = "http://192.168.10.14:3000/mapTiles/{z}/{x}/{y}.png"; //Map von Talas_v5 Server */ +// export const PROXY_TARGET = "http://localhost"; // damit nodejs auf Port 3000 auf dem Server Talas5 auf Port 80 aufgerufen kann, ansonsten gibt CORS Fehler +// export const SERVER_URL = "http://localhost"; //in MapComponent.js wird es verwendet +// export const BASE_URL = "http://localhost/talas5/devices/"; //Station in Tab öffnen +//----------------------------------- +//----------------------------------- +// weil ich keine API habe, ansonsten serverURL ist localhost(IP-Adresse) für GisSystemStatic für die Benutzerrechte +//const serverURL = `${protocol}//${hostname}`; +//const serverURL = `${protocol}//${hostname}${port ? `:${port}` : ""}`; +//const serverURL = "http://localhost:3000"; +//export const SERVER_URL = "http://10.10.0.13"; +//export const SERVER_URL = "http://10.10.0.70"; + +// Online Daten URLs +/* export const MAP_GIS_STATIONS_STATIC_DISTRICT_URL = `${SERVER_URL}/talas5/ClientData/WebserviceMap.asmx/GisStationsStaticDistrict?idMap=${c}&idUser=${user}`; //idMap: 10, idUser: 484 +export const MAP_GIS_STATIONS_STATUS_DISTRICT_URL = `${SERVER_URL}/talas5/ClientData/WebserviceMap.asmx/GisStationsStatusDistrict?idMap=${c}&idUser=${user}`; +export const MAP_GIS_STATIONS_MEASUREMENTS_URL = `${SERVER_URL}/talas5/ClientData/WebserviceMap.asmx/GisStationsMeasurements?idMap=${c}`; +export const MAP_GIS_SYSTEM_STATIC_URL = `${SERVER_URL}/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic?idMap=${c}&idUser=${user}`; +export const MAP_DATA_ICON_URL = `${SERVER_URL}/talas5/ClientData/WebserviceMap.asmx/GetIconsStatic`; +export const WEBSERVICE_GIS_LINES_STATUS_URL = + "http://localhost:3000/api/linesColorApi"; + */ + +/* +Access to fetch at 'http://localhost:3000/api/linesColorApi' from origin 'http://10.10.0.13:3000' has been blocked by CORS policy: + No 'Access-Control-Allow-Origin' header is present on the requested resource. + If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. + */ diff --git a/hooks/talasMarkersLayer.js b/hooks/talasMarkersLayer.js new file mode 100644 index 000000000..58798b1f1 --- /dev/null +++ b/hooks/talasMarkersLayer.js @@ -0,0 +1,47 @@ +import { useEffect, useState } from "react"; +import L from "leaflet"; +import { createAndSetMarkers } from "../utils/markerUtils"; +import { addContextMenuToMarker } from "../utils/contextMenuUtils"; +import { checkOverlappingMarkers } from "../utils/mapUtils"; + +const useTalasMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => { + const [talasMarkers, setTalasMarkers] = useState([]); + + useEffect(() => { + if (GisSystemStatic && GisSystemStatic.length && map) { + createAndSetMarkers(1, setTalasMarkers, GisSystemStatic, priorityConfig); // TALAS-System + } + }, [GisSystemStatic, map, priorityConfig]); + + useEffect(() => { + if (map && talasMarkers.length) { + talasMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + + addContextMenuToMarker(marker); + }); + // Disable map context menu + map.options.contextmenu = false; + map.options.contextmenuItems = []; + + oms.map.options.contextmenu = false; + oms.map.options.contextmenuItems = []; + + // Call the function to check for overlapping markers + checkOverlappingMarkers(oms, map); + } + }, [map, talasMarkers]); + + return talasMarkers; +}; + +export default useTalasMarkersLayer; diff --git a/hooks/useCiscoRouterMarkersLayer.js b/hooks/useCiscoRouterMarkersLayer.js new file mode 100644 index 000000000..74e5a81c9 --- /dev/null +++ b/hooks/useCiscoRouterMarkersLayer.js @@ -0,0 +1,49 @@ +// hooks/useCiscoRouterMarkersLayer.js +import { useEffect, useState } from "react"; +import L from "leaflet"; +import { createAndSetMarkers } from "../utils/markerUtils"; +import { addContextMenuToMarker } from "../utils/contextMenuUtils"; +import { checkOverlappingMarkers } from "../utils/mapUtils"; + +const useCiscoRouterMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => { + const [ciscoRouterMarkers, setCiscoRouterMarkers] = useState([]); + + useEffect(() => { + if (GisSystemStatic && GisSystemStatic.length && map) { + createAndSetMarkers(6, setCiscoRouterMarkers, GisSystemStatic, priorityConfig); // Cisco Router + } + }, [GisSystemStatic, map, priorityConfig]); + + useEffect(() => { + if (map && ciscoRouterMarkers.length) { + ciscoRouterMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup on mouseover and mouseout + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + + addContextMenuToMarker(marker); + }); + + // Disable map context menu + map.options.contextmenu = false; + map.options.contextmenuItems = []; + + oms.map.options.contextmenu = false; + oms.map.options.contextmenuItems = []; + + // Call the function to check for overlapping markers + checkOverlappingMarkers(oms, map); + } + }, [map, ciscoRouterMarkers]); + + return ciscoRouterMarkers; +}; + +export default useCiscoRouterMarkersLayer; diff --git a/hooks/useDauzMarkersLayer.js b/hooks/useDauzMarkersLayer.js new file mode 100644 index 000000000..8ac18611e --- /dev/null +++ b/hooks/useDauzMarkersLayer.js @@ -0,0 +1,45 @@ +// hooks/useDauzMarkersLayer.js +import { useEffect, useState } from "react"; +import L from "leaflet"; +import { addContextMenuToMarker } from "../utils/contextMenuUtils"; +import { createAndSetMarkers } from "../utils/markerUtils"; + +const useDauzMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => { + const [dauzMarkers, setDauzMarkers] = useState([]); + + useEffect(() => { + if (GisSystemStatic && GisSystemStatic.length && map) { + createAndSetMarkers(110, setDauzMarkers, GisSystemStatic, priorityConfig); // DAUZ + } + }, [GisSystemStatic, map, priorityConfig]); + + useEffect(() => { + if (map && dauzMarkers.length) { + dauzMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup on mouseover and mouseout + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + + addContextMenuToMarker(marker); + }); + + // Disable map context menu + map.options.contextmenu = false; + map.options.contextmenuItems = []; + + oms.map.options.contextmenu = false; + oms.map.options.contextmenuItems = []; + } + }, [map, dauzMarkers, oms]); + + return dauzMarkers; +}; + +export default useDauzMarkersLayer; diff --git a/hooks/useEciMarkersLayer.js b/hooks/useEciMarkersLayer.js new file mode 100644 index 000000000..c5b0535bb --- /dev/null +++ b/hooks/useEciMarkersLayer.js @@ -0,0 +1,47 @@ +import { useEffect, useState } from "react"; +import L from "leaflet"; +import { createAndSetMarkers } from "../utils/markerUtils"; +import { addContextMenuToMarker } from "../utils/contextMenuUtils"; +import { checkOverlappingMarkers } from "../utils/mapUtils"; + +const useEciMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => { + const [eciMarkers, setEciMarkers] = useState([]); + + useEffect(() => { + if (GisSystemStatic && GisSystemStatic.length && map) { + createAndSetMarkers(2, setEciMarkers, GisSystemStatic, priorityConfig); // ECI-System + } + }, [GisSystemStatic, map, priorityConfig]); + + useEffect(() => { + if (map && eciMarkers.length) { + eciMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + + addContextMenuToMarker(marker); + }); + // Disable map context menu + map.options.contextmenu = false; + map.options.contextmenuItems = []; + + oms.map.options.contextmenu = false; + oms.map.options.contextmenuItems = []; + + // Call the function to check for overlapping markers + checkOverlappingMarkers(oms, map); + } + }, [map, eciMarkers]); + + return eciMarkers; +}; + +export default useEciMarkersLayer; diff --git a/hooks/useFetchPoiData.js b/hooks/useFetchPoiData.js new file mode 100644 index 000000000..8683c4d7c --- /dev/null +++ b/hooks/useFetchPoiData.js @@ -0,0 +1,25 @@ +// hooks/useFetchPoiData.js +import { useState, useEffect } from "react"; + +const useFetchPoiData = (url) => { + const [poiData, setPoiData] = useState([]); + + useEffect(() => { + const fetchPoiData = async () => { + try { + const response = await fetch(url); + if (!response.ok) throw new Error("Network response was not ok"); + const data = await response.json(); + setPoiData(data); + } catch (error) { + console.error("Fehler beim Abrufen der poiData:", error); + } + }; + + fetchPoiData(); + }, [url]); + + return poiData; +}; + +export default useFetchPoiData; diff --git a/hooks/useGmaMarkersLayer.js b/hooks/useGmaMarkersLayer.js new file mode 100644 index 000000000..a95562b12 --- /dev/null +++ b/hooks/useGmaMarkersLayer.js @@ -0,0 +1,63 @@ +import { useEffect } from "react"; +import { addContextMenuToMarker } from "../utils/contextMenuUtils"; + +const useGmaMarkersLayer = (map, gmaMarkers, GisStationsMeasurements, GMA, oms) => { + useEffect(() => { + if (map && gmaMarkers.length) { + const gmaMeasurements = GisStationsMeasurements.filter((m) => m.Gr === "GMA"); + let area_name = ""; + let measurements = {}; + + gmaMeasurements.forEach((m) => { + area_name = m.Area_Name; + measurements[m.Na] = m.Val; + }); + + gmaMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Logging the data to debug + //console.log("Marker Data:", { area_name, measurements }); + + marker.bindTooltip( + ` +
+
+ ${area_name} +
+
+ LT : ${measurements.LT} °C +
+
+ FBT : ${measurements.FBT} °C +
+
+ GT : ${measurements.GT === "nicht ermittelbar" ? measurements.GT : `${measurements.GT} °C`} +
+
+ RLF : ${measurements.RLF} % +
+
+ `, + { + permanent: true, + direction: "auto", + offset: [20, 0], + }, + ); + + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + map.addLayer(GMA); + } + }, [map, gmaMarkers, GisStationsMeasurements, GMA, oms]); +}; + +export default useGmaMarkersLayer; diff --git a/hooks/useGsmModemMarkersLayer.js b/hooks/useGsmModemMarkersLayer.js new file mode 100644 index 000000000..0b1a69fe3 --- /dev/null +++ b/hooks/useGsmModemMarkersLayer.js @@ -0,0 +1,47 @@ +// hooks/useGsmModemMarkersLayer.js +import { useEffect, useState } from "react"; +import L from "leaflet"; +import { createAndSetMarkers } from "../utils/markerUtils"; +import { addContextMenuToMarker } from "../utils/contextMenuUtils"; +import { checkOverlappingMarkers } from "../utils/mapUtils"; + +const useGsmModemMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => { + const [gsmModemMarkers, setGsmModemMarkers] = useState([]); + + useEffect(() => { + if (GisSystemStatic && GisSystemStatic.length && map) { + createAndSetMarkers(5, setGsmModemMarkers, GisSystemStatic, priorityConfig); // GSM-Modem + } + }, [GisSystemStatic, map, priorityConfig]); + + useEffect(() => { + if (map && gsmModemMarkers.length) { + gsmModemMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + + addContextMenuToMarker(marker); + }); + // Disable map context menu + map.options.contextmenu = false; + map.options.contextmenuItems = []; + + oms.map.options.contextmenu = false; + oms.map.options.contextmenuItems = []; + + // Call the function to check for overlapping markers + checkOverlappingMarkers(oms, map); + } + }, [map, gsmModemMarkers]); + + return gsmModemMarkers; +}; +export default useGsmModemMarkersLayer; diff --git a/hooks/useLayerVisibility.js b/hooks/useLayerVisibility.js new file mode 100644 index 000000000..4b4ab7851 --- /dev/null +++ b/hooks/useLayerVisibility.js @@ -0,0 +1,24 @@ +// hooks/useLayerVisibility.js +import { useEffect } from "react"; +import { useRecoilValue } from "recoil"; +import { mapLayersState } from "../store/atoms/mapLayersState"; + +const useLayerVisibility = (map, markers, mapLayersVisibility, layerKey) => { + useEffect(() => { + if (!map || !markers) return; + + const toggleLayer = (isVisible) => { + markers.forEach((marker) => { + if (isVisible) { + marker.addTo(map); + } else { + map.removeLayer(marker); + } + }); + }; + + toggleLayer(mapLayersVisibility[layerKey]); + }, [map, markers, mapLayersVisibility, layerKey]); +}; + +export default useLayerVisibility; diff --git a/hooks/useLineData - Kopie.js b/hooks/useLineData - Kopie.js new file mode 100644 index 000000000..02b7af93b --- /dev/null +++ b/hooks/useLineData - Kopie.js @@ -0,0 +1,64 @@ +// /hooks/useLineData.js +import { useEffect, useState } from "react"; +import { SERVER_URL } from "../config/urls"; + +const useLineData = (webserviceGisLinesStatusUrl, setLineStatusData) => { + const [lineColors, setLineColors] = useState({}); + const [tooltipContents, setTooltipContents] = useState({}); + + useEffect(() => { + const fetchData = async () => { + try { + const response1 = await fetch(webserviceGisLinesStatusUrl); + const data1 = await response1.json(); + const response2 = await fetch(`${SERVER_URL}:3000/api/talas_v5_DB/gisLines/readGisLines`); + const data2 = await response2.json(); + + const colorsByModule = {}; + const newTooltipContents = {}; + const reversedData = data1.Statis ? data1.Statis.reverse() : []; + reversedData.forEach((stat) => { + const matchingLine = data2.find((item) => item.idLD === stat.IdLD && item.idModul === stat.Modul); + if (matchingLine) { + // Check if PrioColor is #ffffff and change it to green + const prioColor = stat.PrioColor === "#ffffff" ? "green" : stat.PrioColor; + + colorsByModule[matchingLine.idModul] = prioColor; + newTooltipContents[matchingLine.idModul] = ` +
+ ${stat.ModulName || "Unknown"} +
+ ${stat.ModulTyp || "N/A"} +
+ Slot: ${stat.Modul || "N/A"} +
+
+ + ${stat.Message || "N/A"} +
+ (${stat.PrioName || "N/A"}) +
+
+ ${stat.DpName || "N/A"} + : ${stat.Value || "N/A"} +
+
+ `; + } + }); + + setLineColors(colorsByModule); + setTooltipContents(newTooltipContents); + setLineStatusData(reversedData); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + fetchData(); + }, [webserviceGisLinesStatusUrl, setLineStatusData]); + + return { lineColors, tooltipContents }; +}; + +export default useLineData; diff --git a/hooks/useLineData - stationname.js b/hooks/useLineData - stationname.js new file mode 100644 index 000000000..e19365b54 --- /dev/null +++ b/hooks/useLineData - stationname.js @@ -0,0 +1,93 @@ +// /hooks/useLineData.js +import { useEffect, useState } from "react"; +import { SERVER_URL } from "../config/urls"; + +const useLineData = (webserviceGisLinesStatusUrl, setLineStatusData) => { + const [lineColors, setLineColors] = useState({}); + const [tooltipContents, setTooltipContents] = useState({}); + const [locationDevices, setLocationDevices] = useState([]); + + // Funktion zum Abrufen der Stationsnamen + useEffect(() => { + const fetchLocationDevices = async () => { + try { + const response = await fetch(`${process.env.NEXT_PUBLIC_SERVER_URL}:3000/api/talas_v5_DB/station/getStationNameByIdLD`); + const data = await response.json(); + setLocationDevices(data); + console.log("Stationen namen:", data); + } catch (error) { + console.error("Fehler beim Abrufen der Stationen:", error); + } + }; + + fetchLocationDevices(); + }, []); + + useEffect(() => { + const fetchData = async () => { + try { + const response1 = await fetch(webserviceGisLinesStatusUrl); + const data1 = await response1.json(); + const response2 = await fetch(`${SERVER_URL}:3000/api/talas_v5_DB/gisLines/readGisLines`); + const data2 = await response2.json(); + + const colorsByModule = {}; + const newTooltipContents = {}; + const reversedData = data1.Statis ? data1.Statis.reverse() : []; + + reversedData.forEach((stat) => { + // Finden der passenden Linie + const matchingLine = data2.find((item) => item.idLD === stat.IdLD && item.idModul === stat.Modul); + + if (matchingLine) { + // Ermitteln der Farbe basierend auf PrioColor + const prioColor = stat.PrioColor === "#ffffff" ? "green" : stat.PrioColor; + colorsByModule[matchingLine.idModul] = prioColor; + + // Finden des passenden Stationsnamens + const locationDevice = locationDevices.find((device) => device.idLD === stat.IdLD); + + newTooltipContents[matchingLine.idModul] = ` +
+ ${stat.ModulName || "Unknown"} +
+ Station: ${locationDevice ? locationDevice.name : "Unbekannt"} +
+ ${stat.ModulTyp || "N/A"} +
+ Slot: ${stat.Modul || "N/A"} +
+
+ + ${stat.Message || "N/A"} +
+ (${stat.PrioName || "N/A"}) +
+
+ ${stat.DpName || "N/A"} + : ${stat.Value || "N/A"} +
+
+ `; + } + }); + + setLineColors(colorsByModule); + setTooltipContents(newTooltipContents); + setLineStatusData(reversedData); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + fetchData(); + + const interval = setInterval(fetchData, 300000); // 300000 ms = 5 Minuten + + return () => clearInterval(interval); + }, [webserviceGisLinesStatusUrl, setLineStatusData, locationDevices]); + + return { lineColors, tooltipContents }; +}; + +export default useLineData; diff --git a/hooks/useLineData.js b/hooks/useLineData.js new file mode 100644 index 000000000..efc77c981 --- /dev/null +++ b/hooks/useLineData.js @@ -0,0 +1,152 @@ +// /hooks/useLineData.js +import { useEffect, useState } from "react"; +import { SERVER_URL } from "../config/urls"; + +const useLineData = (webserviceGisLinesStatusUrl, setLineStatusData) => { + const [lineColors, setLineColors] = useState({}); + const [tooltipContents, setTooltipContents] = useState({}); + + useEffect(() => { + const fetchData = async () => { + try { + console.log("Daten werden abgerufen..."); + const response1 = await fetch(webserviceGisLinesStatusUrl); + const data1 = await response1.json(); + console.log("Daten vom Webservice:", data1); + const response2 = await fetch(`${SERVER_URL}:3000/api/talas_v5_DB/gisLines/readGisLines`); + const data2 = await response2.json(); + console.log("GIS Linien Daten:", data2); + + const colorsByModule = {}; + const newTooltipContents = {}; + const valueMap = {}; + + // Hier führen wir die Gruppierung durch und loggen sie + logGroupedData(data1.Statis); + + data1.Statis.forEach((statis) => { + const key = `${statis.IdLD}-${statis.Modul}`; + if (!valueMap[key]) { + valueMap[key] = { + messages: [], + messwert: undefined, + schleifenwert: undefined, + }; + } + if (statis.DpName.includes("_Messwert") && statis.Value !== "True" && valueMap[key].messwert === undefined) { + valueMap[key].messwert = statis.Value; + } + if (statis.DpName.includes("_Schleifenwert") && valueMap[key].schleifenwert === undefined) { + valueMap[key].schleifenwert = statis.Value; + } + if (statis.Message && statis.Message !== "?") { + valueMap[key].messages.push(statis.Message); + } + }); + + data1.Statis.reverse().forEach((statis) => { + const matchingLine = data2.find((item) => item.idLD === statis.IdLD && item.idModul === statis.Modul); + if (matchingLine) { + const prioColor = statis.PrioColor === "#ffffff" ? "green" : statis.PrioColor; + const key = `${matchingLine.idLD}-${matchingLine.idModul}`; + const values = valueMap[key]; + + const messageDisplay = values.messages.map((msg) => (msg ? `${msg}
` : "")).join(""); + const prioNameDisplay = statis.PrioName && statis.PrioName !== "?" ? `(${statis.PrioName})` : ""; + + colorsByModule[matchingLine.idModul] = prioColor; + newTooltipContents[matchingLine.idModul] = ` +
+ ${statis.ModulName || "Unknown"} +
+ ${statis.ModulTyp || "N/A"} +
+ Slot: ${statis.Modul || "N/A"} +
+
+ + ${messageDisplay} +
+ ${prioNameDisplay} +
+ ${values.messwert ? `Messwert: ${values.messwert}
` : ""} + ${values.schleifenwert ? `Schleifenwert: ${values.schleifenwert}` : ""} +
+ `; + } + }); + + setLineColors(colorsByModule); + setTooltipContents(newTooltipContents); + setLineStatusData(data1.Statis); + } catch (error) { + console.error("Fehler beim Abrufen der Daten:", error); + } + }; + + fetchData(); + }, [webserviceGisLinesStatusUrl, setLineStatusData]); + + return { lineColors, tooltipContents }; +}; +//---------------------------------------------------------- +// Funktion zum Loggen der gruppierten und aggregierten Daten +function logGroupedData(statisList) { + const grouped = statisList.reduce((acc, item) => { + const { IdLD, Modul, Level, PrioColor, PrioName, ModulName, ModulTyp, Message } = item; + + if (!acc[IdLD]) { + acc[IdLD] = {}; + } + + if (!acc[IdLD][Modul]) { + acc[IdLD][Modul] = { + ModulName: ModulName || "Unknown", + ModulTyp: ModulTyp || "N/A", + TotalLevel: 0, + PrioColors: new Set(), + PrioNames: new Set(), + Messages: [], + }; + } + + // Aggregiere die Level und sammle Prioritätsinformationen und Nachrichten + acc[IdLD][Modul].TotalLevel += Level; + acc[IdLD][Modul].PrioColors.add(PrioColor); + acc[IdLD][Modul].PrioNames.add(PrioName); + if (Message && Message !== "?") { + acc[IdLD][Modul].Messages.push(Message); + } + + return acc; + }, {}); + + // Formatierte Ausgabe der gruppierten Daten, Entfernen von Modulen ohne Namen und Stationen mit leeren Arrays + const formattedData = {}; + Object.entries(grouped).forEach(([stationId, modules]) => { + const filteredModules = Object.entries(modules) + .filter(([modulId, data]) => data.ModulName !== "?") + .map(([modulId, data]) => ({ + Modul: modulId, + ModulName: data.ModulName, + ModulTyp: data.ModulTyp, + TotalLevel: data.TotalLevel, + PrioColors: Array.from(data.PrioColors).join(", "), + PrioNames: Array.from(data.PrioNames).join(", "), + Messages: data.Messages.join(" | "), + })); + + if (filteredModules.length > 0) { + formattedData[stationId] = filteredModules; + } + }); + + console.log("Aggregierte und gruppierte Daten (gefiltert):", formattedData); +} + +// Beispielaufruf der Funktion +// const statisList = data1.Statis; // Verwende die Liste aus deinem API-Aufruf +// logGroupedData(statisList); + +//---------------------------------------------------------- +export default useLineData; diff --git a/hooks/useMapComponentState.js b/hooks/useMapComponentState.js new file mode 100644 index 000000000..2ebc06a04 --- /dev/null +++ b/hooks/useMapComponentState.js @@ -0,0 +1,28 @@ +// hooks/useMapComponentState.js +import { useState, useRef } from "react"; +import usePoiTypData from "./usePoiTypData"; +import { useRecoilValue } from "recoil"; +import { poiLayerVisibleState } from "../store/atoms/poiLayerVisibleState"; + +export const useMapComponentState = () => { + const { poiTypData, isPoiTypLoaded } = usePoiTypData("/api/talas_v5_DB/poiTyp/readPoiTyp"); + const [deviceName, setDeviceName] = useState(""); + const [locationDeviceData, setLocationDeviceData] = useState([]); + const [priorityConfig, setPriorityConfig] = useState([]); + const [menuItemAdded, setMenuItemAdded] = useState(false); + const poiLayerVisible = useRecoilValue(poiLayerVisibleState); + + return { + poiTypData, + isPoiTypLoaded, + deviceName, + setDeviceName, + locationDeviceData, + setLocationDeviceData, + priorityConfig, + setPriorityConfig, + menuItemAdded, + setMenuItemAdded, + poiLayerVisible, + }; +}; diff --git a/hooks/useMarkerLayers.js b/hooks/useMarkerLayers.js new file mode 100644 index 000000000..05422f218 --- /dev/null +++ b/hooks/useMarkerLayers.js @@ -0,0 +1,26 @@ +// hooks/useMarkerLayers.js +import { useEffect } from "react"; +import { useRecoilValue } from "recoil"; +import { mapLayersState } from "../store/atoms/mapLayersState"; + +const useMarkerLayers = (map, markers, layerType) => { + const mapLayersVisibility = useRecoilValue(mapLayersState); + + useEffect(() => { + if (!map || !markers) return; + + const toggleLayer = (isVisible) => { + markers.forEach((marker) => { + if (isVisible) { + marker.addTo(map); + } else { + map.removeLayer(marker); + } + }); + }; + + toggleLayer(mapLayersVisibility[layerType]); + }, [map, markers, mapLayersVisibility, layerType]); +}; + +export default useMarkerLayers; diff --git a/hooks/useMessstellenMarkersLayer.js b/hooks/useMessstellenMarkersLayer.js new file mode 100644 index 000000000..447031824 --- /dev/null +++ b/hooks/useMessstellenMarkersLayer.js @@ -0,0 +1,37 @@ +import { useEffect, useState } from "react"; +import L from "leaflet"; +import { addContextMenuToMarker } from "../utils/contextMenuUtils"; +import { createAndSetMarkers } from "../utils/markerUtils"; + +const useMessstellenMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => { + const [messstellenMarkers, setMessstellenMarkers] = useState([]); + + useEffect(() => { + if (GisSystemStatic && GisSystemStatic.length && map) { + createAndSetMarkers(13, setMessstellenMarkers, GisSystemStatic, priorityConfig); // Messstellen + } + }, [GisSystemStatic, map, priorityConfig]); + + useEffect(() => { + if (map && messstellenMarkers.length) { + messstellenMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup on mouseover and mouseout + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + + addContextMenuToMarker(marker); + }); + } + }, [map, messstellenMarkers, oms]); + + return messstellenMarkers; +}; + +export default useMessstellenMarkersLayer; diff --git a/hooks/useOtdrMarkersLayer.js b/hooks/useOtdrMarkersLayer.js new file mode 100644 index 000000000..659eb1f09 --- /dev/null +++ b/hooks/useOtdrMarkersLayer.js @@ -0,0 +1,45 @@ +// hooks/useOtdrMarkersLayer.js +import { useEffect, useState } from "react"; +import L from "leaflet"; +import { addContextMenuToMarker } from "../utils/contextMenuUtils"; +import { createAndSetMarkers } from "../utils/markerUtils"; // Assuming this function is in markerUtils + +const useOtdrMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => { + const [otdrMarkers, setOtdrMarkers] = useState([]); + + useEffect(() => { + if (GisSystemStatic && GisSystemStatic.length && map) { + createAndSetMarkers(9, setOtdrMarkers, GisSystemStatic, priorityConfig); // OTDR + } + }, [GisSystemStatic, map, priorityConfig]); + + useEffect(() => { + if (map && otdrMarkers.length) { + otdrMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup on mouseover and mouseout + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + + addContextMenuToMarker(marker); + }); + + // Disable map context menu + map.options.contextmenu = false; + map.options.contextmenuItems = []; + + oms.map.options.contextmenu = false; + oms.map.options.contextmenuItems = []; + } + }, [map, otdrMarkers, oms]); + + return otdrMarkers; +}; + +export default useOtdrMarkersLayer; diff --git a/hooks/usePoiTypData.js b/hooks/usePoiTypData.js new file mode 100644 index 000000000..7e1ce2d2e --- /dev/null +++ b/hooks/usePoiTypData.js @@ -0,0 +1,26 @@ +// hooks/usePoiTypData.js +import { useState, useEffect } from "react"; + +const usePoiTypData = (url) => { + const [poiTypData, setPoiTypData] = useState([]); + const [isPoiTypLoaded, setIsPoiTypLoaded] = useState(false); + + useEffect(() => { + const fetchPoiTypData = async () => { + try { + const response = await fetch(url); + const data = await response.json(); + setPoiTypData(data); + setIsPoiTypLoaded(true); + } catch (error) { + console.error("Fehler beim Abrufen der poiTyp-Daten:", error); + } + }; + + fetchPoiTypData(); + }, [url]); + + return { poiTypData, isPoiTypLoaded }; +}; + +export default usePoiTypData; diff --git a/hooks/useSiemensMarkersLayer.js b/hooks/useSiemensMarkersLayer.js new file mode 100644 index 000000000..292860373 --- /dev/null +++ b/hooks/useSiemensMarkersLayer.js @@ -0,0 +1,49 @@ +// hooks/useSiemensMarkersLayer.js +import { useState, useEffect } from "react"; +import L from "leaflet"; +import { addContextMenuToMarker } from "../utils/contextMenuUtils"; +import { createAndSetMarkers } from "../utils/markerUtils"; +import { checkOverlappingMarkers } from "../utils/mapUtils"; + +const useSiemensMarkersLayer = (map, oms, gisSystemStatic, priorityConfig) => { + const [siemensMarkers, setSiemensMarkers] = useState([]); + + useEffect(() => { + if (gisSystemStatic && gisSystemStatic.length && map) { + createAndSetMarkers(8, setSiemensMarkers, gisSystemStatic, priorityConfig); // Siemens-System + } + }, [gisSystemStatic, map, priorityConfig]); + + useEffect(() => { + if (map && siemensMarkers.length) { + siemensMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup on mouseover and mouseout + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + + addContextMenuToMarker(marker); + }); + + // Disable map context menu + map.options.contextmenu = false; + map.options.contextmenuItems = []; + + oms.map.options.contextmenu = false; + oms.map.options.contextmenuItems = []; + + // Call the function to check for overlapping markers + checkOverlappingMarkers(oms, map); + } + }, [map, siemensMarkers, oms]); + + return siemensMarkers; +}; + +export default useSiemensMarkersLayer; diff --git a/hooks/useSmsfunkmodemMarkersLayer.js b/hooks/useSmsfunkmodemMarkersLayer.js new file mode 100644 index 000000000..0cead16b2 --- /dev/null +++ b/hooks/useSmsfunkmodemMarkersLayer.js @@ -0,0 +1,54 @@ +// hooks/useSmsfunkmodemMarkersLayer.js +import { useEffect, useState } from "react"; +import L from "leaflet"; +import "leaflet-contextmenu"; +import { addContextMenuToMarker } from "../utils/contextMenuUtils"; + +const useSmsfunkmodemMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => { + const [smsfunkmodemMarkers, setSmsfunkmodemMarkers] = useState([]); + + useEffect(() => { + if (map && GisSystemStatic) { + const markers = GisSystemStatic.filter((station) => station.System === 111).map((station) => { + const marker = L.marker([station.Latitude, station.Longitude], { + icon: L.icon({ + iconUrl: "/img/icons/pois/sms-funkmodem.png", + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + }), + id: station.id, + areaName: station.Area_Name, + draggable: false, + }).bindPopup(` +
+ ${station.Area_Name || "Unbekannt"}
+ ${station.Description || "No Description"}
+
+ `); + + marker.on("mouseover", function () { + this.openPopup(); + }); + + marker.on("mouseout", function () { + this.closePopup(); + }); + + addContextMenuToMarker(marker); + + return marker; + }); + + setSmsfunkmodemMarkers(markers); + markers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + }); + } + }, [map, GisSystemStatic, priorityConfig]); + + return smsfunkmodemMarkers; +}; + +export default useSmsfunkmodemMarkersLayer; diff --git a/hooks/useSonstigeMarkersLayer.js b/hooks/useSonstigeMarkersLayer.js new file mode 100644 index 000000000..c41490c3a --- /dev/null +++ b/hooks/useSonstigeMarkersLayer.js @@ -0,0 +1,45 @@ +// hooks/useSonstigeMarkersLayer.js +import { useEffect, useState } from "react"; +import L from "leaflet"; +import { addContextMenuToMarker } from "../utils/contextMenuUtils"; +import { createAndSetMarkers } from "../utils/markerUtils"; + +const useSonstigeMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => { + const [sonstigeMarkers, setSonstigeMarkers] = useState([]); + + useEffect(() => { + if (GisSystemStatic && GisSystemStatic.length && map) { + createAndSetMarkers(200, setSonstigeMarkers, GisSystemStatic, priorityConfig); // Sonstige + } + }, [GisSystemStatic, map, priorityConfig]); + + useEffect(() => { + if (map && sonstigeMarkers.length) { + sonstigeMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup on mouseover and mouseout + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + + addContextMenuToMarker(marker); + }); + + // Disable map context menu + map.options.contextmenu = false; + map.options.contextmenuItems = []; + + oms.map.options.contextmenu = false; + oms.map.options.contextmenuItems = []; + } + }, [map, sonstigeMarkers, oms]); + + return sonstigeMarkers; +}; + +export default useSonstigeMarkersLayer; diff --git a/hooks/useTalasMarkers.js b/hooks/useTalasMarkers.js new file mode 100644 index 000000000..0b0f9528d --- /dev/null +++ b/hooks/useTalasMarkers.js @@ -0,0 +1,102 @@ +// /hooks/useTalasMarkers.js +import { useEffect, useState } from "react"; +import L from "leaflet"; +import "leaflet-contextmenu"; +import { useRecoilValue } from "recoil"; +import { mapLayersState } from "../store/atoms/mapLayersState.js"; +import { selectedAreaState } from "../store/atoms/selectedAreaState.js"; +import { zoomTriggerState } from "../store/atoms/zoomTriggerState.js"; +import { addContextMenuToMarker } from "../utils/contextMenuUtils.js"; +import { checkOverlappingMarkers } from "../utils/mapUtils.js"; +import plusRoundIcon from "../components/PlusRoundIcon.js"; +import { gisStationsStaticDistrictState } from "../store/atoms/gisStationState.js"; + +const useTalasMarkers = (map, oms, layers, priorityConfig) => { + const [talasMarkers, setTalasMarkers] = useState([]); + const mapLayersVisibility = useRecoilValue(mapLayersState); + const selectedArea = useRecoilValue(selectedAreaState); + const zoomTrigger = useRecoilValue(zoomTriggerState); + const GisStationsStaticDistrict = useRecoilValue(gisStationsStaticDistrictState); + + // Funktion zum Erstellen und Setzen der Marker + const createAndSetMarkers = (systemId, setMarkers, GisSystemStatic, priorityConfig) => { + const markers = GisSystemStatic.filter((station) => station.System === systemId).map((station) => { + const marker = L.marker([station.Latitude, station.Longitude], { + title: station.Name, + contextmenu: true, + contextmenuItems: [], + }); + + marker.bindPopup(`${station.Name}
${station.Description}`); + + if (priorityConfig.includes(station.Priority)) { + marker.setIcon( + L.icon({ + iconUrl: `/icons/priority_${station.Priority}.png`, + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + }), + ); + } + + return marker; + }); + + setMarkers(markers); + }; + + useEffect(() => { + if (map && talasMarkers.length) { + talasMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + + addContextMenuToMarker(marker); + }); + + map.addLayer(layers.TALAS); + checkOverlappingMarkers(oms, map, plusRoundIcon); + } + }, [map, talasMarkers]); + + useEffect(() => { + if (!map || !talasMarkers) return; + + const toggleLayer = (isVisible) => { + if (isVisible) { + talasMarkers.forEach((marker) => marker.addTo(map)); + } else { + talasMarkers.forEach((marker) => map.removeLayer(marker)); + } + }; + + toggleLayer(mapLayersVisibility.TALAS); + }, [map, talasMarkers, mapLayersVisibility.TALAS]); + + useEffect(() => { + if (selectedArea && map) { + const station = GisStationsStaticDistrict.find((s) => s.Area_Name === selectedArea); + if (station) { + map.flyTo([station.X, station.Y], 14); + } + } + }, [selectedArea, map, GisStationsStaticDistrict]); + + useEffect(() => { + if (zoomTrigger && map) { + map.flyTo([51.41321407879154, 7.739617925303934], 7); + } + }, [zoomTrigger, map]); + + return [talasMarkers, setTalasMarkers, createAndSetMarkers]; +}; + +export default useTalasMarkers; diff --git a/hooks/useTalasiclMarkersLayer.js b/hooks/useTalasiclMarkersLayer.js new file mode 100644 index 000000000..c0bb78ae8 --- /dev/null +++ b/hooks/useTalasiclMarkersLayer.js @@ -0,0 +1,45 @@ +// hooks/useTalasiclMarkersLayer.js +import { useEffect, useState } from "react"; +import L from "leaflet"; +import { addContextMenuToMarker } from "../utils/contextMenuUtils"; +import { createAndSetMarkers } from "../utils/markerUtils"; + +const useTalasiclMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => { + const [talasiclMarkers, setTalasiclMarkers] = useState([]); + + useEffect(() => { + if (GisSystemStatic && GisSystemStatic.length && map) { + createAndSetMarkers(100, setTalasiclMarkers, GisSystemStatic, priorityConfig); // TALASICL + } + }, [GisSystemStatic, map, priorityConfig]); + + useEffect(() => { + if (map && talasiclMarkers.length) { + talasiclMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup on mouseover and mouseout + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + + addContextMenuToMarker(marker); + }); + + // Disable map context menu + map.options.contextmenu = false; + map.options.contextmenuItems = []; + + oms.map.options.contextmenu = false; + oms.map.options.contextmenuItems = []; + } + }, [map, talasiclMarkers, oms]); + + return talasiclMarkers; +}; + +export default useTalasiclMarkersLayer; diff --git a/hooks/useUlafMarkersLayer.js b/hooks/useUlafMarkersLayer.js new file mode 100644 index 000000000..3cc9d0912 --- /dev/null +++ b/hooks/useUlafMarkersLayer.js @@ -0,0 +1,76 @@ +// hooks/useUlafMarkersLayer.js +import { useEffect, useState } from "react"; +import L from "leaflet"; +import { addContextMenuToMarker } from "../utils/contextMenuUtils"; +//import { fetchDeviceNameById } from "../services/apiService"; + +const useUlafMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => { + const [ulafMarkers, setUlafMarkers] = useState([]); + + useEffect(() => { + if (!map || !GisSystemStatic) return; + + const markers = []; + GisSystemStatic.forEach((station) => { + if (station.System === 0) { + // Adjust the condition to match ULAF system identification + const marker = L.marker([station.Lat, station.Lon], { + icon: L.icon({ + iconUrl: "/img/icons/ulaf.png", + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + }), + id: station.id, + name: station.name, + description: station.description, + }); + + marker.bindPopup(` +
+ ${station.name || "Unbekannt"}
+ ${station.description || "Keine Beschreibung"} +
+ `); + + marker.on("mouseover", function () { + this.openPopup(); + }); + + marker.on("mouseout", function () { + this.closePopup(); + }); + + marker.on("click", async () => { + //const deviceName = await fetchDeviceNameById(station.idLD); + marker + .bindPopup( + ` +
+ ${station.name || "Unbekannt"}
+ ${deviceName}
+ ${station.description || "Keine Beschreibung"} +
+ `, + ) + .openPopup(); + }); + + markers.push(marker); + if (map) marker.addTo(map); + if (oms) oms.addMarker(marker); + addContextMenuToMarker(marker); + } + }); + + setUlafMarkers(markers); + + return () => { + markers.forEach((marker) => map.removeLayer(marker)); + }; + }, [map, GisSystemStatic, oms, priorityConfig]); + + return ulafMarkers; +}; + +export default useUlafMarkersLayer; diff --git a/hooks/useWagoMarkersLayer.js b/hooks/useWagoMarkersLayer.js new file mode 100644 index 000000000..3b6bfad16 --- /dev/null +++ b/hooks/useWagoMarkersLayer.js @@ -0,0 +1,49 @@ +// hooks/useWagoMarkersLayer.js +import { useState, useEffect } from "react"; +import L from "leaflet"; +import { addContextMenuToMarker } from "../utils/contextMenuUtils"; +import { createAndSetMarkers } from "../utils/markerUtils"; +import { checkOverlappingMarkers } from "../utils/mapUtils"; + +const useWagoMarkersLayer = (map, oms, gisSystemStatic, priorityConfig) => { + const [wagoMarkers, setWagoMarkers] = useState([]); + + useEffect(() => { + if (gisSystemStatic && gisSystemStatic.length && map) { + createAndSetMarkers(7, setWagoMarkers, gisSystemStatic, priorityConfig); // WAGO-System + } + }, [gisSystemStatic, map, priorityConfig]); + + useEffect(() => { + if (map && wagoMarkers.length) { + wagoMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup on mouseover and mouseout + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + + addContextMenuToMarker(marker); + }); + + // Disable map context menu + map.options.contextmenu = false; + map.options.contextmenuItems = []; + + oms.map.options.contextmenu = false; + oms.map.options.contextmenuItems = []; + + // Call the function to check for overlapping markers + checkOverlappingMarkers(oms, map); + } + }, [map, wagoMarkers, oms]); + + return wagoMarkers; +}; + +export default useWagoMarkersLayer; diff --git a/hooks/useWdmMarkersLayer.js b/hooks/useWdmMarkersLayer.js new file mode 100644 index 000000000..1368c7a46 --- /dev/null +++ b/hooks/useWdmMarkersLayer.js @@ -0,0 +1,45 @@ +// hooks/useWdmMarkersLayer.js +import { useEffect, useState } from "react"; +import L from "leaflet"; +import { addContextMenuToMarker } from "../utils/contextMenuUtils"; +import { createAndSetMarkers } from "../utils/markerUtils"; + +const useWdmMarkersLayer = (map, oms, GisSystemStatic, priorityConfig) => { + const [wdmMarkers, setWdmMarkers] = useState([]); + + useEffect(() => { + if (GisSystemStatic && GisSystemStatic.length && map) { + createAndSetMarkers(10, setWdmMarkers, GisSystemStatic, priorityConfig); // WDM + } + }, [GisSystemStatic, map, priorityConfig]); + + useEffect(() => { + if (map && wdmMarkers.length) { + wdmMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup on mouseover and mouseout + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + + addContextMenuToMarker(marker); + }); + + // Disable map context menu + map.options.contextmenu = false; + map.options.contextmenuItems = []; + + oms.map.options.contextmenu = false; + oms.map.options.contextmenuItems = []; + } + }, [map, wdmMarkers, oms]); + + return wdmMarkers; +}; + +export default useWdmMarkersLayer; diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 000000000..d0761486d --- /dev/null +++ b/jest.config.js @@ -0,0 +1,11 @@ +module.exports = { + setupFilesAfterEnv: ["/jest.setup.js"], + testEnvironment: "jest-environment-jsdom", + testPathIgnorePatterns: ["/.next/", "/node_modules/"], + transform: { + "^.+\\.(js|jsx|ts|tsx)$": "babel-jest", + }, + moduleNameMapper: { + "\\.(css|less|scss|sass)$": "identity-obj-proxy", + }, +}; diff --git a/jest.setup.js b/jest.setup.js new file mode 100644 index 000000000..b44ebd58e --- /dev/null +++ b/jest.setup.js @@ -0,0 +1,3 @@ +// jest.setup.js +global.fetch = require("jest-fetch-mock"); +jest.setMock("node-fetch", fetch); diff --git a/package-lock.json b/package-lock.json index 9fa2f49aa..c14a3bd91 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,43 +1,54 @@ { - "name": "nodeMap 24.06.2024", + "name": "02.08.2027 NodeMap", "lockfileVersion": 3, "requires": true, "packages": { "": { "dependencies": { - "@heroicons/react": "^2.1.3", - "express": "^4.19.2", + "@heroicons/react": "^2.1.5", + "autoprefixer": "^10.4.19", + "dotenv": "^16.4.5", "http-proxy-middleware": "^3.0.0", "leaflet": "^1.9.4", "leaflet-contextmenu": "^1.4.0", - "leaflet.smooth_marker_bouncing": "^3.0.3", - "lodash": "^4.17.21", + "leaflet.smooth_marker_bouncing": "^3.1.0", "mysql": "^2.18.1", - "mysql2": "^3.10.1", - "next": "^14.2.3", + "mysql2": "^3.11.0", + "next": "^14.2.5", + "nextjs-cors": "^2.2.0", "overlapping-marker-spiderfier-leaflet": "^0.2.7", - "react": "^18.2.0", + "postcss": "^8.4.40", + "react": "^18.3.1", "react-dom": "^18.3.1", - "react-leaflet": "^4.2.1", "react-toastify": "^10.0.5", - "recoil": "^0.7.7" + "recoil": "^0.7.7", + "tailwindcss": "^3.4.7" }, "devDependencies": { - "@types/leaflet": "^1.9.12", - "@types/leaflet-contextmenu": "^1.4.3", - "@types/react": "^18.3.1", - "@types/react-dom": "^18.3.0", - "autoprefixer": "^10.4.19", - "postcss": "^8.4.38", - "prettier": "^3.2.5", - "tailwindcss": "^3.4.3" + "@babel/core": "^7.25.2", + "@babel/preset-env": "^7.25.2", + "@babel/preset-react": "^7.24.7", + "@testing-library/jest-dom": "^6.4.8", + "@testing-library/react": "^16.0.0", + "@testing-library/user-event": "^14.5.2", + "babel-jest": "^29.7.0", + "identity-obj-proxy": "^3.0.0", + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", + "jest-fetch-mock": "^3.0.3", + "node-fetch": "^3.3.2" } }, + "node_modules/@adobe/css-tools": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz", + "integrity": "sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==", + "dev": true + }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "dev": true, "engines": { "node": ">=10" }, @@ -45,10 +56,1813 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.2.tgz", + "integrity": "sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz", + "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", + "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", + "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.25.2", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.0.tgz", + "integrity": "sha512-GYM6BxeQsETc9mnct+nIIpf63SAyzvyYN7UB/IlTyd+MBg06afFGp0mIeUqGyWgS2mxad6vqbMrHVlaL3m70sQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.25.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/traverse": "^7.25.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.2.tgz", + "integrity": "sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", + "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", + "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz", + "integrity": "sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-wrap-function": "^7.25.0", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz", + "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==", + "dev": true, + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz", + "integrity": "sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.0", + "@babel/types": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.0.tgz", + "integrity": "sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.3.tgz", + "integrity": "sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.2" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.3.tgz", + "integrity": "sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.0.tgz", + "integrity": "sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.0.tgz", + "integrity": "sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", + "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.0.tgz", + "integrity": "sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", + "integrity": "sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", + "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", + "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", + "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.0.tgz", + "integrity": "sha512-uaIi2FdqzjpAMvVqvB51S42oC2JEVgh0LDsGfZVDysWE8LrJtQC2jvKmOqEYThKyB7bDEb7BP1GYWDm7tABA0Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-remap-async-to-generator": "^7.25.0", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", + "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-remap-async-to-generator": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", + "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.0.tgz", + "integrity": "sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz", + "integrity": "sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", + "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.0.tgz", + "integrity": "sha512-xyi6qjr/fYU304fiRwFbekzkqVJZ6A7hOjWZd+89FVcBqPV3S9Wuozz82xdpLspckeaafntbzglaW4pqpzvtSw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-replace-supers": "^7.25.0", + "@babel/traverse": "^7.25.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", + "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/template": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz", + "integrity": "sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", + "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", + "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.0.tgz", + "integrity": "sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", + "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", + "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", + "dev": true, + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", + "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", + "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.25.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.1.tgz", + "integrity": "sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", + "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.2.tgz", + "integrity": "sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", + "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", + "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", + "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz", + "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-simple-access": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.0.tgz", + "integrity": "sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", + "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", + "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", + "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", + "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", + "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", + "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", + "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", + "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz", + "integrity": "sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", + "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz", + "integrity": "sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", + "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", + "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.7.tgz", + "integrity": "sha512-H/Snz9PFxKsS1JLI4dJLtnJgCJRoo0AUm3chP6NYr+9En1JMKloheEiLIhlp5MDVznWo+H3AAC1Mc8lmUEpsgg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.2.tgz", + "integrity": "sha512-KQsqEAVBpU82NM/B/N9j9WOdphom1SZH3R+2V7INrQUH+V9EBFwZsEJl8eBIVeQE62FxJCc70jzEZwqU7RcVqA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/plugin-syntax-jsx": "^7.24.7", + "@babel/types": "^7.25.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.24.7.tgz", + "integrity": "sha512-QG9EnzoGn+Qar7rxuW+ZOsbWOt56FvvI93xInqsZDC5fsekx1AlIO4KIJ5M+D0p0SqSH156EpmZyXq630B8OlQ==", + "dev": true, + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.7.tgz", + "integrity": "sha512-PLgBVk3fzbmEjBJ/u8kFzOqS9tUeDjiaWud/rRym/yjCo/M9cASPlnrd2ZmmZpQT40fOOrvR8jh+n8jikrOhNA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", + "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", + "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", + "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", + "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", + "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", + "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz", + "integrity": "sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", + "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", + "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", + "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz", + "integrity": "sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.3.tgz", + "integrity": "sha512-QsYW7UeAaXvLPX9tdVliMJE7MD7M6MLYVTovRTIwhoYQVFHR1rM4wO8wqAezYi3/BpSD+NzVCZ69R6smWiIi8g==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.25.2", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-validator-option": "^7.24.8", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.3", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.0", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.0", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.0", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.24.7", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.24.7", + "@babel/plugin-transform-async-generator-functions": "^7.25.0", + "@babel/plugin-transform-async-to-generator": "^7.24.7", + "@babel/plugin-transform-block-scoped-functions": "^7.24.7", + "@babel/plugin-transform-block-scoping": "^7.25.0", + "@babel/plugin-transform-class-properties": "^7.24.7", + "@babel/plugin-transform-class-static-block": "^7.24.7", + "@babel/plugin-transform-classes": "^7.25.0", + "@babel/plugin-transform-computed-properties": "^7.24.7", + "@babel/plugin-transform-destructuring": "^7.24.8", + "@babel/plugin-transform-dotall-regex": "^7.24.7", + "@babel/plugin-transform-duplicate-keys": "^7.24.7", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.0", + "@babel/plugin-transform-dynamic-import": "^7.24.7", + "@babel/plugin-transform-exponentiation-operator": "^7.24.7", + "@babel/plugin-transform-export-namespace-from": "^7.24.7", + "@babel/plugin-transform-for-of": "^7.24.7", + "@babel/plugin-transform-function-name": "^7.25.1", + "@babel/plugin-transform-json-strings": "^7.24.7", + "@babel/plugin-transform-literals": "^7.25.2", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", + "@babel/plugin-transform-member-expression-literals": "^7.24.7", + "@babel/plugin-transform-modules-amd": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.8", + "@babel/plugin-transform-modules-systemjs": "^7.25.0", + "@babel/plugin-transform-modules-umd": "^7.24.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", + "@babel/plugin-transform-new-target": "^7.24.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", + "@babel/plugin-transform-numeric-separator": "^7.24.7", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-object-super": "^7.24.7", + "@babel/plugin-transform-optional-catch-binding": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.8", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.24.7", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-property-literals": "^7.24.7", + "@babel/plugin-transform-regenerator": "^7.24.7", + "@babel/plugin-transform-reserved-words": "^7.24.7", + "@babel/plugin-transform-shorthand-properties": "^7.24.7", + "@babel/plugin-transform-spread": "^7.24.7", + "@babel/plugin-transform-sticky-regex": "^7.24.7", + "@babel/plugin-transform-template-literals": "^7.24.7", + "@babel/plugin-transform-typeof-symbol": "^7.24.8", + "@babel/plugin-transform-unicode-escapes": "^7.24.7", + "@babel/plugin-transform-unicode-property-regex": "^7.24.7", + "@babel/plugin-transform-unicode-regex": "^7.24.7", + "@babel/plugin-transform-unicode-sets-regex": "^7.24.7", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.4", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.37.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.24.7.tgz", + "integrity": "sha512-AAH4lEkpmzFWrGVlHaxJB7RLH21uPQ9+He+eFLWHmF9IuFQVugz8eAsamaW0DXRrTfco5zj1wWtpdcXJUOfsag==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-transform-react-display-name": "^7.24.7", + "@babel/plugin-transform-react-jsx": "^7.24.7", + "@babel/plugin-transform-react-jsx-development": "^7.24.7", + "@babel/plugin-transform-react-pure-annotations": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "dev": true + }, + "node_modules/@babel/runtime": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", + "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.3.tgz", + "integrity": "sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/parser": "^7.25.3", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.2", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz", + "integrity": "sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, "node_modules/@heroicons/react": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.1.3.tgz", - "integrity": "sha512-fEcPfo4oN345SoqdlCDdSa4ivjaKbk0jTd+oubcgNxnNgAfzysfwWfQUr+51wigiWHQQRiZNd1Ao0M5Y3M2EGg==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.1.5.tgz", + "integrity": "sha512-FuzFN+BsHa+7OxbvAERtgBTNeZpUjgM/MIizfVkSCL2/edriN0Hx/DWRCR//aPYwO5QX/YlgLGXk+E3PcfZwjA==", "peerDependencies": { "react": ">= 16" } @@ -57,7 +1871,6 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -70,11 +1883,796 @@ "node": ">=12" } }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/console/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/console/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/console/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/core/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/core/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true + }, + "node_modules/@jest/core/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/reporters/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/reporters/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/reporters/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/transform/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/transform/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/transform/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/types/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/types/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -88,7 +2686,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -97,36 +2694,33 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@next/env": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.3.tgz", - "integrity": "sha512-W7fd7IbkfmeeY2gXrzJYDx8D2lWKbVoTIj1o1ScPHNzvp30s1AuoEFSdr39bC5sjxJaxTtq3OTCZboNp0lNWHA==" + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.5.tgz", + "integrity": "sha512-/zZGkrTOsraVfYjGP8uM0p6r0BDT6xWpkjdVbcz66PJVSpwXX3yNiRycxAuDfBKGWBrZBXRuK/YVlkNgxHGwmA==" }, "node_modules/@next/swc-darwin-arm64": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.3.tgz", - "integrity": "sha512-3pEYo/RaGqPP0YzwnlmPN2puaF2WMLM3apt5jLW2fFdXD9+pqcoTzRk+iZsf8ta7+quAe4Q6Ms0nR0SFGFdS1A==", + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.5.tgz", + "integrity": "sha512-/9zVxJ+K9lrzSGli1///ujyRfon/ZneeZ+v4ptpiPoOU+GKZnm8Wj8ELWU1Pm7GHltYRBklmXMTUqM/DqQ99FQ==", "cpu": [ "arm64" ], @@ -139,9 +2733,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.3.tgz", - "integrity": "sha512-6adp7waE6P1TYFSXpY366xwsOnEXM+y1kgRpjSRVI2CBDOcbRjsJ67Z6EgKIqWIue52d2q/Mx8g9MszARj8IEA==", + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.5.tgz", + "integrity": "sha512-vXHOPCwfDe9qLDuq7U1OYM2wUY+KQ4Ex6ozwsKxp26BlJ6XXbHleOUldenM67JRyBfVjv371oneEvYd3H2gNSA==", "cpu": [ "x64" ], @@ -154,9 +2748,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.3.tgz", - "integrity": "sha512-cuzCE/1G0ZSnTAHJPUT1rPgQx1w5tzSX7POXSLaS7w2nIUJUD+e25QoXD/hMfxbsT9rslEXugWypJMILBj/QsA==", + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.5.tgz", + "integrity": "sha512-vlhB8wI+lj8q1ExFW8lbWutA4M2ZazQNvMWuEDqZcuJJc78iUnLdPPunBPX8rC4IgT6lIx/adB+Cwrl99MzNaA==", "cpu": [ "arm64" ], @@ -169,9 +2763,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.3.tgz", - "integrity": "sha512-0D4/oMM2Y9Ta3nGuCcQN8jjJjmDPYpHX9OJzqk42NZGJocU2MqhBq5tWkJrUQOQY9N+In9xOdymzapM09GeiZw==", + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.5.tgz", + "integrity": "sha512-NpDB9NUR2t0hXzJJwQSGu1IAOYybsfeB+LxpGsXrRIb7QOrYmidJz3shzY8cM6+rO4Aojuef0N/PEaX18pi9OA==", "cpu": [ "arm64" ], @@ -184,9 +2778,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.3.tgz", - "integrity": "sha512-ENPiNnBNDInBLyUU5ii8PMQh+4XLr4pG51tOp6aJ9xqFQ2iRI6IH0Ds2yJkAzNV1CfyagcyzPfROMViS2wOZ9w==", + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.5.tgz", + "integrity": "sha512-8XFikMSxWleYNryWIjiCX+gU201YS+erTUidKdyOVYi5qUQo/gRxv/3N1oZFCgqpesN6FPeqGM72Zve+nReVXQ==", "cpu": [ "x64" ], @@ -199,9 +2793,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.3.tgz", - "integrity": "sha512-BTAbq0LnCbF5MtoM7I/9UeUu/8ZBY0i8SFjUMCbPDOLv+un67e2JgyN4pmgfXBwy/I+RHu8q+k+MCkDN6P9ViQ==", + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.5.tgz", + "integrity": "sha512-6QLwi7RaYiQDcRDSU/os40r5o06b5ue7Jsk5JgdRBGGp8l37RZEh9JsLSM8QF0YDsgcosSeHjglgqi25+m04IQ==", "cpu": [ "x64" ], @@ -214,9 +2808,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.3.tgz", - "integrity": "sha512-AEHIw/dhAMLNFJFJIJIyOFDzrzI5bAjI9J26gbO5xhAKHYTZ9Or04BesFPXiAYXDNdrwTP2dQceYA4dL1geu8A==", + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.5.tgz", + "integrity": "sha512-1GpG2VhbspO+aYoMOQPQiqc/tG3LzmsdBH0LhnDS3JrtDx2QmzXe0B6mSZZiN3Bq7IOMXxv1nlsjzoS1+9mzZw==", "cpu": [ "arm64" ], @@ -229,9 +2823,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.3.tgz", - "integrity": "sha512-vga40n1q6aYb0CLrM+eEmisfKCR45ixQYXuBXxOOmmoV8sYST9k7E3US32FsY+CkkF7NtzdcebiFT4CHuMSyZw==", + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.5.tgz", + "integrity": "sha512-Igh9ZlxwvCDsu6438FXlQTHlRno4gFpJzqPjSIBZooD22tKeI4fE/YMRoHVJHmrQ2P5YL1DoZ0qaOKkbeFWeMg==", "cpu": [ "ia32" ], @@ -244,9 +2838,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.3.tgz", - "integrity": "sha512-Q1/zm43RWynxrO7lW4ehciQVj+5ePBhOK+/K2P7pLFX3JaJ/IZVC69SHidrmZSOkqz7ECIOhhy7XhAFG4JYyHA==", + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.5.tgz", + "integrity": "sha512-tEQ7oinq1/CjSG9uSTerca3v4AZ+dFa+4Yu6ihaG8Ud8ddqLQgFGcnwYls13H5X5CPDPZJdYxyeMui6muOLd4g==", "cpu": [ "x64" ], @@ -262,7 +2856,6 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -275,7 +2868,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, "engines": { "node": ">= 8" } @@ -284,7 +2876,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -297,20 +2888,33 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, "optional": true, "engines": { "node": ">=14" } }, - "node_modules/@react-leaflet/core": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-2.1.0.tgz", - "integrity": "sha512-Qk7Pfu8BSarKGqILj4x7bCSZ1pjuAPZ+qmRwH5S7mDS91VSbVVsJSrW4qA+GPrro8t69gFYVMWb1Zc4yFmPiVg==", - "peerDependencies": { - "leaflet": "^1.9.0", - "react": "^18.0.0", - "react-dom": "^18.0.0" + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" } }, "node_modules/@swc/counter": { @@ -327,12 +2931,302 @@ "tslib": "^2.4.0" } }, - "node_modules/@types/geojson": { - "version": "7946.0.14", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", - "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==", + "node_modules/@testing-library/dom": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", + "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/dom/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@testing-library/dom/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@testing-library/dom/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@testing-library/dom/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/@testing-library/dom/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/dom/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, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.4.8", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.4.8.tgz", + "integrity": "sha512-JD0G+Zc38f5MBHA4NgxQMR5XtO5Jx9g86jqturNTt2WUfRmLDIY7iKkWHDCCTiDuFMre6nxAD5wHw9W5kI4rGw==", + "dev": true, + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "@babel/runtime": "^7.9.2", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "lodash": "^4.17.21", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true + }, + "node_modules/@testing-library/jest-dom/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/react": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.0.0.tgz", + "integrity": "sha512-guuxUKRWQ+FgNX0h0NS0FIq3Q3uLtWVpBzcLOggmfMoUpgBnzBzvLLd4fbm6yS8ydJd94cIfY4yP9qUQjM2KwQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0", + "@types/react-dom": "^18.0.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@testing-library/user-event": { + "version": "14.5.2", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", + "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==", + "dev": true, + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "peer": true + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/http-proxy": { "version": "1.17.14", "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", @@ -341,104 +3235,173 @@ "@types/node": "*" } }, - "node_modules/@types/leaflet": { - "version": "1.9.12", - "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.12.tgz", - "integrity": "sha512-BK7XS+NyRI291HIo0HCfE18Lp8oA30H1gpi1tf0mF3TgiCEzanQjOqNZ4x126SXzzi2oNSZhZ5axJp1k0iM6jg==", + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, "dependencies": { - "@types/geojson": "*" + "@types/istanbul-lib-coverage": "*" } }, - "node_modules/@types/leaflet-contextmenu": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@types/leaflet-contextmenu/-/leaflet-contextmenu-1.4.3.tgz", - "integrity": "sha512-S2FCwMDtgyuykW9tZ0Wg99FDDdtpoMhmoqGgbrqXvMlQ2Yfl7ZuHJqcmvLZznr48pZjfPuvdkeGzcGkIM3ihYg==", + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, "dependencies": { - "@types/leaflet": "*" + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jsdom": { + "version": "20.0.1", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz", + "integrity": "sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/tough-cookie": "*", + "parse5": "^7.0.0" } }, "node_modules/@types/node": { - "version": "20.12.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", - "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", + "version": "22.0.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.0.2.tgz", + "integrity": "sha512-yPL6DyFwY5PiMVEwymNeqUTKsDczQBJ/5T7W/46RwLU/VH+AA8aT5TZkvBviLKLbbm0hlfftEkGrNzfRk/fofQ==", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.11.1" } }, - "node_modules/@types/prop-types": { - "version": "15.7.12", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", "dev": true }, - "node_modules/@types/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.1.tgz", - "integrity": "sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==", + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", "dev": true, "dependencies": { - "@types/prop-types": "*", - "csstype": "^3.0.2" + "@types/yargs-parser": "*" } }, - "node_modules/@types/react-dom": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", - "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true + }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "deprecated": "Use your platform's native atob() and btoa() methods instead", + "dev": true + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "dev": true, - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">= 0.6" + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", + "dev": true, + "dependencies": { + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "dev": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "node": ">=8" } }, "node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "engines": { - "node": ">=12" + "dependencies": { + "color-convert": "^1.9.0" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "engines": { + "node": ">=4" } }, "node_modules/any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -450,19 +3413,36 @@ "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true }, "node_modules/autoprefixer": { "version": "10.4.19", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", - "dev": true, "funding": [ { "type": "opencollective", @@ -495,11 +3475,218 @@ "postcss": "^8.1.0" } }, + "node_modules/aws-ssl-profiles": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.1.tgz", + "integrity": "sha512-+H+kuK34PfMaI9PNU/NSjBKL5hh/KDM9J72kwYeYEm0A8B1AC4fuCy3qsjnA7lxklgyXsB68yn8Z2xoZEjgwCQ==", + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-jest/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/babel-jest/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/babel-jest/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-jest/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.2", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", + "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.1", + "core-js-compat": "^3.36.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/bignumber.js": { "version": "9.0.0", @@ -513,7 +3700,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, "engines": { "node": ">=8" }, @@ -521,67 +3707,31 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", - "dev": true, + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", + "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", "funding": [ { "type": "opencollective", @@ -597,10 +3747,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", + "caniuse-lite": "^1.0.30001640", + "electron-to-chromium": "^1.4.820", "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -609,6 +3759,21 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -620,45 +3785,36 @@ "node": ">=10.16.0" } }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, "engines": { - "node": ">= 0.8" + "node": ">=6" } }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6" } }, "node_modules/camelcase-css": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "dev": true, "engines": { "node": ">= 6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001605", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001605.tgz", - "integrity": "sha512-nXwGlFWo34uliI9z3n6Qc0wZaf7zaZWA1CPZ169La5mV3I/gem7bst0vr5XQH5TJXZIMfDeZyOrZnSlVzKxxHQ==", + "version": "1.0.30001646", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001646.tgz", + "integrity": "sha512-dRg00gudiBDDTmUhClSdv3hqRfpbOnU28IpI1T6PBTLWa+kOj0681C8uML3PifYfREuBrVjDGhL3adYpBT6spw==", "funding": [ { "type": "opencollective", @@ -674,11 +3830,33 @@ } ] }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -702,7 +3880,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -710,11 +3887,46 @@ "node": ">= 6" } }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", + "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", + "dev": true + }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", @@ -723,7 +3935,152 @@ "node": ">=6" } }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true + }, "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/core-js-compat": { + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", + "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", + "dev": true, + "dependencies": { + "browserslist": "^4.23.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/create-jest/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/create-jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/create-jest/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", @@ -735,82 +4092,88 @@ "node": ">=7.0.0" } }, - "node_modules/color-name": { + "node_modules/create-jest/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "node_modules/create-jest/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { - "node": ">= 6" + "node": ">=8" } }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "node_modules/create-jest/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, "dependencies": { - "safe-buffer": "5.2.1" + "has-flag": "^4.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">=8" } }, - "node_modules/content-disposition/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" + "node_modules/cross-fetch": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", + "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", + "dev": true, + "dependencies": { + "node-fetch": "^2.6.12" + } + }, + "node_modules/cross-fetch/node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true } - ] - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "engines": { - "node": ">= 0.6" } }, - "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "engines": { - "node": ">= 0.6" + "node_modules/cross-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "node_modules/cross-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/cross-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" } }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -820,11 +4183,16 @@ "node": ">= 8" } }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, "bin": { "cssesc": "bin/cssesc" }, @@ -832,16 +4200,57 @@ "node": ">=4" } }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "node_modules/cssom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", "dev": true }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", "dependencies": { "ms": "2.1.2" }, @@ -854,20 +4263,42 @@ } } }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "dev": true + }, + "node_modules/dedent": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", + "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", + "dev": true, + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" } }, "node_modules/denque": { @@ -878,105 +4309,189 @@ "node": ">=0.10" } }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, "engines": { - "node": ">= 0.8" + "node": ">=6" } }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": ">=8" } }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "peer": true + }, + "node_modules/domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "deprecated": "Use your platform's native DOMException instead", + "dev": true, + "dependencies": { + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, "node_modules/electron-to-chromium": { - "version": "1.4.726", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.726.tgz", - "integrity": "sha512-xtjfBXn53RORwkbyKvDfTajtnTp0OJoPOIBzXvkNbb7+YYvCHJflba3L7Txyx/6Fov3ov2bGPr/n5MTixmPhdQ==", - "dev": true + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.4.tgz", + "integrity": "sha512-orzA81VqLyIGUEA77YkVA1D+N+nNfl2isJVjjmOyrlxuooZ19ynb+dOlaDTqd/idKRS9lDCSBmtzM+kyCsMnkA==" + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } }, "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, "engines": { - "node": ">= 0.8" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dependencies": { - "get-intrinsic": "^1.2.4" + "node": ">=0.12" }, - "engines": { - "node": ">= 0.4" + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "engines": { - "node": ">= 0.4" + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" } }, "node_modules/escalade": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "dev": true, "engines": { "node": ">=6" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, "node_modules/eventemitter3": { @@ -984,84 +4499,58 @@ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" }, - "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.6.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" }, "engines": { - "node": ">= 0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, "dependencies": { - "ms": "2.0.0" + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/express/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -1077,7 +4566,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -1085,19 +4573,56 @@ "node": ">= 6" } }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, "dependencies": { "reusify": "^1.0.4" } }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -1105,36 +4630,19 @@ "node": ">=8" } }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">=8" } }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, "node_modules/follow-redirects": { "version": "1.15.6", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", @@ -1155,10 +4663,9 @@ } }, "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -1170,19 +4677,47 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "engines": { - "node": ">= 0.6" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dev": true, + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" } }, "node_modules/fraction.js": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", - "dev": true, "engines": { "node": "*" }, @@ -1191,19 +4726,16 @@ "url": "https://github.com/sponsors/rawify" } }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "engines": { - "node": ">= 0.6" - } + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -1229,41 +4761,61 @@ "is-property": "^1.0.2" } }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, "engines": { - "node": ">= 0.4" + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/glob": { - "version": "10.3.12", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", - "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.6", - "minimatch": "^9.0.1", - "minipass": "^7.0.4", - "path-scurry": "^1.10.2" - }, - "bin": { - "glob": "dist/esm/bin.mjs" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "*" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -1273,7 +4825,6 @@ "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, "dependencies": { "is-glob": "^4.0.3" }, @@ -1281,15 +4832,13 @@ "node": ">=10.13.0" } }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" } }, "node_modules/graceful-fs": { @@ -1302,37 +4851,19 @@ "resolved": "https://registry.npmjs.org/hamt_plus/-/hamt_plus-1.0.2.tgz", "integrity": "sha512-t2JXKaehnMb9paaYA7J0BX8QQAY8lwfQ9Gjf4pg/mk4krt+cmwmU652HOoWonf+7+EQV97ARPMhhVgU1ra2GhA==" }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/harmony-reflect": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", + "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==", + "dev": true }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=4" } }, "node_modules/hasown": { @@ -1346,21 +4877,24 @@ "node": ">= 0.4" } }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" + "whatwg-encoding": "^2.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">=12" } }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, "node_modules/http-proxy": { "version": "1.18.1", "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", @@ -1374,6 +4908,20 @@ "node": ">=8.0.0" } }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/http-proxy-middleware": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.0.tgz", @@ -1390,35 +4938,114 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" } }, + "node_modules/identity-obj-proxy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", + "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==", + "dev": true, + "dependencies": { + "harmony-reflect": "^1.4.6" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -1427,12 +5054,14 @@ } }, "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dev": true, + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", + "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1450,11 +5079,19 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "engines": { "node": ">=8" } }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -1485,11 +5122,29 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, "node_modules/is-property": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -1498,19 +5153,101 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, - "node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, "dependencies": { - "@isaacs/cliui": "^8.0.2" + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" }, "engines": { - "node": ">=14" + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -1519,11 +5256,1891 @@ "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/jiti": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", - "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-circus/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-circus/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-circus/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true + }, + "node_modules/jest-circus/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dev": true, + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-cli/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-cli/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-cli/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-config/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-config/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-config/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true + }, + "node_modules/jest-config/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-diff/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-diff/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true + }, + "node_modules/jest-diff/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-each/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-each/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-each/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true + }, + "node_modules/jest-each/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.7.0.tgz", + "integrity": "sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/jsdom": "^20.0.0", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0", + "jsdom": "^20.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-fetch-mock": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/jest-fetch-mock/-/jest-fetch-mock-3.0.3.tgz", + "integrity": "sha512-Ux1nWprtLrdrH4XwE7O7InRY6psIi3GOsqNESJgMJ+M5cv4A8Lh7SN9d2V2kKRZ8ebAfcd1LNyZguAOb6JiDqw==", + "dev": true, + "dependencies": { + "cross-fetch": "^3.0.4", + "promise-polyfill": "^8.1.3" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-leak-detector/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-leak-detector/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-leak-detector/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-matcher-utils/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-matcher-utils/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true + }, + "node_modules/jest-matcher-utils/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-message-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-message-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true + }, + "node_modules/jest-message-util/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-resolve/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-resolve/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runner/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-runner/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runtime/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-runtime/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-snapshot/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-validate/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-validate/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-validate/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true + }, + "node_modules/jest-validate/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-watcher/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-watcher/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-watcher/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", "bin": { "jiti": "bin/jiti.js" } @@ -1533,6 +7150,103 @@ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdom": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", + "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "acorn": "^8.8.1", + "acorn-globals": "^7.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.2", + "decimal.js": "^10.4.2", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0", + "ws": "^8.11.0", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/leaflet": { "version": "1.9.4", "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", @@ -1544,15 +7258,23 @@ "integrity": "sha512-BXASCmJ5bLkuJGDCpWmvGqhZi5AzeOY0IbQalfkgBcMAMfAOFSvD4y0gIQxF/XzEyLkjXaRiUpibVj4+Cf3tUA==" }, "node_modules/leaflet.smooth_marker_bouncing": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/leaflet.smooth_marker_bouncing/-/leaflet.smooth_marker_bouncing-3.0.3.tgz", - "integrity": "sha512-Y+1MJ1nX0vy/NjvzW4Kq2gE3Pnpz3fgP3dZJQNMQW90bFQ8d2TjXrqazP5oWKNUWjvrVVzfMv/FrB7vUFmsLDA==" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leaflet.smooth_marker_bouncing/-/leaflet.smooth_marker_bouncing-3.1.0.tgz", + "integrity": "sha512-Gz5DmYwV5UZJCL8xfYLLTn716YF6ljinflf3v/MQSjNdf4G8K8CjGicMXY6ceL3jRJzZ23VihaxeuBaQ6zYDPQ==" + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } }, "node_modules/lilconfig": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true, "engines": { "node": ">=10" } @@ -1560,13 +7282,31 @@ "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true }, "node_modules/long": { "version": "5.2.3", @@ -1585,71 +7325,91 @@ } }, "node_modules/lru-cache": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", - "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, - "engines": { - "node": "14 || >=16.14" + "dependencies": { + "yallist": "^3.0.2" } }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "engines": { - "node": ">= 0.6" + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "peer": true, + "bin": { + "lz-string": "bin/bin.js" } }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, "engines": { "node": ">= 8" } }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, "engines": { "node": ">= 0.6" } @@ -1658,6 +7418,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, "dependencies": { "mime-db": "1.52.0" }, @@ -1665,26 +7426,40 @@ "node": ">= 0.6" } }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "*" } }, "node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", - "dev": true, + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "engines": { "node": ">=16 || 14 >=14.17" } @@ -1709,10 +7484,11 @@ } }, "node_modules/mysql2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.10.1.tgz", - "integrity": "sha512-6zo1T3GILsXMCex3YEu7hCz2OXLUarxFsxvFcUHWMpkPtmZLeTTWgRdc1gWyNJiYt6AxITmIf9bZDRy/jAfWew==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.11.0.tgz", + "integrity": "sha512-J9phbsXGvTOcRVPR95YedzVSxJecpW5A5+cQ57rhHIFXteTP10HCs+VBjS7DHIKfEaI1zQ5tlVrquCd64A6YvA==", "dependencies": { + "aws-ssl-profiles": "^1.1.1", "denque": "^2.1.0", "generate-function": "^2.3.1", "iconv-lite": "^0.6.3", @@ -1726,17 +7502,6 @@ "node": ">= 8.0" } }, - "node_modules/mysql2/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/mysql2/node_modules/lru-cache": { "version": "8.0.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", @@ -1757,7 +7522,6 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", @@ -1800,20 +7564,18 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true }, "node_modules/next": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/next/-/next-14.2.3.tgz", - "integrity": "sha512-dowFkFTR8v79NPJO4QsBUtxv0g9BrS/phluVpMAt2ku7H+cbcBJlopXjkWlwxrk/xGqMemr7JkGPGemPrLLX7A==", + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/next/-/next-14.2.5.tgz", + "integrity": "sha512-0f8aRfBVL+mpzfBjYfQuLWh2WyAwtJXCRfkPF4UJ5qd2YwrHczsrSzXU4tRMV0OAxR8ZJZWPFn6uhSC56UTsLA==", "dependencies": { - "@next/env": "14.2.3", + "@next/env": "14.2.5", "@swc/helpers": "0.5.5", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -1828,15 +7590,15 @@ "node": ">=18.17.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "14.2.3", - "@next/swc-darwin-x64": "14.2.3", - "@next/swc-linux-arm64-gnu": "14.2.3", - "@next/swc-linux-arm64-musl": "14.2.3", - "@next/swc-linux-x64-gnu": "14.2.3", - "@next/swc-linux-x64-musl": "14.2.3", - "@next/swc-win32-arm64-msvc": "14.2.3", - "@next/swc-win32-ia32-msvc": "14.2.3", - "@next/swc-win32-x64-msvc": "14.2.3" + "@next/swc-darwin-arm64": "14.2.5", + "@next/swc-darwin-x64": "14.2.5", + "@next/swc-linux-arm64-gnu": "14.2.5", + "@next/swc-linux-arm64-musl": "14.2.5", + "@next/swc-linux-x64-gnu": "14.2.5", + "@next/swc-linux-x64-musl": "14.2.5", + "@next/swc-win32-arm64-msvc": "14.2.5", + "@next/swc-win32-ia32-msvc": "14.2.5", + "@next/swc-win32-x64-msvc": "14.2.5" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", @@ -1884,17 +7646,69 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "node_modules/nextjs-cors": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nextjs-cors/-/nextjs-cors-2.2.0.tgz", + "integrity": "sha512-FZu/A+L59J4POJNqwXYyCPDvsLDeu5HjSBvytzS6lsrJeDz5cmnH45zV+VoNic0hjaeER9xGaiIjZIWzEHnxQg==", + "dependencies": { + "cors": "^2.8.5" + }, + "peerDependencies": { + "next": "^8.1.1-canary.54 || ^9.0.0 || ^10.0.0-0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dev": true, + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -1903,16 +7717,32 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nwsapi": { + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.12.tgz", + "integrity": "sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w==", + "dev": true + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -1921,28 +7751,32 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "dev": true, "engines": { "node": ">= 6" } }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" } }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, "dependencies": { - "ee-first": "1.1.1" + "mimic-fn": "^2.1.0" }, "engines": { - "node": ">= 0.8" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/overlapping-marker-spiderfier-leaflet": { @@ -1950,19 +7784,114 @@ "resolved": "https://registry.npmjs.org/overlapping-marker-spiderfier-leaflet/-/overlapping-marker-spiderfier-leaflet-0.2.7.tgz", "integrity": "sha512-U2biV2Ge0SU+4IEmq4BZOglvzA8Aj8G7/hp5v6lBnF9Kd3/Xf6ZEPsJyPOExtLvMxOqlrlTAfl55s6JJDND7Ew==" }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, "engines": { - "node": ">= 0.8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "engines": { "node": ">=8" } @@ -1970,34 +7899,32 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-scurry": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", - "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", - "dev": true, + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -2014,7 +7941,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -2023,16 +7949,26 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dev": true, "engines": { "node": ">= 6" } }, - "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss": { + "version": "8.4.40", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.40.tgz", + "integrity": "sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==", "funding": [ { "type": "opencollective", @@ -2049,7 +7985,7 @@ ], "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "source-map-js": "^1.2.0" }, "engines": { @@ -2060,7 +7996,6 @@ "version": "15.1.0", "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dev": true, "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", @@ -2077,7 +8012,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "dev": true, "dependencies": { "camelcase-css": "^2.0.1" }, @@ -2096,7 +8030,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", - "dev": true, "funding": [ { "type": "opencollective", @@ -2128,10 +8061,9 @@ } }, "node_modules/postcss-load-config/node_modules/lilconfig": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", - "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", - "dev": true, + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", "engines": { "node": ">=14" }, @@ -2140,29 +8072,33 @@ } }, "node_modules/postcss-nested": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", - "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", - "dev": true, + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "postcss-selector-parser": "^6.0.11" + "postcss-selector-parser": "^6.1.1" }, "engines": { "node": ">=12.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, "peerDependencies": { "postcss": "^8.2.14" } }, "node_modules/postcss-selector-parser": { - "version": "6.0.16", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", - "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", - "dev": true, + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz", + "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -2174,22 +8110,34 @@ "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, - "node_modules/prettier": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", - "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, - "bin": { - "prettier": "bin/prettier.cjs" + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" }, "engines": { - "node": ">=14" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/process-nextick-args": { @@ -2197,37 +8145,66 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "node_modules/promise-polyfill": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.3.0.tgz", + "integrity": "sha512-H5oELycFml5yto/atYqmjyigJoAo3+OXwolYiH7OfQuYlAqhxNvTfiNMbV9hsC6Yp83yE5r2KTVmtrG6R9i6Pg==", + "dev": true + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" }, "engines": { - "node": ">= 0.10" + "node": ">= 6" } }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6" } }, + "node_modules/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, "funding": [ { "type": "github", @@ -2243,28 +8220,6 @@ } ] }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", @@ -2288,18 +8243,12 @@ "react": "^18.3.1" } }, - "node_modules/react-leaflet": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-4.2.1.tgz", - "integrity": "sha512-p9chkvhcKrWn/H/1FFeVSqLdReGwn2qmiobOQGO3BifX+/vV/39qhY8dGqbdcPh1e6jxh/QHriLXr7a4eLFK4Q==", - "dependencies": { - "@react-leaflet/core": "^2.1.0" - }, - "peerDependencies": { - "leaflet": "^1.9.0", - "react": "^18.0.0", - "react-dom": "^18.0.0" - } + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "peer": true }, "node_modules/react-toastify": { "version": "10.0.5", @@ -2317,7 +8266,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, "dependencies": { "pify": "^2.3.0" } @@ -2340,7 +8288,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -2367,6 +8314,99 @@ } } }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dev": true, + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -2376,7 +8416,6 @@ "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -2389,11 +8428,40 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -2403,7 +8471,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "funding": [ { "type": "github", @@ -2432,6 +8499,18 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, "node_modules/scheduler": { "version": "0.23.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", @@ -2440,92 +8519,24 @@ "loose-envify": "^1.1.0" } }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, "node_modules/seq-queue": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -2537,38 +8548,38 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "engines": { "node": ">=8" } }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=0.10.0" } }, "node_modules/source-map-js": { @@ -2579,6 +8590,22 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, "node_modules/sqlstring": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", @@ -2587,12 +8614,25 @@ "node": ">= 0.6" } }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, "engines": { - "node": ">= 0.8" + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" } }, "node_modules/streamsearch": { @@ -2611,29 +8651,23 @@ "safe-buffer": "~5.1.0" } }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=10" } }, - "node_modules/string-width-cjs": { - "name": "string-width", + "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -2643,46 +8677,29 @@ "node": ">=8" } }, - "node_modules/string-width-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dependencies": { - "ansi-regex": "^5.0.1" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { - "ansi-regex": "^6.0.1" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": ">=8" } }, "node_modules/strip-ansi-cjs": { @@ -2690,7 +8707,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -2698,15 +8714,48 @@ "node": ">=8" } }, - "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, "engines": { "node": ">=8" } }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/styled-jsx": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", @@ -2733,7 +8782,6 @@ "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", @@ -2751,11 +8799,63 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/sucrase/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sucrase/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -2763,11 +8863,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, "node_modules/tailwindcss": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz", - "integrity": "sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==", - "dev": true, + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.7.tgz", + "integrity": "sha512-rxWZbe87YJb4OcSopb7up2Ba4U82BoiSGUdoDr3Ydrg9ckxFS/YWsvhN323GMcddgU65QRy7JndC7ahhInhvlQ==", "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -2800,11 +8905,24 @@ "node": ">=14.0.0" } }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, "dependencies": { "any-promise": "^1.0.0" } @@ -2813,7 +8931,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dev": true, "dependencies": { "thenify": ">= 3.1.0 < 4" }, @@ -2821,6 +8938,21 @@ "node": ">=0.8" } }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -2832,55 +8964,122 @@ "node": ">=8.0" } }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, "engines": { - "node": ">=0.6" + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dev": true, + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" } }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" }, "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.11.1.tgz", + "integrity": "sha512-mIDEX2ek50x0OlRgxryxsenE5XaQD4on5U2inY7RApK3SOJpofyw7uW2AyfMKkhAxXIceo2DeWGVGwyvng1GNQ==" }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true, "engines": { - "node": ">= 0.8" + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" } }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", - "dev": true, + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", "funding": [ { "type": "opencollective", @@ -2896,8 +9095,8 @@ } ], "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -2906,17 +9105,33 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, "engines": { - "node": ">= 0.4.0" + "node": ">=10.12.0" } }, "node_modules/vary": { @@ -2927,11 +9142,83 @@ "node": ">= 0.8" } }, + "node_modules/w3c-xmlserializer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", + "dev": true, + "dependencies": { + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dev": true, + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -2943,24 +9230,6 @@ } }, "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", @@ -2977,16 +9246,54 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", @@ -3001,49 +9308,143 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" }, "engines": { - "node": ">=8" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, "engines": { - "node": ">=8" + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, + "node_modules/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, "node_modules/yaml": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", - "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", - "dev": true, + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz", + "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==", "bin": { "yaml": "bin.mjs" }, "engines": { "node": ">= 14" } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/package.json b/package.json index 6437c6ae5..4c93a0397 100644 --- a/package.json +++ b/package.json @@ -1,36 +1,43 @@ { "dependencies": { - "@heroicons/react": "^2.1.3", - "express": "^4.19.2", + "@heroicons/react": "^2.1.5", + "autoprefixer": "^10.4.19", + "dotenv": "^16.4.5", "http-proxy-middleware": "^3.0.0", "leaflet": "^1.9.4", "leaflet-contextmenu": "^1.4.0", - "leaflet.smooth_marker_bouncing": "^3.0.3", - "lodash": "^4.17.21", + "leaflet.smooth_marker_bouncing": "^3.1.0", "mysql": "^2.18.1", - "mysql2": "^3.10.1", - "next": "^14.2.3", + "mysql2": "^3.11.0", + "next": "^14.2.5", + "nextjs-cors": "^2.2.0", "overlapping-marker-spiderfier-leaflet": "^0.2.7", - "react": "^18.2.0", + "postcss": "^8.4.40", + "react": "^18.3.1", "react-dom": "^18.3.1", - "react-leaflet": "^4.2.1", "react-toastify": "^10.0.5", - "recoil": "^0.7.7" + "recoil": "^0.7.7", + "tailwindcss": "^3.4.7" }, "scripts": { "dev": "next dev", "build": "next build", "start": "next start", - "export": "next export" + "export": "next export", + "test": "jest" }, "devDependencies": { - "@types/leaflet": "^1.9.12", - "@types/leaflet-contextmenu": "^1.4.3", - "@types/react": "^18.3.1", - "@types/react-dom": "^18.3.0", - "autoprefixer": "^10.4.19", - "postcss": "^8.4.38", - "prettier": "^3.2.5", - "tailwindcss": "^3.4.3" + "@babel/core": "^7.25.2", + "@babel/preset-env": "^7.25.2", + "@babel/preset-react": "^7.24.7", + "@testing-library/jest-dom": "^6.4.8", + "@testing-library/react": "^16.0.0", + "@testing-library/user-event": "^14.5.2", + "babel-jest": "^29.7.0", + "identity-obj-proxy": "^3.0.0", + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", + "jest-fetch-mock": "^3.0.3", + "node-fetch": "^3.3.2" } } diff --git a/pages/_app.js b/pages/_app.js index f17f73891..fc74da978 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -1,5 +1,6 @@ // Pfad: pages/_app.js -import { RecoilRoot } from 'recoil'; +import React from "react"; +import { RecoilRoot } from "recoil"; import "../styles/global.css"; function MyApp({ Component, pageProps }) { diff --git a/pages/api back30/[...path].js b/pages/api back30/[...path].js new file mode 100644 index 000000000..0578e8448 --- /dev/null +++ b/pages/api back30/[...path].js @@ -0,0 +1,20 @@ +// pages/api/[...path].js +import { createProxyMiddleware } from "http-proxy-middleware"; +import { SERVER_URL } from "../config/urls.js"; +console.log("SERVER_URL:", SERVER_URL); // Debug-Ausgabe + +export default createProxyMiddleware({ + //target: "http://192.168.10.58:3001", + // Stationen bekommen + //target: "http://10.10.0.13", // Ziel-URL des Proxys // API Aufruf zum mapGisStationsStaticDistrictUrl, mapGisStationsStatusDistrictUrl, mapGisStationsMeasurementsUrl, mapGisSystemStaticUrl und mapDataIconUrl + target: `${SERVER_URL}`, // + //target: urls.PROXY_TARGET, + //target: "http://localhost:3000", // Ziel-URL des Proxys + //target: "http://192.168.10.187:3000", // Ziel-URL des Proxys + //target: "http://192.168.10.14", + changeOrigin: true, + pathRewrite: { + "^/api": "/", // Optional: Entfernt /api aus dem Pfad, wenn das Backend dies nicht erfordert + }, + logLevel: "debug", // Setzt das Logging-Level auf "debug" für detaillierte Ausgaben +}); diff --git a/pages/api back30/get-talasIP.js b/pages/api back30/get-talasIP.js new file mode 100644 index 000000000..1216fbbb7 --- /dev/null +++ b/pages/api back30/get-talasIP.js @@ -0,0 +1,20 @@ +// pages/api/get-talasIP.js + +export default function handler(req, res) { + // Der x-forwarded-for Header könnte mehrere IP-Adressen enthalten, getrennt durch Kommas + let clientIp = + req.headers["x-forwarded-for"]?.split(",").map((ip) => ip.trim())[0] || + req.socket.remoteAddress; + + // Entfernen möglicher IPv6 "mapped" IPv4 Adressen + if (clientIp?.includes("::ffff:")) { + clientIp = clientIp.split("::ffff:")[1]; + } + + // Nur IPv4 Adressen weitergeben, IPv6 Adressen ausschließen + if (clientIp && clientIp.includes(":")) { + clientIp = ""; // Dies setzt die IP auf leer, wenn es sich um eine IPv6-Adresse handelt + } + + res.status(200).json({ ip: clientIp }); +} diff --git a/pages/api back30/gis-proxy.js b/pages/api back30/gis-proxy.js new file mode 100644 index 000000000..b76883298 --- /dev/null +++ b/pages/api back30/gis-proxy.js @@ -0,0 +1,34 @@ +// /pages/api/gis-proxy.js +// Importieren der erforderlichen Module +import httpProxy from "http-proxy"; +import Cookies from "cookies"; + +// Erstellen eines Proxy-Servers +const proxy = httpProxy.createProxyServer(); + +export default (req, res) => { + return new Promise((resolve) => { + // CORS-Headers einstellen + res.setHeader("Access-Control-Allow-Credentials", true); + res.setHeader("Access-Control-Allow-Origin", "*"); + + // Cookies initialisieren + const cookies = new Cookies(req, res); + const targetUrl = `${process.env.NEXT_PUBLIC_SERVER_URL}/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic`; + + // Proxy-Konfiguration und Event-Listener + req.on("data", () => {}); + req.on("end", () => { + proxy.web(req, res, { target: targetUrl, changeOrigin: true, selfHandleResponse: false }, (e) => { + if (e) { + console.error(e); + res.status(500).json({ error: "Proxy-Fehler", e }); + } + resolve(); + }); + }); + + // Weiterleitung der Headers + req.headers.cookie = cookies.get("cookie-name") || ""; + }); +}; diff --git a/pages/api back30/linesColorApi.js b/pages/api back30/linesColorApi.js new file mode 100644 index 000000000..57ee59262 --- /dev/null +++ b/pages/api back30/linesColorApi.js @@ -0,0 +1,64 @@ +// /pages/api/linesColorApi.js +// http://10.10.0.13/talas5/ClientData/WebServiceMap.asmx/GisStationsStatusDistrict +//In DB gis_lines idLD und idModul anpassen entsprechend + +// /pages/api/linesColorApi.js +import NextCors from "nextjs-cors"; + +export default async function handler(req, res) { + // Run the cors middleware + await NextCors(req, res, { + // Options + methods: ["GET", "HEAD", "PUT", "PATCH", "POST", "DELETE"], + origin: "*", // Erlauben Sie alle Ursprünge, oder geben Sie spezifische Ursprünge an + optionsSuccessStatus: 200, // Legacy-Browser-Unterstützung für 204 + }); + + const response = { + Name: "Liste aller Statis der Linien", + Zeitstempel: new Date().toISOString(), // Aktuellen Zeitstempel hinzufügen + IdMap: "10", + Statis: [ + /* { + IdLD: 50922, + Modul: 1, + DpName: "KUE01_Ausfall", + ModulName: "42 Wippershain Sender", + // ModulTyp: "nicht vorhanden", + ModulTyp: "KÜ705-FO", + Message: "KUEG 01: 42 Wippershain Sender Messwerkausfall kommend", + Level: 4, + PrioColor: "#FFFF00", + PrioName: "system", + Value: "10 MOhm", + }, + { + IdLD: 25440, + Modul: 3, + DpName: "KUE03_Ausfall", + ModulName: "42 Solz Sender", + //ModulTyp: "nicht vorhanden", + ModulTyp: "KÜSS V2", + Message: "KUEG 03: 42 Solz Sender Messwerkausfall kommend", + Level: 4, + PrioColor: "#FF0000", + PrioName: "system", + Value: "10 MOhm", + }, + { + IdLD: 25440, + Modul: 4, + DpName: "KUE04_Ausfall", + ModulName: "42/13 Bad Hersfeld Gaswerk", + ModulTyp: "Kue705-FO", + Message: "KUEG 04: 42/13 Bad Hersfeld Gaswerk Messwerkausfall kommend", + Level: 4, + PrioColor: "#FF00FF", + PrioName: "system", + Value: "10 MOhm", + }, */ + ], + }; + + res.status(200).json(response); +} diff --git a/pages/api back30/rights.js b/pages/api back30/rights.js new file mode 100644 index 000000000..507228147 --- /dev/null +++ b/pages/api back30/rights.js @@ -0,0 +1,29 @@ +// pages/api/rights.js + +export default function handler(req, res) { + const { idMap, idUser } = req.query; + + // Beispielhafte Rechte, die je nach idMap und idUser variieren können + const rights = { + '10': [ + { IdRight: 1, Name: "Zugriff auf Dashboard" }, + { IdRight: 56, Name: "Erweiterte Berechtigungen" } + ], + '2': [ + { IdRight: 2, Name: "Zugriff auf Einstellungen" } + ], + '1': [ + { IdRight: 10, Name: "Admin-Zugriff" }, + { IdRight: 11, Name: "Zugriff auf alle Daten" } + ] + }; + + // Prüfung, ob eine gültige idMap und idUser vorhanden sind + if (rights[idMap] && idUser === '484') { + // Rückgabe der spezifischen Rechte basierend auf der idMap und idUser + res.status(200).json({ Rights: rights[idMap] }); + } else { + // Rückgabe leerer Rechte für ungültige idMap oder andere Benutzer + res.status(200).json({ Rights: [] }); + } +} diff --git a/pages/api back30/talas5/area.js b/pages/api back30/talas5/area.js new file mode 100644 index 000000000..9205aa5ca --- /dev/null +++ b/pages/api back30/talas5/area.js @@ -0,0 +1,40 @@ +// pages/api/talas_v5/area.js +// Lesen von talas_v5 MySQL-Datenbank -> area Tabelle enthält DAUZ Geräte +// Wenn gebraucht wird, dann nutzen ansonsten löschen + +import mysql from "mysql"; + +const dbConfig = { + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + port: process.env.DB_PORT, +}; +//console.log("my dbconfig: ", dbConfig); +export default function handler(req, res) { + const connection = mysql.createConnection(dbConfig); + + connection.connect((err) => { + if (err) { + console.error("Fehler beim Verbinden:", err.stack); + res.status(500).json({ error: "Verbindungsfehler zur Datenbank" }); + return; + } + + //console.log("Verbunden als ID", connection.threadId); + //Fehler weil, existiertdie Tabelle auf localhost:3000 nicht + connection.query("SELECT ..., ..., ..., ... FROM ... WHERE ... = ...", (error, results) => { + if (error) { + console.error("Fehler beim Abrufen der API", error); + res.status(500).json({ error: "Fehler bei der Abfrage" }); + return; + } + + // Wichtig: Senden Sie die Antwort zurück + res.status(200).json(results); + + connection.end(); + }); + }); +} diff --git a/pages/api back30/talas5/location_device.js b/pages/api back30/talas5/location_device.js new file mode 100644 index 000000000..8c956f459 --- /dev/null +++ b/pages/api back30/talas5/location_device.js @@ -0,0 +1,39 @@ +// pages/api/talas_v5/location_device.js +// talas_v5 Datenbank -> location_device Tabelle enthält DAUZ Geräte + +import mysql from "mysql"; + +const dbConfig = { + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + port: process.env.DB_PORT, +}; +//console.log("my dbconfig: ", dbConfig); +export default function handler(req, res) { + const connection = mysql.createConnection(dbConfig); + + connection.connect((err) => { + if (err) { + console.error("Fehler beim Verbinden:", err.stack); + res.status(500).json({ error: "Verbindungsfehler zur Datenbank" }); + return; + } + + //console.log("Verbunden als ID", connection.threadId); + //Fehler weil, existiertdie Tabelle auf localhost:3000 nicht + connection.query("SELECT idLD, iddevice, iddevice, name FROM location_device WHERE iddevice = 160", (error, results) => { + if (error) { + console.error("Fehler beim Abrufen der API", error); + res.status(500).json({ error: "Fehler bei der Abfrage" }); + return; + } + + // Wichtig: Senden Sie die Antwort zurück + res.status(200).json(results); + + connection.end(); + }); + }); +} diff --git a/pages/api back30/talas5/webserviceMap/GisStationsMeasurements.js b/pages/api back30/talas5/webserviceMap/GisStationsMeasurements.js new file mode 100644 index 000000000..5aba69fc6 --- /dev/null +++ b/pages/api back30/talas5/webserviceMap/GisStationsMeasurements.js @@ -0,0 +1,116 @@ +// /pages/api/talas5/webserviceMap/GisStationsMeasurements.js +const GisStationsMeasurements = { + "Name": "Liste aller Messungen der Geraete", + "Zeitstempel": "2024-05-31T15:25:32.5047629+02:00", + "IdMap": "10", + "Statis": [ + { + "IdLD": 50004, + "IdL": 18624, + "IdDP": 3, + "Na": "FBT", + "Val": "20.5", + "Unit": "°C", + "Gr": "GMA", + "Area_Name": "Renzenhof (RG)" + }, + { + "IdLD": 50004, + "IdL": 18624, + "IdDP": 10, + "Na": "GT", + "Val": "nicht ermittelbar", + "Unit": "°C", + "Gr": "GMA", + "Area_Name": "Renzenhof (RG)" + }, + { + "IdLD": 50004, + "IdL": 18624, + "IdDP": 2, + "Na": "LT", + "Val": "Datenlücke", + "Unit": "°C", + "Gr": "GMA", + "Area_Name": "Renzenhof (RG)" + }, + { + "IdLD": 50004, + "IdL": 18624, + "IdDP": 6, + "Na": "RLF", + "Val": "100.0", + "Unit": "%", + "Gr": "GMA", + "Area_Name": "Renzenhof (RG)" + }, + { + "IdLD": 50004, + "IdL": 18624, + "IdDP": 11, + "Na": "TPT", + "Val": "8.3", + "Unit": "°C", + "Gr": "GMA", + "Area_Name": "Renzenhof (RG)" + }, + { + "IdLD": 50004, + "IdL": 18624, + "IdDP": 12, + "Na": "TT1", + "Val": "---", + "Unit": "°C", + "Gr": "GMA", + "Area_Name": "Renzenhof (RG)" + }, + { + "IdLD": 50004, + "IdL": 18624, + "IdDP": 16, + "Na": "WFD", + "Val": "0.12", + "Unit": "mm", + "Gr": "GMA", + "Area_Name": "Renzenhof (RG)" + }, + { + "IdLD": 50004, + "IdL": 18624, + "IdDP": 8, + "Na": "WGM", + "Val": "---", + "Unit": "m/s", + "Gr": "GMA", + "Area_Name": "Renzenhof (RG)" + }, + { + "IdLD": 50004, + "IdL": 18624, + "IdDP": 9, + "Na": "WGS", + "Val": "---", + "Unit": "m/s", + "Gr": "GMA", + "Area_Name": "Renzenhof (RG)" + } + ] + } + + // Export an async function handler for the API route. + export default async function handler(req, res) { + // Initialize an empty params object to store query parameters. + const params = { + idMap: req.query.idMap, + + }; + + // Check if the requested ID map and user match certain conditions. + if (params.idMap === '10') { + // If the conditions are met, return the GisStationsMeasurements object with a 200 status code. + res.status(200).json(GisStationsMeasurements); + } else { + // If not, return a 404 error with the message "Not Found". + res.status(404).send('Not Found'); + } + }; \ No newline at end of file diff --git a/pages/api back30/talas5/webserviceMap/GisStationsStaticDistrict.js b/pages/api back30/talas5/webserviceMap/GisStationsStaticDistrict.js new file mode 100644 index 000000000..bf302f3d7 --- /dev/null +++ b/pages/api back30/talas5/webserviceMap/GisStationsStaticDistrict.js @@ -0,0 +1,281 @@ +// /pages/api/talas5/webserviceMap/GisStationsStaticDistrict.js +const GisStationsStaticDistrict = { + "Name": "Liste aller Geraete einer bestimmten Karte", + "Zeitstempel": "2024-05-31T15:26:56.9235766+02:00", + "IdMap": "10", + "Points": [ + { + "LD_Name": "CPL Bentheim", + "IdLD": 50017, + "Device": "CPL V3.5 mit 16 Kü", + "Link": "cpl.aspx?ver=35&kue=16&id=50017", + "Location_Name": "Technikraum", + "Location_Short": "BEHE", + "IdLocation": 17448, + "Area_Name": "Bad-Bentheim", + "Area_Short": "BEHE--00", + "IdArea": 16418, + "X": 51.5728, + "Y": 9.00056, + "Icon": 20, + "System": 1, + "Active": 0 + }, + { + "LD_Name": "Drucker", + "IdLD": 50084, + "Device": "Basisgerät", + "Link": "basis.aspx?ver=1&id=50084", + "Location_Name": "Technikraum", + "Location_Short": "SLUE", + "IdLocation": 17776, + "Area_Name": "Schlüchtern II", + "Area_Short": "SLUE--00", + "IdArea": 14688, + "X": 53.2455, + "Y": 8.1614, + "Icon": 14, + "System": 200, + "Active": 0 + }, + { + "LD_Name": "Türkontakt", + "IdLD": 50666, + "Device": "ECI", + "Link": "eci.aspx?ver=1&id=50666", + "Location_Name": "Technikraum", + "Location_Short": "SLUE", + "IdLocation": 17776, + "Area_Name": "Schlüchtern II", + "Area_Short": "SLUE--00", + "IdArea": 14688, + "X": 53.2455, + "Y": 8.1614, + "Icon": 17, + "System": 2, + "Active": 0 + }, + { + "LD_Name": "Triptis", + "IdLD": 50888, + "Device": "CPL 200", + "Link": "cpl.aspx?ver=30&kue=16&id=50888", + "Location_Name": "Technikraum", + "Location_Short": "SLUE", + "IdLocation": 17776, + "Area_Name": "Schlüchtern II", + "Area_Short": "SLUE--00", + "IdArea": 14688, + "X": 53.2455, + "Y": 8.1614, + "Icon": 20, + "System": 1, + "Active": 0 + }, + { + "LD_Name": "Rodaborn I", + "IdLD": 50889, + "Device": "cpl.mio V>6", + "Link": "cplmio.aspx?ver=1&id=50889", + "Location_Name": "Technikraum", + "Location_Short": "SLUE", + "IdLocation": 17776, + "Area_Name": "Schlüchtern II", + "Area_Short": "SLUE--00", + "IdArea": 14688, + "X": 53.2455, + "Y": 8.1614, + "Icon": 20, + "System": 1, + "Active": 0 + }, + { + "LD_Name": "Rodaborn II", + "IdLD": 50900, + "Device": "cpl.mio V>6", + "Link": "cplmio.aspx?ver=1&id=50900", + "Location_Name": "Technikraum", + "Location_Short": "SLUE", + "IdLocation": 17776, + "Area_Name": "Schlüchtern II", + "Area_Short": "SLUE--00", + "IdArea": 14688, + "X": 53.2455, + "Y": 8.1614, + "Icon": 20, + "System": 1, + "Active": 0 + }, + { + "LD_Name": "Hermsdorf", + "IdLD": 50901, + "Device": "CPL V3.5 mit 24 Kü", + "Link": "cpl.aspx?ver=35&kue=24&id=50901", + "Location_Name": "Technikraum", + "Location_Short": "SLUE", + "IdLocation": 17776, + "Area_Name": "Schlüchtern II", + "Area_Short": "SLUE--00", + "IdArea": 14688, + "X": 53.2455, + "Y": 8.1614, + "Icon": 20, + "System": 1, + "Active": 1 + }, + { + "LD_Name": "GMA Littwin (TEST)", + "IdLD": 50004, + "Device": "Glättemeldeanlage", + "Link": "gma.aspx?ver=1&id=50004", + "Location_Name": "RG Relaisraum", + "Location_Short": "REZR", + "IdLocation": 18624, + "Area_Name": "Renzenhof (RG)", + "Area_Short": "REZHRG00", + "IdArea": 16570, + "X": 53.246036, + "Y": 8.163293, + "Icon": 1, + "System": 11, + "Active": 0 + }, + { + "LD_Name": "NRS Testserver", + "IdLD": 50005, + "Device": "Notruf Server", + "Link": "nrs_server.aspx?ver=1&id=50005", + "Location_Name": "(EV Ammersricht BZR REL)", + "Location_Short": "AMME", + "IdLocation": 21118, + "Area_Name": "Ammersricht BZR (FGN)", + "Area_Short": "AMMER--00", + "IdArea": 15958, + "X": 52.52726, + "Y": 12.165488, + "Icon": 19, + "System": 8, + "Active": 0 + }, + { + "LD_Name": "Gateway 2", + "IdLD": 50007, + "Device": "Notruf Server", + "Link": "nrs_server.aspx?ver=1&id=50007", + "Location_Name": "(EV Ammersricht BZR REL)", + "Location_Short": "AMME", + "IdLocation": 21118, + "Area_Name": "Ammersricht BZR (FGN)", + "Area_Short": "AMMER--00", + "IdArea": 15958, + "X": 52.52726, + "Y": 12.165488, + "Icon": 19, + "System": 8, + "Active": 0 + }, + { + "LD_Name": "Basisgerät mit SNMP MVP", + "IdLD": 50669, + "Device": "Basisgerät + SNMP", + "Link": "basisSNMP.aspx?&ver=1&id=50669", + "Location_Name": "Mylinghauserstraße Engelbert", + "Location_Short": "G-GEVELSBE-1", + "IdLocation": 24012, + "Area_Name": "Gevelsberg", + "Area_Short": "GMA-GEVELSBE", + "IdArea": 20919, + "X": 51.316799, + "Y": 7.33281, + "Icon": 14, + "System": 200, + "Active": 1 + }, + { + "LD_Name": "Server 3", + "IdLD": 50009, + "Device": "Notruf Server", + "Link": "nrs_server.aspx?ver=1&id=50009", + "Location_Name": "Militärringstraße Militärringstraße", + "Location_Short": "G-KÖLN-1", + "IdLocation": 24015, + "Area_Name": "Köln", + "Area_Short": "GMA-KÖLN", + "IdArea": 20921, + "X": 50.898399, + "Y": 6.92278, + "Icon": 19, + "System": 8, + "Active": 0 + }, + { + "LD_Name": "ICL Test 5", + "IdLD": 50054, + "Device": "ICL", + "Link": "icl.aspx?ver=1&id=50054", + "Location_Name": "Recheder Mühlenweg Dortmund-Ems-Kanal", + "Location_Short": "G-OLFEN-SE-1", + "IdLocation": 24022, + "Area_Name": "Olfen-Selm", + "Area_Short": "GMA-OLFEN-SE", + "IdArea": 20926, + "X": 51.702202, + "Y": 7.40822, + "Icon": 23, + "System": 100, + "Active": 0 + }, + { + "LD_Name": "ICL Test 3", + "IdLD": 50052, + "Device": "ICL", + "Link": "icl.aspx?ver=1&id=50052", + "Location_Name": "Weidenstraße Hestenberg", + "Location_Short": "G-PLETTENB-1", + "IdLocation": 24024, + "Area_Name": "Plettenberg", + "Area_Short": "GMA-PLETTENB", + "IdArea": 20928, + "X": 51.224098, + "Y": 7.86969, + "Icon": 23, + "System": 100, + "Active": 0 + }, + { + "LD_Name": "Test Februar Kai", + "IdLD": 50912, + "Device": "Dauerzählstelle DZ", + "Link": "dauz.aspx?ver=1&id=50912", + "Location_Name": "In der Hoffnung Kiesberg - BG Ost", + "Location_Short": "G-WUPPERTA-4", + "IdLocation": 24039, + "Area_Name": "Wuppertal", + "Area_Short": "GMA-WUPPERTA", + "IdArea": 20937, + "X": 51.238899, + "Y": 7.12715, + "Icon": 14, + "System": 110, + "Active": 1 + } + ] + } + + // Export an async function handler for the API route. + export default async function handler(req, res) { + // Initialize an empty params object to store query parameters. + const params = { + idMap: req.query.idMap, + idUser: req.query.idUser + }; + + // Check if the requested ID map and user match certain conditions. + if (params.idMap === '10' && params.idUser === '484') { + // If the conditions are met, return the GisStationsStaticDistrict object with a 200 status code. + res.status(200).json(GisStationsStaticDistrict); + } else { + // If not, return a 404 error with the message "Not Found". + res.status(404).send('Not Found'); + } + }; \ No newline at end of file diff --git a/pages/api back30/talas5/webserviceMap/GisStationsStatusDistrict.js b/pages/api back30/talas5/webserviceMap/GisStationsStatusDistrict.js new file mode 100644 index 000000000..9d0f2024c --- /dev/null +++ b/pages/api back30/talas5/webserviceMap/GisStationsStatusDistrict.js @@ -0,0 +1,100 @@ +import mysql from "mysql2/promise"; + +const dbConfig = { + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + port: process.env.DB_PORT, +}; + +export default async function handler(req, res) { + const { idMap, idUser } = req.query; + + if (!idMap || !idUser) { + res.status(400).json({ error: "idMap and idUser are required" }); + return; + } + + let connection; + try { + connection = await mysql.createConnection(dbConfig); + + let onlySystem = -1; + let districtCounter = 0; + + // Get onlySystem + const [mapResult] = await connection.execute( + "SELECT idsystem_typ FROM maps WHERE id = ?", + [idMap] + ); + if (mapResult.length > 0) { + onlySystem = mapResult[0].idsystem_typ ?? -1; + } + + // Get districtCounter + if (idUser > 0) { + const [userLayerResult] = await connection.execute( + "SELECT count(*) as count FROM user_User_layer1 WHERE iduser = ?", + [idUser] + ); + districtCounter = userLayerResult[0].count; + } + + // Get GisStatusStations + let query = ` + SELECT ld.idLD, dc.message, p.level, p.name, p.color, ld.idDevice, de.isService, dc.idIcon + FROM location as l + LEFT JOIN location_coordinates AS co ON l.idLocation = co.idLocation and co.idMaps = ? + LEFT JOIN location_device AS ld ON ld.idLocation = l.idLocation + LEFT JOIN datapoint as d ON d.idLD = ld.idLD + LEFT JOIN datapoint_conditions AS dc ON dc.idcondition = d.last_message_condition + LEFT JOIN prio AS p ON p.idPrio = dc.idprio + LEFT JOIN devices AS de ON de.idDevice = ld.idDevice + LEFT JOIN area as a on a.idArea = l.idArea + WHERE p.level < 100 AND co.X > 0 + `; + + if (districtCounter > 0) { + query += ` AND a.iddistrict IN (SELECT iddistrict FROM user_user_layer1 WHERE iduser = ?)`; + } + + if (onlySystem >= 0) { + query += ` AND de.idsystem_typ = ?`; + } + + query += ` ORDER BY p.level desc`; + + const queryParams = [idMap]; + if (districtCounter > 0) { + queryParams.push(idUser); + } + if (onlySystem >= 0) { + queryParams.push(onlySystem); + } + + const [results] = await connection.execute(query, queryParams); + + const mpss = { + IdMap: idMap.toString(), + Statis: results.map((row) => ({ + IdLD: row.idLD ?? -1, + Le: row.level ?? -1, + Me: row.message ?? "?", + Na: row.name ?? "?", + Co: row.color ?? "#ffffff", + Feld: row.idDevice ?? -1, + Icon: row.idIcon ?? 0, + })), + }; + + res.status(200).json(mpss); + } catch (error) { + console.error("Fehler beim Laden der Daten:", error); + res.status(500).json({ error: "Interner Serverfehler" }); + } finally { + if (connection) { + await connection.end(); + } + } +} diff --git a/pages/api back30/talas5/webserviceMap/GisSystemStatic.js b/pages/api back30/talas5/webserviceMap/GisSystemStatic.js new file mode 100644 index 000000000..b2fb56635 --- /dev/null +++ b/pages/api back30/talas5/webserviceMap/GisSystemStatic.js @@ -0,0 +1,273 @@ +// /pages/api/webServiceMap.js +const gisSystemStatic = { + "Name": "Liste aller angezeigten Systeme", + "Zeitstempel": "2024-05-31T15:08:49.8599542+02:00", + "IdMap": "10", + "Systems": [ + { + "IdSystem": 1, + "Name": "TALAS", + "Longname": "Talas Meldestationen", + "Allow": 1, + "Icon": 1 + }, + { + "IdSystem": 2, + "Name": "ECI", + "Longname": "ECI Geräte", + "Allow": 1, + "Icon": 2 + }, + { + "IdSystem": 5, + "Name": "GSM Modem", + "Longname": "LR77 GSM Modems", + "Allow": 1, + "Icon": 5 + }, + { + "IdSystem": 6, + "Name": "Cisco Router", + "Longname": "Cisco Router", + "Allow": 1, + "Icon": 6 + }, + { + "IdSystem": 7, + "Name": "WAGO", + "Longname": "WAGO I/O Systeme", + "Allow": 1, + "Icon": 7 + }, + { + "IdSystem": 8, + "Name": "Siemens", + "Longname": "Siemens Notrufsystem", + "Allow": 0, + "Icon": 8 + }, + { + "IdSystem": 9, + "Name": "OTDR", + "Longname": "Glasfaserüberwachung OTU", + "Allow": 0, + "Icon": 9 + }, + { + "IdSystem": 10, + "Name": "WDM", + "Longname": " Wavelength Division Multiplexing", + "Allow": 0, + "Icon": 10 + }, + { + "IdSystem": 11, + "Name": "GMA", + "Longname": "Glättemeldeanlagen", + "Allow": 1, + "Icon": 11 + }, + { + "IdSystem": 13, + "Name": "Messstellen", + "Longname": "Messstellen", + "Allow": 0, + "Icon": 13 + }, + { + "IdSystem": 100, + "Name": "TALAS ICL", + "Longname": "Talas ICL Unterstationen", + "Allow": 1, + "Icon": 100 + }, + { + "IdSystem": 110, + "Name": "DAUZ", + "Longname": "Dauerzählstellen", + "Allow": 1, + "Icon": 110 + }, + { + "IdSystem": 111, + "Name": "SMS-Funkmodem", + "Longname": "SMS-Funkmodem", + "Allow": 0, + "Icon": 111 + }, + { + "IdSystem": 200, + "Name": "Sonstige", + "Longname": "Sonstige", + "Allow": 1, + "Icon": 200 + } + ], + "Rights": [ + { + "IdRight": 1 + }, + { + "IdRight": 2 + }, + { + "IdRight": 3 + }, + { + "IdRight": 5 + }, + { + "IdRight": 6 + }, + { + "IdRight": 7 + }, + { + "IdRight": 8 + }, + { + "IdRight": 10 + }, + { + "IdRight": 11 + }, + { + "IdRight": 12 + }, + { + "IdRight": 20 + }, + { + "IdRight": 22 + }, + { + "IdRight": 23 + }, + { + "IdRight": 25 + }, + { + "IdRight": 30 + }, + { + "IdRight": 40 + }, + { + "IdRight": 41 + }, + { + "IdRight": 42 + }, + { + "IdRight": 43 + }, + { + "IdRight": 44 + }, + { + "IdRight": 45 + }, + { + "IdRight": 46 + }, + { + "IdRight": 47 + }, + { + "IdRight": 48 + }, + { + "IdRight": 49 + }, + { + "IdRight": 50 + }, + { + "IdRight": 51 + }, + { + "IdRight": 52 + }, + { + "IdRight": 55 + }, + { + "IdRight": 56 + }, + { + "IdRight": 60 + }, + { + "IdRight": 61 + }, + { + "IdRight": 62 + }, + { + "IdRight": 63 + }, + { + "IdRight": 64 + }, + { + "IdRight": 65 + }, + { + "IdRight": 68 + }, + { + "IdRight": 69 + }, + { + "IdRight": 70 + }, + { + "IdRight": 71 + }, + { + "IdRight": 72 + }, + { + "IdRight": 73 + }, + { + "IdRight": 79 + }, + { + "IdRight": 80 + }, + { + "IdRight": 90 + }, + { + "IdRight": 93 + }, + { + "IdRight": 94 + }, + { + "IdRight": 95 + }, + { + "IdRight": 96 + } + ] +} + +// Export an async function handler for the API route. +export default async function handler(req, res) { + // Initialize an empty params object to store query parameters. + const params = { + idMap: req.query.idMap, + idUser: req.query.idUser + }; + + // Check if the requested ID map and user match certain conditions. + if (params.idMap === '10' && params.idUser === '484') { + // If the conditions are met, return the gisSystemStatic object with a 200 status code. + res.status(200).json(gisSystemStatic); + } else { + // If not, return a 404 error with the message "Not Found". + res.status(404).send('Not Found'); + } +}; \ No newline at end of file diff --git a/pages/api back30/talas5/webserviceMap/gisStationsMeasurementsSQL.js b/pages/api back30/talas5/webserviceMap/gisStationsMeasurementsSQL.js new file mode 100644 index 000000000..de3670b6d --- /dev/null +++ b/pages/api back30/talas5/webserviceMap/gisStationsMeasurementsSQL.js @@ -0,0 +1,70 @@ +import mysql from "mysql"; + +const dbConfig = { + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + port: process.env.DB_PORT, +}; + +const connection = mysql.createConnection(dbConfig); +connection.connect((err) => { + if (err) { + console.error("Fehler beim Verbinden:", err.stack); + return; + } + console.log("Database connected successfully."); +}); + +export default function handler(req, res) { + const idMap = req.query.idMap; + if (req.method !== "GET") { + return res.status(405).json({ error: "Nur GET Methode erlaubt" }); + } + + connection.query(` + SELECT + ld.idLD, + dp.idDP, + dp.name AS Na, + dp.value AS Val, + dp.unit AS Unit, + mg.name AS Gr, + ld.idLocation, + area.Name AS Area_Name + FROM location_device as ld + LEFT JOIN location_coordinates AS co ON ld.idLocation = co.idLocation and co.idMaps = ${idMap} + LEFT JOIN devices AS de ON de.idDevice = ld.idDevice + LEFT JOIN datapoint AS dp ON ld.idLD = dp.idLD + LEFT JOIN message_group AS mg ON dp.idmessage_group = mg.idmessage_group + LEFT JOIN location AS loc ON ld.idLocation = loc.idLocation + LEFT JOIN area AS area ON loc.idArea = area.idArea + WHERE co.X > 0 AND dp.idmessage_group>0 AND length(dp.unit)> 0 AND length(dp.value)> 0 + `, (error, results) => { + if (error) { + console.error("Fehler beim Abrufen der gis_lines:", error); + return res + .status(500) + .json({ error: "Fehler beim Abrufen der gis_lines" }); + } + + const response = { + "Name": "Liste aller Messungen der Geraete", + "Zeitstempel": new Date().toISOString(), + "IdMap":idMap, + "Statis": results.map((row) => ({ + IdLD: row.idLD, + IdDP: row.idDP, + Na: row.Na, + Val: row.Val, + Unit: row.Unit, + Gr: row.Gr, + IdLocation: row.IdLocation, + Area_Name: row.Area_Name, + })), + }; + + res.json(response); + }); +} \ No newline at end of file diff --git a/pages/api back30/talas_v5_DB/gisLines/readGisLines.js b/pages/api back30/talas_v5_DB/gisLines/readGisLines.js new file mode 100644 index 000000000..7d8900a83 --- /dev/null +++ b/pages/api back30/talas_v5_DB/gisLines/readGisLines.js @@ -0,0 +1,37 @@ +// /pages/api/talas_v5_DB/gisLines/readGisLines.js +import mysql from "mysql"; + +const dbConfig = { + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + port: process.env.DB_PORT, +}; + +const connection = mysql.createConnection(dbConfig); +connection.connect((err) => { + if (err) { + console.error("Fehler beim Verbinden:", err.stack); + return; + } + //console.log("Database connected successfully."); +}); + +export default function handler(req, res) { + if (req.method !== "GET") { + return res.status(405).json({ error: "Nur GET Methode erlaubt" }); + } + const query = "SELECT * FROM talas_v5.gis_lines;"; + connection.query(query, (error, results) => { + if (error) { + console.error("Fehler beim Abrufen der gis_lines:", error); + return res.status(500).json({ error: "Fehler beim Abrufen der gis_lines" }); + } + if (results.length > 0) { + res.json(results); + } else { + res.status(404).json({ error: "Gerät nicht gefunden" }); + } + }); +} diff --git a/pages/api back30/talas_v5_DB/gisLines/updateLineCoordinates.js b/pages/api back30/talas_v5_DB/gisLines/updateLineCoordinates.js new file mode 100644 index 000000000..48dfa36bc --- /dev/null +++ b/pages/api back30/talas_v5_DB/gisLines/updateLineCoordinates.js @@ -0,0 +1,61 @@ +// /pages/api/talas_v5_DB/gisLines/updateLineCoordinates.js +import mysql from "mysql"; + +const dbConfig = { + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + port: process.env.DB_PORT, +}; + +const connection = mysql.createConnection(dbConfig); +connection.connect((err) => { + if (err) { + console.error("Fehler beim Verbinden:", err.stack); + return; + } + //console.log("Database connected successfully."); +}); + +export default function handler(req, res) { + if (req.method !== "POST") { + return res.status(405).json({ error: "Nur POST Methode erlaubt" }); + } + + const { idLD, idModul, newCoordinates } = req.body; + if (!idLD || !idModul || !newCoordinates) { + return res.status(400).json({ error: "Fehlende Daten" }); + } + + const newLineString = `LINESTRING(${newCoordinates.map((coord) => `${coord[0]} ${coord[1]}`).join(",")})`; + + const query = "UPDATE talas_v5.gis_lines SET points = ST_GeomFromText(?) WHERE idLD = ? AND idModul = ?;"; + + connection.beginTransaction((err) => { + if (err) { + throw err; + } + connection.query(query, [newLineString, idLD, idModul], (error, results, fields) => { + if (error) { + return connection.rollback(() => { + console.error("Fehler beim Aktualisieren der gis_lines:", error); + res.status(500).json({ error: "Fehler beim Aktualisieren der gis_lines" }); + }); + } + + connection.commit((err) => { + if (err) { + return connection.rollback(() => { + throw err; + }); + } + console.log("Transaction Complete."); + res.status(200).json({ + success: "Updated successfully.", + affectedRows: results.affectedRows, + }); + }); + }); + }); +} diff --git a/pages/api back30/talas_v5_DB/locationDevice/getDeviceId.js b/pages/api back30/talas_v5_DB/locationDevice/getDeviceId.js new file mode 100644 index 000000000..fa373c80c --- /dev/null +++ b/pages/api back30/talas_v5_DB/locationDevice/getDeviceId.js @@ -0,0 +1,40 @@ +// API in /api/talas_v5_DB/locationDevice/getDeviceId.js +import mysql from "mysql"; + +const dbConfig = { + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + port: process.env.DB_PORT, +}; + +const connection = mysql.createConnection(dbConfig); +connection.connect((err) => { + if (err) { + console.error("Fehler beim Verbinden:", err.stack); + return; + } +}); + +export default function handler(req, res) { + if (req.method !== "GET") { + return res.status(405).json({ error: "Nur GET Methode erlaubt" }); + } + const { deviceName } = req.query; + + const query = "SELECT idLD FROM location_device WHERE name = ?"; + connection.query(query, [deviceName], (error, results) => { + if (error) { + console.error("Fehler beim Abrufen der Geräte-ID:", error); + return res + .status(500) + .json({ error: "Fehler beim Abrufen der Geräte-ID" }); + } + if (results.length > 0) { + res.json({ idLD: results[0].idLD }); + } else { + res.status(404).json({ error: "Gerät nicht gefunden" }); + } + }); +} diff --git a/pages/api back30/talas_v5_DB/locationDevice/locationDeviceNameById.js b/pages/api back30/talas_v5_DB/locationDevice/locationDeviceNameById.js new file mode 100644 index 000000000..efccd89d9 --- /dev/null +++ b/pages/api back30/talas_v5_DB/locationDevice/locationDeviceNameById.js @@ -0,0 +1,46 @@ +// API in /api/talas_v5_DB/locationDevice/locationDeviceNameById.js +import mysql from "mysql"; + +const dbConfig = { + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + port: process.env.DB_PORT, +}; + +const connection = mysql.createConnection(dbConfig); +connection.connect((err) => { + if (err) { + console.error("Fehler beim Verbinden:", err.stack); + return; + } +}); + +export default async function handler(req, res) { + if (req.method !== "GET") { + return res.status(405).json({ error: "Nur GET Methode erlaubt" }); + } + const { idLD } = req.query; + + try { + const query = "SELECT name FROM location_device WHERE idLD = ?"; + const [results] = await new Promise((resolve, reject) => { + connection.query(query, [idLD], (error, results) => { + if (error) { + return reject(error); + } + resolve(results); + }); + }); + + if (results.length > 0) { + res.json({ name: results[0].name }); + } else { + res.status(404).json({ error: "Gerät nicht gefunden", idLD, results }); + } + } catch (error) { + console.error("Fehler beim Abrufen des Gerätenamens in locationDeviceNameById.js :", error); + res.status(500).json({ error: "Fehler beim Abrufen des Gerätenamens" }); + } +} diff --git a/pages/api back30/talas_v5_DB/locationDevice/locationDevices.js b/pages/api back30/talas_v5_DB/locationDevice/locationDevices.js new file mode 100644 index 000000000..bfaf57654 --- /dev/null +++ b/pages/api back30/talas_v5_DB/locationDevice/locationDevices.js @@ -0,0 +1,35 @@ +// API in /api/talas_v5_DB/locationDevice/locationDevices.js +import mysql from "mysql"; + +const dbConfig = { + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + port: process.env.DB_PORT, +}; + +const connection = mysql.createConnection(dbConfig); +connection.connect((err) => { + if (err) { + console.error("Fehler beim Verbinden:", err.stack); + return; + } +}); + +export default function handler(req, res) { + if (req.method !== "GET") { + return res.status(405).json({ error: "Nur GET Methode erlaubt" }); + } + + const query = "SELECT * FROM location_device WHERE iddevice = 160"; + connection.query(query, (error, results) => { + if (error) { + console.error("Fehler beim Abrufen der Geräteinformationen:", error); + return res + .status(500) + .json({ error: "Fehler beim Abrufen der Geräteinformationen" }); + } + res.json(results); + }); +} diff --git a/pages/api back30/talas_v5_DB/poiTyp/readPoiTyp.js b/pages/api back30/talas_v5_DB/poiTyp/readPoiTyp.js new file mode 100644 index 000000000..062c442cd --- /dev/null +++ b/pages/api back30/talas_v5_DB/poiTyp/readPoiTyp.js @@ -0,0 +1,33 @@ +// pages/api/talas_v5_DB/poiTyp/readPoiTyp.js +import mysql from "mysql"; + +const pool = mysql.createPool({ + //connectionLimit: 10, + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + port: process.env.DB_PORT, +}); + +export default function handler(req, res) { + if (req.method === "GET") { + const query = "SELECT * FROM poityp"; + + pool.query(query, (error, results) => { + if (error) { + console.error("Fehler beim Abfragen der Datenbank:", error); + return res.status(500).json({ error: "Ein Fehler ist aufgetreten" }); + } + + if (results.length === 0) { + return res.status(404).json({ message: "Keine Einträge gefunden" }); + } + + res.status(200).json(results); + }); + } else { + res.setHeader("Allow", ["GET"]); + res.status(405).end(`Method ${req.method} Not Allowed`); + } +} diff --git a/pages/api back30/talas_v5_DB/pois/addLocation.js b/pages/api back30/talas_v5_DB/pois/addLocation.js new file mode 100644 index 000000000..118704d7d --- /dev/null +++ b/pages/api back30/talas_v5_DB/pois/addLocation.js @@ -0,0 +1,38 @@ +// pages/api/talas_v5_DB/pois/addLocation.js +import mysql from "mysql"; + +const dbConfig = { + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + port: process.env.DB_PORT, +}; + +export default function handler(req, res) { + if (req.method === "POST") { + const { name, poiTypeId, latitude, longitude, idLD } = req.body; + console.log("Received data:", req.body); // Überprüfen der empfangenen Daten + const connection = mysql.createConnection(dbConfig); + + const query = + "INSERT INTO poi (description, idPoiTyp, position, idLD) VALUES (?, ?, ST_GeomFromText(?),?)"; + const point = `POINT(${longitude} ${latitude})`; + const values = [name, poiTypeId, point, idLD]; // Stellen Sie sicher, dass poiTypeId korrekt ist + + connection.query(query, values, (error, results) => { + connection.end(); + if (error) { + console.error("Fehler beim Einfügen des Standorts:", error); + return res.status(500).json({ error: "Ein Fehler ist aufgetreten" }); + } + res.status(200).json({ + id: results.insertId, + message: "Standort erfolgreich hinzugefügt", + }); + }); + } else { + res.setHeader("Allow", ["POST"]); + res.status(405).end(`Method ${req.method} Not Allowed`); + } +} diff --git a/pages/api back30/talas_v5_DB/pois/deletePoi.js b/pages/api back30/talas_v5_DB/pois/deletePoi.js new file mode 100644 index 000000000..ca1cc77a0 --- /dev/null +++ b/pages/api back30/talas_v5_DB/pois/deletePoi.js @@ -0,0 +1,45 @@ +// pages/api/talas_v5_DB/pois/deletePoi.js +import mysql from "mysql"; + +// Datenbankkonfiguration +const dbConfig = { + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + port: process.env.DB_PORT, +}; + +const connection = mysql.createConnection(dbConfig); +connection.connect((err) => { + if (err) { + console.error("Fehler beim Verbinden:", err.stack); + return; + } + console.log("Verbunden als ID", connection.threadId); +}); + +export default function handler(req, res) { + if (req.method !== "DELETE") { + return res.status(405).json({ error: "Nur DELETE Methode erlaubt" }); + } + + const { id } = req.query; // ID aus der Anfrage holen + + if (!id) { + return res.status(400).json({ error: "POI ID ist erforderlich" }); + } + + const query = "DELETE FROM poi WHERE idPoi = ?"; + connection.query(query, [id], (error, results) => { + if (error) { + console.error("Fehler beim Löschen des POI:", error); + return res.status(500).json({ error: "Fehler beim Löschen des POI" }); + } + if (results.affectedRows > 0) { + res.json({ message: "POI erfolgreich gelöscht" }); + } else { + res.status(404).json({ error: "POI nicht gefunden" }); + } + }); +} diff --git a/pages/api back30/talas_v5_DB/pois/getPoiById.js b/pages/api back30/talas_v5_DB/pois/getPoiById.js new file mode 100644 index 000000000..4ebf5b62c --- /dev/null +++ b/pages/api back30/talas_v5_DB/pois/getPoiById.js @@ -0,0 +1,42 @@ +// pages/api/talas_v5_DB/pois/getPoiById.js +import mysql from "mysql"; + +const dbConfig = { + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + port: process.env.DB_PORT, +}; + +export default function handler(req, res) { + if (req.method === "GET") { + const { idPoi } = req.query; + const connection = mysql.createConnection(dbConfig); + + connection.connect((err) => { + if (err) { + console.error("Fehler beim Verbinden:", err.stack); + return res + .status(500) + .json({ error: "Verbindungsfehler zur Datenbank" }); + } + + const query = "SELECT description FROM poi WHERE idPoi = ?"; + connection.query(query, [idPoi], (error, results) => { + connection.end(); + if (error) { + console.error("Fehler bei der Abfrage:", error); + return res.status(500).json({ error: "Fehler bei der Abfrage" }); + } + if (results.length === 0) { + return res.status(404).json({ error: "POI nicht gefunden" }); + } + res.status(200).json(results[0]); + }); + }); + } else { + res.setHeader("Allow", ["GET"]); + res.status(405).end(`Method ${req.method} Not Allowed`); + } +} diff --git a/pages/api back30/talas_v5_DB/pois/poi-icons.js b/pages/api back30/talas_v5_DB/pois/poi-icons.js new file mode 100644 index 000000000..ee092c226 --- /dev/null +++ b/pages/api back30/talas_v5_DB/pois/poi-icons.js @@ -0,0 +1,42 @@ +// pages/api/talas_v5_DB/pois/poi-icons.js +import mysql from "mysql"; + +const dbConfig = { + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + port: process.env.DB_PORT, +}; + +const connection = mysql.createConnection(dbConfig); + +connection.connect((err) => { + if (err) { + console.error("Fehler beim Verbinden:", err.stack); + return; + } +}); + +export default function handler(req, res) { + if (req.method !== "GET") { + return res.status(405).json({ error: "Nur GET Methode erlaubt" }); + } + + const query = `SELECT p.idPoi, i.path + FROM poi p + JOIN poiTyp pt ON p.idPoiTyp = pt.idPoiTyp + JOIN poiicons i ON pt.icon = i.idpoiicons;`; + + connection.query(query, (error, results) => { + try { + if (error) { + throw error; + } + res.json(results); + } catch (err) { + console.error("Fehler beim Abrufen der icons:", err); + res.status(500).json({ error: "Fehler beim Abrufen der icons" }); + } + }); +} diff --git a/pages/api back30/talas_v5_DB/pois/readLocations.js b/pages/api back30/talas_v5_DB/pois/readLocations.js new file mode 100644 index 000000000..98a33cc88 --- /dev/null +++ b/pages/api back30/talas_v5_DB/pois/readLocations.js @@ -0,0 +1,42 @@ +// pages/api/talas_v5_DB/pois/readLocations.js +import mysql from "mysql"; + +const dbConfig = { + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + port: process.env.DB_PORT, +}; +//console.log("my dbconfig: ", dbConfig); +export default function handler(req, res) { + const connection = mysql.createConnection(dbConfig); + + connection.connect((err) => { + if (err) { + console.error("Fehler beim Verbinden:", err.stack); + res.status(500).json({ error: "Verbindungsfehler zur Datenbank" }); + return; + } + + //console.log("Verbunden als ID", connection.threadId); + + connection.query("SELECT idPoi, description, idPoiTyp, idLD, ST_AsText(position) AS position FROM poi", (error, results) => { + if (error) { + console.error("Fehler beim Abrufen der API", error); + res.status(500).json({ error: "Fehler bei der Abfrage" }); + return; + } + + // Wichtig: Senden Sie die Antwort zurück + res.status(200).json(results); + /* console.log( + "--------------- location.js ---------------", + "results in location.js : ", + results, + "---------------------- location.js end ---------------------------" + ); */ + connection.end(); + }); + }); +} diff --git a/pages/api back30/talas_v5_DB/pois/updateLocation.js b/pages/api back30/talas_v5_DB/pois/updateLocation.js new file mode 100644 index 000000000..625be5a75 --- /dev/null +++ b/pages/api back30/talas_v5_DB/pois/updateLocation.js @@ -0,0 +1,39 @@ +// pages/api/talas_v5_DB/pois/updateLocation.js +import mysql from "mysql"; +import util from "util"; + +const dbConfig = { + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + port: process.env.DB_PORT, + charset: "utf8mb4", +}; + +export default async function handler(req, res) { + if (req.method !== "POST") { + res.setHeader("Allow", ["POST"]); + return res.status(405).end(`Method ${req.method} Not Allowed`); + } + + const { id, latitude, longitude } = req.body; + + const connection = mysql.createConnection(dbConfig); + // Promisify the query method + const query = util.promisify(connection.query).bind(connection); + + try { + await query("UPDATE poi SET position = POINT(?, ?) WHERE idPoi = ?", [ + longitude, + latitude, + id, + ]); + res.status(200).json({ success: true }); + } catch (error) { + console.error(error); + res.status(500).json({ error: "Ein Fehler ist aufgetreten" }); + } finally { + connection.end(); + } +} diff --git a/pages/api back30/talas_v5_DB/pois/updatePoi.js b/pages/api back30/talas_v5_DB/pois/updatePoi.js new file mode 100644 index 000000000..0eb9eeed3 --- /dev/null +++ b/pages/api back30/talas_v5_DB/pois/updatePoi.js @@ -0,0 +1,46 @@ +// pages/api/talas_v5_DB/pois/updatePoi.js +import mysql from "mysql"; + +const dbConfig = { + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + port: process.env.DB_PORT, +}; + +const connection = mysql.createConnection(dbConfig); +connection.connect((err) => { + if (err) { + console.error("Fehler beim Verbinden:", err.stack); + return; + } + //console.log("Verbunden als ID", connection.threadId); +}); + +export default function handler(req, res) { + if (req.method !== "POST") { + return res.status(405).json({ error: "Nur POST Methode erlaubt" }); + } + + const { idPoi, description, idPoiTyp, idLD } = req.body; // Stellen Sie sicher, dass die Felder korrekt benannt sind + + //console.log("Empfangene Daten:", req.body); // Loggen der empfangenen Daten zur Überprüfung + + if (!idPoi) { + return res.status(400).json({ error: "POI ID ist erforderlich" }); + } + + const query = "UPDATE talas_v5.poi SET description = ?, idPoiTyp = ?, idLD = ? WHERE idPoi = ?"; + connection.query(query, [description, idPoiTyp, idLD, idPoi], (error, results) => { + if (error) { + console.error("Fehler beim Aktualisieren des POI:", error); + return res.status(500).json({ error: "Fehler beim Aktualisieren des POI" }); + } + if (results.affectedRows > 0) { + res.json({ message: "POI erfolgreich aktualisiert" }); + } else { + res.status(404).json({ error: "POI nicht gefunden" }); + } + }); +} diff --git a/pages/api back30/talas_v5_DB/priorityConfig.js b/pages/api back30/talas_v5_DB/priorityConfig.js new file mode 100644 index 000000000..06bfefe3d --- /dev/null +++ b/pages/api back30/talas_v5_DB/priorityConfig.js @@ -0,0 +1,40 @@ +// pages/api/talas_v5_DB/priorityConfig.js +// in tals5 http://10.10.0.13/talas5/Management/PriorityConfig.aspx beinhaltet die Tabelle prio die Prioritäten der Meldungen (Level 1-4) oder (0-4) je nachdem DB-Design +// das ist die API, die die Prioritäten zurückgibt + +import mysql from "mysql"; + +const dbConfig = { + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + port: process.env.DB_PORT, +}; +//console.log("my dbconfig: ", dbConfig); +export default function handler(req, res) { + const connection = mysql.createConnection(dbConfig); + + connection.connect((err) => { + if (err) { + console.error("Fehler beim Verbinden:", err.stack); + res.status(500).json({ error: "Verbindungsfehler zur Datenbank" }); + return; + } + + //console.log("Verbunden als ID", connection.threadId); + //Fehler weil, existiertdie Tabelle auf localhost:3000 nicht + connection.query("SELECT idprio, level, name, color FROM prio ", (error, results) => { + if (error) { + console.error("Fehler beim Abrufen der API", error); + res.status(500).json({ error: "Fehler bei der Abfrage" }); + return; + } + + // Wichtig: Senden Sie die Antwort zurück + res.status(200).json(results); + + connection.end(); + }); + }); +} diff --git a/pages/api/[...path].js b/pages/api/[...path].js index febda1fa8..b270661b1 100644 --- a/pages/api/[...path].js +++ b/pages/api/[...path].js @@ -1,11 +1,14 @@ // pages/api/[...path].js import { createProxyMiddleware } from "http-proxy-middleware"; +//import { SERVER_URL } from "../config/urls.js"; +//console.log("SERVER_URL:", SERVER_URL); // Debug-Ausgabe export default createProxyMiddleware({ //target: "http://192.168.10.58:3001", // Stationen bekommen - target: "http://10.10.0.13", // Ziel-URL des Proxys // API Aufruf zum mapGisStationsStaticDistrictUrl, mapGisStationsStatusDistrictUrl, mapGisStationsMeasurementsUrl, mapGisSystemStaticUrl und mapDataIconUrl - + //target: "http://10.10.0.13", // Ziel-URL des Proxys // API Aufruf zum mapGisStationsStaticDistrictUrl, mapGisStationsStatusDistrictUrl, mapGisStationsMeasurementsUrl, mapGisSystemStaticUrl und mapDataIconUrl + target: `${process.env.NEXT_PUBLIC_SERVER_URL}`, // + //target: urls.PROXY_TARGET, //target: "http://localhost:3000", // Ziel-URL des Proxys //target: "http://192.168.10.187:3000", // Ziel-URL des Proxys //target: "http://192.168.10.14", diff --git a/pages/api/gis-proxy.js b/pages/api/gis-proxy.js new file mode 100644 index 000000000..b76883298 --- /dev/null +++ b/pages/api/gis-proxy.js @@ -0,0 +1,34 @@ +// /pages/api/gis-proxy.js +// Importieren der erforderlichen Module +import httpProxy from "http-proxy"; +import Cookies from "cookies"; + +// Erstellen eines Proxy-Servers +const proxy = httpProxy.createProxyServer(); + +export default (req, res) => { + return new Promise((resolve) => { + // CORS-Headers einstellen + res.setHeader("Access-Control-Allow-Credentials", true); + res.setHeader("Access-Control-Allow-Origin", "*"); + + // Cookies initialisieren + const cookies = new Cookies(req, res); + const targetUrl = `${process.env.NEXT_PUBLIC_SERVER_URL}/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic`; + + // Proxy-Konfiguration und Event-Listener + req.on("data", () => {}); + req.on("end", () => { + proxy.web(req, res, { target: targetUrl, changeOrigin: true, selfHandleResponse: false }, (e) => { + if (e) { + console.error(e); + res.status(500).json({ error: "Proxy-Fehler", e }); + } + resolve(); + }); + }); + + // Weiterleitung der Headers + req.headers.cookie = cookies.get("cookie-name") || ""; + }); +}; diff --git a/pages/api/linesColorApi.js b/pages/api/linesColorApi.js index 353c8527a..57ee59262 100644 --- a/pages/api/linesColorApi.js +++ b/pages/api/linesColorApi.js @@ -2,13 +2,24 @@ // http://10.10.0.13/talas5/ClientData/WebServiceMap.asmx/GisStationsStatusDistrict //In DB gis_lines idLD und idModul anpassen entsprechend -export default function handler(req, res) { +// /pages/api/linesColorApi.js +import NextCors from "nextjs-cors"; + +export default async function handler(req, res) { + // Run the cors middleware + await NextCors(req, res, { + // Options + methods: ["GET", "HEAD", "PUT", "PATCH", "POST", "DELETE"], + origin: "*", // Erlauben Sie alle Ursprünge, oder geben Sie spezifische Ursprünge an + optionsSuccessStatus: 200, // Legacy-Browser-Unterstützung für 204 + }); + const response = { Name: "Liste aller Statis der Linien", Zeitstempel: new Date().toISOString(), // Aktuellen Zeitstempel hinzufügen IdMap: "10", Statis: [ - { + /* { IdLD: 50922, Modul: 1, DpName: "KUE01_Ausfall", @@ -19,7 +30,7 @@ export default function handler(req, res) { Level: 4, PrioColor: "#FFFF00", PrioName: "system", - Value: "?", + Value: "10 MOhm", }, { IdLD: 25440, @@ -32,7 +43,7 @@ export default function handler(req, res) { Level: 4, PrioColor: "#FF0000", PrioName: "system", - Value: "?", + Value: "10 MOhm", }, { IdLD: 25440, @@ -44,8 +55,8 @@ export default function handler(req, res) { Level: 4, PrioColor: "#FF00FF", PrioName: "system", - Value: "?", - }, + Value: "10 MOhm", + }, */ ], }; diff --git a/pages/api/talas5/area.js b/pages/api/talas5/area.js index fac90b0da..9205aa5ca 100644 --- a/pages/api/talas5/area.js +++ b/pages/api/talas5/area.js @@ -11,7 +11,7 @@ const dbConfig = { database: process.env.DB_NAME, port: process.env.DB_PORT, }; -console.log("my dbconfig: ", dbConfig); +//console.log("my dbconfig: ", dbConfig); export default function handler(req, res) { const connection = mysql.createConnection(dbConfig); @@ -22,22 +22,19 @@ export default function handler(req, res) { return; } - console.log("Verbunden als ID", connection.threadId); + //console.log("Verbunden als ID", connection.threadId); //Fehler weil, existiertdie Tabelle auf localhost:3000 nicht - connection.query( - "SELECT ..., ..., ..., ... FROM ... WHERE ... = ...", - (error, results) => { - if (error) { - console.error("Fehler beim Abrufen der API", error); - res.status(500).json({ error: "Fehler bei der Abfrage" }); - return; - } - - // Wichtig: Senden Sie die Antwort zurück - res.status(200).json(results); - - connection.end(); + connection.query("SELECT ..., ..., ..., ... FROM ... WHERE ... = ...", (error, results) => { + if (error) { + console.error("Fehler beim Abrufen der API", error); + res.status(500).json({ error: "Fehler bei der Abfrage" }); + return; } - ); + + // Wichtig: Senden Sie die Antwort zurück + res.status(200).json(results); + + connection.end(); + }); }); } diff --git a/pages/api/talas5/location_device.js b/pages/api/talas5/location_device.js index 8a41f779e..9292690e0 100644 --- a/pages/api/talas5/location_device.js +++ b/pages/api/talas5/location_device.js @@ -1,42 +1,42 @@ -// pages/api/talas_v5/location_device.js -// talas_v5 Datenbank -> location_device Tabelle enthält DAUZ Geräte +// Importieren des mysql2 Pakets +import mysql from "mysql2"; -import mysql from "mysql"; - -const dbConfig = { +// Erstellen eines Pools von Datenbankverbindungen +const pool = mysql.createPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, port: process.env.DB_PORT, -}; -console.log("my dbconfig: ", dbConfig); -export default function handler(req, res) { - const connection = mysql.createConnection(dbConfig); + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0, +}); - connection.connect((err) => { - if (err) { - console.error("Fehler beim Verbinden:", err.stack); - res.status(500).json({ error: "Verbindungsfehler zur Datenbank" }); - return; - } - - console.log("Verbunden als ID", connection.threadId); - //Fehler weil, existiertdie Tabelle auf localhost:3000 nicht - connection.query( - "SELECT idLD, iddevice, iddevice, name FROM location_device WHERE iddevice = 160", - (error, results) => { - if (error) { - console.error("Fehler beim Abrufen der API", error); - res.status(500).json({ error: "Fehler bei der Abfrage" }); - return; - } - - // Wichtig: Senden Sie die Antwort zurück - res.status(200).json(results); - - connection.end(); +// Ein Hilfsfunktion, um Anfragen zu vereinfachen +function queryDatabase(query, params) { + return new Promise((resolve, reject) => { + pool.query(query, params, (error, results) => { + if (error) { + return reject(error); } - ); + resolve(results); + }); }); } + +// API-Handler +export default async function handler(req, res) { + try { + // Dein SQL-Query und die Parameter + const sql = "SELECT idLD, iddevice, name FROM location_device WHERE iddevice = ?"; + const params = [160]; // Beispielparameter + + // Ausführen der Datenbankabfrage + const results = await queryDatabase(sql, params); + res.status(200).json(results); + } catch (error) { + console.error("Fehler beim Abrufen der API", error); + res.status(500).json({ error: "Fehler bei der Abfrage" }); + } +} diff --git a/pages/api/talas5/webserviceMap/GisStationsStatusDistrict.js b/pages/api/talas5/webserviceMap/GisStationsStatusDistrict.js index 9d0f2024c..ae7c25bde 100644 --- a/pages/api/talas5/webserviceMap/GisStationsStatusDistrict.js +++ b/pages/api/talas5/webserviceMap/GisStationsStatusDistrict.js @@ -1,47 +1,42 @@ +// /pages/api/talas5/webserviceMap/gisStationsMeasurementsSQL.js import mysql from "mysql2/promise"; -const dbConfig = { +// Erstellen eines Verbindungspools anstelle einer einzelnen Verbindung +const pool = mysql.createPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, port: process.env.DB_PORT, -}; + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0, +}); export default async function handler(req, res) { const { idMap, idUser } = req.query; if (!idMap || !idUser) { - res.status(400).json({ error: "idMap and idUser are required" }); - return; + return res.status(400).json({ error: "idMap and idUser are required" }); } - let connection; try { - connection = await mysql.createConnection(dbConfig); - let onlySystem = -1; let districtCounter = 0; // Get onlySystem - const [mapResult] = await connection.execute( - "SELECT idsystem_typ FROM maps WHERE id = ?", - [idMap] - ); + const [mapResult] = await pool.query("SELECT idsystem_typ FROM maps WHERE id = ?", [idMap]); if (mapResult.length > 0) { onlySystem = mapResult[0].idsystem_typ ?? -1; } // Get districtCounter if (idUser > 0) { - const [userLayerResult] = await connection.execute( - "SELECT count(*) as count FROM user_User_layer1 WHERE iduser = ?", - [idUser] - ); + const [userLayerResult] = await pool.query("SELECT count(*) as count FROM user_User_layer1 WHERE iduser = ?", [idUser]); districtCounter = userLayerResult[0].count; } - // Get GisStatusStations + // Building the query let query = ` SELECT ld.idLD, dc.message, p.level, p.name, p.color, ld.idDevice, de.isService, dc.idIcon FROM location as l @@ -55,25 +50,18 @@ export default async function handler(req, res) { WHERE p.level < 100 AND co.X > 0 `; - if (districtCounter > 0) { - query += ` AND a.iddistrict IN (SELECT iddistrict FROM user_user_layer1 WHERE iduser = ?)`; - } - - if (onlySystem >= 0) { - query += ` AND de.idsystem_typ = ?`; - } - - query += ` ORDER BY p.level desc`; - const queryParams = [idMap]; if (districtCounter > 0) { + query += ` AND a.iddistrict IN (SELECT iddistrict FROM user_user_layer1 WHERE iduser = ?)`; queryParams.push(idUser); } if (onlySystem >= 0) { + query += ` AND de.idsystem_typ = ?`; queryParams.push(onlySystem); } + query += ` ORDER BY p.level desc`; - const [results] = await connection.execute(query, queryParams); + const [results] = await pool.query(query, queryParams); const mpss = { IdMap: idMap.toString(), @@ -92,9 +80,5 @@ export default async function handler(req, res) { } catch (error) { console.error("Fehler beim Laden der Daten:", error); res.status(500).json({ error: "Interner Serverfehler" }); - } finally { - if (connection) { - await connection.end(); - } } } diff --git a/pages/api/talas5/webserviceMap/gisStationsMeasurementsSQL.js b/pages/api/talas5/webserviceMap/gisStationsMeasurementsSQL.js index de3670b6d..90c535086 100644 --- a/pages/api/talas5/webserviceMap/gisStationsMeasurementsSQL.js +++ b/pages/api/talas5/webserviceMap/gisStationsMeasurementsSQL.js @@ -1,20 +1,24 @@ -import mysql from "mysql"; +// /pages/api/talas5/webserviceMap/gisStationsMeasurementsSQL.js +import mysql from "mysql2"; -const dbConfig = { +// Erstellen eines Pools von Datenbankverbindungen +const pool = mysql.createPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, port: process.env.DB_PORT, -}; + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0, +}); -const connection = mysql.createConnection(dbConfig); -connection.connect((err) => { - if (err) { - console.error("Fehler beim Verbinden:", err.stack); - return; - } - console.log("Database connected successfully."); +pool.on("connection", function (connection) { + console.log("Database connected successfully."); +}); + +pool.on("error", function (err) { + console.error("Fehler beim Verbinden:", err); }); export default function handler(req, res) { @@ -23,7 +27,7 @@ export default function handler(req, res) { return res.status(405).json({ error: "Nur GET Methode erlaubt" }); } - connection.query(` + const sqlQuery = ` SELECT ld.idLD, dp.idDP, @@ -34,37 +38,37 @@ export default function handler(req, res) { ld.idLocation, area.Name AS Area_Name FROM location_device as ld - LEFT JOIN location_coordinates AS co ON ld.idLocation = co.idLocation and co.idMaps = ${idMap} + LEFT JOIN location_coordinates AS co ON ld.idLocation = co.idLocation and co.idMaps = ? LEFT JOIN devices AS de ON de.idDevice = ld.idDevice LEFT JOIN datapoint AS dp ON ld.idLD = dp.idLD LEFT JOIN message_group AS mg ON dp.idmessage_group = mg.idmessage_group LEFT JOIN location AS loc ON ld.idLocation = loc.idLocation LEFT JOIN area AS area ON loc.idArea = area.idArea WHERE co.X > 0 AND dp.idmessage_group>0 AND length(dp.unit)> 0 AND length(dp.value)> 0 - `, (error, results) => { + `; + + pool.query(sqlQuery, [idMap], (error, results) => { if (error) { console.error("Fehler beim Abrufen der gis_lines:", error); - return res - .status(500) - .json({ error: "Fehler beim Abrufen der gis_lines" }); + return res.status(500).json({ error: "Fehler beim Abrufen der gis_lines" }); } const response = { - "Name": "Liste aller Messungen der Geraete", - "Zeitstempel": new Date().toISOString(), - "IdMap":idMap, - "Statis": results.map((row) => ({ + Name: "Liste aller Messungen der Geraete", + Zeitstempel: new Date().toISOString(), + IdMap: idMap, + Statis: results.map((row) => ({ IdLD: row.idLD, IdDP: row.idDP, Na: row.Na, Val: row.Val, Unit: row.Unit, Gr: row.Gr, - IdLocation: row.IdLocation, + IdLocation: row.idLocation, Area_Name: row.Area_Name, })), }; res.json(response); }); -} \ No newline at end of file +} diff --git a/pages/api/talas_v5_DB/gisLines/readGisLines.js b/pages/api/talas_v5_DB/gisLines/readGisLines.js index 709feeb2d..d734ed011 100644 --- a/pages/api/talas_v5_DB/gisLines/readGisLines.js +++ b/pages/api/talas_v5_DB/gisLines/readGisLines.js @@ -1,39 +1,34 @@ // /pages/api/talas_v5_DB/gisLines/readGisLines.js -import mysql from "mysql"; +import mysql from "mysql2/promise"; -const dbConfig = { +// Erstellen eines Pools von Datenbankverbindungen +const pool = mysql.createPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, port: process.env.DB_PORT, -}; - -const connection = mysql.createConnection(dbConfig); -connection.connect((err) => { - if (err) { - console.error("Fehler beim Verbinden:", err.stack); - return; - } - console.log("Database connected successfully."); + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0, }); -export default function handler(req, res) { +export default async function handler(req, res) { if (req.method !== "GET") { return res.status(405).json({ error: "Nur GET Methode erlaubt" }); } + const query = "SELECT * FROM talas_v5.gis_lines;"; - connection.query(query, (error, results) => { - if (error) { - console.error("Fehler beim Abrufen der gis_lines:", error); - return res - .status(500) - .json({ error: "Fehler beim Abrufen der gis_lines" }); - } + + try { + const [results] = await pool.query(query); if (results.length > 0) { - res.json(results); + res.status(200).json(results); } else { res.status(404).json({ error: "Gerät nicht gefunden" }); } - }); + } catch (error) { + console.error("Fehler beim Abrufen der gis_lines:", error); + res.status(500).json({ error: "Fehler beim Abrufen der gis_lines" }); + } } diff --git a/pages/api/talas_v5_DB/gisLines/updateLineCoordinates.js b/pages/api/talas_v5_DB/gisLines/updateLineCoordinates.js index d6fa5179f..4271160a0 100644 --- a/pages/api/talas_v5_DB/gisLines/updateLineCoordinates.js +++ b/pages/api/talas_v5_DB/gisLines/updateLineCoordinates.js @@ -1,24 +1,18 @@ -// /pages/api/talas_v5_DB/gisLines/updateLineCoordinates.js -import mysql from "mysql"; +import mysql from "mysql2/promise"; -const dbConfig = { +// Erstellen eines Pools von Datenbankverbindungen +const pool = mysql.createPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, port: process.env.DB_PORT, -}; - -const connection = mysql.createConnection(dbConfig); -connection.connect((err) => { - if (err) { - console.error("Fehler beim Verbinden:", err.stack); - return; - } - console.log("Database connected successfully."); + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0, }); -export default function handler(req, res) { +export default async function handler(req, res) { if (req.method !== "POST") { return res.status(405).json({ error: "Nur POST Methode erlaubt" }); } @@ -30,39 +24,35 @@ export default function handler(req, res) { const newLineString = `LINESTRING(${newCoordinates.map((coord) => `${coord[0]} ${coord[1]}`).join(",")})`; - const query = - "UPDATE talas_v5.gis_lines SET points = ST_GeomFromText(?) WHERE idLD = ? AND idModul = ?;"; + const query = "UPDATE talas_v5.gis_lines SET points = ST_GeomFromText(?) WHERE idLD = ? AND idModul = ?;"; - connection.beginTransaction((err) => { - if (err) { - throw err; - } - connection.query( - query, - [newLineString, idLD, idModul], - (error, results, fields) => { - if (error) { - return connection.rollback(() => { - console.error("Fehler beim Aktualisieren der gis_lines:", error); - res - .status(500) - .json({ error: "Fehler beim Aktualisieren der gis_lines" }); - }); - } + let connection; - connection.commit((err) => { - if (err) { - return connection.rollback(() => { - throw err; - }); - } - console.log("Transaction Complete."); - res.status(200).json({ - success: "Updated successfully.", - affectedRows: results.affectedRows, - }); - }); - } - ); - }); + try { + // Hole eine Verbindung aus dem Pool + connection = await pool.getConnection(); + + // Beginne eine Transaktion + await connection.beginTransaction(); + + // Führe die Abfrage aus + const [results] = await connection.query(query, [newLineString, idLD, idModul]); + + // Commit der Transaktion + await connection.commit(); + + console.log("Transaction Complete."); + res.status(200).json({ + success: "Updated successfully.", + affectedRows: results.affectedRows, + }); + } catch (error) { + // Rollback im Falle eines Fehlers + if (connection) await connection.rollback(); + console.error("Fehler beim Aktualisieren der gis_lines:", error); + res.status(500).json({ error: "Fehler beim Aktualisieren der gis_lines" }); + } finally { + // Stelle sicher, dass die Verbindung zurückgegeben wird + if (connection) connection.release(); + } } diff --git a/pages/api/talas_v5_DB/locationDevice/getDeviceId.js b/pages/api/talas_v5_DB/locationDevice/getDeviceId.js index fa373c80c..8b2326316 100644 --- a/pages/api/talas_v5_DB/locationDevice/getDeviceId.js +++ b/pages/api/talas_v5_DB/locationDevice/getDeviceId.js @@ -1,40 +1,41 @@ // API in /api/talas_v5_DB/locationDevice/getDeviceId.js -import mysql from "mysql"; +import mysql from "mysql2/promise"; -const dbConfig = { +// Erstellen eines Pools von Datenbankverbindungen +const pool = mysql.createPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, port: process.env.DB_PORT, -}; - -const connection = mysql.createConnection(dbConfig); -connection.connect((err) => { - if (err) { - console.error("Fehler beim Verbinden:", err.stack); - return; - } + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0, }); -export default function handler(req, res) { +export default async function handler(req, res) { if (req.method !== "GET") { return res.status(405).json({ error: "Nur GET Methode erlaubt" }); } + const { deviceName } = req.query; + if (!deviceName) { + return res.status(400).json({ error: "deviceName ist erforderlich" }); + } + const query = "SELECT idLD FROM location_device WHERE name = ?"; - connection.query(query, [deviceName], (error, results) => { - if (error) { - console.error("Fehler beim Abrufen der Geräte-ID:", error); - return res - .status(500) - .json({ error: "Fehler beim Abrufen der Geräte-ID" }); - } + + try { + // Ausführen der Abfrage mit dem Pool + const [results] = await pool.query(query, [deviceName]); if (results.length > 0) { - res.json({ idLD: results[0].idLD }); + res.status(200).json({ idLD: results[0].idLD }); } else { res.status(404).json({ error: "Gerät nicht gefunden" }); } - }); + } catch (error) { + console.error("Fehler beim Abrufen der Geräte-ID:", error); + res.status(500).json({ error: "Fehler beim Abrufen der Geräte-ID" }); + } } diff --git a/pages/api/talas_v5_DB/locationDevice/locationDeviceNameById.js b/pages/api/talas_v5_DB/locationDevice/locationDeviceNameById.js index aaf24778d..575541547 100644 --- a/pages/api/talas_v5_DB/locationDevice/locationDeviceNameById.js +++ b/pages/api/talas_v5_DB/locationDevice/locationDeviceNameById.js @@ -1,43 +1,40 @@ // API in /api/talas_v5_DB/locationDevice/locationDeviceNameById.js -import mysql from "mysql"; +import mysql from "mysql2/promise"; -const dbConfig = { +// Erstellen eines Pools von Datenbankverbindungen +const pool = mysql.createPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, port: process.env.DB_PORT, -}; - -const connection = mysql.createConnection(dbConfig); -connection.connect((err) => { - if (err) { - console.error("Fehler beim Verbinden:", err.stack); - return; - } + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0, }); -export default function handler(req, res) { +export default async function handler(req, res) { if (req.method !== "GET") { return res.status(405).json({ error: "Nur GET Methode erlaubt" }); } + const { idLD } = req.query; - const query = "SELECT name FROM location_device WHERE idLD = ?"; - connection.query(query, [idLD], (error, results) => { - if (error) { - console.error( - "Fehler beim Abrufen des Gerätenamens in locationDeviceNameById.js :", - error - ); - return res - .status(500) - .json({ error: "Fehler beim Abrufen des Gerätenamens" }); - } + if (!idLD) { + return res.status(400).json({ error: "idLD ist erforderlich" }); + } + + try { + const query = "SELECT name FROM location_device WHERE idLD = ?"; + const [results] = await pool.query(query, [idLD]); + if (results.length > 0) { - res.json({ name: results[0].name }); + res.status(200).json({ name: results[0].name }); } else { - res.status(404).json({ error: "Gerät nicht gefunden" }); + res.status(404).json({ error: "Gerät nicht gefunden", idLD }); } - }); + } catch (error) { + console.error("Fehler beim Abrufen des Gerätenamens:", error); + res.status(500).json({ error: "Fehler beim Abrufen des Gerätenamens" }); + } } diff --git a/pages/api/talas_v5_DB/locationDevice/locationDevices.js b/pages/api/talas_v5_DB/locationDevice/locationDevices.js index bfaf57654..082dc2929 100644 --- a/pages/api/talas_v5_DB/locationDevice/locationDevices.js +++ b/pages/api/talas_v5_DB/locationDevice/locationDevices.js @@ -1,35 +1,32 @@ // API in /api/talas_v5_DB/locationDevice/locationDevices.js -import mysql from "mysql"; +import mysql from "mysql2/promise"; -const dbConfig = { +// Erstellen eines Pools von Datenbankverbindungen +const pool = mysql.createPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, port: process.env.DB_PORT, -}; - -const connection = mysql.createConnection(dbConfig); -connection.connect((err) => { - if (err) { - console.error("Fehler beim Verbinden:", err.stack); - return; - } + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0, }); -export default function handler(req, res) { +export default async function handler(req, res) { if (req.method !== "GET") { return res.status(405).json({ error: "Nur GET Methode erlaubt" }); } const query = "SELECT * FROM location_device WHERE iddevice = 160"; - connection.query(query, (error, results) => { - if (error) { - console.error("Fehler beim Abrufen der Geräteinformationen:", error); - return res - .status(500) - .json({ error: "Fehler beim Abrufen der Geräteinformationen" }); - } - res.json(results); - }); + + try { + // Ausführen der Abfrage mit dem Verbindungspool + const [results] = await pool.query(query); + + res.status(200).json(results); + } catch (error) { + console.error("Fehler beim Abrufen der Geräteinformationen:", error); + res.status(500).json({ error: "Fehler beim Abrufen der Geräteinformationen" }); + } } diff --git a/pages/api/talas_v5_DB/poiTyp/readPoiTyp.js b/pages/api/talas_v5_DB/poiTyp/readPoiTyp.js index 062c442cd..baff8f83d 100644 --- a/pages/api/talas_v5_DB/poiTyp/readPoiTyp.js +++ b/pages/api/talas_v5_DB/poiTyp/readPoiTyp.js @@ -1,33 +1,37 @@ // pages/api/talas_v5_DB/poiTyp/readPoiTyp.js -import mysql from "mysql"; +import mysql from "mysql2/promise"; +// Erstellen eines Pools von Datenbankverbindungen const pool = mysql.createPool({ - //connectionLimit: 10, host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, port: process.env.DB_PORT, + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0, }); -export default function handler(req, res) { - if (req.method === "GET") { - const query = "SELECT * FROM poityp"; - - pool.query(query, (error, results) => { - if (error) { - console.error("Fehler beim Abfragen der Datenbank:", error); - return res.status(500).json({ error: "Ein Fehler ist aufgetreten" }); - } - - if (results.length === 0) { - return res.status(404).json({ message: "Keine Einträge gefunden" }); - } - - res.status(200).json(results); - }); - } else { +export default async function handler(req, res) { + if (req.method !== "GET") { res.setHeader("Allow", ["GET"]); - res.status(405).end(`Method ${req.method} Not Allowed`); + return res.status(405).end(`Method ${req.method} Not Allowed`); + } + + const query = "SELECT * FROM poityp"; + + try { + // Ausführen der Abfrage mit dem Verbindungspool + const [results] = await pool.query(query); + + if (results.length === 0) { + return res.status(404).json({ message: "Keine Einträge gefunden" }); + } + + res.status(200).json(results); + } catch (error) { + console.error("Fehler beim Abfragen der Datenbank:", error); + res.status(500).json({ error: "Ein Fehler ist aufgetreten" }); } } diff --git a/pages/api/talas_v5_DB/pois/addLocation.js b/pages/api/talas_v5_DB/pois/addLocation.js index 118704d7d..245049ff0 100644 --- a/pages/api/talas_v5_DB/pois/addLocation.js +++ b/pages/api/talas_v5_DB/pois/addLocation.js @@ -1,36 +1,45 @@ // pages/api/talas_v5_DB/pois/addLocation.js -import mysql from "mysql"; +import mysql from "mysql2/promise"; -const dbConfig = { +// Erstellen eines Pools von Datenbankverbindungen +const pool = mysql.createPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, port: process.env.DB_PORT, -}; + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0, +}); -export default function handler(req, res) { +export default async function handler(req, res) { if (req.method === "POST") { const { name, poiTypeId, latitude, longitude, idLD } = req.body; console.log("Received data:", req.body); // Überprüfen der empfangenen Daten - const connection = mysql.createConnection(dbConfig); - const query = - "INSERT INTO poi (description, idPoiTyp, position, idLD) VALUES (?, ?, ST_GeomFromText(?),?)"; + if (!name || !poiTypeId || !latitude || !longitude || !idLD) { + return res.status(400).json({ error: "Alle Felder sind erforderlich" }); + } + + const query = ` + INSERT INTO poi (description, idPoiTyp, position, idLD) + VALUES (?, ?, ST_GeomFromText(?), ?) + `; const point = `POINT(${longitude} ${latitude})`; - const values = [name, poiTypeId, point, idLD]; // Stellen Sie sicher, dass poiTypeId korrekt ist + const values = [name, poiTypeId, point, idLD]; - connection.query(query, values, (error, results) => { - connection.end(); - if (error) { - console.error("Fehler beim Einfügen des Standorts:", error); - return res.status(500).json({ error: "Ein Fehler ist aufgetreten" }); - } + try { + // Ausführen der Abfrage mit dem Verbindungspool + const [results] = await pool.query(query, values); res.status(200).json({ id: results.insertId, message: "Standort erfolgreich hinzugefügt", }); - }); + } catch (error) { + console.error("Fehler beim Einfügen des Standorts:", error); + res.status(500).json({ error: "Ein Fehler ist aufgetreten" }); + } } else { res.setHeader("Allow", ["POST"]); res.status(405).end(`Method ${req.method} Not Allowed`); diff --git a/pages/api/talas_v5_DB/pois/deletePoi.js b/pages/api/talas_v5_DB/pois/deletePoi.js index ca1cc77a0..b229d0b8d 100644 --- a/pages/api/talas_v5_DB/pois/deletePoi.js +++ b/pages/api/talas_v5_DB/pois/deletePoi.js @@ -1,25 +1,19 @@ // pages/api/talas_v5_DB/pois/deletePoi.js -import mysql from "mysql"; +import mysql from "mysql2/promise"; -// Datenbankkonfiguration -const dbConfig = { +// Erstellen eines Pools von Datenbankverbindungen +const pool = mysql.createPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, port: process.env.DB_PORT, -}; - -const connection = mysql.createConnection(dbConfig); -connection.connect((err) => { - if (err) { - console.error("Fehler beim Verbinden:", err.stack); - return; - } - console.log("Verbunden als ID", connection.threadId); + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0, }); -export default function handler(req, res) { +export default async function handler(req, res) { if (req.method !== "DELETE") { return res.status(405).json({ error: "Nur DELETE Methode erlaubt" }); } @@ -31,15 +25,18 @@ export default function handler(req, res) { } const query = "DELETE FROM poi WHERE idPoi = ?"; - connection.query(query, [id], (error, results) => { - if (error) { - console.error("Fehler beim Löschen des POI:", error); - return res.status(500).json({ error: "Fehler beim Löschen des POI" }); - } + + try { + // Ausführen der Abfrage mit dem Verbindungspool + const [results] = await pool.query(query, [id]); + if (results.affectedRows > 0) { - res.json({ message: "POI erfolgreich gelöscht" }); + res.status(200).json({ message: "POI erfolgreich gelöscht" }); } else { res.status(404).json({ error: "POI nicht gefunden" }); } - }); + } catch (error) { + console.error("Fehler beim Löschen des POI:", error); + res.status(500).json({ error: "Fehler beim Löschen des POI" }); + } } diff --git a/pages/api/talas_v5_DB/pois/getPoiById.js b/pages/api/talas_v5_DB/pois/getPoiById.js index 4ebf5b62c..3bd2f1023 100644 --- a/pages/api/talas_v5_DB/pois/getPoiById.js +++ b/pages/api/talas_v5_DB/pois/getPoiById.js @@ -1,42 +1,43 @@ // pages/api/talas_v5_DB/pois/getPoiById.js -import mysql from "mysql"; +import mysql from "mysql2/promise"; -const dbConfig = { +// Erstellen eines Pools von Datenbankverbindungen +const pool = mysql.createPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, port: process.env.DB_PORT, -}; + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0, +}); -export default function handler(req, res) { - if (req.method === "GET") { - const { idPoi } = req.query; - const connection = mysql.createConnection(dbConfig); - - connection.connect((err) => { - if (err) { - console.error("Fehler beim Verbinden:", err.stack); - return res - .status(500) - .json({ error: "Verbindungsfehler zur Datenbank" }); - } - - const query = "SELECT description FROM poi WHERE idPoi = ?"; - connection.query(query, [idPoi], (error, results) => { - connection.end(); - if (error) { - console.error("Fehler bei der Abfrage:", error); - return res.status(500).json({ error: "Fehler bei der Abfrage" }); - } - if (results.length === 0) { - return res.status(404).json({ error: "POI nicht gefunden" }); - } - res.status(200).json(results[0]); - }); - }); - } else { +export default async function handler(req, res) { + if (req.method !== "GET") { res.setHeader("Allow", ["GET"]); - res.status(405).end(`Method ${req.method} Not Allowed`); + return res.status(405).end(`Method ${req.method} Not Allowed`); + } + + const { idPoi } = req.query; + + if (!idPoi) { + return res.status(400).json({ error: "idPoi ist erforderlich" }); + } + + const query = "SELECT description FROM poi WHERE idPoi = ?"; + + try { + // Ausführen der Abfrage mit dem Verbindungspool + const [results] = await pool.query(query, [idPoi]); + + if (results.length === 0) { + return res.status(404).json({ error: "POI nicht gefunden" }); + } + + res.status(200).json(results[0]); + } catch (error) { + console.error("Fehler bei der Abfrage:", error); + res.status(500).json({ error: "Fehler bei der Abfrage" }); } } diff --git a/pages/api/talas_v5_DB/pois/poi-icons.js b/pages/api/talas_v5_DB/pois/poi-icons.js index ee092c226..407704538 100644 --- a/pages/api/talas_v5_DB/pois/poi-icons.js +++ b/pages/api/talas_v5_DB/pois/poi-icons.js @@ -1,42 +1,36 @@ // pages/api/talas_v5_DB/pois/poi-icons.js -import mysql from "mysql"; +import mysql from "mysql2/promise"; -const dbConfig = { +// Erstellen eines Pools von Datenbankverbindungen +const pool = mysql.createPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, port: process.env.DB_PORT, -}; - -const connection = mysql.createConnection(dbConfig); - -connection.connect((err) => { - if (err) { - console.error("Fehler beim Verbinden:", err.stack); - return; - } + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0, }); -export default function handler(req, res) { +export default async function handler(req, res) { if (req.method !== "GET") { return res.status(405).json({ error: "Nur GET Methode erlaubt" }); } - const query = `SELECT p.idPoi, i.path - FROM poi p - JOIN poiTyp pt ON p.idPoiTyp = pt.idPoiTyp - JOIN poiicons i ON pt.icon = i.idpoiicons;`; + const query = ` + SELECT p.idPoi, i.path + FROM poi p + JOIN poiTyp pt ON p.idPoiTyp = pt.idPoiTyp + JOIN poiicons i ON pt.icon = i.idpoiicons; + `; - connection.query(query, (error, results) => { - try { - if (error) { - throw error; - } - res.json(results); - } catch (err) { - console.error("Fehler beim Abrufen der icons:", err); - res.status(500).json({ error: "Fehler beim Abrufen der icons" }); - } - }); + try { + // Ausführen der Abfrage mit dem Verbindungspool + const [results] = await pool.query(query); + res.status(200).json(results); + } catch (error) { + console.error("Fehler beim Abrufen der Icons:", error); + res.status(500).json({ error: "Fehler beim Abrufen der Icons" }); + } } diff --git a/pages/api/talas_v5_DB/pois/readLocations.js b/pages/api/talas_v5_DB/pois/readLocations.js index a5922ef50..308de78af 100644 --- a/pages/api/talas_v5_DB/pois/readLocations.js +++ b/pages/api/talas_v5_DB/pois/readLocations.js @@ -1,45 +1,32 @@ // pages/api/talas_v5_DB/pois/readLocations.js -import mysql from "mysql"; +import mysql from "mysql2/promise"; -const dbConfig = { +// Erstellen eines Pools von Datenbankverbindungen +const pool = mysql.createPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, port: process.env.DB_PORT, -}; -console.log("my dbconfig: ", dbConfig); -export default function handler(req, res) { - const connection = mysql.createConnection(dbConfig); + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0, +}); - connection.connect((err) => { - if (err) { - console.error("Fehler beim Verbinden:", err.stack); - res.status(500).json({ error: "Verbindungsfehler zur Datenbank" }); - return; - } +export default async function handler(req, res) { + const query = ` + SELECT idPoi, description, idPoiTyp, idLD, ST_AsText(position) AS position + FROM poi + `; - console.log("Verbunden als ID", connection.threadId); + try { + // Ausführen der Abfrage mit dem Verbindungspool + const [results] = await pool.query(query); - connection.query( - "SELECT idPoi, description, idPoiTyp, idLD, ST_AsText(position) AS position FROM poi", - (error, results) => { - if (error) { - console.error("Fehler beim Abrufen der API", error); - res.status(500).json({ error: "Fehler bei der Abfrage" }); - return; - } - - // Wichtig: Senden Sie die Antwort zurück - res.status(200).json(results); - console.log( - "--------------- location.js ---------------", - "results in location.js : ", - results, - "---------------------- location.js end ---------------------------" - ); - connection.end(); - } - ); - }); + // Senden der Antwort zurück + res.status(200).json(results); + } catch (error) { + console.error("Fehler beim Abrufen der API:", error); + res.status(500).json({ error: "Fehler bei der Abfrage" }); + } } diff --git a/pages/api/talas_v5_DB/pois/updateLocation.js b/pages/api/talas_v5_DB/pois/updateLocation.js index 625be5a75..ee61070f2 100644 --- a/pages/api/talas_v5_DB/pois/updateLocation.js +++ b/pages/api/talas_v5_DB/pois/updateLocation.js @@ -1,5 +1,48 @@ // pages/api/talas_v5_DB/pois/updateLocation.js -import mysql from "mysql"; +import mysql from "mysql2/promise"; + +// Erstellen eines Pools von Datenbankverbindungen +const pool = mysql.createPool({ + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + port: process.env.DB_PORT, + charset: "utf8mb4", + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0, +}); + +export default async function handler(req, res) { + if (req.method !== "POST") { + res.setHeader("Allow", ["POST"]); + return res.status(405).end(`Method ${req.method} Not Allowed`); + } + + const { id, latitude, longitude } = req.body; + + if (!id || latitude === undefined || longitude === undefined) { + return res.status(400).json({ error: "id, latitude, und longitude sind erforderlich" }); + } + + const query = "UPDATE poi SET position = POINT(?, ?) WHERE idPoi = ?"; + + try { + const [result] = await pool.query(query, [longitude, latitude, id]); + + if (result.affectedRows > 0) { + res.status(200).json({ success: true }); + } else { + res.status(404).json({ error: "POI nicht gefunden" }); + } + } catch (error) { + console.error("Fehler beim Aktualisieren der Position:", error); + res.status(500).json({ error: "Ein Fehler ist aufgetreten" }); + } +} + +/* import mysql from "mysql"; import util from "util"; const dbConfig = { @@ -36,4 +79,4 @@ export default async function handler(req, res) { } finally { connection.end(); } -} +} */ diff --git a/pages/api/talas_v5_DB/pois/updatePoi.js b/pages/api/talas_v5_DB/pois/updatePoi.js index ad9c52b60..bc3356a2f 100644 --- a/pages/api/talas_v5_DB/pois/updatePoi.js +++ b/pages/api/talas_v5_DB/pois/updatePoi.js @@ -1,53 +1,45 @@ // pages/api/talas_v5_DB/pois/updatePoi.js -import mysql from "mysql"; +import mysql from "mysql2/promise"; -const dbConfig = { +// Erstellen eines Pools von Datenbankverbindungen +const pool = mysql.createPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, port: process.env.DB_PORT, -}; - -const connection = mysql.createConnection(dbConfig); -connection.connect((err) => { - if (err) { - console.error("Fehler beim Verbinden:", err.stack); - return; - } - console.log("Verbunden als ID", connection.threadId); + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0, }); -export default function handler(req, res) { +export default async function handler(req, res) { if (req.method !== "POST") { return res.status(405).json({ error: "Nur POST Methode erlaubt" }); } - const { idPoi, description, idPoiTyp, idLD } = req.body; // Stellen Sie sicher, dass die Felder korrekt benannt sind - - console.log("Empfangene Daten:", req.body); // Loggen der empfangenen Daten zur Überprüfung + const { idPoi, description, idPoiTyp, idLD } = req.body; if (!idPoi) { return res.status(400).json({ error: "POI ID ist erforderlich" }); } - const query = - "UPDATE talas_v5.poi SET description = ?, idPoiTyp = ?, idLD = ? WHERE idPoi = ?"; - connection.query( - query, - [description, idPoiTyp, idLD, idPoi], - (error, results) => { - if (error) { - console.error("Fehler beim Aktualisieren des POI:", error); - return res - .status(500) - .json({ error: "Fehler beim Aktualisieren des POI" }); - } - if (results.affectedRows > 0) { - res.json({ message: "POI erfolgreich aktualisiert" }); - } else { - res.status(404).json({ error: "POI nicht gefunden" }); - } + const query = ` + UPDATE talas_v5.poi + SET description = ?, idPoiTyp = ?, idLD = ? + WHERE idPoi = ? + `; + + try { + const [results] = await pool.query(query, [description, idPoiTyp, idLD, idPoi]); + + if (results.affectedRows > 0) { + res.status(200).json({ message: "POI erfolgreich aktualisiert" }); + } else { + res.status(404).json({ error: "POI nicht gefunden" }); } - ); + } catch (error) { + console.error("Fehler beim Aktualisieren des POI:", error); + res.status(500).json({ error: "Fehler beim Aktualisieren des POI" }); + } } diff --git a/pages/api/talas_v5_DB/priorityConfig.js b/pages/api/talas_v5_DB/priorityConfig.js index dc239f619..719007020 100644 --- a/pages/api/talas_v5_DB/priorityConfig.js +++ b/pages/api/talas_v5_DB/priorityConfig.js @@ -2,42 +2,30 @@ // in tals5 http://10.10.0.13/talas5/Management/PriorityConfig.aspx beinhaltet die Tabelle prio die Prioritäten der Meldungen (Level 1-4) oder (0-4) je nachdem DB-Design // das ist die API, die die Prioritäten zurückgibt -import mysql from "mysql"; +import mysql from "mysql2/promise"; -const dbConfig = { +// Erstellen eines Pools von Datenbankverbindungen +const pool = mysql.createPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, port: process.env.DB_PORT, -}; -console.log("my dbconfig: ", dbConfig); -export default function handler(req, res) { - const connection = mysql.createConnection(dbConfig); + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0, +}); - connection.connect((err) => { - if (err) { - console.error("Fehler beim Verbinden:", err.stack); - res.status(500).json({ error: "Verbindungsfehler zur Datenbank" }); - return; - } +export default async function handler(req, res) { + try { + // Ausführen der Datenbankabfrage + const query = "SELECT idprio, level, name, color FROM prio"; + const results = await pool.query(query); - console.log("Verbunden als ID", connection.threadId); - //Fehler weil, existiertdie Tabelle auf localhost:3000 nicht - connection.query( - "SELECT idprio, level, name, color FROM prio ", - (error, results) => { - if (error) { - console.error("Fehler beim Abrufen der API", error); - res.status(500).json({ error: "Fehler bei der Abfrage" }); - return; - } - - // Wichtig: Senden Sie die Antwort zurück - res.status(200).json(results); - - connection.end(); - } - ); - }); + // Wichtig: Senden Sie die Antwort zurück + res.status(200).json(results[0]); // Da mysql2 Tuple [rows, fields] zurückgibt, wählen wir nur rows mit [0] + } catch (error) { + console.error("Fehler beim Abrufen der API", error); + res.status(500).json({ error: "Fehler bei der Abfrage" }); + } } diff --git a/pages/api/talas_v5_DB/station/getStationNameByIdLD.js b/pages/api/talas_v5_DB/station/getStationNameByIdLD.js new file mode 100644 index 000000000..83b4d03e6 --- /dev/null +++ b/pages/api/talas_v5_DB/station/getStationNameByIdLD.js @@ -0,0 +1,31 @@ +// /pages/api/talas_v5_DB/station/getStationNameByIdLD.js +import mysql from "mysql2/promise"; + +// Verbindungspool-Konfiguration +const pool = mysql.createPool({ + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + port: process.env.DB_PORT, + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0, +}); + +export default async function handler(req, res) { + if (req.method !== "GET") { + res.setHeader("Allow", ["GET"]); + return res.status(405).end(`Method ${req.method} Not Allowed`); + } + + try { + // Verwenden des Verbindungspools, um die Abfrage auszuführen + const [results] = await pool.query("SELECT * FROM location_device"); + + res.status(200).json(results); + } catch (err) { + console.error("Fehler beim Abrufen der Daten:", err); + res.status(500).json({ error: "Error retrieving data from the database" }); + } +} diff --git a/pages/index.js b/pages/index.js index 7378fdc45..98ae1daf6 100644 --- a/pages/index.js +++ b/pages/index.js @@ -1,14 +1,10 @@ -// pages/index.js -import { useEffect, useState } from "react"; +import React, { useEffect, useState } from "react"; import dynamic from "next/dynamic"; import { useRecoilState, useRecoilValue } from "recoil"; -import { readPoiMarkersStore } from "../store/selectors/readPoiMarkersStore"; // Aktualisiert mit atom +import { readPoiMarkersStore } from "../store/selectors/readPoiMarkersStore"; import { poiReadFromDbTriggerAtom } from "../store/atoms/poiReadFromDbTriggerAtom"; -const MapComponentWithNoSSR = dynamic( - () => import("../components/MapComponent"), - { ssr: false } -); +const MapComponentWithNoSSR = dynamic(() => import("../components/MapComponent"), { ssr: false }); export default function Home() { const poiReadTrigger = useRecoilValue(poiReadFromDbTriggerAtom); @@ -24,14 +20,12 @@ export default function Home() { } const data = await response.json(); setLocations(data); - //console.log("Geladene Daten in Home.js:", data); } catch (error) { console.error(error.message); } }; useEffect(() => { - // URL-Parameter abfragen function getURLParameter(name) { const params = new URLSearchParams(window.location.search); return params.get(name); @@ -39,10 +33,7 @@ export default function Home() { setMParam(getURLParameter("m")); setUParam(getURLParameter("u")); - // Daten beim Laden der Seite holen loadData(); - - //console.log("poiReadTrigger in Home.js:", poiReadTrigger); }, [poiReadTrigger]); const handleAddLocation = async (name, type, lat, lng) => { @@ -55,37 +46,24 @@ export default function Home() { if (!response.ok) { throw new Error("Fehler beim Hinzufügen des Standorts"); } - console.log("Standort erfolgreich hinzugefügt"); - loadData(); // Aktualisiere die Daten nach dem Hinzufügen - console.log("poiReadTrigger in Home.js:", poiReadTrigger); + //console.log("Standort erfolgreich hinzugefügt"); + loadData(); } catch (error) { console.error(error.message); } }; const handleLocationUpdate = (id, newLatitude, newLongitude) => { - setLocations((prevLocations) => - prevLocations.map((location) => - location.idPoi === id - ? { ...location, position: `POINT(${newLongitude} ${newLatitude})` } - : location - ) - ); + setLocations((prevLocations) => prevLocations.map((location) => (location.idPoi === id ? { ...location, position: `POINT(${newLongitude} ${newLatitude})` } : location))); }; - //------------------------------------ - // Daten beim Laden der Seite holen + useEffect(() => { loadData(); - //console.log("poiReadTrigger in Home.js:", poiReadTrigger); }, [poiReadTrigger]); - //------------------------------------ + return (
- +
); } diff --git a/public/img/icons/gisLines/add-support-point.svg b/public/img/icons/gisLines/add-support-point.svg new file mode 100644 index 000000000..7aaf86289 --- /dev/null +++ b/public/img/icons/gisLines/add-support-point.svg @@ -0,0 +1,4 @@ + + + + + diff --git a/public/img/icons/gisLines/remove-support-point.svg b/public/img/icons/gisLines/remove-support-point.svg new file mode 100644 index 000000000..aa5ab6b46 --- /dev/null +++ b/public/img/icons/gisLines/remove-support-point.svg @@ -0,0 +1,4 @@ + + + - + diff --git a/services/apiService.js b/services/apiService.js new file mode 100644 index 000000000..c3f5d57ba --- /dev/null +++ b/services/apiService.js @@ -0,0 +1,129 @@ +// services/apiService.js +import * as config from "../config/config"; +import * as urls from "../config/urls"; + +export const fetchGisStatusStations = async (idMap, idUser) => { + try { + const response = await fetch(`/api/talas5/webserviceMap/GisStationsStatusDistrict?idMap=${idMap}&idUser=${idUser}`); + if (!response.ok) { + throw new Error(`Error: ${response.statusText} + MySQL Datenbankverbindung fehlgeschlagen und + MySQL-Mode prüfen!`); + } + const data = await response.json(); + //console.log("GisStatusStations:", data); + return data; + } catch (error) { + console.error("Fehler beim Abrufen der Daten:", error); + throw error; // Fehler weiter werfen, um ihn in der Komponente behandeln zu können + } +}; + +// ---------------------------------------------- +/* export const fetchPriorityConfig = async () => { + try { + const response = await fetch("/api/talas_v5_DB/priorityConfig"); + const data = await response.json(); + console.log("Prioritätskonfiguration:", data); + setPriorityConfig(data); + } catch (error) { + console.error("Fehler beim Laden der Prioritätskonfiguration:", error); + } +}; */ + +// ---------------------------------------------- +export const fetchPoiData = async (idPoi) => { + try { + const response = await fetch(`/api/talas_v5_DB/pois/getPoiById?idPoi=${idPoi}`); + if (!response.ok) { + throw new Error("Fehler beim Abrufen der POI-Daten"); + } + const data = await response.json(); + return { + idPoi, + name: data.name, + description: data.description, + }; + } catch (error) { + console.error("Fehler beim Abrufen der POI-Daten", error); + return null; + } +}; +// ---------------------------------------------- +// Funktion zum Aktualisieren der Position in der Datenbank +export const updateLocationInDatabase = async (id, newLatitude, newLongitude) => { + const response = await fetch("/api/talas_v5_DB/pois/updateLocation", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + id, + latitude: newLatitude, + longitude: newLongitude, + }), + }); + + if (response.ok) { + //schreib die neue Kooridnaten in die Console + //akuellisiere die Position in der Datenbank mit den neuen Koordinaten mit updateLocation mit SQL Anweisung UPDATE + } else { + console.error("Fehler beim Aktualisieren der Position"); + } +}; + +// ---------------------------------------------- +// Funktionen zur Überwachung der Internetverbindung +export const checkInternet = () => { + fetch("https://tile.openstreetmap.org/1/1/1.png", { method: "HEAD" }) + .then((response) => setOnline(response.ok)) + .catch(() => setOnline(false)); +}; + +// ---------------------------------------------- +export const fetchDeviceNameById = async (idLD) => { + try { + const response = await fetch(`/api/talas_v5_DB/locationDevice/locationDeviceNameById?idLD=${idLD}`); + const data = await response.json(); + if (response.ok) { + return data.name; + } else { + //throw new Error(data.error || "Gerät nicht gefunden"); + throw new Error("Gerät nicht gefunden in apiService.js"); + } + } catch (error) { + console.error("Fehler beim Abrufen des Gerätenamens in apiService.js:", error); + return "Unbekannt"; + } +}; + +// ---------------------------------------------- +// services/apiService.js +export const fetchUserRights = async () => { + try { + // const response = await fetch(`${urls.SERVER_URL}/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic?idMap=${config.idMap}&idUser=${config.idUser}`); + const response = await fetch(`${process.env.NEXT_PUBLIC_SERVER_URL}/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic?idMap=${config.idMap}&idUser=${config.idUser}`); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const data = await response.json(); + // console.log("Benutzerrechte in fetchRights:", data); + + // Überprüfen der Struktur der Antwort + if (!data || !data.Rights || !Array.isArray(data.Rights)) { + throw new Error("Invalid response structure"); + } + + const rightsArray = data.Rights; // Nehmen an, dass 'Rights' das Array von Rechten ist + //console.log("rightsArray in apiService:", rightsArray); + + // Speichert die IDs der Rechte in einem Array + const userRightsIds = rightsArray.map((right) => right.IdRight); + + // Wenn alles gut geht, logge die erfolgreichen Abschluss + // console.log("Benutzerrechte erfolgreich abgerufen:", userRightsIds); + return userRightsIds; + } catch (error) { + console.error("Fehler beim Abrufen der Benutzerrechte", error); + return []; + } +}; diff --git a/services/fetchData.js b/services/fetchData.js new file mode 100644 index 000000000..2b036abb5 --- /dev/null +++ b/services/fetchData.js @@ -0,0 +1,62 @@ +// services/fetchData.js +export const fetchGisStationsStaticDistrict = async (url, setGisStationsStaticDistrict) => { + try { + const response = await fetch(url); + const jsonResponse = await response.json(); + if (jsonResponse && jsonResponse.Points) { + setGisStationsStaticDistrict(jsonResponse.Points); + } else { + console.error('Erwartete Daten im "Points"-Array nicht gefunden', jsonResponse); + setGisStationsStaticDistrict([]); + } + } catch (error) { + console.error("Fehler beim Laden der Daten: ", error); + setGisStationsStaticDistrict([]); + } +}; +export const fetchGisStationsStatusDistrict = async (url, setGisStationsStatusDistrict) => { + try { + const response = await fetch(url); + const jsonResponse = await response.json(); + if (jsonResponse && jsonResponse.Statis) { + setGisStationsStatusDistrict(jsonResponse.Statis); + } else { + console.error('Erwartete Daten im "Statis"-Array nicht gefunden', jsonResponse); + setGisStationsStatusDistrict([]); + } + } catch (error) { + console.error("Fehler beim Laden der Daten: ", error); + setGisStationsStatusDistrict([]); + } +}; +export const fetchGisStationsMeasurements = async (url, setGisStationsMeasurements) => { + try { + const response = await fetch(url); + const jsonResponse = await response.json(); + if (jsonResponse && jsonResponse.Statis) { + setGisStationsMeasurements(jsonResponse.Statis); + } else { + console.error('Erwartete Daten im "Statis"-Array nicht gefunden', jsonResponse); + setGisStationsMeasurements([]); + } + } catch (error) { + console.error("Fehler beim Laden der Daten: ", error); + setGisStationsMeasurements([]); + } +}; +export const fetchGisSystemStatic = async (url, setGisSystemStatic, setGisSystemStaticLoaded) => { + try { + const response = await fetch(url); + const jsonResponse = await response.json(); + if (jsonResponse && jsonResponse.Systems) { + setGisSystemStatic(jsonResponse.Systems); + setGisSystemStaticLoaded(true); + } else { + console.error('Erwartete Daten im "Systems"-Array nicht gefunden', jsonResponse); + setGisSystemStatic([]); + } + } catch (error) { + console.error("Fehler beim Laden der Daten: ", error); + setGisSystemStatic([]); + } +}; diff --git a/setupTests.js b/setupTests.js new file mode 100644 index 000000000..4d9bf73a2 --- /dev/null +++ b/setupTests.js @@ -0,0 +1,2 @@ +// setupTests.js +import "@testing-library/jest-dom"; diff --git a/store/atoms/gisSystemState.js b/store/atoms/gisSystemState.js index 784b41776..e31c490d8 100644 --- a/store/atoms/gisSystemState.js +++ b/store/atoms/gisSystemState.js @@ -1,4 +1,4 @@ -// Pfad: store/atoms/gisStationState.js +// Pfad: store/atoms/gisSystemtate.js import { atom } from "recoil"; export const gisSystemStaticState = atom({ diff --git a/store/atoms/poiDeviceNameState.js b/store/atoms/poiDeviceNameState.js new file mode 100644 index 000000000..b368995c9 --- /dev/null +++ b/store/atoms/poiDeviceNameState.js @@ -0,0 +1,7 @@ +// store/atoms/poiDeviceNameState.js +import { atom } from "recoil"; + +export const poiDeviceNameState = atom({ + key: "poiDeviceNameState", + default: "", +}); diff --git a/store/atoms/poiLayerVisibleState.js b/store/atoms/poiLayerVisibleState.js new file mode 100644 index 000000000..5304cf0d7 --- /dev/null +++ b/store/atoms/poiLayerVisibleState.js @@ -0,0 +1,8 @@ +// /store/atoms/poiLayerVisibleState.js +// Recoil atom for the visibility of the POI layer +import { atom } from "recoil"; + +export const poiLayerVisibleState = atom({ + key: "poiLayerVisibleState", + default: true, +}); diff --git a/styles/global.css b/styles/global.css index bd47f3630..99f9fd85e 100644 --- a/styles/global.css +++ b/styles/global.css @@ -16,3 +16,16 @@ padding: 10px !important; color: white !important; } +/* GMA Farben */ +.text-blue-700 { + color: #1d4ed8; +} +.text-red-700 { + color: #dc2626; +} +.text-yellow-500 { + color: #f59e0b; +} +.text-green-700 { + color: #10b981; +} diff --git a/tailwind.config.js b/tailwind.config.js index 4d3dfc078..f0ab949f8 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,7 +1,6 @@ /** @type {import('tailwindcss').Config} */ module.exports = { - purge: ["./pages/**/*.{js,ts,jsx,tsx}", "./components/**/*.{js,ts,jsx,tsx}"], - content: [], + content: ["./pages/**/*.{js,ts,jsx,tsx}", "./components/**/*.{js,ts,jsx,tsx}", "./hooks/**/*.{js,ts,jsx,tsx}"], theme: { extend: { zIndex: { diff --git a/tree_included.ps1 b/tree_included.ps1 new file mode 100644 index 000000000..269ab55eb --- /dev/null +++ b/tree_included.ps1 @@ -0,0 +1,42 @@ +param ( + [string]$Path, + [string[]]$Include +) + +function Get-IncludedTree { + param ( + [string]$Directory, + [string[]]$Include, + [int]$Indent = 0 + ) + + # Check if the current directory should be included + $includeCurrent = $false + foreach ($include in $Include) { + if ($Directory -like "*\$include*") { + $includeCurrent = $true + break + } + } + + if ($includeCurrent) { + # Output the current directory with indentation + Write-Host (" " * $Indent) + "+---" + (Split-Path -Leaf $Directory) + + # Process subdirectories and files + Get-ChildItem -Path $Directory | ForEach-Object { + if ($_.PSIsContainer) { + Get-IncludedTree -Directory $_.FullName -Include $Include -Indent ($Indent + 4) + } else { + Write-Host (" " * ($Indent + 4)) + "+---" + $_.Name + } + } + } +} + +# Start processing from the given path +Write-Host "Starting at path: $Path" +Get-ChildItem -Path $Path -Directory | ForEach-Object { + Get-IncludedTree -Directory $_.FullName -Include $Include +} +Write-Host "Processing completed." diff --git a/utils/contextMenuUtils.js b/utils/contextMenuUtils.js new file mode 100644 index 000000000..8a6b59e25 --- /dev/null +++ b/utils/contextMenuUtils.js @@ -0,0 +1,33 @@ +// contextMenuUtils.js +import { BASE_URL } from "../config/urls"; +export function addContextMenuToMarker(marker) { + marker.unbindContextMenu(); // Entferne das Kontextmenü, um Duplikate zu vermeiden + + marker.bindContextMenu({ + contextmenu: true, + contextmenuWidth: 140, + contextmenuItems: [ + /* { + text: "Station öffnen (Tab)", + icon: "/img/screen_new.png", + callback: (e) => openInNewTab(e, marker), + }, + { + text: "Station öffnen", + icon: "/img/screen_same.png", + callback: (e) => openInSameWindow(e, marker), + }, */ + ], + }); +} +// Funktion zum Öffnen in einem neuen Tab +export function openInNewTab(e, marker) { + const baseUrl = BASE_URL; + //console.log("baseUrl:", baseUrl); + if (marker && marker.options && marker.options.link) { + //console.log("Marker data:", baseUrl + marker.options.link); + window.open(baseUrl + marker.options.link, "_blank"); + } else { + console.error("Fehler: Marker hat keine gültige 'link' Eigenschaft"); + } +} diff --git a/utils/geometryUtils.js b/utils/geometryUtils.js new file mode 100644 index 000000000..35bfdd668 --- /dev/null +++ b/utils/geometryUtils.js @@ -0,0 +1,19 @@ +// utils/geometryUtils.js + +export const findClosestPoints = (coordinates, newPoint, map) => { + if (!map) { + console.error("Map is not defined. Cannot find closest points."); + return []; + } + + let minDist = Infinity; + let closestPair = []; + for (let i = 1; i < coordinates.length; i++) { + const dist = L.LineUtil.pointToSegmentDistance(map.latLngToLayerPoint(newPoint), map.latLngToLayerPoint(coordinates[i - 1]), map.latLngToLayerPoint(coordinates[i])); + if (dist < minDist) { + minDist = dist; + closestPair = [coordinates[i - 1], coordinates[i], i]; + } + } + return closestPair; +}; diff --git a/utils/handlePoiSelect.js b/utils/handlePoiSelect.js new file mode 100644 index 000000000..2dc5688c3 --- /dev/null +++ b/utils/handlePoiSelect.js @@ -0,0 +1,39 @@ +// utils/handlePoiSelect.js +const handlePoiSelect = async (poiData, setSelectedPoi, setLocationDeviceData, setDeviceName, poiLayerRef, poiTypMap) => { + setSelectedPoi(poiData); // poiData should be the data of the selected POI + //console.log("Selected POI:", poiData); + //console.log("Selected POI idLD:", poiData.deviceId); + + try { + const response = await fetch("/api/talas_v5_DB/locationDevice/locationDevices"); + const data = await response.json(); + setLocationDeviceData(data); + //console.log("Standort- und Gerätedaten:", data); + + const currentDevice = data.find((device) => device.idLD === poiData.deviceId); + if (currentDevice) { + setDeviceName(currentDevice.name); + //console.log("Current Device name in poiUpdate2:", currentDevice.name); + + // Update the marker popup with the device name and type + const marker = poiLayerRef.current.getLayers().find((m) => m.options.id === poiData.id); + if (marker) { + marker.setPopupContent( + ` +
+ ${poiData.description || "Unbekannt"}
+ ${currentDevice.name}
+ ${poiTypMap.get(poiData.idPoiTyp) || "Unbekannt"}
+
+ `, + ); + marker.openPopup(); + } + } + } catch (error) { + console.error("Fehler beim Abrufen der Gerätedaten2:", error); + setLocationDeviceData([]); + } +}; + +export default handlePoiSelect; diff --git a/utils/mapFeatures.js b/utils/mapFeatures.js new file mode 100644 index 000000000..774c90ee1 --- /dev/null +++ b/utils/mapFeatures.js @@ -0,0 +1,272 @@ +// utils/mapFeatures.js +import { findClosestPoints } from "./geometryUtils"; +import handlePoiSelect from "./handlePoiSelect"; +import { updateLocationInDatabase } from "../services/apiService"; +import { handleEditPoi, insertNewMarker, removeMarker } from "./markerUtils"; // Import removeMarker here +import circleIcon from "../components/gisPolylines/icons/CircleIcon"; +import startIcon from "../components/gisPolylines/icons/StartIcon"; +import endIcon from "../components/gisPolylines/icons/EndIcon"; +import { AddSupportPointIcon, RemoveSupportPointIcon } from "../components/gisPolylines/icons/SupportPointIcons"; +import { redrawPolyline } from "./mapUtils"; // Import redrawPolyline here + +export const setupMarkers = async ( + map, + locations, + poiData, + poiTypMap, + userRights, + poiLayerRef, + setSelectedPoi, + setLocationDeviceData, + setDeviceName, + setCurrentPoi, + poiLayerVisible, + fetchPoiData, + toast, + setShowPoiUpdateModal, + setCurrentPoiData, + deviceName +) => { + if (map && poiLayerRef.current) { + map.removeLayer(poiLayerRef.current); + poiLayerRef.current = new L.LayerGroup().addTo(map); + + for (const location of locations) { + try { + const { latitude, longitude } = parsePoint(location.position); + const poiTypName = poiTypMap.get(location.idPoiTyp) || "Unbekannt"; + const canDrag = userRights ? userRights.includes(56) : false; + const matchingIcon = poiData.find((poi) => poi.idPoi === location.idPoi); + const iconUrl = matchingIcon ? `/img/icons/pois/${matchingIcon.path}` : "/img/icons/pois/default-icon.png"; + + //console.log("Setting up marker for location:", location); + + const marker = L.marker([latitude, longitude], { + icon: L.icon({ + iconUrl: iconUrl, + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + }), + draggable: canDrag, + id: location.idPoi, + name: location.name, + description: location.description, + }).bindContextMenu({ + contextmenu: true, + contextmenuWidth: 140, + contextmenuItems: [ + { + text: "POI Bearbeiten", + icon: "/img/poi-edit.png", + callback: () => handleEditPoi(marker, userRights, setCurrentPoiData, setShowPoiUpdateModal, fetchPoiData, toast), + }, + ], + }); + + marker.bindPopup(` +
+ ${location.description || "Unbekannt"}
+ ${deviceName}
+ ${poiTypName}
+
+ `); + + marker.on("mouseover", function () { + handlePoiSelect( + { + id: location.idPoi, + deviceId: location.idLD, + idPoiTyp: location.idPoiTyp, + typ: poiTypName, + description: location.description, + }, + setSelectedPoi, + setLocationDeviceData, + setDeviceName, + poiLayerRef, + poiTypMap + ); + setCurrentPoi(location); + this.openPopup(); + }); + + marker.on("mouseout", function () { + this.closePopup(); + }); + + marker.on("dragend", (e) => { + if (canDrag) { + const newLat = e.target.getLatLng().lat; + const newLng = e.target.getLatLng().lng; + const markerId = e.target.options.id; + updateLocationInDatabase(markerId, newLat, newLng).then(() => { + //onLocationUpdate(markerId, newLat, newLng); + }); + } else { + console.error("Drag operation not allowed"); + } + }); + + if (poiLayerVisible) { + marker.addTo(poiLayerRef.current); + } + } catch (error) { + console.error("Error processing a location:", error); + } + } + } +}; +//---------------------------------- +export const setupPolylines = (map, linePositions, lineColors, tooltipContents, setNewCoords, tempMarker, currentZoom, currentCenter) => { + const markers = []; + const polylines = []; + + linePositions.forEach((lineData, lineIndex) => { + const lineMarkers = []; + lineData.coordinates.forEach((coord, index) => { + let icon = circleIcon; + if (index === 0) { + icon = startIcon; + } else if (index === lineData.coordinates.length - 1) { + icon = endIcon; + } + + const marker = L.marker(coord, { + icon: icon, + draggable: true, + contextmenu: true, + contextmenuInheritItems: false, + contextmenuItems: [], + }).addTo(map); + + marker.on("dragend", () => { + const newCoords = marker.getLatLng(); + setNewCoords(newCoords); + const newCoordinates = [...lineData.coordinates]; + newCoordinates[index] = [newCoords.lat, newCoords.lng]; + + const updatedPolyline = L.polyline(newCoordinates, { + color: lineColors[lineData.idModul] || "#000000", + }).addTo(map); + + updatedPolyline.bindTooltip(tooltipContents[lineData.idModul] || "Standard-Tooltip-Inhalt", { + permanent: false, + direction: "auto", + }); + + updatedPolyline.on("mouseover", () => { + updatedPolyline.setStyle({ weight: 10 }); + updatedPolyline.bringToFront(); + }); + updatedPolyline.on("mouseout", () => { + updatedPolyline.setStyle({ weight: 3 }); + }); + + polylines[lineIndex].remove(); + polylines[lineIndex] = updatedPolyline; + lineData.coordinates = newCoordinates; + + const requestData = { + idModul: lineData.idModul, + idLD: lineData.idLD, + newCoordinates, + }; + + fetch("/api/talas_v5_DB/gisLines/updateLineCoordinates", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(requestData), + }) + .then((response) => { + if (!response.ok) { + return response.json().then((data) => { + throw new Error(data.error || "Unbekannter Fehler"); + }); + } + return response.json(); + }) + .then((data) => { + console.log("Koordinaten erfolgreich aktualisiert:", data); + }) + .catch((error) => { + console.error("Fehler beim Aktualisieren der Koordinaten:", error.message); + }); + }); + + marker.on("mouseover", function () { + this.bindContextMenu({ + contextmenuItems: [ + { + text: "Stützpunkt entfernen", + icon: "/img/icons/gisLines/remove-support-point.svg", + callback: () => { + const newCoords = marker.getLatLng(); + const newCoordinates = [...lineData.coordinates]; + newCoordinates[index] = [newCoords.lat, newCoords.lng]; + + removeMarker(marker, lineData, currentZoom, currentCenter); // Pass currentZoom and currentCenter here + polylines[lineIndex].remove(); + lineData.coordinates = newCoordinates; + }, + }, + ], + }); + }); + + marker.on("mouseout", function () { + this.unbindContextMenu(); + }); + + lineMarkers.push(marker); + }); + + const polyline = L.polyline(lineData.coordinates, { + color: lineColors[lineData.idModul] || "#000000", + contextmenu: true, + contextmenuItems: [ + { + text: "Stützpunkt hinzufügen", + icon: "/img/icons/gisLines/add-support-point.svg", + callback: (e) => { + if (tempMarker) { + tempMarker.remove(); + } + const newPoint = e.latlng; + const closestPoints = findClosestPoints(lineData.coordinates, newPoint, map); + insertNewMarker(closestPoints, newPoint, lineData, map); // Make sure this is defined + redrawPolyline(lineData, lineColors, tooltipContents, map); // Add missing parameters + window.location.reload(); + }, + }, + ], + }).addTo(map); + + polyline.on("mouseover", (e) => { + polyline.setStyle({ weight: 10 }); + }); + + polyline.on("mouseout", (e) => { + polyline.setStyle({ weight: 3 }); + polyline.setStyle({ color: lineColors[lineData.idModul] || "#000000" }); + }); + + polyline.bindTooltip(tooltipContents[lineData.idModul] || "Standard-Tooltip-Inhalt", { + permanent: false, + direction: "auto", + }); + + polylines.push(polyline); + markers.push(...lineMarkers); + }); + + return { markers, polylines }; +}; + +// geometryUtils.js +export const parsePoint = (position) => { + const [longitude, latitude] = position.slice(6, -1).split(" "); + return { latitude: parseFloat(latitude), longitude: parseFloat(longitude) }; +}; diff --git a/utils/mapInitialization.js b/utils/mapInitialization.js new file mode 100644 index 000000000..47105a1d7 --- /dev/null +++ b/utils/mapInitialization.js @@ -0,0 +1,75 @@ +// /utils/mapInitialization.js +import L from "leaflet"; +//import OverlappingMarkerSpiderfier from "overlapping-marker-spiderfier-leaflet"; +import "leaflet-contextmenu"; +import "leaflet/dist/leaflet.css"; +import "leaflet-contextmenu/dist/leaflet.contextmenu.css"; +import * as urls from "../config/urls.js"; +import * as layers from "../config/layers.js"; +import { addContextMenuToMarker, openInNewTab } from "../utils/contextMenuUtils.js"; + +export const initializeMap = (mapRef, setMap, setOms, setMenuItemAdded, addItemsToMapContextMenu, hasRights) => { + const offlineTileLayer = urls.OFFLINE_TILE_LAYER; + //const offlineTileLayer = process.env.OFFLINE_TILE_LAYER; + const onlineTileLayer = urls.ONLINE_TILE_LAYER; + //const onlineTileLayer = process.env.ONLINE_TILE_LAYER; + const TALAS = layers.MAP_LAYERS.TALAS; + const ECI = layers.MAP_LAYERS.ECI; + const ULAF = layers.MAP_LAYERS.ULAF; + const GSMModem = layers.MAP_LAYERS.GSMModem; + const CiscoRouter = layers.MAP_LAYERS.CiscoRouter; + const WAGO = layers.MAP_LAYERS.WAGO; + const Siemens = layers.MAP_LAYERS.Siemens; + const OTDR = layers.MAP_LAYERS.OTDR; + const WDM = layers.MAP_LAYERS.WDM; + const GMA = layers.MAP_LAYERS.GMA; + const Sonstige = layers.MAP_LAYERS.Sonstige; + const TALASICL = layers.MAP_LAYERS.TALASICL; + + if (mapRef.current) { + const initMap = L.map(mapRef.current, { + center: [53.111111, 8.4625], + zoom: 12, + layers: [TALAS, ECI, ULAF, GSMModem, CiscoRouter, WAGO, Siemens, OTDR, WDM, GMA, Sonstige, TALASICL], + minZoom: 5, + maxZoom: 15, + zoomControl: false, + contextmenu: true, + contextmenuItems: [ + { + text: "Station öffnen (Tab)", + icon: "/img/screen_new.png", + callback: (e) => { + const clickedMarker = e.relatedTarget; + openInNewTab(e, clickedMarker); + }, + }, + "-", + ], + }); + + L.tileLayer(onlineTileLayer, { + attribution: '© OpenStreetMap contributors', + }).addTo(initMap); + + const overlappingMarkerSpiderfier = new OverlappingMarkerSpiderfier(initMap, { + nearbyDistance: 20, + }); + + setMap(initMap); + setOms(overlappingMarkerSpiderfier); + + initMap.on("zoomend", function () { + if (initMap.getZoom() > 15) { + initMap.setZoom(15); + } else if (initMap.getZoom() < 5) { + initMap.setZoom(5); + } + }); + + initMap.whenReady(() => { + console.log("Karte ist jetzt bereit und initialisiert."); + addItemsToMapContextMenu(hasRights); + }); + } +}; diff --git a/utils/mapUtils.js b/utils/mapUtils.js new file mode 100644 index 000000000..ca7cfb2c7 --- /dev/null +++ b/utils/mapUtils.js @@ -0,0 +1,110 @@ +// /utils/mapUtils.js +import L from "leaflet"; + +export const redrawPolyline = (lineData, lineColors, tooltipContents, map) => { + if (!lineData || !lineColors || !tooltipContents || !map) { + console.error("Invalid parameters for redrawPolyline"); + return; + } + + if (!lineData.coordinates || !Array.isArray(lineData.coordinates)) { + console.error("Invalid coordinates in lineData"); + return; + } + + const color = lineColors[lineData.idModul] || "#000000"; + const tooltipContent = tooltipContents[lineData.idModul] || "Standard-Tooltip-Inhalt"; + + if (lineData.polyline) map.removeLayer(lineData.polyline); + + lineData.polyline = L.polyline(lineData.coordinates, { + color: color, + }).addTo(map); + + lineData.polyline.bindTooltip(tooltipContent, { + permanent: false, + direction: "auto", + }); + + lineData.polyline.on("mouseover", () => { + lineData.polyline.setStyle({ weight: 10 }); + lineData.polyline.bringToFront(); + }); + + lineData.polyline.on("mouseout", () => { + lineData.polyline.setStyle({ weight: 5 }); + }); +}; + +export const saveLineData = (lineData) => { + fetch("/api/talas_v5_DB/gisLines/updateLineCoordinates", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + idModul: lineData.idModul, + idLD: lineData.idLD, + newCoordinates: lineData.coordinates, + }), + }) + .then((response) => { + if (!response.ok) { + throw new Error("Fehler beim Speichern der Linienänderungen"); + } + return response.json(); + }) + .then((data) => { + //console.log("Linienänderungen gespeichert:", data); + }) + .catch((error) => { + console.error("Fehler beim Speichern der Linienänderungen:", error); + }); +}; +// Call this function on page load to restore zoom and center +export const restoreMapSettings = (map) => { + const savedZoom = localStorage.getItem("mapZoom"); + const savedCenter = localStorage.getItem("mapCenter"); + + if (savedZoom && savedCenter) { + try { + const centerCoords = JSON.parse(savedCenter); + map.setView(centerCoords, parseInt(savedZoom)); + } catch (e) { + console.error("Error parsing stored map center:", e); + map.setView([53.111111, 8.4625], 12); // Standardkoordinaten und -zoom + } + } +}; + +// Now update checkOverlappingMarkers to check if oms is initialized +export const checkOverlappingMarkers = (map, markers, plusIcon) => { + // Ensure markers is always an array + if (!Array.isArray(markers)) { + //console.error("The `markers` argument is not an array:", markers); + return; + } + + const overlappingGroups = {}; + + // Group markers by coordinates as strings + markers.forEach((marker) => { + const latlngStr = marker.getLatLng().toString(); + if (overlappingGroups[latlngStr]) { + overlappingGroups[latlngStr].push(marker); + } else { + overlappingGroups[latlngStr] = [marker]; + } + }); + + // Add plus markers at coordinates where overlaps occur + for (const coords in overlappingGroups) { + if (overlappingGroups[coords].length > 1) { + const latLng = L.latLng(coords.match(/[-.\d]+/g).map(Number)); + const plusMarker = L.marker(latLng, { icon: plusIcon }); + plusMarker.addTo(map); + + //console.log("Adding plus icon marker at", latLng); + } + } +}; diff --git a/utils/markerUtils.js b/utils/markerUtils.js new file mode 100644 index 000000000..4ba0aef6a --- /dev/null +++ b/utils/markerUtils.js @@ -0,0 +1,199 @@ +// /utils/markerUtils.js +import circleIcon from "../components/gisPolylines/icons/CircleIcon"; +import { saveLineData, redrawPolyline } from "./mapUtils"; +import L from "leaflet"; +import "leaflet.smooth_marker_bouncing"; +import { toast } from "react-toastify"; +import * as config from "../config/config.js"; + +export const insertNewMarker = (closestPoints, newPoint, lineData, map) => { + const newMarker = L.marker(newPoint, { + icon: circleIcon, + draggable: true, + }).addTo(map); + lineData.coordinates.splice(closestPoints[2], 0, [newPoint.lat, newPoint.lng]); + + // Hier direkt speichern nach Einfügen + saveLineData(lineData); + + redrawPolyline(lineData); + + // Event-Listener für das Verschieben des Markers hinzufügen + newMarker.on("dragend", () => { + const newCoords = newMarker.getLatLng(); + setNewCoords(newCoords); + const newCoordinates = [...lineData.coordinates]; + newCoordinates[closestPoints[2]] = [newCoords.lat, newCoords.lng]; + lineData.coordinates = newCoordinates; + redrawPolyline(lineData); + + updateMarkerPosition(newMarker.getLatLng(), lineData, newMarker); + saveLineData(lineData); // Speichern der neuen Koordinaten nach dem Verschieben + }); +}; + +export const removeMarker = (marker, lineData, currentZoom, currentCenter) => { + // Save zoom and center to localStorage + //localStorage.setItem("mapZoom", currentZoom); + //localStorage.setItem("mapCenter", JSON.stringify(currentCenter)); + + // Find the index of the coordinate that matches the marker's position + const index = lineData.coordinates.findIndex((coord) => L.latLng(coord[0], coord[1]).equals(marker.getLatLng())); + + if (index !== -1) { + // Remove the coordinate from the line data + lineData.coordinates.splice(index, 1); + + // Redraw the polyline with the updated coordinates + redrawPolyline(lineData); + + // Remove the marker from the map + marker.remove(); + + // Save the updated line data + saveLineData(lineData); + + // Refresh the browser + window.location.reload(); + } +}; + +export const handleEditPoi = ( + marker, + userRights, + setCurrentPoiData, + setShowPoiUpdateModal, + fetchPoiData, + toast // Hier toast als Parameter erhalten +) => { + //console.log("Selected Marker ID (idPoi):", marker.options.id); + //console.log("Selected Marker Description:", marker.options.description); + //console.log("User Rights:", userRights); + + // Sicherstellen, dass userRights ein Array ist + if (!Array.isArray(userRights)) { + console.error("User Rights is not an array:", userRights); + toast.error("Benutzerrechte sind ungültig.", { + position: "top-center", + autoClose: 5000, + hideProgressBar: false, + closeOnClick: true, + pauseOnHover: true, + draggable: true, + progress: undefined, + }); + return; + } + + console.log("User Rights includes 56:", userRights.includes(56)); + + // Prüfung, ob der Benutzer die notwendigen Rechte hat + if (!userRights.includes(56)) { + toast.error("Benutzer hat keine Berechtigung zum Bearbeiten.", { + position: "top-center", + autoClose: 5000, + hideProgressBar: false, + closeOnClick: true, + pauseOnHover: true, + draggable: true, + progress: undefined, + }); + console.log("Benutzer hat keine Berechtigung zum Bearbeiten."); + return; // Beendet die Funktion frühzeitig, wenn keine Berechtigung vorliegt + } + + setCurrentPoiData({ + idPoi: marker.options.id, + name: marker.options.name, + description: marker.options.description, + }); + + fetchPoiData(marker.options.id); + + setShowPoiUpdateModal(true); +}; +//------------------------------------------------------------------- +// Funktion zum Bestimmen der Priorität basierend auf dem Icon-Pfad +const determinePriority = (iconPath, priorityConfig) => { + for (let priority of priorityConfig) { + if (iconPath.includes(priority.name.toLowerCase())) { + return priority.level; + } + } + return 5; // Standardpriorität (niedrigste) +}; + +// Funktion zum Erstellen und Setzen von Markern +export const createAndSetMarkers = async (systemId, setMarkersFunction, GisSystemStatic, priorityConfig) => { + try { + const response1 = await fetch(config.mapGisStationsStaticDistrictUrl); + const jsonResponse = await response1.json(); + const response2 = await fetch(config.mapGisStationsStatusDistrictUrl); + const statusResponse = await response2.json(); + + const getIdSystemAndAllowValueMap = new Map(GisSystemStatic.map((system) => [system.IdSystem, system.Allow])); + + if (jsonResponse.Points && statusResponse.Statis) { + const statisMap = new Map(statusResponse.Statis.map((s) => [s.IdLD, s])); + let markersData = jsonResponse.Points.filter((station) => station.System === systemId && getIdSystemAndAllowValueMap.get(station.System) === 1).map((station) => { + //console.log("Station: ", station); + const statis = statisMap.get(station.IdLD); + //console.log("Statis: ", statis); + const iconPath = statis ? `img/icons/${statis.Na}-marker-icon-${station.Icon}.png` : `img/icons/marker-icon-${station.Icon}.png`; + + const priority = determinePriority(iconPath, priorityConfig); + //console.log("Priority: ", priority); + //console.log("statis.Le: ", statis.Le); + const zIndexOffset = 100 * (5 - priority); // Adjusted for simplicity and positive values + //console.log("Z-Index Offset: ", zIndexOffset); + + const marker = L.marker([station.X, station.Y], { + icon: L.icon({ + iconUrl: iconPath, + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + }), + areaName: station.Area_Name, // Stelle sicher, dass dieser Bereich gesetzt wird + link: station.Link, + zIndexOffset: zIndexOffset, + }); + + // Überprüfe, ob die bounce-Funktion verfügbar ist und verwende sie + if (typeof marker.bounce === "function" && statis) { + marker.on("add", () => marker.bounce(3)); + } else if (statis) { + //console.error("Bounce function is not available on marker"); + } + + const statusInfo = statusResponse.Statis.filter((status) => status.IdLD === station.IdLD) + .reverse() + .map( + (status) => ` +
+
+ ${status.Me} (${status.Na}) +
+ ` + ) + .join(""); + + marker.bindPopup(` +
+ ${station.LD_Name} + ${station.Device}
+ ${station.Area_Short} (${station.Area_Name})
+ ${station.Location_Short} (${station.Location_Name}) +
${statusInfo}
+
+ `); + + return marker; + }); + + setMarkersFunction(markersData); + } + } catch (error) { + //console.error("Error fetching data: ", error); + } +}; diff --git a/utils/openInSameWindow.js b/utils/openInSameWindow.js new file mode 100644 index 000000000..214c4719c --- /dev/null +++ b/utils/openInSameWindow.js @@ -0,0 +1,10 @@ +// utils/openInSameWindow.js + +export function openInSameWindow(e, marker, baseUrl) { + if (marker && marker.options && marker.options.link) { + //console.log("Marker data:", baseUrl + marker.options.link); + window.location.href = baseUrl + marker.options.link; + } else { + console.error("Fehler: Marker hat keine gültige 'link' Eigenschaft"); + } +} diff --git a/utils/zoomAndCenterUtils.js b/utils/zoomAndCenterUtils.js new file mode 100644 index 000000000..4d1e46c4b --- /dev/null +++ b/utils/zoomAndCenterUtils.js @@ -0,0 +1,45 @@ +// utils/zoomAndCenterUtils.js +/* export const zoomIn = (e, map) => { + if (!map) { + console.error("map is not defined in zoomIn"); + return; + } + map.flyTo(e.latlng, map.getZoom() + 1); + localStorage.setItem("mapZoom", map.getZoom()); + localStorage.setItem("mapCenter", JSON.stringify(map.getCenter())); +}; */ + +export const zoomIn = (e, map) => { + if (!map) { + console.error("map is not defined in zoomIn"); + return; + } + map.flyTo(e.latlng, 12); + localStorage.setItem("mapZoom", map.getZoom()); + localStorage.setItem("mapCenter", JSON.stringify(map.getCenter())); +}; + +export const zoomOut = (map) => { + if (!map) { + console.error("map is not defined in zoomOut"); + return; + } + const x = 51.41321407879154; + const y = 7.739617925303934; + const zoom = 7; + //console.log("map"); + //console.log(map); + map.flyTo([x, y], zoom); + localStorage.setItem("mapZoom", map.getZoom()); + localStorage.setItem("mapCenter", JSON.stringify(map.getCenter())); +}; + +export const centerHere = (e, map) => { + if (!map) { + console.error("map is not defined in centerHere"); + return; + } + map.panTo(e.latlng); + localStorage.setItem("mapZoom", map.getZoom()); + localStorage.setItem("mapCenter", JSON.stringify(map.getCenter())); +};