From a926741ae5d627cf73aff736c63387617fa49d9c Mon Sep 17 00:00:00 2001 From: D-Unit Date: Thu, 22 Aug 2024 11:22:19 +0200 Subject: [PATCH 01/44] started work on map with drawing feature --- apps/digitaltwins/.env | 1 + .../src/config/formsections/citation.ts | 15 +- packages/deposit/package.json | 8 +- .../src/features/metadata/MetadataFields.tsx | 4 + .../src/features/metadata/fields/Map.css | 13 + .../src/features/metadata/fields/Map.tsx | 218 +++ .../deposit/src/languages/locales/en/map.json | 7 + .../deposit/src/languages/locales/nl/map.json | 7 + packages/deposit/src/types/MetadataFields.ts | 15 +- pnpm-lock.yaml | 1234 ++++++++++++++++- 10 files changed, 1505 insertions(+), 17 deletions(-) create mode 100644 packages/deposit/src/features/metadata/fields/Map.css create mode 100644 packages/deposit/src/features/metadata/fields/Map.tsx create mode 100644 packages/deposit/src/languages/locales/en/map.json create mode 100644 packages/deposit/src/languages/locales/nl/map.json diff --git a/apps/digitaltwins/.env b/apps/digitaltwins/.env index baab0bde..d3de12f6 100644 --- a/apps/digitaltwins/.env +++ b/apps/digitaltwins/.env @@ -23,6 +23,7 @@ VITE_OIDC_SCOPE = 'openid profile' ## API keys VITE_GEONAMES_API_KEY = '' +VITE_MAPTILER_API_KEY = '' ## Freshdesk ticketing VITE_FRESHDESK_API_KEY = '' diff --git a/apps/digitaltwins/src/config/formsections/citation.ts b/apps/digitaltwins/src/config/formsections/citation.ts index 4db9e916..b2c2c925 100644 --- a/apps/digitaltwins/src/config/formsections/citation.ts +++ b/apps/digitaltwins/src/config/formsections/citation.ts @@ -48,19 +48,18 @@ const section: InitialSectionType = { }, }, { - type: "autocomplete", + type: "drawmap", label: { - en: "Publisher", - nl: "Uitgever", + en: "Map", + nl: "Map", }, - name: "publisher", + name: "map", required: true, description: { - en: "Institution - often the rights holder", - nl: "Instituut - vaak de rechthebbende", + en: "Some desc", + nl: "Iets van beschrijving", }, - options: "ror", - allowFreeText: true, + fullWidth: true, }, { type: "group", diff --git a/packages/deposit/package.json b/packages/deposit/package.json index eaf84eb2..8f8a4866 100644 --- a/packages/deposit/package.json +++ b/packages/deposit/package.json @@ -9,12 +9,11 @@ "@dans-framework/utils": "workspace:*", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", + "@mapbox/mapbox-gl-draw": "^1.4.3", "@mui/icons-material": "^5.14.3", "@mui/material": "^5.14.3", "@mui/x-date-pickers": "^6.11.0", "@reduxjs/toolkit": "^1.9.5", - "@types/jest": "^29.5.3", - "@types/node": "^20.4.7", "axios": "^1.6.0", "fast-xml-parser": "^4.2.7", "framer-motion": "^10.15.0", @@ -22,12 +21,15 @@ "i18next": "^23.4.1", "i18next-browser-languagedetector": "^7.1.0", "i18next-resources-to-backend": "^1.1.4", + "mapbox-gl": "^3.6.0", + "maplibre-gl": "^4.5.2", "moment": "^2.29.4", "notistack": "^3.0.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-dropzone": "^14.2.3", "react-i18next": "^13.0.3", + "react-map-gl": "^7.1.7", "react-oidc-context": "^2.2.2", "react-redux": "^8.1.2", "react-router-dom": "^6.14.2", @@ -38,6 +40,8 @@ }, "devDependencies": { "@dans-framework/pages": "workspace:*", + "@types/jest": "^29.5.3", + "@types/node": "^20.4.7", "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", "@types/react-transition-group": "^4.4.6", diff --git a/packages/deposit/src/features/metadata/MetadataFields.tsx b/packages/deposit/src/features/metadata/MetadataFields.tsx index d2e11373..c3cc9b53 100644 --- a/packages/deposit/src/features/metadata/MetadataFields.tsx +++ b/packages/deposit/src/features/metadata/MetadataFields.tsx @@ -38,6 +38,7 @@ import AutocompleteField from "./fields/AutocompleteField"; import TextField from "./fields/TextField"; import { DateTimeField, DateRangeField } from "./fields/DateTimeField"; import { RadioField, CheckField } from "./fields/RadioCheckField"; +import DrawMap from "./fields/Map"; import { TransitionGroup } from "react-transition-group"; import { lookupLanguageString } from "@dans-framework/utils"; import { useTranslation } from "react-i18next"; @@ -131,6 +132,9 @@ const SingleField = memo(({ field, sectionIndex }: SingleFieldProps) => { {field.type === "check" && ( )} + {field.type === "drawmap" && ( + + )} ); }); diff --git a/packages/deposit/src/features/metadata/fields/Map.css b/packages/deposit/src/features/metadata/fields/Map.css new file mode 100644 index 00000000..9d58bd9e --- /dev/null +++ b/packages/deposit/src/features/metadata/fields/Map.css @@ -0,0 +1,13 @@ +.mode-draw_polygon .maplibregl-canvas-container.maplibregl-interactive, +.mode-draw_point .maplibregl-canvas-container.maplibregl-interactive, +.mode-draw_line_string .maplibregl-canvas-container.maplibregl-interactive { + cursor: crosshair; +} + +.mouse-pointer .maplibregl-canvas-container.maplibregl-interactive { + cursor: pointer; +} + +.mouse-move .maplibregl-canvas-container.maplibregl-interactive { + cursor: move; +} \ No newline at end of file diff --git a/packages/deposit/src/features/metadata/fields/Map.tsx b/packages/deposit/src/features/metadata/fields/Map.tsx new file mode 100644 index 00000000..a76a07bd --- /dev/null +++ b/packages/deposit/src/features/metadata/fields/Map.tsx @@ -0,0 +1,218 @@ +import { useEffect, useState, useCallback } from "react"; +import Box from "@mui/material/Box"; +import Paper from "@mui/material/Paper"; +import Stack from "@mui/material/Stack"; +import TextField from "@mui/material/TextField"; +import IconButton from "@mui/material/IconButton"; +import Tooltip from "@mui/material/Tooltip"; +import InputAdornment from "@mui/material/InputAdornment"; +import { useTranslation } from "react-i18next"; +import { useAppDispatch, useAppSelector } from "../../../redux/hooks"; +import { StatusIcon } from "../../generic/Icons"; +import { setField } from "../metadataSlice"; +import { getFieldStatus } from "../metadataHelpers"; +import type { TextFieldProps } from "../../../types/MetadataProps"; +import { lookupLanguageString } from "@dans-framework/utils"; +import { getFormDisabled } from "../../../deposit/depositSlice"; +import Map, { ScaleControl, NavigationControl, useControl } from "react-map-gl/maplibre"; +import MapboxDraw from '@mapbox/mapbox-gl-draw'; +import 'maplibre-gl/dist/maplibre-gl.css'; +import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css'; +import './Map.css'; + +import List from '@mui/material/List'; +import ListSubheader from '@mui/material/ListSubheader'; +import ListItem from '@mui/material/ListItem'; +import ListItemButton from '@mui/material/ListItemButton'; +import ListItemIcon from '@mui/material/ListItemIcon'; +import ListItemText from '@mui/material/ListItemText'; +import PolylineIcon from '@mui/icons-material/Polyline'; +import PlaceIcon from '@mui/icons-material/Place'; +import HighlightAltIcon from '@mui/icons-material/HighlightAlt'; +import PentagonIcon from '@mui/icons-material/Pentagon'; + +/** + * Map field + * Lookup base location/point via Geonames. + * Allows user to edit selected point from Geonames location, or draw a line, square, polygon, circle. + * Gets saved as GeoJSON. + * Also allows user to select Geobasis standard. +*/ + +const DrawMap = ({ + field, + sectionIndex, +}: any) => { + const dispatch = useAppDispatch(); + const status = getFieldStatus(field); + const { t, i18n } = useTranslation("metadata"); + const formDisabled = useAppSelector(getFormDisabled); + + return ( + + + + dispatch( + setField({ + sectionIndex: sectionIndex, + id: field.id, + value: e.target.value, + }), + ) + } + placeholder={field.placeholder} + InputProps={{ + endAdornment: ( + + + + ), + }} + inputProps={{ "data-testid": `${field.name}-${field.id}` }} + /> + + + + + + + + ); +}; + +export default DrawMap; + +const controls = ["simple_select", "draw_point", "draw_line_string", "draw_polygon"]; + +const DrawControls = () => { + const { t } = useTranslation("map"); + const [ selectedMode, setSelectedMode ] = useState(controls[0]); + const [ features, setFeatures ] = useState({}); + + console.log(features) + + const onUpdate = useCallback(e => { + setFeatures(currFeatures => { + const newFeatures = {...currFeatures}; + for (const f of e.features) { + newFeatures[f.id] = f; + } + return newFeatures; + }); + setSelectedMode(controls[0]) + }, []); + + const onDelete = useCallback(e => { + console.log('delete called') + setFeatures(currFeatures => { + const newFeatures = {...currFeatures}; + for (const f of e.features) { + delete newFeatures[f.id]; + } + return newFeatures; + }); + setSelectedMode(controls[0]) + }, []); + + return ( + + + {t('draw')} + + }> + {controls.map(control => + + setSelectedMode(control)} + selected={control === selectedMode} + > + + { + control === "simple_select" + ? + : control === "draw_point" + ? + : control === "draw_line_string" + ? + : control === "draw_polygon" + ? + : null + } + + + + + )} + + + + ) +} + +const DrawControl = ({ + onCreate, + onUpdate, + onDelete, + mode +}) => { + const control = useControl( + () => new MapboxDraw({ + displayControlsDefault: false, + defaultMode: mode, + keybindings: true, + }), + ({map}: {map: MapRef}) => { + map.on('draw.create', onCreate); + map.on('draw.update', onUpdate); + map.on('draw.delete', onDelete); + }, + ({map}: {map: MapRef}) => { + map.off('draw.create', onCreate); + map.off('draw.update', onUpdate); + map.off('draw.delete', onDelete); + } + ); + + useEffect(() => { + control.changeMode(mode); + }, [mode]) + + return null; +} diff --git a/packages/deposit/src/languages/locales/en/map.json b/packages/deposit/src/languages/locales/en/map.json new file mode 100644 index 00000000..abda175b --- /dev/null +++ b/packages/deposit/src/languages/locales/en/map.json @@ -0,0 +1,7 @@ +{ + "draw": "Draw features", + "simple_select": "Select/move", + "draw_point": "Point", + "draw_line_string": "Line", + "draw_polygon": "Polygon" +} \ No newline at end of file diff --git a/packages/deposit/src/languages/locales/nl/map.json b/packages/deposit/src/languages/locales/nl/map.json new file mode 100644 index 00000000..abda175b --- /dev/null +++ b/packages/deposit/src/languages/locales/nl/map.json @@ -0,0 +1,7 @@ +{ + "draw": "Draw features", + "simple_select": "Select/move", + "draw_point": "Point", + "draw_line_string": "Line", + "draw_polygon": "Polygon" +} \ No newline at end of file diff --git a/packages/deposit/src/types/MetadataFields.ts b/packages/deposit/src/types/MetadataFields.ts index a65af4ec..b38ed19d 100644 --- a/packages/deposit/src/types/MetadataFields.ts +++ b/packages/deposit/src/types/MetadataFields.ts @@ -9,7 +9,8 @@ export type InputField = | AutocompleteFieldType | RadioFieldType | CheckFieldType - | RepeatTextFieldType; + | RepeatTextFieldType + | DrawMapFieldType; // General field, can be input or group export type Field = InputField | GroupedFieldType | RepeatGroupedFieldType; @@ -165,6 +166,18 @@ export interface CheckFieldType maxDateField?: never; } +export interface DrawMapFieldType + extends Omit { + type: "drawmap"; + value?: string[]; + multiApiValue?: never; + fields?: never; + format?: never; + autofill?: never; + minDateField?: never; + maxDateField?: never; +} + // Date and time formats to be used in a Date field export type DateTimeFormat = | "DD-MM-YYYY HH:mm" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 653d5c75..5554024e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -544,6 +544,9 @@ importers: '@emotion/styled': specifier: ^11.11.0 version: 11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) + '@mapbox/mapbox-gl-draw': + specifier: ^1.4.3 + version: 1.4.3 '@mui/icons-material': specifier: ^5.14.3 version: 5.14.3(@mui/material@5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) @@ -556,12 +559,6 @@ importers: '@reduxjs/toolkit': specifier: ^1.9.5 version: 1.9.5(react-redux@8.1.2(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(redux@4.2.1))(react@18.2.0) - '@types/jest': - specifier: ^29.5.3 - version: 29.5.3 - '@types/node': - specifier: ^20.4.7 - version: 20.5.3 axios: specifier: ^1.6.0 version: 1.6.0 @@ -583,6 +580,12 @@ importers: i18next-resources-to-backend: specifier: ^1.1.4 version: 1.1.4 + mapbox-gl: + specifier: ^3.6.0 + version: 3.6.0 + maplibre-gl: + specifier: ^4.5.2 + version: 4.5.2 moment: specifier: ^2.29.4 version: 2.29.4 @@ -601,6 +604,9 @@ importers: react-i18next: specifier: ^13.0.3 version: 13.0.3(i18next@23.4.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + react-map-gl: + specifier: ^7.1.7 + version: 7.1.7(mapbox-gl@3.6.0)(maplibre-gl@4.5.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react-oidc-context: specifier: ^2.2.2 version: 2.2.2(oidc-client-ts@2.2.4)(react@18.2.0) @@ -626,6 +632,12 @@ importers: '@dans-framework/pages': specifier: workspace:* version: link:../pages + '@types/jest': + specifier: ^29.5.3 + version: 29.5.3 + '@types/node': + specifier: ^20.4.7 + version: 20.5.3 '@types/react': specifier: ^18.2.15 version: 18.2.15 @@ -1599,20 +1611,68 @@ packages: '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@mapbox/extent@0.4.0': + resolution: {integrity: sha512-MSoKw3qPceGuupn04sdaJrFeLKvcSETVLZCGS8JA9x6zXQL3FWiKaIXYIZEDXd5jpXpWlRxinCZIN49yRy0C9A==} + + '@mapbox/geojson-area@0.2.2': + resolution: {integrity: sha512-bBqqFn1kIbLBfn7Yq1PzzwVkPYQr9lVUeT8Dhd0NL5n76PBuXzOcuLV7GOSbEB1ia8qWxH4COCvFpziEu/yReA==} + + '@mapbox/geojson-coords@0.0.2': + resolution: {integrity: sha512-YuVzpseee/P1T5BWyeVVPppyfmuXYHFwZHmybkqaMfu4BWlOf2cmMGKj2Rr92MwfSTOCSUA0PAsVGRG8akY0rg==} + + '@mapbox/geojson-extent@1.0.1': + resolution: {integrity: sha512-hh8LEO3djT4fqfr8sSC6wKt+p0TMiu+KOLMBUiFOyj+zGq7+IXwQGl0ppCVDkyzCewyd9LoGe9zAvDxXrLfhLw==} + hasBin: true + + '@mapbox/geojson-normalize@0.0.1': + resolution: {integrity: sha512-82V7YHcle8lhgIGqEWwtXYN5cy0QM/OHq3ypGhQTbvHR57DF0vMHMjjVSQKFfVXBe/yWCBZTyOuzvK7DFFnx5Q==} + hasBin: true + + '@mapbox/geojson-rewind@0.5.2': + resolution: {integrity: sha512-tJaT+RbYGJYStt7wI3cq4Nl4SXxG8W7JDG5DMJu97V25RnbNg3QtQtf+KD+VLjNpWKYsRvXDNmNrBgEETr1ifA==} + hasBin: true + '@mapbox/jsonlint-lines-primitives@2.0.2': resolution: {integrity: sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==} engines: {node: '>= 0.6'} + '@mapbox/mapbox-gl-draw@1.4.3': + resolution: {integrity: sha512-03qIJgyGmm0IoTZbV/cfODru9jRGogi4LcQ3maxIJDKccq1gY3ofgt2UYPkeU143ElxitZahEythNQv1NpsLhg==} + '@mapbox/mapbox-gl-style-spec@13.28.0': resolution: {integrity: sha512-B8xM7Fp1nh5kejfIl4SWeY0gtIeewbuRencqO3cJDrCHZpaPg7uY+V8abuR+esMeuOjRl5cLhVTP40v+1ywxbg==} hasBin: true + '@mapbox/mapbox-gl-supported@3.0.0': + resolution: {integrity: sha512-2XghOwu16ZwPJLOFVuIOaLbN0iKMn867evzXFyf0P22dqugezfJwLmdanAgU25ITvz1TvOfVP4jsDImlDJzcWg==} + '@mapbox/point-geometry@0.1.0': resolution: {integrity: sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==} + '@mapbox/tiny-sdf@2.0.6': + resolution: {integrity: sha512-qMqa27TLw+ZQz5Jk+RcwZGH7BQf5G/TrutJhspsca/3SHwmgKQ1iq+d3Jxz5oysPVYTGP6aXxCo5Lk9Er6YBAA==} + '@mapbox/unitbezier@0.0.0': resolution: {integrity: sha512-HPnRdYO0WjFjRTSwO3frz1wKaU649OBFPX3Zo/2WZvuRi6zMiRGui8SnPQiQABgqCf8YikDe5t3HViTVw1WUzA==} + '@mapbox/unitbezier@0.0.1': + resolution: {integrity: sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==} + + '@mapbox/vector-tile@1.3.1': + resolution: {integrity: sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==} + + '@mapbox/whoots-js@3.1.0': + resolution: {integrity: sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==} + engines: {node: '>=6.0.0'} + + '@maplibre/maplibre-gl-style-spec@19.3.3': + resolution: {integrity: sha512-cOZZOVhDSulgK0meTsTkmNXb1ahVvmTmWmfx9gRBwc6hq98wS9JP35ESIoNq3xqEan+UN+gn8187Z6E4NKhLsw==} + hasBin: true + + '@maplibre/maplibre-gl-style-spec@20.3.1': + resolution: {integrity: sha512-5ueL4UDitzVtceQ8J4kY+Px3WK+eZTsmGwha3MBKHKqiHvKrjWWwBCIl1K8BuJSc5OFh83uI8IFNoFvQxX2uUw==} + hasBin: true + '@mui/base@5.0.0-beta.11': resolution: {integrity: sha512-FdKZGPd8qmC3ZNke7CNhzcEgToc02M6WYZc9hcBsNQ17bgAd3s9F//1bDDYgMVBYxDM71V0sv/hBHlOY4I1ZVA==} engines: {node: '>=12.0.0'} @@ -1823,6 +1883,12 @@ packages: '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + '@types/geojson-vt@3.2.5': + resolution: {integrity: sha512-qDO7wqtprzlpe8FfQ//ClPV9xiuoh2nkIgiouIptON9w5jvD/fA4szvP9GBlDVdJ5dldAl0kX/sy3URbWwLx0g==} + + '@types/geojson@7946.0.14': + resolution: {integrity: sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==} + '@types/hoist-non-react-statics@3.3.1': resolution: {integrity: sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==} @@ -1847,6 +1913,15 @@ packages: '@types/lodash@4.14.199': resolution: {integrity: sha512-Vrjz5N5Ia4SEzWWgIVwnHNEnb1UE1XMkvY5DGXrAeOGE9imk0hgTHh5GyDjLDJi9OTCn9oo9dXH1uToK1VRfrg==} + '@types/mapbox-gl@3.4.0': + resolution: {integrity: sha512-tbn++Mm94H1kE7W6FF0oVC9rMXHVzDDNUbS7KfBMRF8NV/8csFi+67ytKcZJ4LsrpsJ+8MC6Os6ZinEDCsrunw==} + + '@types/mapbox__point-geometry@0.1.4': + resolution: {integrity: sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA==} + + '@types/mapbox__vector-tile@1.3.4': + resolution: {integrity: sha512-bpd8dRn9pr6xKvuEBQup8pwQfD4VUyqO/2deGjfpe6AwC8YRlyEipvefyRJUSiCJTZuCb8Pl1ciVV5ekqJ96Bg==} + '@types/md5@2.3.3': resolution: {integrity: sha512-4K40FjTW0tiIx9NfV+/DHJ56ih3fcdkDqBYz5CffKwJVWYho1FxzjkddGcgEEIs+fP2DqmQ3lujC5c4bUOESTQ==} @@ -1865,6 +1940,9 @@ packages: '@types/parse-json@4.0.0': resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} + '@types/pbf@3.0.5': + resolution: {integrity: sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==} + '@types/prop-types@15.7.9': resolution: {integrity: sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g==} @@ -1895,6 +1973,9 @@ packages: '@types/styled-components@5.1.28': resolution: {integrity: sha512-nu0VKNybkjvUqJAXWtRqKd7j3iRUl8GbYSTvZNuIBJcw/HUp1Y4QUXNLlj7gcnRV/t784JnHAlvRnSnE3nPbJA==} + '@types/supercluster@7.1.3': + resolution: {integrity: sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==} + '@types/use-sync-external-store@0.0.3': resolution: {integrity: sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==} @@ -2018,10 +2099,26 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + arr-union@3.1.0: + resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} + engines: {node: '>=0.10.0'} + + array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} + array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} + arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + engines: {node: '>= 0.4'} + + assign-symbols@1.0.0: + resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} + engines: {node: '>=0.10.0'} + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -2029,6 +2126,10 @@ packages: resolution: {integrity: sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==} engines: {node: '>=4'} + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + axios@1.6.0: resolution: {integrity: sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==} @@ -2063,6 +2164,16 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + bytewise-core@1.2.3: + resolution: {integrity: sha512-nZD//kc78OOxeYtRlVk8/zXqTB4gf/nlguL1ggWA8FuchMyOxcyHR4QPQZMUmA7czC+YnaBrPUCubqAWe50DaA==} + + bytewise@1.1.0: + resolution: {integrity: sha512-rHuuseJ9iQ0na6UDhnrRVDh8YnWVlU6xM3VH6q/+yHDeUH2zIhUzP+2/h3LIrhLDBtTqzWpE3p3tP/boefskKQ==} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -2088,6 +2199,9 @@ packages: charenc@0.0.2: resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} + cheap-ruler@4.0.0: + resolution: {integrity: sha512-0BJa8f4t141BYKQyn9NSQt1PguFQXMXwZiA5shfoaBYHAb2fFk2RAX+tiWMoQU+Agtzt3mdt0JtuyshAXqZ+Vw==} + chokidar@3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} @@ -2176,6 +2290,18 @@ packages: custom-error-instance@2.1.1: resolution: {integrity: sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg==} + data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} + debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -2188,6 +2314,14 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -2228,6 +2362,9 @@ packages: earcut@2.2.4: resolution: {integrity: sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==} + earcut@3.0.0: + resolution: {integrity: sha512-41Fs7Q/PLq1SDbqjsgcY7GA42T0jvaCNGXgGtsNdvg+Yv8eIu06bxv4/PoREkZ9nMDNwnUSG9OFB9+yv8eKhDg==} + echarts@5.4.3: resolution: {integrity: sha512-mYKxLxhzy6zyTi/FaEbJMOZU1ULGEQHaeIeuMR5L+JnJTpz+YR03mnnpBhbR4+UYJAgiXgpyTVLffPAjOTLkZA==} @@ -2241,6 +2378,30 @@ packages: error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + esbuild-css-modules-plugin@3.0.3: resolution: {integrity: sha512-2NPTBoQMu+cs3JKl28MrrgYJFClY7RJRdHbUJu7P3wg9NOx3SAnT1Ywso0CGQUCRuzmbTMXfzR1/8E/bmwWTxg==} engines: {node: '>= 16.20.0'} @@ -2327,6 +2488,14 @@ packages: resolution: {integrity: sha512-x1vY4LlEMWUYVZQrFi4ZANXFwqYbJ/JNQspLVvzhW2BNY28aNcXMQH6imBbt+RBf5sVRTodYHXtSP/TLEU0Dxw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + extend-shallow@3.0.2: + resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==} + engines: {node: '>=0.10.0'} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -2347,6 +2516,9 @@ packages: fastq@1.15.0: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + fflate@0.8.2: + resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -2382,6 +2554,9 @@ packages: debug: optional: true + for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + form-data@4.0.0: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} @@ -2421,14 +2596,49 @@ packages: function-bind@1.1.1: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} + geojson-flatten@1.1.1: + resolution: {integrity: sha512-k/6BCd0qAt7vdqdM1LkLfAy72EsLDy0laNwX0x2h49vfYCiQkRc4PSra8DNEdJ10EKRpwEvDXMb0dBknTJuWpQ==} + + geojson-vt@4.0.2: + resolution: {integrity: sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A==} + geotiff@2.0.7: resolution: {integrity: sha512-FKvFTNowMU5K6lHYY2f83d4lS2rsCNdpUC28AX61x9ZzzqPNaWFElWv93xj0eJFaNyOYA63ic5OzJ88dHpoA5Q==} engines: {node: '>=10.19'} + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + engines: {node: '>= 0.4'} + + get-value@2.0.6: + resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} + engines: {node: '>=0.10.0'} + + gl-matrix@3.4.3: + resolution: {integrity: sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -2440,6 +2650,10 @@ packages: glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + global-prefix@3.0.0: + resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==} + engines: {node: '>=6'} + globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} @@ -2448,6 +2662,10 @@ packages: resolution: {integrity: sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==} engines: {node: '>=8'} + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} @@ -2457,12 +2675,21 @@ packages: peerDependencies: csstype: ^3.0.10 + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + grid-index@1.1.0: + resolution: {integrity: sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA==} + + has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} @@ -2471,10 +2698,32 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + has@1.0.3: resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} engines: {node: '>= 0.4.0'} + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hat@0.0.3: + resolution: {integrity: sha512-zpImx2GoKXy42fVDSEad2BPKuSQdLcqsCYa48K3zHSzM/ugWuYjLDr8IXxpVuL7uCLHw56eaiLxCRthhOzf5ug==} + hoist-non-react-statics@3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} @@ -2529,22 +2778,60 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + inline-style-parser@0.1.1: resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} + internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} + is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} + is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + is-buffer@1.1.6: resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + is-core-module@2.13.0: resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==} + is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} + + is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-extendable@1.0.1: + resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} + engines: {node: '>=0.10.0'} + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -2553,6 +2840,14 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -2561,13 +2856,47 @@ packages: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} + is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + + is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} + is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} + is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + + is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + + is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + jest-diff@29.6.3: resolution: {integrity: sha512-3sw+AdWnwH9sSNohMRKA7JiYUJSRr/WS6+sEFfBuhxU5V5GlEVKfvUn8JuMHE0wqKowemR1C2aHy8VtXbaV8dQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -2615,6 +2944,12 @@ packages: json-stringify-pretty-compact@2.0.0: resolution: {integrity: sha512-WRitRfs6BGq4q8gTgOy4ek7iPFXjbra0H3PmDLKm2xnZ+Gh1HUhiKGgCZkSPNULlP7mvfu6FV/mOLhCarspADQ==} + json-stringify-pretty-compact@3.0.0: + resolution: {integrity: sha512-Rc2suX5meI0S3bfdZuA7JMFBGkJ875ApfVyq2WHELjBiiG22My/l7/8zPpH/CfFVQHuVLd8NLR0nv6vi0BYYKA==} + + json-stringify-pretty-compact@4.0.0: + resolution: {integrity: sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==} + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -2626,6 +2961,13 @@ packages: jwt-decode@3.1.2: resolution: {integrity: sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==} + kdbush@4.0.2: + resolution: {integrity: sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + lerc@3.0.0: resolution: {integrity: sha512-Rm4J/WaHhRa93nCN2mwWDZFoRVF18G1f47C+kvQWyHGEZxFpTUi73p7lMVSAndyxGt6lJ2/CFbOcf9ra5p8aww==} @@ -2722,6 +3064,9 @@ packages: lodash.debounce@4.0.8: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} @@ -2752,9 +3097,16 @@ packages: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true + mapbox-gl@3.6.0: + resolution: {integrity: sha512-xjYHHIJDh6haYcKY+/9jh1eywwYfIOWCgT5Fowj4JriZexx/oOtg2S7BQDMZtpFyg9IN4VLCysmUWxY0pFNRWA==} + mapbox-to-css-font@2.4.2: resolution: {integrity: sha512-f+NBjJJY4T3dHtlEz1wCG7YFlkODEjFIYlxDdLIDMNpkSksqTt+l/d4rjuwItxuzkuMFvPyrjzV2lxRM4ePcIA==} + maplibre-gl@4.5.2: + resolution: {integrity: sha512-vlWL9EY2bSGg5FAt0mKPfYqlfX15uLW5D3kKv4Xjn54nIVn01MKdfUJMAVIr+8fXVqfSX6c095Iy5XnV+T76kQ==} + engines: {node: '>=16.14.0', npm: '>=8.1.0'} + md5@2.3.0: resolution: {integrity: sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==} @@ -2789,6 +3141,9 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + murmurhash-js@1.0.0: + resolution: {integrity: sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==} + nanoid@3.3.6: resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -2823,6 +3178,18 @@ packages: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} + object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + oidc-client-ts@2.2.4: resolution: {integrity: sha512-nOZwIomju+AmXObl5Oq5PjrES/qTt8bLsENJCIydVgi9TEWk7SCkOU6X3RNkY7yfySRM1OJJvDKdREZdmnDT2g==} engines: {node: '>=12.13.0'} @@ -2885,6 +3252,10 @@ packages: resolution: {integrity: sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==} hasBin: true + pbf@3.3.0: + resolution: {integrity: sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q==} + hasBin: true + picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} @@ -2902,6 +3273,10 @@ packages: engines: {node: '>=16'} hasBin: true + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} @@ -2909,6 +3284,9 @@ packages: resolution: {integrity: sha512-Z7V5j0cq8oEKyejIKfpD8b4eBy9cwW2JWPk0+fB1HOAMsfHbnAXLLS+PfVWlzMSLQaWttKDt607I0XHmpE67Vw==} engines: {node: ^10 || ^12 || >=14} + potpack@2.0.0: + resolution: {integrity: sha512-Q+/tYsFU9r7xoOJ+y/ZTtdVQwTWfzjbiXBDMM/JKUux3+QPP02iUuIoeBQ+Ot6oEDlC+/PGjB/5A3K7KKb7hcw==} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -2951,6 +3329,9 @@ packages: quickselect@2.0.0: resolution: {integrity: sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==} + quickselect@3.0.0: + resolution: {integrity: sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==} + rbush@3.0.1: resolution: {integrity: sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w==} @@ -2984,6 +3365,19 @@ packages: react-is@18.2.0: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + react-map-gl@7.1.7: + resolution: {integrity: sha512-mwjc0obkBJOXCcoXQr3VoLqmqwo9vS4bXfbGsdxXzEgVCv/PM0v+1QggL7W0d/ccIy+VCjbXNlGij+PENz6VNg==} + peerDependencies: + mapbox-gl: '>=1.13.0' + maplibre-gl: '>=1.13.0' + react: '>=16.3.0' + react-dom: '>=16.3.0' + peerDependenciesMeta: + mapbox-gl: + optional: true + maplibre-gl: + optional: true + react-oidc-context@2.2.2: resolution: {integrity: sha512-rke8goKuxxQhSAR11h8wVn56m7kEa1mcAfYDlIycsIgmbZOFzKA0Un0y0RodHZ/M/CG6u0JD1I8RKZHqRJjWnA==} engines: {node: '>=12.13.0'} @@ -3057,6 +3451,10 @@ packages: regenerator-runtime@0.14.0: resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} + regexp.prototype.flags@1.5.2: + resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + engines: {node: '>= 0.4'} + requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} @@ -3094,9 +3492,20 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + rw@0.1.4: + resolution: {integrity: sha512-vSj3D96kMcjNyqPcp65wBRIDImGSrUuMxngNNxvw8MQaO+aQ6llzRPH7XcJy5zrpb3wU++045+Uz/IDIM684iw==} + rw@1.3.3: resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + engines: {node: '>=0.4'} + + safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} + scheduler@0.23.0: resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} @@ -3112,6 +3521,22 @@ packages: engines: {node: '>=10'} hasBin: true + serialize-to-js@3.1.2: + resolution: {integrity: sha512-owllqNuDDEimQat7EPG0tH7JjO090xKNzUtYz6X+Sk2BXDnOCilDdNLwjWeFywG9xkJul1ULvtUQa9O4pUaY0w==} + engines: {node: '>=4.0.0'} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-value@2.0.1: + resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} + engines: {node: '>=0.10.0'} + shallowequal@1.1.0: resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} @@ -3123,6 +3548,10 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -3134,14 +3563,26 @@ packages: resolution: {integrity: sha512-jBgdDd+rQ+HkZF2/OHCmace5dvpos/aWQpcxuyRs9QUbPRnkEJmYVo81PIGpjIdpOcsnJ4rGjStfDHsbn+UVyw==} engines: {node: '>=0.10.0'} + sort-asc@0.2.0: + resolution: {integrity: sha512-umMGhjPeHAI6YjABoSTrFp2zaBtXBej1a0yKkuMUyjjqu6FJsTF+JYwCswWDg+zJfk/5npWUUbd33HH/WLzpaA==} + engines: {node: '>=0.10.0'} + sort-desc@0.1.1: resolution: {integrity: sha512-jfZacW5SKOP97BF5rX5kQfJmRVZP5/adDUTY8fCSPvNcXDVpUEe2pr/iKGlcyZzchRJZrswnp68fgk3qBXgkJw==} engines: {node: '>=0.10.0'} + sort-desc@0.2.0: + resolution: {integrity: sha512-NqZqyvL4VPW+RAxxXnB8gvE1kyikh8+pR+T+CXLksVRN9eiQqkQlPwqWYU0mF9Jm7UnctShlxLyAt1CaBOTL1w==} + engines: {node: '>=0.10.0'} + sort-object@0.3.2: resolution: {integrity: sha512-aAQiEdqFTTdsvUFxXm3umdo04J7MRljoVGbBlkH7BgNsMvVNAJyGj7C/wV1A8wHWAJj/YikeZbfuCKqhggNWGA==} engines: {node: '>=0.10.0'} + sort-object@3.0.3: + resolution: {integrity: sha512-nK7WOY8jik6zaG9CRwZTaD5O7ETWDLZYMM12pqY8htll+7dYeqGfEUPcUBHOpSJg2vJOrvFIY2Dl5cX2ih1hAQ==} + engines: {node: '>=0.10.0'} + source-map-js@1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} @@ -3150,6 +3591,10 @@ packages: resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} engines: {node: '>=0.10.0'} + split-string@3.1.0: + resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} + engines: {node: '>=0.10.0'} + ssf@0.11.2: resolution: {integrity: sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==} engines: {node: '>=0.8'} @@ -3158,6 +3603,17 @@ packages: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} + string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -3186,6 +3642,9 @@ packages: stylis@4.2.0: resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} + supercluster@8.0.1: + resolution: {integrity: sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==} + supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -3204,6 +3663,9 @@ packages: tiny-invariant@1.3.1: resolution: {integrity: sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==} + tinyqueue@3.0.0: + resolution: {integrity: sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==} + to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} @@ -3212,6 +3674,10 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + traverse@0.6.9: + resolution: {integrity: sha512-7bBrcF+/LQzSgFmT0X5YclVqQxtv7TDJ1f8Wj7ibBu/U6BMLeOpUxuZjV7rMc44UtKxlnMFigdhFAIszSX1DMg==} + engines: {node: '>= 0.4'} + ts-api-utils@1.0.2: resolution: {integrity: sha512-Cbu4nIqnEdd+THNEsBdkolnOXhg0I8XteoHaEKgvsxpsbWda4IsUut2c187HxywQCvveojow0Dgw/amxtSKVkQ==} engines: {node: '>=16.13.0'} @@ -3262,6 +3728,9 @@ packages: resolution: {integrity: sha512-e/nC/kJahvNYBcnwcqzuhFIvVELMMpbVXIoOOKdUn74SdQCvJd2JjqV2jZLv2EFOVbV4qLiO0lV7BxBXF21b6Q==} engines: {node: '>=18'} + tweakpane@4.0.4: + resolution: {integrity: sha512-RkWD54zDlEbnN01wQPk0ANHGbdCvlJx/E8A1QxhTfCbX+ROWos1Ws2MnhOm39aUGMOh+36TjUwpDmLfmwTr1Fg==} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -3274,11 +3743,40 @@ packages: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} + typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + engines: {node: '>= 0.4'} + + typedarray.prototype.slice@1.0.3: + resolution: {integrity: sha512-8WbVAQAUlENo1q3c3zZYuy5k9VzBQvp8AX9WOtbvyWlLM1v5JaSRmjubLjzHF4JFtptjH/5c/i95yaElvcjC0A==} + engines: {node: '>= 0.4'} + typescript@5.1.6: resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==} engines: {node: '>=14.17'} hasBin: true + typewise-core@1.2.0: + resolution: {integrity: sha512-2SCC/WLzj2SbUwzFOzqMCkz5amXLlxtJqDKTICqg30x+2DZxcfZN2MvQZmGfXWKNWaKK9pBPsvkcwv8bF/gxKg==} + + typewise@1.0.3: + resolution: {integrity: sha512-aXofE06xGhaQSPzt8hlTY+/YWQhm9P0jYUp1f2XtmW/3Bk0qzXcyFWAtPoo2uTGQj1ZwbDuSyuxicq+aDo8lCQ==} + + unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} @@ -3286,6 +3784,10 @@ packages: resolution: {integrity: sha512-450yJxT29qKMf3aoudzFpIciqpx6Pji3hEWaXqXmanbXF58LTAGCKxcJjxMXWu3iG+Mudgo3ZUfDB6YDFd/dAw==} engines: {node: '>=14.0'} + union-value@1.0.1: + resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} + engines: {node: '>=0.10.0'} + universalify@2.0.0: resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} engines: {node: '>= 10.0.0'} @@ -3404,12 +3906,29 @@ packages: vscode-uri@3.0.7: resolution: {integrity: sha512-eOpPHogvorZRobNqJGhapa0JdwaxpjVvyBp0QIUMRMSf8ZAlqOdEquKuRmw9Qwu0qXtJIWqFtMkmvJjUZmMjVA==} + vt-pbf@3.1.3: + resolution: {integrity: sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA==} + web-vitals@3.4.0: resolution: {integrity: sha512-n9fZ5/bG1oeDkyxLWyep0eahrNcPDF6bFqoyispt7xkW0xhDzpUBTgyDKqWDi1twT0MgH4HvvqzpUyh0ZxZV4A==} web-worker@1.2.0: resolution: {integrity: sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==} + wgs84@0.0.0: + resolution: {integrity: sha512-ANHlY4Rb5kHw40D0NJ6moaVfOCMrp9Gpd1R/AIQYg2ko4/jzcJ+TVXYYF6kXJqQwITvEZP4yEthjM7U6rYlljQ==} + + which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + + which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + engines: {node: '>= 0.4'} + + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -3434,6 +3953,10 @@ packages: xml-utils@1.7.0: resolution: {integrity: sha512-bWB489+RQQclC7A9OW8e5BzbT8Tu//jtAOvkYwewFr+Q9T9KDGvfzC1lp0pYPEQPEoPQLDkmxkepSC/2gIAZGw==} + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} @@ -3931,8 +4454,43 @@ snapshots: '@jridgewell/resolve-uri': 3.1.1 '@jridgewell/sourcemap-codec': 1.4.15 + '@mapbox/extent@0.4.0': {} + + '@mapbox/geojson-area@0.2.2': + dependencies: + wgs84: 0.0.0 + + '@mapbox/geojson-coords@0.0.2': + dependencies: + '@mapbox/geojson-normalize': 0.0.1 + geojson-flatten: 1.1.1 + + '@mapbox/geojson-extent@1.0.1': + dependencies: + '@mapbox/extent': 0.4.0 + '@mapbox/geojson-coords': 0.0.2 + rw: 0.1.4 + traverse: 0.6.9 + + '@mapbox/geojson-normalize@0.0.1': {} + + '@mapbox/geojson-rewind@0.5.2': + dependencies: + get-stream: 6.0.1 + minimist: 1.2.8 + '@mapbox/jsonlint-lines-primitives@2.0.2': {} + '@mapbox/mapbox-gl-draw@1.4.3': + dependencies: + '@mapbox/geojson-area': 0.2.2 + '@mapbox/geojson-extent': 1.0.1 + '@mapbox/geojson-normalize': 0.0.1 + '@mapbox/point-geometry': 0.1.0 + hat: 0.0.3 + lodash.isequal: 4.5.0 + xtend: 4.0.2 + '@mapbox/mapbox-gl-style-spec@13.28.0': dependencies: '@mapbox/jsonlint-lines-primitives': 2.0.2 @@ -3944,10 +4502,42 @@ snapshots: rw: 1.3.3 sort-object: 0.3.2 + '@mapbox/mapbox-gl-supported@3.0.0': {} + '@mapbox/point-geometry@0.1.0': {} + '@mapbox/tiny-sdf@2.0.6': {} + '@mapbox/unitbezier@0.0.0': {} + '@mapbox/unitbezier@0.0.1': {} + + '@mapbox/vector-tile@1.3.1': + dependencies: + '@mapbox/point-geometry': 0.1.0 + + '@mapbox/whoots-js@3.1.0': {} + + '@maplibre/maplibre-gl-style-spec@19.3.3': + dependencies: + '@mapbox/jsonlint-lines-primitives': 2.0.2 + '@mapbox/unitbezier': 0.0.1 + json-stringify-pretty-compact: 3.0.0 + minimist: 1.2.8 + rw: 1.3.3 + sort-object: 3.0.3 + + '@maplibre/maplibre-gl-style-spec@20.3.1': + dependencies: + '@mapbox/jsonlint-lines-primitives': 2.0.2 + '@mapbox/unitbezier': 0.0.1 + json-stringify-pretty-compact: 4.0.0 + minimist: 1.2.8 + quickselect: 2.0.0 + rw: 1.3.3 + sort-object: 3.0.3 + tinyqueue: 3.0.0 + '@mui/base@5.0.0-beta.11(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@babel/runtime': 7.23.2 @@ -4143,6 +4733,12 @@ snapshots: '@sinclair/typebox@0.27.8': {} + '@types/geojson-vt@3.2.5': + dependencies: + '@types/geojson': 7946.0.14 + + '@types/geojson@7946.0.14': {} + '@types/hoist-non-react-statics@3.3.1': dependencies: '@types/react': 18.2.15 @@ -4171,6 +4767,18 @@ snapshots: '@types/lodash@4.14.199': {} + '@types/mapbox-gl@3.4.0': + dependencies: + '@types/geojson': 7946.0.14 + + '@types/mapbox__point-geometry@0.1.4': {} + + '@types/mapbox__vector-tile@1.3.4': + dependencies: + '@types/geojson': 7946.0.14 + '@types/mapbox__point-geometry': 0.1.4 + '@types/pbf': 3.0.5 + '@types/md5@2.3.3': {} '@types/ngeohash@0.6.5': {} @@ -4185,6 +4793,8 @@ snapshots: '@types/parse-json@4.0.0': {} + '@types/pbf@3.0.5': {} + '@types/prop-types@15.7.9': {} '@types/react-dom@18.2.7': @@ -4221,6 +4831,10 @@ snapshots: '@types/react': 18.2.15 csstype: 3.1.2 + '@types/supercluster@7.1.3': + dependencies: + '@types/geojson': 7946.0.14 + '@types/use-sync-external-store@0.0.3': {} '@types/uuid@9.0.2': {} @@ -4366,12 +4980,36 @@ snapshots: argparse@2.0.1: {} + arr-union@3.1.0: {} + + array-buffer-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + is-array-buffer: 3.0.4 + array-union@2.1.0: {} + arraybuffer.prototype.slice@1.0.3: + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 + + assign-symbols@1.0.0: {} + asynckit@0.4.0: {} attr-accept@2.2.2: {} + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 + axios@1.6.0: dependencies: follow-redirects: 1.15.2 @@ -4419,6 +5057,23 @@ snapshots: buffer-from@1.1.2: {} + bytewise-core@1.2.3: + dependencies: + typewise-core: 1.2.0 + + bytewise@1.1.0: + dependencies: + bytewise-core: 1.2.3 + typewise: 1.0.3 + + call-bind@1.0.7: + 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.2 + callsites@3.1.0: {} camelize@1.0.1: {} @@ -4443,6 +5098,8 @@ snapshots: charenc@0.0.2: {} + cheap-ruler@4.0.0: {} + chokidar@3.5.3: dependencies: anymatch: 3.1.3 @@ -4526,6 +5183,24 @@ snapshots: custom-error-instance@2.1.1: {} + data-view-buffer@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-offset@1.0.0: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + debug@4.3.4(supports-color@5.5.0): dependencies: ms: 2.1.2 @@ -4534,6 +5209,18 @@ snapshots: deep-is@0.1.4: {} + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + delayed-stream@1.0.0: {} detect-libc@1.0.3: {} @@ -4573,6 +5260,8 @@ snapshots: earcut@2.2.4: {} + earcut@3.0.0: {} + echarts@5.4.3: dependencies: tslib: 2.3.0 @@ -4586,6 +5275,77 @@ snapshots: dependencies: is-arrayish: 0.2.1 + es-abstract@1.23.3: + dependencies: + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + data-view-buffer: 1.0.1 + data-view-byte-length: 1.0.1 + data-view-byte-offset: 1.0.0 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-set-tostringtag: 2.0.3 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 + globalthis: 1.0.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 + is-callable: 1.2.7 + is-data-view: 1.0.1 + is-negative-zero: 2.0.3 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + is-string: 1.0.7 + is-typed-array: 1.1.13 + is-weakref: 1.0.2 + object-inspect: 1.13.2 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 + safe-array-concat: 1.1.2 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.6 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.15 + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + + es-object-atoms@1.0.0: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.0.3: + dependencies: + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-to-primitive@1.2.1: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + esbuild-css-modules-plugin@3.0.3(esbuild@0.17.19): dependencies: esbuild: 0.17.19 @@ -4738,6 +5498,15 @@ snapshots: jest-message-util: 29.6.3 jest-util: 29.6.3 + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + extend-shallow@3.0.2: + dependencies: + assign-symbols: 1.0.0 + is-extendable: 1.0.1 + fast-deep-equal@3.1.3: {} fast-glob@3.3.1: @@ -4760,6 +5529,8 @@ snapshots: dependencies: reusify: 1.0.4 + fflate@0.8.2: {} + file-entry-cache@6.0.1: dependencies: flat-cache: 3.0.4 @@ -4788,6 +5559,10 @@ snapshots: follow-redirects@1.15.2: {} + for-each@0.3.3: + dependencies: + is-callable: 1.2.7 + form-data@4.0.0: dependencies: asynckit: 0.4.0 @@ -4820,8 +5595,23 @@ snapshots: function-bind@1.1.1: {} + function-bind@1.1.2: {} + + function.prototype.name@1.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + functions-have-names: 1.2.3 + + functions-have-names@1.2.3: {} + gensync@1.0.0-beta.2: {} + geojson-flatten@1.1.1: {} + + geojson-vt@4.0.2: {} + geotiff@2.0.7: dependencies: '@petamoriken/float16': 3.8.4 @@ -4832,6 +5622,26 @@ snapshots: web-worker: 1.2.0 xml-utils: 1.7.0 + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + get-stream@6.0.1: {} + + get-symbol-description@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + + get-value@2.0.6: {} + + gl-matrix@3.4.3: {} + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -4849,12 +5659,23 @@ snapshots: once: 1.4.0 path-is-absolute: 1.0.1 + global-prefix@3.0.0: + dependencies: + ini: 1.3.8 + kind-of: 6.0.3 + which: 1.3.1 + globals@11.12.0: {} globals@13.21.0: dependencies: type-fest: 0.20.2 + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.0.1 + globby@11.1.0: dependencies: array-union: 2.1.0 @@ -4868,18 +5689,44 @@ snapshots: dependencies: csstype: 3.1.2 + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + graceful-fs@4.2.11: {} graphemer@1.4.0: {} + grid-index@1.1.0: {} + + has-bigints@1.0.2: {} + has-flag@3.0.0: {} has-flag@4.0.0: {} + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.0.3 + has@1.0.3: dependencies: function-bind: 1.1.1 + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hat@0.0.3: {} + hoist-non-react-statics@3.3.2: dependencies: react-is: 16.13.1 @@ -4942,34 +5789,111 @@ snapshots: inherits@2.0.4: {} + ini@1.3.8: {} + inline-style-parser@0.1.1: {} + internal-slot@1.0.7: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.0.6 + + is-array-buffer@3.0.4: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + is-arrayish@0.2.1: {} + is-bigint@1.0.4: + dependencies: + has-bigints: 1.0.2 + is-binary-path@2.1.0: dependencies: binary-extensions: 2.2.0 + is-boolean-object@1.1.2: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + is-buffer@1.1.6: {} + is-callable@1.2.7: {} + is-core-module@2.13.0: dependencies: has: 1.0.3 + is-data-view@1.0.1: + dependencies: + is-typed-array: 1.1.13 + + is-date-object@1.0.5: + dependencies: + has-tostringtag: 1.0.2 + + is-extendable@0.1.1: {} + + is-extendable@1.0.1: + dependencies: + is-plain-object: 2.0.4 + is-extglob@2.1.1: {} is-glob@4.0.3: dependencies: is-extglob: 2.1.1 + is-negative-zero@2.0.3: {} + + is-number-object@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + is-number@7.0.0: {} is-path-inside@3.0.3: {} + is-plain-object@2.0.4: + dependencies: + isobject: 3.0.1 + + is-regex@1.1.4: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-shared-array-buffer@1.0.3: + dependencies: + call-bind: 1.0.7 + is-stream@2.0.1: {} + is-string@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-symbol@1.0.4: + dependencies: + has-symbols: 1.0.3 + + is-typed-array@1.1.13: + dependencies: + which-typed-array: 1.1.15 + + is-weakref@1.0.2: + dependencies: + call-bind: 1.0.7 + + isarray@2.0.5: {} + isexe@2.0.0: {} + isobject@3.0.1: {} + jest-diff@29.6.3: dependencies: chalk: 4.1.2 @@ -5025,6 +5949,10 @@ snapshots: json-stringify-pretty-compact@2.0.0: {} + json-stringify-pretty-compact@3.0.0: {} + + json-stringify-pretty-compact@4.0.0: {} + json5@2.2.3: {} jsonfile@6.1.0: @@ -5035,6 +5963,10 @@ snapshots: jwt-decode@3.1.2: {} + kdbush@4.0.2: {} + + kind-of@6.0.3: {} + lerc@3.0.0: {} levn@0.4.1: @@ -5112,6 +6044,8 @@ snapshots: lodash.debounce@4.0.8: {} + lodash.isequal@4.5.0: {} + lodash.merge@4.6.2: {} lodash.pick@4.4.0: {} @@ -5139,8 +6073,67 @@ snapshots: lz-string@1.5.0: {} + mapbox-gl@3.6.0: + dependencies: + '@mapbox/jsonlint-lines-primitives': 2.0.2 + '@mapbox/mapbox-gl-supported': 3.0.0 + '@mapbox/point-geometry': 0.1.0 + '@mapbox/tiny-sdf': 2.0.6 + '@mapbox/unitbezier': 0.0.1 + '@mapbox/vector-tile': 1.3.1 + '@mapbox/whoots-js': 3.1.0 + '@types/geojson': 7946.0.14 + '@types/mapbox__vector-tile': 1.3.4 + cheap-ruler: 4.0.0 + csscolorparser: 1.0.3 + earcut: 3.0.0 + fflate: 0.8.2 + geojson-vt: 4.0.2 + gl-matrix: 3.4.3 + grid-index: 1.1.0 + kdbush: 4.0.2 + murmurhash-js: 1.0.0 + pbf: 3.3.0 + potpack: 2.0.0 + quickselect: 3.0.0 + rw: 1.3.3 + serialize-to-js: 3.1.2 + supercluster: 8.0.1 + tinyqueue: 3.0.0 + tweakpane: 4.0.4 + vt-pbf: 3.1.3 + mapbox-to-css-font@2.4.2: {} + maplibre-gl@4.5.2: + dependencies: + '@mapbox/geojson-rewind': 0.5.2 + '@mapbox/jsonlint-lines-primitives': 2.0.2 + '@mapbox/point-geometry': 0.1.0 + '@mapbox/tiny-sdf': 2.0.6 + '@mapbox/unitbezier': 0.0.1 + '@mapbox/vector-tile': 1.3.1 + '@mapbox/whoots-js': 3.1.0 + '@maplibre/maplibre-gl-style-spec': 20.3.1 + '@types/geojson': 7946.0.14 + '@types/geojson-vt': 3.2.5 + '@types/mapbox__point-geometry': 0.1.4 + '@types/mapbox__vector-tile': 1.3.4 + '@types/pbf': 3.0.5 + '@types/supercluster': 7.1.3 + earcut: 3.0.0 + geojson-vt: 4.0.2 + gl-matrix: 3.4.3 + global-prefix: 3.0.0 + kdbush: 4.0.2 + murmurhash-js: 1.0.0 + pbf: 3.3.0 + potpack: 2.0.0 + quickselect: 3.0.0 + supercluster: 8.0.1 + tinyqueue: 3.0.0 + vt-pbf: 3.1.3 + md5@2.3.0: dependencies: charenc: 0.0.2 @@ -5172,6 +6165,8 @@ snapshots: ms@2.1.3: {} + murmurhash-js@1.0.0: {} + nanoid@3.3.6: {} natural-compare@1.4.0: {} @@ -5197,6 +6192,17 @@ snapshots: object-assign@4.1.1: {} + object-inspect@1.13.2: {} + + object-keys@1.1.1: {} + + object.assign@4.1.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + oidc-client-ts@2.2.4: dependencies: crypto-js: 4.1.1 @@ -5267,6 +6273,11 @@ snapshots: ieee754: 1.2.1 resolve-protobuf-schema: 2.1.0 + pbf@3.3.0: + dependencies: + ieee754: 1.2.1 + resolve-protobuf-schema: 2.1.0 + picocolors@1.0.0: {} picomatch@2.3.1: {} @@ -5279,6 +6290,8 @@ snapshots: optionalDependencies: fsevents: 2.3.2 + possible-typed-array-names@1.0.0: {} + postcss-value-parser@4.2.0: {} postcss@8.4.28: @@ -5287,6 +6300,8 @@ snapshots: picocolors: 1.0.0 source-map-js: 1.0.2 + potpack@2.0.0: {} + prelude-ls@1.2.1: {} prettier@3.1.0: {} @@ -5323,6 +6338,8 @@ snapshots: quickselect@2.0.0: {} + quickselect@3.0.0: {} + rbush@3.0.1: dependencies: quickselect: 2.0.0 @@ -5353,6 +6370,16 @@ snapshots: react-is@18.2.0: {} + react-map-gl@7.1.7(mapbox-gl@3.6.0)(maplibre-gl@4.5.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + dependencies: + '@maplibre/maplibre-gl-style-spec': 19.3.3 + '@types/mapbox-gl': 3.4.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + optionalDependencies: + mapbox-gl: 3.6.0 + maplibre-gl: 4.5.2 + react-oidc-context@2.2.2(oidc-client-ts@2.2.4)(react@18.2.0): dependencies: oidc-client-ts: 2.2.4 @@ -5416,6 +6443,13 @@ snapshots: regenerator-runtime@0.14.0: {} + regexp.prototype.flags@1.5.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 + requires-port@1.0.0: {} reselect@4.1.8: {} @@ -5448,8 +6482,23 @@ snapshots: dependencies: queue-microtask: 1.2.3 + rw@0.1.4: {} + rw@1.3.3: {} + safe-array-concat@1.1.2: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + isarray: 2.0.5 + + safe-regex-test@1.0.3: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-regex: 1.1.4 + scheduler@0.23.0: dependencies: loose-envify: 1.4.0 @@ -5462,6 +6511,31 @@ snapshots: dependencies: lru-cache: 6.0.0 + serialize-to-js@3.1.2: {} + + set-function-length@1.2.2: + 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 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-value@2.0.1: + dependencies: + extend-shallow: 2.0.1 + is-extendable: 0.1.1 + is-plain-object: 2.0.4 + split-string: 3.1.0 + shallowequal@1.1.0: {} shebang-command@2.0.0: @@ -5470,23 +6544,47 @@ snapshots: shebang-regex@3.0.0: {} + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.2 + signal-exit@3.0.7: {} slash@3.0.0: {} sort-asc@0.1.0: {} + sort-asc@0.2.0: {} + sort-desc@0.1.1: {} + sort-desc@0.2.0: {} + sort-object@0.3.2: dependencies: sort-asc: 0.1.0 sort-desc: 0.1.1 + sort-object@3.0.3: + dependencies: + bytewise: 1.1.0 + get-value: 2.0.6 + is-extendable: 0.1.1 + sort-asc: 0.2.0 + sort-desc: 0.2.0 + union-value: 1.0.1 + source-map-js@1.0.2: {} source-map@0.5.7: {} + split-string@3.1.0: + dependencies: + extend-shallow: 3.0.2 + ssf@0.11.2: dependencies: frac: 1.1.2 @@ -5495,6 +6593,25 @@ snapshots: dependencies: escape-string-regexp: 2.0.0 + string.prototype.trim@1.2.9: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + string.prototype.trimend@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -5531,6 +6648,10 @@ snapshots: stylis@4.2.0: {} + supercluster@8.0.1: + dependencies: + kdbush: 4.0.2 + supports-color@5.5.0: dependencies: has-flag: 3.0.0 @@ -5545,12 +6666,20 @@ snapshots: tiny-invariant@1.3.1: {} + tinyqueue@3.0.0: {} + to-fast-properties@2.0.0: {} to-regex-range@5.0.1: dependencies: is-number: 7.0.0 + traverse@0.6.9: + dependencies: + gopd: 1.0.1 + typedarray.prototype.slice: 1.0.3 + which-typed-array: 1.1.15 + ts-api-utils@1.0.2(typescript@5.1.6): dependencies: typescript: 5.1.6 @@ -5596,6 +6725,8 @@ snapshots: proper-lockfile: 4.1.2 url-parse: 1.5.10 + tweakpane@4.0.4: {} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -5604,14 +6735,75 @@ snapshots: type-fest@0.21.3: {} + typed-array-buffer@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 + + typed-array-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-byte-offset@1.0.2: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-length@1.0.6: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 + + typedarray.prototype.slice@1.0.3: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + typed-array-buffer: 1.0.2 + typed-array-byte-offset: 1.0.2 + typescript@5.1.6: {} + typewise-core@1.2.0: {} + + typewise@1.0.3: + dependencies: + typewise-core: 1.2.0 + + unbox-primitive@1.0.2: + dependencies: + call-bind: 1.0.7 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + undici-types@5.26.5: {} undici@5.25.4: dependencies: '@fastify/busboy': 2.0.0 + union-value@1.0.1: + dependencies: + arr-union: 3.1.0 + get-value: 2.0.6 + is-extendable: 0.1.1 + set-value: 2.0.1 + universalify@2.0.0: {} update-browserslist-db@1.0.11(browserslist@4.21.10): @@ -5699,10 +6891,38 @@ snapshots: vscode-uri@3.0.7: {} + vt-pbf@3.1.3: + dependencies: + '@mapbox/point-geometry': 0.1.0 + '@mapbox/vector-tile': 1.3.1 + pbf: 3.3.0 + web-vitals@3.4.0: {} web-worker@1.2.0: {} + wgs84@0.0.0: {} + + which-boxed-primitive@1.0.2: + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + + which-typed-array@1.1.15: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.2 + + which@1.3.1: + dependencies: + isexe: 2.0.0 + which@2.0.2: dependencies: isexe: 2.0.0 @@ -5725,6 +6945,8 @@ snapshots: xml-utils@1.7.0: {} + xtend@4.0.2: {} + yallist@3.1.1: {} yallist@4.0.0: {} From 10d7a533acf762a06d3b0d228df395e833d71d64 Mon Sep 17 00:00:00 2001 From: D-Unit Date: Thu, 22 Aug 2024 13:38:16 +0200 Subject: [PATCH 02/44] updates --- .../src/features/metadata/fields/Map.tsx | 150 +++++++++++++----- .../deposit/src/languages/locales/en/map.json | 5 +- .../deposit/src/languages/locales/nl/map.json | 2 +- 3 files changed, 112 insertions(+), 45 deletions(-) diff --git a/packages/deposit/src/features/metadata/fields/Map.tsx b/packages/deposit/src/features/metadata/fields/Map.tsx index a76a07bd..1ce1f86b 100644 --- a/packages/deposit/src/features/metadata/fields/Map.tsx +++ b/packages/deposit/src/features/metadata/fields/Map.tsx @@ -6,7 +6,7 @@ import TextField from "@mui/material/TextField"; import IconButton from "@mui/material/IconButton"; import Tooltip from "@mui/material/Tooltip"; import InputAdornment from "@mui/material/InputAdornment"; -import { useTranslation } from "react-i18next"; +import { useTranslation, Trans } from "react-i18next"; import { useAppDispatch, useAppSelector } from "../../../redux/hooks"; import { StatusIcon } from "../../generic/Icons"; import { setField } from "../metadataSlice"; @@ -20,6 +20,7 @@ import 'maplibre-gl/dist/maplibre-gl.css'; import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css'; import './Map.css'; +import InfoRoundedIcon from '@mui/icons-material/InfoRounded'; import List from '@mui/material/List'; import ListSubheader from '@mui/material/ListSubheader'; import ListItem from '@mui/material/ListItem'; @@ -30,6 +31,12 @@ import PolylineIcon from '@mui/icons-material/Polyline'; import PlaceIcon from '@mui/icons-material/Place'; import HighlightAltIcon from '@mui/icons-material/HighlightAlt'; import PentagonIcon from '@mui/icons-material/Pentagon'; +import { useFetchGeonamesFreeTextQuery } from "../api/geonames"; +import type { QueryReturnType } from "../../../types/Api"; +import CircularProgress from "@mui/material/CircularProgress"; +import Autocomplete from "@mui/material/Autocomplete"; +import Typography from "@mui/material/Typography"; +import { useDebounce } from "use-debounce"; /** * Map field @@ -47,52 +54,38 @@ const DrawMap = ({ const status = getFieldStatus(field); const { t, i18n } = useTranslation("metadata"); const formDisabled = useAppSelector(getFormDisabled); + const [geonamesValue, setGeonamesValue] = useState(""); + const [viewState, setViewState] = useState({ + longitude: 4.342779, + latitude: 52.080738, + zoom: 8, + }); + + // move map to selected GeoNames value + useEffect(() => { + geonamesValue && setViewState({ + longitude: geonamesValue.coordinates[1], + latitude: geonamesValue.coordinates[0], + zoom: 10, + }); + }, [geonamesValue]) return ( - - - dispatch( - setField({ - sectionIndex: sectionIndex, - id: field.id, - value: e.target.value, - }), - ) - } - placeholder={field.placeholder} - InputProps={{ - endAdornment: ( - - - - ), - }} - inputProps={{ "data-testid": `${field.name}-${field.id}` }} - /> - + setViewState(e.viewState)} style={{ width: '100%', height: 400, + borderRadius: '5px', + border: "1px solid rgba(0,0,0,0.23)" }} mapStyle={`https://api.maptiler.com/maps/landscape/style.json?key=${import.meta.env.VITE_MAPTILER_API_KEY}`} > @@ -111,6 +104,8 @@ const controls = ["simple_select", "draw_point", "draw_line_string", "draw_polyg const DrawControls = () => { const { t } = useTranslation("map"); const [ selectedMode, setSelectedMode ] = useState(controls[0]); + + // move this to redux store const [ features, setFeatures ] = useState({}); console.log(features) @@ -148,8 +143,18 @@ const DrawControls = () => { > + {t('draw')} + , + ]} + /> + }> + + }> {controls.map(control => @@ -158,7 +163,7 @@ const DrawControls = () => { onClick={() => setSelectedMode(control)} selected={control === selectedMode} > - + { control === "simple_select" ? @@ -216,3 +221,64 @@ const DrawControl = ({ return null; } + +const GeonamesApiField = ({ + value, + setValue, + disabled, + label +}) => { + const { t } = useTranslation("metadata"); + const [inputValue, setInputValue] = useState(""); + const debouncedInputValue = useDebounce(inputValue, 500)[0]; + // Fetch data on input change + const { data, isFetching, isLoading } = + useFetchGeonamesFreeTextQuery(debouncedInputValue, { + skip: debouncedInputValue === "", + }); + + return ( + ( + + )} + onChange={(_e, newValue, _reason) => setValue(newValue as OptionsType)} + filterOptions={(x) => x} + onInputChange={(e, newValue) => { + e && e.type === "change" && setInputValue(newValue); + e && (e.type === "click" || e.type === "blur") && setInputValue(""); + }} + noOptionsText={!inputValue ? t("startTyping", {api: t("geonames")}) : t("noResults")} + loading={isLoading || isFetching || inputValue !== debouncedInputValue} + loadingText={ + + {t("loading")} + + } + forcePopupIcon + clearOnBlur + disabled={disabled} + /> + ); +}; \ No newline at end of file diff --git a/packages/deposit/src/languages/locales/en/map.json b/packages/deposit/src/languages/locales/en/map.json index abda175b..45ccea56 100644 --- a/packages/deposit/src/languages/locales/en/map.json +++ b/packages/deposit/src/languages/locales/en/map.json @@ -1,7 +1,8 @@ { "draw": "Draw features", - "simple_select": "Select/move", + "simple_select": "Select", "draw_point": "Point", "draw_line_string": "Line", - "draw_polygon": "Polygon" + "draw_polygon": "Polygon", + "drawExplanation": "<0>Select a shape type and click on the map to start drawing. In case of a multipoint shape, double click or press enter to finish drawing.<0>To delete a shape, select it and press 'Delete' on your keyboard." } \ No newline at end of file diff --git a/packages/deposit/src/languages/locales/nl/map.json b/packages/deposit/src/languages/locales/nl/map.json index abda175b..11fd0cea 100644 --- a/packages/deposit/src/languages/locales/nl/map.json +++ b/packages/deposit/src/languages/locales/nl/map.json @@ -1,6 +1,6 @@ { "draw": "Draw features", - "simple_select": "Select/move", + "simple_select": "Select", "draw_point": "Point", "draw_line_string": "Line", "draw_polygon": "Polygon" From a63013c524b479df62b5ca5ad5eac43786058dee Mon Sep 17 00:00:00 2001 From: D-Unit Date: Fri, 23 Aug 2024 13:17:34 +0200 Subject: [PATCH 03/44] updates to map, updated mui --- apps/4tu/package.json | 6 +- apps/cat/package.json | 9 +- apps/digitaltwins/package.json | 2 +- .../src/config/formsections/citation.ts | 4 +- apps/ohsmart/package.json | 2 +- apps/rda/package.json | 9 +- apps/swh/package.json | 6 +- packages/deposit/package.json | 4 +- .../src/features/metadata/fields/Map.tsx | 191 ++++++--- .../deposit/src/languages/locales/en/map.json | 8 - .../src/languages/locales/en/metadata.json | 10 +- .../deposit/src/languages/locales/nl/map.json | 7 - .../src/languages/locales/nl/metadata.json | 10 +- packages/deposit/src/types/MetadataFields.ts | 1 + packages/file-mapper/package.json | 56 +-- packages/layout/package.json | 4 +- packages/pages/package.json | 2 +- packages/repo-advisor/package.json | 58 +-- packages/theme/package.json | 2 +- packages/user-auth/package.json | 2 +- packages/utils/error/package.json | 36 +- pnpm-lock.yaml | 363 +++++++++++------- 22 files changed, 492 insertions(+), 300 deletions(-) delete mode 100644 packages/deposit/src/languages/locales/en/map.json delete mode 100644 packages/deposit/src/languages/locales/nl/map.json diff --git a/apps/4tu/package.json b/apps/4tu/package.json index 48aebc6f..1431e3bd 100644 --- a/apps/4tu/package.json +++ b/apps/4tu/package.json @@ -18,13 +18,13 @@ "@dans-framework/user-auth": "workspace:*", "@dans-framework/utils": "workspace:*", "@fontsource/roboto": "^5.0.7", - "@mui/material": "^5.14.3", + "@mui/material": "^5.16.7", "framer-motion": "^10.15.0", - "lz-string": "^1.5.0", - "notistack": "^3.0.1", "i18next": "^23.4.1", "i18next-browser-languagedetector": "^7.1.0", "i18next-resources-to-backend": "^1.1.4", + "lz-string": "^1.5.0", + "notistack": "^3.0.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-i18next": "^13.0.3", diff --git a/apps/cat/package.json b/apps/cat/package.json index 804ef618..7c42a5ba 100644 --- a/apps/cat/package.json +++ b/apps/cat/package.json @@ -10,16 +10,16 @@ "preview": "vite preview" }, "dependencies": { - "@dans-framework/user-auth": "workspace:*", "@dans-framework/deposit": "workspace:*", - "@dans-framework/utils": "workspace:*", "@dans-framework/layout": "workspace:*", "@dans-framework/pages": "workspace:*", - "@dans-framework/theme": "workspace:*", "@dans-framework/rdt-search-ui": "workspace:*", + "@dans-framework/theme": "workspace:*", + "@dans-framework/user-auth": "workspace:*", + "@dans-framework/utils": "workspace:*", "@fontsource/roboto": "^5.0.7", "@mui/icons-material": "^5.14.3", - "@mui/material": "^5.14.3", + "@mui/material": "^5.16.7", "html-react-parser": "^4.2.2", "i18next": "^23.4.1", "i18next-browser-languagedetector": "^7.1.0", @@ -40,4 +40,3 @@ "vite-plugin-checker": "^0.6.2" } } - diff --git a/apps/digitaltwins/package.json b/apps/digitaltwins/package.json index 929cfbb3..43c7a5a9 100644 --- a/apps/digitaltwins/package.json +++ b/apps/digitaltwins/package.json @@ -18,7 +18,7 @@ "@dans-framework/user-auth": "workspace:*", "@dans-framework/utils": "workspace:*", "@fontsource/roboto": "^5.0.7", - "@mui/material": "^5.14.3", + "@mui/material": "^5.16.7", "i18next": "^23.4.1", "i18next-browser-languagedetector": "^7.1.0", "i18next-resources-to-backend": "^1.1.4", diff --git a/apps/digitaltwins/src/config/formsections/citation.ts b/apps/digitaltwins/src/config/formsections/citation.ts index b2c2c925..0d9b8c79 100644 --- a/apps/digitaltwins/src/config/formsections/citation.ts +++ b/apps/digitaltwins/src/config/formsections/citation.ts @@ -50,13 +50,13 @@ const section: InitialSectionType = { { type: "drawmap", label: { - en: "Map", + en: "Find on a map and draw locations", nl: "Map", }, name: "map", required: true, description: { - en: "Some desc", + en: "Search and select to open and focus a map on this location. Then select a shape type and start drawing.", nl: "Iets van beschrijving", }, fullWidth: true, diff --git a/apps/ohsmart/package.json b/apps/ohsmart/package.json index f3223092..d72a78fd 100644 --- a/apps/ohsmart/package.json +++ b/apps/ohsmart/package.json @@ -17,7 +17,7 @@ "@dans-framework/user-auth": "workspace:*", "@dans-framework/utils": "workspace:*", "@fontsource/roboto": "^5.0.7", - "@mui/material": "^5.14.3", + "@mui/material": "^5.16.7", "i18next": "^23.4.1", "i18next-browser-languagedetector": "^7.1.0", "i18next-resources-to-backend": "^1.1.4", diff --git a/apps/rda/package.json b/apps/rda/package.json index dd77bbea..a6d442e1 100644 --- a/apps/rda/package.json +++ b/apps/rda/package.json @@ -10,16 +10,16 @@ "preview": "vite preview" }, "dependencies": { - "@dans-framework/user-auth": "workspace:*", "@dans-framework/deposit": "workspace:*", - "@dans-framework/utils": "workspace:*", "@dans-framework/layout": "workspace:*", "@dans-framework/pages": "workspace:*", - "@dans-framework/theme": "workspace:*", "@dans-framework/rdt-search-ui": "workspace:*", + "@dans-framework/theme": "workspace:*", + "@dans-framework/user-auth": "workspace:*", + "@dans-framework/utils": "workspace:*", "@fontsource/roboto": "^5.0.7", "@mui/icons-material": "^5.14.3", - "@mui/material": "^5.14.3", + "@mui/material": "^5.16.7", "html-react-parser": "^4.2.2", "i18next": "^23.4.1", "i18next-browser-languagedetector": "^7.1.0", @@ -40,4 +40,3 @@ "vite-plugin-checker": "^0.6.2" } } - diff --git a/apps/swh/package.json b/apps/swh/package.json index 713fe569..3874bff7 100644 --- a/apps/swh/package.json +++ b/apps/swh/package.json @@ -10,14 +10,14 @@ "preview": "vite preview" }, "dependencies": { - "@dans-framework/user-auth": "workspace:*", "@dans-framework/deposit": "workspace:*", - "@dans-framework/utils": "workspace:*", "@dans-framework/layout": "workspace:*", "@dans-framework/pages": "workspace:*", "@dans-framework/theme": "workspace:*", + "@dans-framework/user-auth": "workspace:*", + "@dans-framework/utils": "workspace:*", "@fontsource/roboto": "^5.0.7", - "@mui/material": "^5.14.3", + "@mui/material": "^5.16.7", "i18next": "^23.4.1", "i18next-browser-languagedetector": "^7.1.0", "i18next-resources-to-backend": "^1.1.4", diff --git a/packages/deposit/package.json b/packages/deposit/package.json index 8f8a4866..87368982 100644 --- a/packages/deposit/package.json +++ b/packages/deposit/package.json @@ -11,7 +11,7 @@ "@emotion/styled": "^11.11.0", "@mapbox/mapbox-gl-draw": "^1.4.3", "@mui/icons-material": "^5.14.3", - "@mui/material": "^5.14.3", + "@mui/material": "^5.16.7", "@mui/x-date-pickers": "^6.11.0", "@reduxjs/toolkit": "^1.9.5", "axios": "^1.6.0", @@ -41,6 +41,8 @@ "devDependencies": { "@dans-framework/pages": "workspace:*", "@types/jest": "^29.5.3", + "@types/mapbox-gl": "^3.4.0", + "@types/mapbox__mapbox-gl-draw": "^1.4.7", "@types/node": "^20.4.7", "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", diff --git a/packages/deposit/src/features/metadata/fields/Map.tsx b/packages/deposit/src/features/metadata/fields/Map.tsx index 1ce1f86b..558a064e 100644 --- a/packages/deposit/src/features/metadata/fields/Map.tsx +++ b/packages/deposit/src/features/metadata/fields/Map.tsx @@ -3,15 +3,14 @@ import Box from "@mui/material/Box"; import Paper from "@mui/material/Paper"; import Stack from "@mui/material/Stack"; import TextField from "@mui/material/TextField"; -import IconButton from "@mui/material/IconButton"; +import Button from "@mui/material/Button"; import Tooltip from "@mui/material/Tooltip"; -import InputAdornment from "@mui/material/InputAdornment"; import { useTranslation, Trans } from "react-i18next"; import { useAppDispatch, useAppSelector } from "../../../redux/hooks"; import { StatusIcon } from "../../generic/Icons"; import { setField } from "../metadataSlice"; import { getFieldStatus } from "../metadataHelpers"; -import type { TextFieldProps } from "../../../types/MetadataProps"; +import type { OptionsType } from "../../../types/MetadataFields"; import { lookupLanguageString } from "@dans-framework/utils"; import { getFormDisabled } from "../../../deposit/depositSlice"; import Map, { ScaleControl, NavigationControl, useControl } from "react-map-gl/maplibre"; @@ -28,6 +27,7 @@ import ListItemButton from '@mui/material/ListItemButton'; import ListItemIcon from '@mui/material/ListItemIcon'; import ListItemText from '@mui/material/ListItemText'; import PolylineIcon from '@mui/icons-material/Polyline'; +import DeleteIcon from '@mui/icons-material/Delete'; import PlaceIcon from '@mui/icons-material/Place'; import HighlightAltIcon from '@mui/icons-material/HighlightAlt'; import PentagonIcon from '@mui/icons-material/Pentagon'; @@ -37,6 +37,8 @@ import CircularProgress from "@mui/material/CircularProgress"; import Autocomplete from "@mui/material/Autocomplete"; import Typography from "@mui/material/Typography"; import { useDebounce } from "use-debounce"; +import Collapse from '@mui/material/Collapse'; +import PublicIcon from '@mui/icons-material/Public'; /** * Map field @@ -54,7 +56,8 @@ const DrawMap = ({ const status = getFieldStatus(field); const { t, i18n } = useTranslation("metadata"); const formDisabled = useAppSelector(getFormDisabled); - const [geonamesValue, setGeonamesValue] = useState(""); + const [geonamesValue, setGeonamesValue] = useState(); + const [openMap, setOpenMap] = useState(false); const [viewState, setViewState] = useState({ longitude: 4.342779, latitude: 52.080738, @@ -63,36 +66,55 @@ const DrawMap = ({ // move map to selected GeoNames value useEffect(() => { - geonamesValue && setViewState({ - longitude: geonamesValue.coordinates[1], - latitude: geonamesValue.coordinates[0], - zoom: 10, - }); - }, [geonamesValue]) + if (geonamesValue) { + setViewState({ + longitude: geonamesValue.coordinates![1], + latitude: geonamesValue.coordinates![0], + zoom: 10, + }); + setOpenMap(true); + } + }, [geonamesValue]); return ( - - setViewState(e.viewState)} - style={{ - width: '100%', - height: 400, - borderRadius: '5px', - border: "1px solid rgba(0,0,0,0.23)" - }} - mapStyle={`https://api.maptiler.com/maps/landscape/style.json?key=${import.meta.env.VITE_MAPTILER_API_KEY}`} - > - - - - + + + + + + + setViewState(e.viewState)} + style={{ + width: '100%', + height: 400, + borderRadius: '5px', + border: "1px solid rgba(0,0,0,0.23)" + }} + mapStyle={`https://api.maptiler.com/maps/landscape/style.json?key=${import.meta.env.VITE_MAPTILER_API_KEY}`} + > + + + + + ); }; @@ -101,38 +123,63 @@ export default DrawMap; const controls = ["simple_select", "draw_point", "draw_line_string", "draw_polygon"]; +interface Feature { + id?: string | number; +} + +type FeaturesEvent = {features: Feature[], action?: string}; + +type FeatureObject = { + [id: string]: Feature; +} + const DrawControls = () => { - const { t } = useTranslation("map"); + const { t } = useTranslation("metadata"); const [ selectedMode, setSelectedMode ] = useState(controls[0]); - // move this to redux store - const [ features, setFeatures ] = useState({}); - + // write this to redux store + const [ features, setFeatures ] = useState(); console.log(features) - const onUpdate = useCallback(e => { + const onUpdate = useCallback((e: FeaturesEvent) => { setFeatures(currFeatures => { const newFeatures = {...currFeatures}; for (const f of e.features) { - newFeatures[f.id] = f; + if (f.id) { + newFeatures[f.id] = f; + } } return newFeatures; }); setSelectedMode(controls[0]) }, []); - const onDelete = useCallback(e => { - console.log('delete called') + const onDelete = useCallback((e: FeaturesEvent) => { setFeatures(currFeatures => { const newFeatures = {...currFeatures}; for (const f of e.features) { - delete newFeatures[f.id]; + if (f.id) { + delete newFeatures[f.id]; + } } return newFeatures; }); setSelectedMode(controls[0]) }, []); + // manual key listener, since delete is broken in the map libre / mapbox draw combo + const handleKeyDown = useCallback((event: KeyboardEvent, drawControl: MapboxDraw) => { + const selectedFeatures = drawControl.getSelected(); + if (event.key === 'Delete' && selectedFeatures.features.length > 0) { + event.preventDefault(); + event.stopPropagation(); + // remove features from store + onDelete(selectedFeatures); + // remove them from map + drawControl.trash(); + } + }, []); + return ( { )} + + { + // just simulate the delete keyboard press event on the map canvas + const target = document.querySelector('.maplibregl-canvas'); + if (target) { + const keyboardEvent = new KeyboardEvent('keydown', { + key: 'Delete', + code: 'Delete', + keyCode: 46, + charCode: 46, + bubbles: true, + cancelable: true + }); + target.dispatchEvent(keyboardEvent); + } + }}> + + + + + + ) } +type DrawControlProps = { + onCreate: (e: FeaturesEvent) => void; + onUpdate: (e: FeaturesEvent) => void; + onDelete: (e: FeaturesEvent) => void; + mode: string; + onKeyDown: (e: KeyboardEvent, c: MapboxDraw) => void; +}; + +// Some MapboxDraw typescript issues, changed to any type for now + const DrawControl = ({ onCreate, onUpdate, onDelete, - mode -}) => { - const control = useControl( + mode, + onKeyDown, +}: DrawControlProps) => { + const control = useControl( () => new MapboxDraw({ + // remove default controls displayControlsDefault: false, defaultMode: mode, keybindings: true, + clickBuffer: 5, }), - ({map}: {map: MapRef}) => { + ({map}: {map: any}) => { map.on('draw.create', onCreate); map.on('draw.update', onUpdate); map.on('draw.delete', onDelete); + + // Attach the keydown event to the map container + const canvas = map.getCanvas(); + const handleKeyDownInternal = (event: KeyboardEvent) => onKeyDown(event, control); + canvas.addEventListener('keydown', handleKeyDownInternal); + // Store the reference to the internal handler for cleanup + map._handleKeyDownInternal = handleKeyDownInternal; + }, - ({map}: {map: MapRef}) => { + ({map}: {map: any}) => { map.off('draw.create', onCreate); map.off('draw.update', onUpdate); map.off('draw.delete', onDelete); + + // Clean up the keydown event listener + const canvas = map.getCanvas(); + canvas.removeEventListener('keydown', map._handleKeyDownInternal); } ); @@ -227,6 +322,11 @@ const GeonamesApiField = ({ setValue, disabled, label +}: { + value?: OptionsType; + setValue: (v: OptionsType) => void; + disabled: boolean; + label?: string; }) => { const { t } = useTranslation("metadata"); const [inputValue, setInputValue] = useState(""); @@ -279,6 +379,7 @@ const GeonamesApiField = ({ forcePopupIcon clearOnBlur disabled={disabled} + getOptionKey={(option) => option.value} /> ); }; \ No newline at end of file diff --git a/packages/deposit/src/languages/locales/en/map.json b/packages/deposit/src/languages/locales/en/map.json deleted file mode 100644 index 45ccea56..00000000 --- a/packages/deposit/src/languages/locales/en/map.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "draw": "Draw features", - "simple_select": "Select", - "draw_point": "Point", - "draw_line_string": "Line", - "draw_polygon": "Polygon", - "drawExplanation": "<0>Select a shape type and click on the map to start drawing. In case of a multipoint shape, double click or press enter to finish drawing.<0>To delete a shape, select it and press 'Delete' on your keyboard." -} \ No newline at end of file diff --git a/packages/deposit/src/languages/locales/en/metadata.json b/packages/deposit/src/languages/locales/en/metadata.json index 22a33706..2fedc16e 100644 --- a/packages/deposit/src/languages/locales/en/metadata.json +++ b/packages/deposit/src/languages/locales/en/metadata.json @@ -43,5 +43,13 @@ "dateMaxRange": "Date must be before end date, or date too far in the future", "apiFetchError": "Could not get data from {{api}}", "generate": "Regenerate value", - "generateDisabled": "Cannot generate value, as not all required fields have been filled in or are public data." + "generateDisabled": "Cannot generate value, as not all required fields have been filled in or are public data.", + "draw": "Draw", + "simple_select": "Select", + "draw_point": "Point", + "draw_line_string": "Line", + "draw_polygon": "Polygon", + "drawExplanation": "<0>Select a shape type and click on the map to start drawing. In case of a multipoint shape, double click or press 'Enter' to finish drawing.<0>To edit a shape, click on it to select it, and drag it around, or add or move individual points.<0>To delete a shape, select it and press 'Delete' on your keyboard.", + "delete": "Delete", + "toggleMap": "Toggle map" } \ No newline at end of file diff --git a/packages/deposit/src/languages/locales/nl/map.json b/packages/deposit/src/languages/locales/nl/map.json deleted file mode 100644 index 11fd0cea..00000000 --- a/packages/deposit/src/languages/locales/nl/map.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "draw": "Draw features", - "simple_select": "Select", - "draw_point": "Point", - "draw_line_string": "Line", - "draw_polygon": "Polygon" -} \ No newline at end of file diff --git a/packages/deposit/src/languages/locales/nl/metadata.json b/packages/deposit/src/languages/locales/nl/metadata.json index 844dabee..ce6c0982 100644 --- a/packages/deposit/src/languages/locales/nl/metadata.json +++ b/packages/deposit/src/languages/locales/nl/metadata.json @@ -41,5 +41,13 @@ "dateEnd": "Eind", "apiFetchError": "Kan geen data ophalen van {{api}}", "generate": "Vul automatisch in", - "generateDisabled": "Kan dit veld niet automatisch invullen, aangezien niet alle benodigde velden zijn ingevuld of publieke data zijn." + "generateDisabled": "Kan dit veld niet automatisch invullen, aangezien niet alle benodigde velden zijn ingevuld of publieke data zijn.", + "draw": "Draw", + "simple_select": "Select", + "draw_point": "Point", + "draw_line_string": "Line", + "draw_polygon": "Polygon", + "drawExplanation": "<0>Select a shape type and click on the map to start drawing. In case of a multipoint shape, double click or press 'Enter' to finish drawing.<0>To edit a shape, click on it to select it, and drag it around, or add or move individual points.<0>To delete a shape, select it and press 'Delete' on your keyboard.", + "delete": "Delete", + "toggleMap": "Toggle map" } \ No newline at end of file diff --git a/packages/deposit/src/types/MetadataFields.ts b/packages/deposit/src/types/MetadataFields.ts index b38ed19d..fcc745b4 100644 --- a/packages/deposit/src/types/MetadataFields.ts +++ b/packages/deposit/src/types/MetadataFields.ts @@ -228,6 +228,7 @@ export interface OptionsType { categoryLabel?: string; // used for nested options categoryContent?: string; // used for nested options url?: string; + coordinates?: number[]; } // Validation for text fields diff --git a/packages/file-mapper/package.json b/packages/file-mapper/package.json index 834c18ea..1cb4a84c 100644 --- a/packages/file-mapper/package.json +++ b/packages/file-mapper/package.json @@ -1,28 +1,28 @@ -{ - "name": "@dans-framework/file-mapper", - "type": "module", - "main": "lib/index.tsx", - "private": true, - "version": "1.0.0", - "dependencies": { - "@dans-framework/utils": "workspace:*", - "@mui/icons-material": "^5.14.3", - "@mui/material": "^5.14.3", - "@reduxjs/toolkit": "^1.9.5", - "i18next": "^23.4.1", - "i18next-browser-languagedetector": "^7.1.0", - "i18next-resources-to-backend": "^1.1.4", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-dropzone": "^14.2.3", - "react-i18next": "^13.0.3", - "react-redux": "^8.1.2", - "xlsx": "^0.18.5" - }, - "devDependencies": { - "@dans-framework/deposit": "workspace:*", - "@dans-framework/pages": "workspace:*", - "@types/react": "^18.2.15", - "@types/react-dom": "^18.2.7" - } -} +{ + "name": "@dans-framework/file-mapper", + "type": "module", + "main": "lib/index.tsx", + "private": true, + "version": "1.0.0", + "dependencies": { + "@dans-framework/utils": "workspace:*", + "@mui/icons-material": "^5.14.3", + "@mui/material": "^5.16.7", + "@reduxjs/toolkit": "^1.9.5", + "i18next": "^23.4.1", + "i18next-browser-languagedetector": "^7.1.0", + "i18next-resources-to-backend": "^1.1.4", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-dropzone": "^14.2.3", + "react-i18next": "^13.0.3", + "react-redux": "^8.1.2", + "xlsx": "^0.18.5" + }, + "devDependencies": { + "@dans-framework/deposit": "workspace:*", + "@dans-framework/pages": "workspace:*", + "@types/react": "^18.2.15", + "@types/react-dom": "^18.2.7" + } +} diff --git a/packages/layout/package.json b/packages/layout/package.json index 13c006b6..c5f3490d 100644 --- a/packages/layout/package.json +++ b/packages/layout/package.json @@ -5,11 +5,11 @@ "version": "0.0.0", "type": "module", "dependencies": { - "@dans-framework/user-auth": "workspace:*", "@dans-framework/pages": "workspace:*", + "@dans-framework/user-auth": "workspace:*", "@dans-framework/utils": "workspace:*", "@mui/icons-material": "^5.14.3", - "@mui/material": "^5.14.3", + "@mui/material": "^5.16.7", "country-flag-icons": "^1.5.7", "html-react-parser": "^4.2.2", "i18next": "^23.4.1", diff --git a/packages/pages/package.json b/packages/pages/package.json index 71e63040..c150492e 100644 --- a/packages/pages/package.json +++ b/packages/pages/package.json @@ -8,7 +8,7 @@ "dependencies": { "@dans-framework/user-auth": "workspace:*", "@dans-framework/utils": "workspace:*", - "@mui/material": "^5.14.3", + "@mui/material": "^5.16.7", "html-react-parser": "^4.2.2", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/packages/repo-advisor/package.json b/packages/repo-advisor/package.json index e5079751..db8f1aaf 100644 --- a/packages/repo-advisor/package.json +++ b/packages/repo-advisor/package.json @@ -1,29 +1,29 @@ -{ - "name": "@dans-framework/repo-advisor", - "type": "module", - "main": "lib/index.tsx", - "private": true, - "version": "1.0.0", - "dependencies": { - "@dans-framework/deposit": "workspace:*", - "@dans-framework/utils": "workspace:*", - "@mui/material": "^5.14.3", - "@reduxjs/toolkit": "^1.9.5", - "framer-motion": "^10.15.0", - "i18next": "^23.4.1", - "i18next-browser-languagedetector": "^7.1.0", - "i18next-resources-to-backend": "^1.1.4", - "notistack": "^3.0.1", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-i18next": "^13.0.3", - "react-redux": "^8.1.2", - "react-router-dom": "^6.14.2", - "use-debounce": "^9.0.4" - }, - "devDependencies": { - "@dans-framework/pages": "workspace:*", - "@types/react": "^18.2.15", - "@types/react-dom": "^18.2.7" - } -} +{ + "name": "@dans-framework/repo-advisor", + "type": "module", + "main": "lib/index.tsx", + "private": true, + "version": "1.0.0", + "dependencies": { + "@dans-framework/deposit": "workspace:*", + "@dans-framework/utils": "workspace:*", + "@mui/material": "^5.16.7", + "@reduxjs/toolkit": "^1.9.5", + "framer-motion": "^10.15.0", + "i18next": "^23.4.1", + "i18next-browser-languagedetector": "^7.1.0", + "i18next-resources-to-backend": "^1.1.4", + "notistack": "^3.0.1", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-i18next": "^13.0.3", + "react-redux": "^8.1.2", + "react-router-dom": "^6.14.2", + "use-debounce": "^9.0.4" + }, + "devDependencies": { + "@dans-framework/pages": "workspace:*", + "@types/react": "^18.2.15", + "@types/react-dom": "^18.2.7" + } +} diff --git a/packages/theme/package.json b/packages/theme/package.json index 1607eb61..7f9b6365 100644 --- a/packages/theme/package.json +++ b/packages/theme/package.json @@ -7,7 +7,7 @@ "author": "", "dependencies": { "@dans-framework/utils": "workspace:*", - "@mui/material": "^5.14.3", + "@mui/material": "^5.16.7", "@mui/utils": "^5.14.7", "notistack": "^3.0.1", "react": "^18.2.0" diff --git a/packages/user-auth/package.json b/packages/user-auth/package.json index b3d45e4c..1ca7bdb3 100644 --- a/packages/user-auth/package.json +++ b/packages/user-auth/package.json @@ -7,7 +7,7 @@ "dependencies": { "@dans-framework/utils": "workspace:*", "@mui/icons-material": "^5.14.3", - "@mui/material": "^5.14.3", + "@mui/material": "^5.16.7", "@mui/x-data-grid": "^6.16.3", "@reduxjs/toolkit": "^1.9.5", "framer-motion": "^10.15.0", diff --git a/packages/utils/error/package.json b/packages/utils/error/package.json index d8dc60bd..d9978574 100644 --- a/packages/utils/error/package.json +++ b/packages/utils/error/package.json @@ -1,18 +1,18 @@ -{ - "name": "@dans-framework/utils/error", - "main": "index.tsx", - "version": "1.0.0", - "description": "", - "keywords": [], - "author": "", - "dependencies": { - "@reduxjs/toolkit": "^1.9.5", - "@mui/material": "^5.14.3", - "notistack": "^3.0.1", - "react": "^18.2.0", - "@dans-framework/utils": "workspace:*" - }, - "devDependencies": { - "@types/react": "^18.2.15" - } -} +{ + "name": "@dans-framework/utils/error", + "main": "index.tsx", + "version": "1.0.0", + "description": "", + "keywords": [], + "author": "", + "dependencies": { + "@dans-framework/utils": "workspace:*", + "@mui/material": "^5.16.7", + "@reduxjs/toolkit": "^1.9.5", + "notistack": "^3.0.1", + "react": "^18.2.0" + }, + "devDependencies": { + "@types/react": "^18.2.15" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5554024e..4e984246 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -57,8 +57,8 @@ importers: specifier: ^5.0.7 version: 5.0.7 '@mui/material': - specifier: ^5.14.3 - version: 5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) framer-motion: specifier: ^10.15.0 version: 10.15.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -76,7 +76,7 @@ importers: version: 1.5.0 notistack: specifier: ^3.0.1 - version: 3.0.1(csstype@3.1.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 3.0.1(csstype@3.1.3)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: specifier: ^18.2.0 version: 18.2.0 @@ -149,10 +149,10 @@ importers: version: 5.0.7 '@mui/icons-material': specifier: ^5.14.3 - version: 5.14.3(@mui/material@5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) + version: 5.14.3(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) '@mui/material': - specifier: ^5.14.3 - version: 5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) html-react-parser: specifier: ^4.2.2 version: 4.2.2(react@18.2.0) @@ -230,8 +230,8 @@ importers: specifier: ^5.0.7 version: 5.0.7 '@mui/material': - specifier: ^5.14.3 - version: 5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) i18next: specifier: ^23.4.1 version: 23.4.1 @@ -306,8 +306,8 @@ importers: specifier: ^5.0.7 version: 5.0.7 '@mui/material': - specifier: ^5.14.3 - version: 5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) i18next: specifier: ^23.4.1 version: 23.4.1 @@ -389,10 +389,10 @@ importers: version: 5.0.7 '@mui/icons-material': specifier: ^5.14.3 - version: 5.14.3(@mui/material@5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) + version: 5.14.3(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) '@mui/material': - specifier: ^5.14.3 - version: 5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) html-react-parser: specifier: ^4.2.2 version: 4.2.2(react@18.2.0) @@ -467,8 +467,8 @@ importers: specifier: ^5.0.7 version: 5.0.7 '@mui/material': - specifier: ^5.14.3 - version: 5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) i18next: specifier: ^23.4.1 version: 23.4.1 @@ -549,13 +549,13 @@ importers: version: 1.4.3 '@mui/icons-material': specifier: ^5.14.3 - version: 5.14.3(@mui/material@5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) + version: 5.14.3(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) '@mui/material': - specifier: ^5.14.3 - version: 5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@mui/x-date-pickers': specifier: ^6.11.0 - version: 6.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@mui/base@5.0.0-beta.11(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@mui/material@5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@mui/system@5.14.5(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(moment@2.29.4)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 6.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@mui/base@5.0.0-beta.11(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@mui/system@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(moment@2.29.4)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@reduxjs/toolkit': specifier: ^1.9.5 version: 1.9.5(react-redux@8.1.2(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(redux@4.2.1))(react@18.2.0) @@ -591,7 +591,7 @@ importers: version: 2.29.4 notistack: specifier: ^3.0.1 - version: 3.0.1(csstype@3.1.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 3.0.1(csstype@3.1.3)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: specifier: ^18.2.0 version: 18.2.0 @@ -635,6 +635,12 @@ importers: '@types/jest': specifier: ^29.5.3 version: 29.5.3 + '@types/mapbox-gl': + specifier: ^3.4.0 + version: 3.4.0 + '@types/mapbox__mapbox-gl-draw': + specifier: ^1.4.7 + version: 1.4.7 '@types/node': specifier: ^20.4.7 version: 20.5.3 @@ -658,10 +664,10 @@ importers: version: link:../utils '@mui/icons-material': specifier: ^5.14.3 - version: 5.14.3(@mui/material@5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) + version: 5.14.3(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) '@mui/material': - specifier: ^5.14.3 - version: 5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@reduxjs/toolkit': specifier: ^1.9.5 version: 1.9.5(react-redux@8.1.2(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(redux@4.2.1))(react@18.2.0) @@ -719,10 +725,10 @@ importers: version: link:../utils '@mui/icons-material': specifier: ^5.14.3 - version: 5.14.3(@mui/material@5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) + version: 5.14.3(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) '@mui/material': - specifier: ^5.14.3 - version: 5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) country-flag-icons: specifier: ^1.5.7 version: 1.5.7 @@ -764,8 +770,8 @@ importers: specifier: workspace:* version: link:../utils '@mui/material': - specifier: ^5.14.3 - version: 5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) html-react-parser: specifier: ^4.2.2 version: 4.2.2(react@18.2.0) @@ -802,10 +808,10 @@ importers: version: 8.10.0 '@mui/icons-material': specifier: ^5.14.3 - version: 5.14.3(@mui/material@5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) + version: 5.14.3(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) '@mui/material': - specifier: ^5.14.3 - version: 5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) clsx: specifier: ^2.0.0 version: 2.0.0 @@ -838,7 +844,7 @@ importers: version: 0.6.3 notistack: specifier: ^3.0.1 - version: 3.0.1(csstype@3.1.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 3.0.1(csstype@3.1.3)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) ol: specifier: ^7.3.0 version: 7.5.2 @@ -853,7 +859,7 @@ importers: version: 6.14.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) styled-components: specifier: ^5.3.10 - version: 5.3.10(@babel/core@7.22.10)(react-dom@18.2.0(react@18.2.0))(react-is@18.2.0)(react@18.2.0) + version: 5.3.10(@babel/core@7.22.10)(react-dom@18.2.0(react@18.2.0))(react-is@18.3.1)(react@18.2.0) devDependencies: '@types/lodash.debounce': specifier: ^4.0.7 @@ -895,8 +901,8 @@ importers: specifier: workspace:* version: link:../utils '@mui/material': - specifier: ^5.14.3 - version: 5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@reduxjs/toolkit': specifier: ^1.9.5 version: 1.9.5(react-redux@8.1.2(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(redux@4.2.1))(react@18.2.0) @@ -914,7 +920,7 @@ importers: version: 1.1.4 notistack: specifier: ^3.0.1 - version: 3.0.1(csstype@3.1.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 3.0.1(csstype@3.1.3)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: specifier: ^18.2.0 version: 18.2.0 @@ -950,14 +956,14 @@ importers: specifier: workspace:* version: link:../utils '@mui/material': - specifier: ^5.14.3 - version: 5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@mui/utils': specifier: ^5.14.7 version: 5.14.7(react@18.2.0) notistack: specifier: ^3.0.1 - version: 3.0.1(csstype@3.1.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 3.0.1(csstype@3.1.3)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: specifier: ^18.2.0 version: 18.2.0 @@ -973,13 +979,13 @@ importers: version: link:../utils '@mui/icons-material': specifier: ^5.14.3 - version: 5.14.3(@mui/material@5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) + version: 5.14.3(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) '@mui/material': - specifier: ^5.14.3 - version: 5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@mui/x-data-grid': specifier: ^6.16.3 - version: 6.16.3(@mui/material@5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@mui/system@5.14.5(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 6.16.3(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@mui/system@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@reduxjs/toolkit': specifier: ^1.9.5 version: 1.9.5(react-redux@8.1.2(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(redux@4.2.1))(react@18.2.0) @@ -997,7 +1003,7 @@ importers: version: 2.29.4 notistack: specifier: ^3.0.1 - version: 3.0.1(csstype@3.1.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 3.0.1(csstype@3.1.3)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) oidc-client-ts: specifier: ^2.2.4 version: 2.2.4 @@ -1035,14 +1041,14 @@ importers: specifier: workspace:* version: link:.. '@mui/material': - specifier: ^5.14.3 - version: 5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^5.16.7 + version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@reduxjs/toolkit': specifier: ^1.9.5 version: 1.9.5(react-redux@8.1.2(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(redux@4.2.1))(react@18.2.0) notistack: specifier: ^3.0.1 - version: 3.0.1(csstype@3.1.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 3.0.1(csstype@3.1.3)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: specifier: ^18.2.0 version: 18.2.0 @@ -1192,6 +1198,10 @@ packages: resolution: {integrity: sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==} engines: {node: '>=6.9.0'} + '@babel/runtime@7.25.4': + resolution: {integrity: sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==} + engines: {node: '>=6.9.0'} + '@babel/template@7.22.5': resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} engines: {node: '>=6.9.0'} @@ -1218,6 +1228,9 @@ packages: '@emotion/cache@11.11.0': resolution: {integrity: sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==} + '@emotion/cache@11.13.1': + resolution: {integrity: sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==} + '@emotion/hash@0.9.1': resolution: {integrity: sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==} @@ -1227,12 +1240,18 @@ packages: '@emotion/is-prop-valid@1.2.1': resolution: {integrity: sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==} + '@emotion/is-prop-valid@1.3.0': + resolution: {integrity: sha512-SHetuSLvJDzuNbOdtPVbq6yMMMlLoW5Q94uDqJZqy50gcmAjxFkVqmzqSGEFq9gT2iMuIeKV1PXVWmvUhuZLlQ==} + '@emotion/memoize@0.7.4': resolution: {integrity: sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==} '@emotion/memoize@0.8.1': resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} + '@emotion/memoize@0.9.0': + resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==} + '@emotion/react@11.11.1': resolution: {integrity: sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==} peerDependencies: @@ -1248,6 +1267,9 @@ packages: '@emotion/sheet@1.2.2': resolution: {integrity: sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==} + '@emotion/sheet@1.4.0': + resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==} + '@emotion/styled@11.11.0': resolution: {integrity: sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==} peerDependencies: @@ -1275,9 +1297,15 @@ packages: '@emotion/utils@1.2.1': resolution: {integrity: sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==} + '@emotion/utils@1.4.0': + resolution: {integrity: sha512-spEnrA1b6hDR/C68lC2M7m6ALPUHZC0lIY7jAS/B/9DuuO1ZP04eov8SMv/6fwRd8pzmsn2AuJEznRREWlQrlQ==} + '@emotion/weak-memoize@0.3.1': resolution: {integrity: sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==} + '@emotion/weak-memoize@0.4.0': + resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==} + '@esbuild/android-arm64@0.17.19': resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} engines: {node: '>=12'} @@ -1684,19 +1712,8 @@ packages: '@types/react': optional: true - '@mui/base@5.0.0-beta.9': - resolution: {integrity: sha512-gm6gnPnc/lS5Z3neH0iuOrK7IbS02+oh6KsMtXYLhI6bJpHs+PNWFsBmISx7x4FSPVJZvZkb8Bw6pEXpIMFt7Q==} - engines: {node: '>=12.0.0'} - peerDependencies: - '@types/react': ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - - '@mui/core-downloads-tracker@5.14.5': - resolution: {integrity: sha512-+wpGH1USwPcKMFPMvXqYPC6fEvhxM3FzxC8lyDiNK/imLyyJ6y2DPb1Oue7OGIKJWBmYBqrWWtfovrxd1aJHTA==} + '@mui/core-downloads-tracker@5.16.7': + resolution: {integrity: sha512-RtsCt4Geed2/v74sbihWzzRs+HsIQCfclHeORh5Ynu2fS4icIKozcSubwuG7vtzq2uW3fOR1zITSP84TNt2GoQ==} '@mui/icons-material@5.14.3': resolution: {integrity: sha512-XkxWPhageu1OPUm2LWjo5XqeQ0t2xfGe8EiLkRW9oz2LHMMZmijvCxulhgquUVTF1DnoSh+3KoDLSsoAFtVNVw==} @@ -1709,8 +1726,8 @@ packages: '@types/react': optional: true - '@mui/material@5.14.3': - resolution: {integrity: sha512-dlu4SOcCp9Cy+wkcfZ/ns9ZkP40nr/WPgqxX0HmrE0o+dkE1ropY9BbHsLrTlYJCko8yzcC8bLghrD4xqZG1og==} + '@mui/material@5.16.7': + resolution: {integrity: sha512-cwwVQxBhK60OIOqZOVLFt55t01zmarKJiJUWbk0+8s/Ix5IaUzAShqlJchxsIQ4mSrWqgcKCCXKtIlG5H+/Jmg==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -1726,8 +1743,8 @@ packages: '@types/react': optional: true - '@mui/private-theming@5.14.5': - resolution: {integrity: sha512-cC4C5RrpXpDaaZyH9QwmPhRLgz+f2SYbOty3cPkk4qPSOSfif2ZEcDD9HTENKDDd9deB+xkPKzzZhi8cxIx8Ig==} + '@mui/private-theming@5.16.6': + resolution: {integrity: sha512-rAk+Rh8Clg7Cd7shZhyt2HGTTE5wYKNSJ5sspf28Fqm/PZ69Er9o6KX25g03/FG2dfpg5GCwZh/xOojiTfm3hw==} engines: {node: '>=12.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 @@ -1736,8 +1753,8 @@ packages: '@types/react': optional: true - '@mui/styled-engine@5.13.2': - resolution: {integrity: sha512-VCYCU6xVtXOrIN8lcbuPmoG+u7FYuOERG++fpY74hPpEWkyFQG97F+/XfTQVYzlR2m7nPjnwVUgATcTCMEaMvw==} + '@mui/styled-engine@5.16.6': + resolution: {integrity: sha512-zaThmS67ZmtHSWToTiHslbI8jwrmITcN93LQaR2lKArbvS7Z3iLkwRoiikNWutx9MBs8Q6okKvbZq1RQYB3v7g==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.4.1 @@ -1749,8 +1766,8 @@ packages: '@emotion/styled': optional: true - '@mui/system@5.14.5': - resolution: {integrity: sha512-mextXZHDeGcR7E1kx43TRARrVXy+gI4wzpUgNv7MqZs1dvTVXQGVeAT6ydj9d6FUqHBPMNLGV/21vJOrpqsL+w==} + '@mui/system@5.16.7': + resolution: {integrity: sha512-Jncvs/r/d/itkxh7O7opOunTqbbSSzMTHzZkNLM+FjAOg+cYAZHrPDlYe1ZGKUYORwwb2XexlWnpZp0kZ4AHuA==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -1765,10 +1782,10 @@ packages: '@types/react': optional: true - '@mui/types@7.2.4': - resolution: {integrity: sha512-LBcwa8rN84bKF+f5sDyku42w1NTxaPgPyYKODsh01U1fVstTClbUoSA96oyRBnSNyEiAVjKm6Gwx9vjR+xyqHA==} + '@mui/types@7.2.15': + resolution: {integrity: sha512-nbo7yPhtKJkdf9kcVOF8JZHPZTmqXjJ/tI0bdWgHg5tp9AnIN4Y7f7wm9T+0SyGYJk76+GYZ8Q5XaTYAsUHN0Q==} peerDependencies: - '@types/react': '*' + '@types/react': ^17.0.0 || ^18.0.0 peerDependenciesMeta: '@types/react': optional: true @@ -1795,6 +1812,16 @@ packages: peerDependencies: react: ^17.0.0 || ^18.0.0 + '@mui/utils@5.16.6': + resolution: {integrity: sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@mui/x-data-grid@6.16.3': resolution: {integrity: sha512-msohYxn11JHzeQOywaH5wGSCb/fESootqHLKG6LuET7xOxjHS8GlN/GuW/4kKcbQRunSVh/ADwqpqq+SmWrSeQ==} engines: {node: '>=14.0.0'} @@ -1916,6 +1943,9 @@ packages: '@types/mapbox-gl@3.4.0': resolution: {integrity: sha512-tbn++Mm94H1kE7W6FF0oVC9rMXHVzDDNUbS7KfBMRF8NV/8csFi+67ytKcZJ4LsrpsJ+8MC6Os6ZinEDCsrunw==} + '@types/mapbox__mapbox-gl-draw@1.4.7': + resolution: {integrity: sha512-SNiewXzHCgbJ4EIEG6B7ZMFTwYhHAoEWLdD179AujwmGBaYjn/LZBEQRJLjjq2utB4dEsy5ys2t4cXwEmShpPQ==} + '@types/mapbox__point-geometry@0.1.4': resolution: {integrity: sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA==} @@ -1943,6 +1973,9 @@ packages: '@types/pbf@3.0.5': resolution: {integrity: sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==} + '@types/prop-types@15.7.12': + resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} + '@types/prop-types@15.7.9': resolution: {integrity: sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g==} @@ -1955,6 +1988,9 @@ packages: '@types/react-is@18.2.1': resolution: {integrity: sha512-wyUkmaaSZEzFZivD8F2ftSyAfk6L+DfFliVj/mYdOXbVjRcS87fQJLTnhk6dRZPuJjI+9g6RZJO4PNCngUrmyw==} + '@types/react-transition-group@4.4.11': + resolution: {integrity: sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==} + '@types/react-transition-group@4.4.6': resolution: {integrity: sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==} @@ -2218,6 +2254,10 @@ packages: resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==} engines: {node: '>=6'} + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + codepage@1.15.0: resolution: {integrity: sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==} engines: {node: '>=0.8'} @@ -2287,6 +2327,9 @@ packages: csstype@3.1.2: resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + custom-error-instance@2.1.1: resolution: {integrity: sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg==} @@ -3365,6 +3408,9 @@ packages: react-is@18.2.0: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + react-map-gl@7.1.7: resolution: {integrity: sha512-mwjc0obkBJOXCcoXQr3VoLqmqwo9vS4bXfbGsdxXzEgVCv/PM0v+1QggL7W0d/ccIy+VCjbXNlGij+PENz6VNg==} peerDependencies: @@ -3451,6 +3497,9 @@ packages: regenerator-runtime@0.14.0: resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + regexp.prototype.flags@1.5.2: resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} engines: {node: '>= 0.4'} @@ -4110,6 +4159,10 @@ snapshots: dependencies: regenerator-runtime: 0.14.0 + '@babel/runtime@7.25.4': + dependencies: + regenerator-runtime: 0.14.1 + '@babel/template@7.22.5': dependencies: '@babel/code-frame': 7.22.10 @@ -4177,6 +4230,14 @@ snapshots: '@emotion/weak-memoize': 0.3.1 stylis: 4.2.0 + '@emotion/cache@11.13.1': + dependencies: + '@emotion/memoize': 0.9.0 + '@emotion/sheet': 1.4.0 + '@emotion/utils': 1.4.0 + '@emotion/weak-memoize': 0.4.0 + stylis: 4.2.0 + '@emotion/hash@0.9.1': {} '@emotion/is-prop-valid@0.8.8': @@ -4188,11 +4249,17 @@ snapshots: dependencies: '@emotion/memoize': 0.8.1 + '@emotion/is-prop-valid@1.3.0': + dependencies: + '@emotion/memoize': 0.9.0 + '@emotion/memoize@0.7.4': optional: true '@emotion/memoize@0.8.1': {} + '@emotion/memoize@0.9.0': {} + '@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0)': dependencies: '@babel/runtime': 7.22.10 @@ -4217,6 +4284,8 @@ snapshots: '@emotion/sheet@1.2.2': {} + '@emotion/sheet@1.4.0': {} + '@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0)': dependencies: '@babel/runtime': 7.22.10 @@ -4242,8 +4311,12 @@ snapshots: '@emotion/utils@1.2.1': {} + '@emotion/utils@1.4.0': {} + '@emotion/weak-memoize@0.3.1': {} + '@emotion/weak-memoize@0.4.0': {} + '@esbuild/android-arm64@0.17.19': optional: true @@ -4540,94 +4613,79 @@ snapshots: '@mui/base@5.0.0-beta.11(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: - '@babel/runtime': 7.23.2 - '@emotion/is-prop-valid': 1.2.1 - '@mui/types': 7.2.4(@types/react@18.2.15) - '@mui/utils': 5.14.14(@types/react@18.2.15)(react@18.2.0) + '@babel/runtime': 7.25.4 + '@emotion/is-prop-valid': 1.3.0 + '@mui/types': 7.2.15(@types/react@18.2.15) + '@mui/utils': 5.16.6(@types/react@18.2.15)(react@18.2.0) '@popperjs/core': 2.11.8 - clsx: 2.0.0 + clsx: 2.1.1 prop-types: 15.8.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-is: 18.2.0 + react-is: 18.3.1 optionalDependencies: '@types/react': 18.2.15 - '@mui/base@5.0.0-beta.9(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': - dependencies: - '@babel/runtime': 7.23.2 - '@emotion/is-prop-valid': 1.2.1 - '@mui/types': 7.2.4(@types/react@18.2.15) - '@mui/utils': 5.14.14(@types/react@18.2.15)(react@18.2.0) - '@popperjs/core': 2.11.8 - clsx: 2.0.0 - prop-types: 15.8.1 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-is: 18.2.0 - optionalDependencies: - '@types/react': 18.2.15 + '@mui/core-downloads-tracker@5.16.7': {} - '@mui/core-downloads-tracker@5.14.5': {} - - '@mui/icons-material@5.14.3(@mui/material@5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0)': + '@mui/icons-material@5.14.3(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0)': dependencies: '@babel/runtime': 7.23.2 - '@mui/material': 5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@mui/material': 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: 18.2.0 optionalDependencies: '@types/react': 18.2.15 - '@mui/material@5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: - '@babel/runtime': 7.23.2 - '@mui/base': 5.0.0-beta.9(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@mui/core-downloads-tracker': 5.14.5 - '@mui/system': 5.14.5(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) - '@mui/types': 7.2.4(@types/react@18.2.15) - '@mui/utils': 5.14.14(@types/react@18.2.15)(react@18.2.0) - '@types/react-transition-group': 4.4.6 - clsx: 2.0.0 - csstype: 3.1.2 + '@babel/runtime': 7.25.4 + '@mui/core-downloads-tracker': 5.16.7 + '@mui/system': 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) + '@mui/types': 7.2.15(@types/react@18.2.15) + '@mui/utils': 5.16.6(@types/react@18.2.15)(react@18.2.0) + '@popperjs/core': 2.11.8 + '@types/react-transition-group': 4.4.11 + clsx: 2.1.1 + csstype: 3.1.3 prop-types: 15.8.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-is: 18.2.0 + react-is: 18.3.1 react-transition-group: 4.4.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) optionalDependencies: '@emotion/react': 11.11.1(@types/react@18.2.15)(react@18.2.0) '@emotion/styled': 11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) '@types/react': 18.2.15 - '@mui/private-theming@5.14.5(@types/react@18.2.15)(react@18.2.0)': + '@mui/private-theming@5.16.6(@types/react@18.2.15)(react@18.2.0)': dependencies: - '@babel/runtime': 7.23.2 - '@mui/utils': 5.14.7(react@18.2.0) + '@babel/runtime': 7.25.4 + '@mui/utils': 5.16.6(@types/react@18.2.15)(react@18.2.0) prop-types: 15.8.1 react: 18.2.0 optionalDependencies: '@types/react': 18.2.15 - '@mui/styled-engine@5.13.2(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(react@18.2.0)': + '@mui/styled-engine@5.16.6(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(react@18.2.0)': dependencies: - '@babel/runtime': 7.23.2 - '@emotion/cache': 11.11.0 - csstype: 3.1.2 + '@babel/runtime': 7.25.4 + '@emotion/cache': 11.13.1 + csstype: 3.1.3 prop-types: 15.8.1 react: 18.2.0 optionalDependencies: '@emotion/react': 11.11.1(@types/react@18.2.15)(react@18.2.0) '@emotion/styled': 11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) - '@mui/system@5.14.5(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0)': + '@mui/system@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0)': dependencies: - '@babel/runtime': 7.23.2 - '@mui/private-theming': 5.14.5(@types/react@18.2.15)(react@18.2.0) - '@mui/styled-engine': 5.13.2(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(react@18.2.0) - '@mui/types': 7.2.4(@types/react@18.2.15) - '@mui/utils': 5.14.14(@types/react@18.2.15)(react@18.2.0) - clsx: 2.0.0 - csstype: 3.1.2 + '@babel/runtime': 7.25.4 + '@mui/private-theming': 5.16.6(@types/react@18.2.15)(react@18.2.0) + '@mui/styled-engine': 5.16.6(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(react@18.2.0) + '@mui/types': 7.2.15(@types/react@18.2.15) + '@mui/utils': 5.16.6(@types/react@18.2.15)(react@18.2.0) + clsx: 2.1.1 + csstype: 3.1.3 prop-types: 15.8.1 react: 18.2.0 optionalDependencies: @@ -4635,7 +4693,7 @@ snapshots: '@emotion/styled': 11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) '@types/react': 18.2.15 - '@mui/types@7.2.4(@types/react@18.2.15)': + '@mui/types@7.2.15(@types/react@18.2.15)': optionalDependencies: '@types/react': 18.2.15 @@ -4667,11 +4725,23 @@ snapshots: react: 18.2.0 react-is: 18.2.0 - '@mui/x-data-grid@6.16.3(@mui/material@5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@mui/system@5.14.5(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@mui/utils@5.16.6(@types/react@18.2.15)(react@18.2.0)': + dependencies: + '@babel/runtime': 7.25.4 + '@mui/types': 7.2.15(@types/react@18.2.15) + '@types/prop-types': 15.7.12 + clsx: 2.1.1 + prop-types: 15.8.1 + react: 18.2.0 + react-is: 18.3.1 + optionalDependencies: + '@types/react': 18.2.15 + + '@mui/x-data-grid@6.16.3(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@mui/system@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@babel/runtime': 7.23.2 - '@mui/material': 5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@mui/system': 5.14.5(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) + '@mui/material': 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@mui/system': 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) '@mui/utils': 5.14.14(@types/react@18.2.15)(react@18.2.0) clsx: 2.0.0 prop-types: 15.8.1 @@ -4681,12 +4751,12 @@ snapshots: transitivePeerDependencies: - '@types/react' - '@mui/x-date-pickers@6.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@mui/base@5.0.0-beta.11(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@mui/material@5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@mui/system@5.14.5(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(moment@2.29.4)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@mui/x-date-pickers@6.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@mui/base@5.0.0-beta.11(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@mui/system@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(moment@2.29.4)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@babel/runtime': 7.22.10 '@mui/base': 5.0.0-beta.11(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@mui/material': 5.14.3(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@mui/system': 5.14.5(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) + '@mui/material': 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@mui/system': 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) '@mui/utils': 5.14.5(react@18.2.0) '@types/react-transition-group': 4.4.6 clsx: 1.2.1 @@ -4771,6 +4841,11 @@ snapshots: dependencies: '@types/geojson': 7946.0.14 + '@types/mapbox__mapbox-gl-draw@1.4.7': + dependencies: + '@types/geojson': 7946.0.14 + mapbox-gl: 3.6.0 + '@types/mapbox__point-geometry@0.1.4': {} '@types/mapbox__vector-tile@1.3.4': @@ -4795,6 +4870,8 @@ snapshots: '@types/pbf@3.0.5': {} + '@types/prop-types@15.7.12': {} + '@types/prop-types@15.7.9': {} '@types/react-dom@18.2.7': @@ -4809,6 +4886,10 @@ snapshots: dependencies: '@types/react': 18.2.15 + '@types/react-transition-group@4.4.11': + dependencies: + '@types/react': 18.2.15 + '@types/react-transition-group@4.4.6': dependencies: '@types/react': 18.2.15 @@ -5024,14 +5105,14 @@ snapshots: cosmiconfig: 7.1.0 resolve: 1.22.4 - babel-plugin-styled-components@2.1.4(@babel/core@7.22.10)(styled-components@5.3.10(@babel/core@7.22.10)(react-dom@18.2.0(react@18.2.0))(react-is@18.2.0)(react@18.2.0)): + babel-plugin-styled-components@2.1.4(@babel/core@7.22.10)(styled-components@5.3.10(@babel/core@7.22.10)(react-dom@18.2.0(react@18.2.0))(react-is@18.3.1)(react@18.2.0)): dependencies: '@babel/helper-annotate-as-pure': 7.22.5 '@babel/helper-module-imports': 7.22.5 '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.10) lodash: 4.17.21 picomatch: 2.3.1 - styled-components: 5.3.10(@babel/core@7.22.10)(react-dom@18.2.0(react@18.2.0))(react-is@18.2.0)(react@18.2.0) + styled-components: 5.3.10(@babel/core@7.22.10)(react-dom@18.2.0(react@18.2.0))(react-is@18.3.1)(react@18.2.0) transitivePeerDependencies: - '@babel/core' @@ -5118,6 +5199,8 @@ snapshots: clsx@2.0.0: {} + clsx@2.1.1: {} + codepage@1.15.0: {} color-convert@1.9.3: @@ -5181,6 +5264,8 @@ snapshots: csstype@3.1.2: {} + csstype@3.1.3: {} + custom-error-instance@2.1.1: {} data-view-buffer@1.0.1: @@ -5685,9 +5770,9 @@ snapshots: merge2: 1.4.1 slash: 3.0.0 - goober@2.1.13(csstype@3.1.2): + goober@2.1.13(csstype@3.1.3): dependencies: - csstype: 3.1.2 + csstype: 3.1.3 gopd@1.0.1: dependencies: @@ -6177,10 +6262,10 @@ snapshots: normalize-path@3.0.0: {} - notistack@3.0.1(csstype@3.1.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + notistack@3.0.1(csstype@3.1.3)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: clsx: 1.2.1 - goober: 2.1.13(csstype@3.1.2) + goober: 2.1.13(csstype@3.1.3) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) transitivePeerDependencies: @@ -6370,6 +6455,8 @@ snapshots: react-is@18.2.0: {} + react-is@18.3.1: {} + react-map-gl@7.1.7(mapbox-gl@3.6.0)(maplibre-gl@4.5.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: '@maplibre/maplibre-gl-style-spec': 19.3.3 @@ -6443,6 +6530,8 @@ snapshots: regenerator-runtime@0.14.0: {} + regenerator-runtime@0.14.1: {} + regexp.prototype.flags@1.5.2: dependencies: call-bind: 1.0.7 @@ -6628,19 +6717,19 @@ snapshots: dependencies: inline-style-parser: 0.1.1 - styled-components@5.3.10(@babel/core@7.22.10)(react-dom@18.2.0(react@18.2.0))(react-is@18.2.0)(react@18.2.0): + styled-components@5.3.10(@babel/core@7.22.10)(react-dom@18.2.0(react@18.2.0))(react-is@18.3.1)(react@18.2.0): dependencies: '@babel/helper-module-imports': 7.22.5 '@babel/traverse': 7.22.10(supports-color@5.5.0) '@emotion/is-prop-valid': 1.2.1 '@emotion/stylis': 0.8.5 '@emotion/unitless': 0.7.5 - babel-plugin-styled-components: 2.1.4(@babel/core@7.22.10)(styled-components@5.3.10(@babel/core@7.22.10)(react-dom@18.2.0(react@18.2.0))(react-is@18.2.0)(react@18.2.0)) + babel-plugin-styled-components: 2.1.4(@babel/core@7.22.10)(styled-components@5.3.10(@babel/core@7.22.10)(react-dom@18.2.0(react@18.2.0))(react-is@18.3.1)(react@18.2.0)) css-to-react-native: 3.2.0 hoist-non-react-statics: 3.3.2 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-is: 18.2.0 + react-is: 18.3.1 shallowequal: 1.1.0 supports-color: 5.5.0 transitivePeerDependencies: From 989a72ca952ff149fe850cafd46e9d81be51c237 Mon Sep 17 00:00:00 2001 From: Daan Janssen Date: Mon, 26 Aug 2024 14:34:12 +0200 Subject: [PATCH 04/44] updates to mapping func --- .../src/features/metadata/api/geonames.ts | 3 +- .../src/features/metadata/fields/Map.tsx | 114 +++++++++++------- packages/deposit/src/types/MetadataFields.ts | 12 +- packages/deposit/src/types/MetadataProps.ts | 5 + pnpm-lock.yaml | 2 +- 5 files changed, 92 insertions(+), 44 deletions(-) diff --git a/packages/deposit/src/features/metadata/api/geonames.ts b/packages/deposit/src/features/metadata/api/geonames.ts index 8c481c85..fa4cc575 100644 --- a/packages/deposit/src/features/metadata/api/geonames.ts +++ b/packages/deposit/src/features/metadata/api/geonames.ts @@ -23,7 +23,8 @@ export const geonamesApi = createApi({ item.countryName ? `, ${item.countryName}` : "" }`, value: `https://www.geonames.org/${item.geonameId}`, - coordinates: [item.lat, item.lng], + coordinates: [parseFloat(item.lng), parseFloat(item.lat)], + id: item.geonameId.toString(), })), } : []; diff --git a/packages/deposit/src/features/metadata/fields/Map.tsx b/packages/deposit/src/features/metadata/fields/Map.tsx index 558a064e..1f88ad6b 100644 --- a/packages/deposit/src/features/metadata/fields/Map.tsx +++ b/packages/deposit/src/features/metadata/fields/Map.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState, useCallback } from "react"; +import { useEffect, useState, useCallback, type SetStateAction, type Dispatch } from "react"; import Box from "@mui/material/Box"; import Paper from "@mui/material/Paper"; import Stack from "@mui/material/Stack"; @@ -11,9 +11,10 @@ import { StatusIcon } from "../../generic/Icons"; import { setField } from "../metadataSlice"; import { getFieldStatus } from "../metadataHelpers"; import type { OptionsType } from "../../../types/MetadataFields"; +import type { DrawMapFieldProps } from "../../../types/MetadataProps"; import { lookupLanguageString } from "@dans-framework/utils"; import { getFormDisabled } from "../../../deposit/depositSlice"; -import Map, { ScaleControl, NavigationControl, useControl } from "react-map-gl/maplibre"; +import GLMap, { ScaleControl, NavigationControl, useControl } from "react-map-gl/maplibre"; import MapboxDraw from '@mapbox/mapbox-gl-draw'; import 'maplibre-gl/dist/maplibre-gl.css'; import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css'; @@ -51,7 +52,7 @@ import PublicIcon from '@mui/icons-material/Public'; const DrawMap = ({ field, sectionIndex, -}: any) => { +}: DrawMapFieldProps) => { const dispatch = useAppDispatch(); const status = getFieldStatus(field); const { t, i18n } = useTranslation("metadata"); @@ -63,16 +64,34 @@ const DrawMap = ({ latitude: 52.080738, zoom: 8, }); + const [ features, setFeatures ] = useState([]); + // todo: write this to redux store, import proper geojson type from map lib + console.log(features) - // move map to selected GeoNames value useEffect(() => { if (geonamesValue) { + // move map to selected GeoNames value setViewState({ - longitude: geonamesValue.coordinates![1], - latitude: geonamesValue.coordinates![0], + longitude: geonamesValue.coordinates![0], + latitude: geonamesValue.coordinates![1], zoom: 10, }); setOpenMap(true); + // and add it to map if not added yet, checks geonames id + const newFeature = { + id: geonamesValue.id, + type: "Feature", + properties: { + geoNames: true, + }, + geometry: { + type: "Point", + coordinates: geonamesValue.coordinates, + }, + }; + setFeatures( + [...new Map([...features, newFeature].map(item => [item.id, item])).values()] + ); } }, [geonamesValue]); @@ -99,7 +118,7 @@ const DrawMap = ({ - setViewState(e.viewState)} style={{ @@ -108,19 +127,35 @@ const DrawMap = ({ borderRadius: '5px', border: "1px solid rgba(0,0,0,0.23)" }} - mapStyle={`https://api.maptiler.com/maps/landscape/style.json?key=${import.meta.env.VITE_MAPTILER_API_KEY}`} + mapStyle={`https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json`} > - - + + + {features.length > 0 && + // let's user edit features coordinates directly + // todo: how to present this?? + // also, let user select a corresponding geonames option??? + + {features.map(feature => + + {feature.geometry.type} + {feature.geometry.coordinates.map(coord => + Array.isArray(coord) ? coord.map(c => c) : coord + )} + + )} + + } ); }; export default DrawMap; + const controls = ["simple_select", "draw_point", "draw_line_string", "draw_polygon"]; interface Feature { @@ -129,42 +164,28 @@ interface Feature { type FeaturesEvent = {features: Feature[], action?: string}; -type FeatureObject = { - [id: string]: Feature; -} - -const DrawControls = () => { +const DrawControls = ({ features, setFeatures }: { + features: Feature[]; + setFeatures: Dispatch>; +}) => { const { t } = useTranslation("metadata"); const [ selectedMode, setSelectedMode ] = useState(controls[0]); - // write this to redux store - const [ features, setFeatures ] = useState(); - console.log(features) - const onUpdate = useCallback((e: FeaturesEvent) => { - setFeatures(currFeatures => { - const newFeatures = {...currFeatures}; - for (const f of e.features) { - if (f.id) { - newFeatures[f.id] = f; - } - } - return newFeatures; - }); - setSelectedMode(controls[0]) + console.log('update called') + setFeatures(currFeatures => + // making sure here points added from a geonames lookup cannot be moved + [...new Map([...currFeatures, ...e.features.filter(f => !f.properties.geoNames)].map(item => [item.id, item])).values()] + ); + setSelectedMode(controls[0]); }, []); const onDelete = useCallback((e: FeaturesEvent) => { - setFeatures(currFeatures => { - const newFeatures = {...currFeatures}; - for (const f of e.features) { - if (f.id) { - delete newFeatures[f.id]; - } - } - return newFeatures; - }); - setSelectedMode(controls[0]) + const changedFeatureIds = new Set(e.features.map(feature => feature.id)); + setFeatures(currFeatures => + currFeatures.filter(feature => !changedFeatureIds.has(feature.id)) + ); + setSelectedMode(controls[0]); }, []); // manual key listener, since delete is broken in the map libre / mapbox draw combo @@ -256,6 +277,7 @@ const DrawControls = () => { onDelete={onDelete} mode={selectedMode} onKeyDown={handleKeyDown} + features={features} /> ) @@ -267,6 +289,7 @@ type DrawControlProps = { onDelete: (e: FeaturesEvent) => void; mode: string; onKeyDown: (e: KeyboardEvent, c: MapboxDraw) => void; + features: Feature[]; }; // Some MapboxDraw typescript issues, changed to any type for now @@ -277,6 +300,7 @@ const DrawControl = ({ onDelete, mode, onKeyDown, + features, }: DrawControlProps) => { const control = useControl( () => new MapboxDraw({ @@ -311,8 +335,16 @@ const DrawControl = ({ ); useEffect(() => { + // change drawing mode based on user selection control.changeMode(mode); - }, [mode]) + }, [mode]); + + useEffect(() => { + // if features prop changes, reflect that on map + if (control && features.length > 0) { + features.map(f => control.add(f)) + } + }, [features, control]); return null; } @@ -325,7 +357,7 @@ const GeonamesApiField = ({ }: { value?: OptionsType; setValue: (v: OptionsType) => void; - disabled: boolean; + disabled?: boolean; label?: string; }) => { const { t } = useTranslation("metadata"); diff --git a/packages/deposit/src/types/MetadataFields.ts b/packages/deposit/src/types/MetadataFields.ts index fcc745b4..d7b3e17e 100644 --- a/packages/deposit/src/types/MetadataFields.ts +++ b/packages/deposit/src/types/MetadataFields.ts @@ -166,10 +166,20 @@ export interface CheckFieldType maxDateField?: never; } +interface GeoJSON { + id: string; + type: string; + properties: Object; + geometry: { + type: string; + coordinates: string[] | string[][]; + }; +} + export interface DrawMapFieldType extends Omit { type: "drawmap"; - value?: string[]; + value?: GeoJSON; multiApiValue?: never; fields?: never; format?: never; diff --git a/packages/deposit/src/types/MetadataProps.ts b/packages/deposit/src/types/MetadataProps.ts index d244c363..cbf4c254 100644 --- a/packages/deposit/src/types/MetadataProps.ts +++ b/packages/deposit/src/types/MetadataProps.ts @@ -12,6 +12,7 @@ import type { TypeaheadAPI, OptionsType, DateRangeFieldType, + DrawMapFieldType, } from "./MetadataFields"; import type { AutocompleteRenderGetTagProps } from "@mui/material"; @@ -67,6 +68,10 @@ export interface AutocompleteAPIFieldProps extends AutocompleteFieldProps { isFetching: boolean; } +export interface DrawMapFieldProps extends Omit { + field: DrawMapFieldType; +} + interface FieldButtonProps { sectionIndex: number; groupedFieldId: string; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4e984246..59c665b4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -810,7 +810,7 @@ importers: specifier: ^5.14.3 version: 5.14.3(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) '@mui/material': - specifier: ^5.16.7 + specifier: ^5.14.3 version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) clsx: specifier: ^2.0.0 From 5d7ade66715241681f862223f7d39d85ccfc35c3 Mon Sep 17 00:00:00 2001 From: D-Unit Date: Wed, 28 Aug 2024 12:34:58 +0200 Subject: [PATCH 05/44] saving changes --- .../src/features/metadata/api/geonames.ts | 29 ++- .../src/features/metadata/fields/Map.tsx | 204 ++++++++++++++++-- 2 files changed, 214 insertions(+), 19 deletions(-) diff --git a/packages/deposit/src/features/metadata/api/geonames.ts b/packages/deposit/src/features/metadata/api/geonames.ts index fa4cc575..dcd362cf 100644 --- a/packages/deposit/src/features/metadata/api/geonames.ts +++ b/packages/deposit/src/features/metadata/api/geonames.ts @@ -33,7 +33,34 @@ export const geonamesApi = createApi({ error: i18n.t("metadata:apiFetchError", { api: "Geonames" }), }), }), + fetchPlaceReverseLookup: build.query({ + query: ({lat, lng}) => ({ + url: `findNearbyPlaceName?lat=${lat}&lng=${lng}&radius=10&maxRows=100&username=${ + import.meta.env.VITE_GEONAMES_API_KEY + }`, + headers: { Accept: "application/json" }, + }), + transformResponse: (response: GeonamesResponse, _meta, arg) => { + // Return an empty array when no results, which is what the Autocomplete field expects + return response.geonames.length > 0 ? + { + arg: arg, + response: response.geonames.map((item) => ({ + label: `${item.name}${ + item.countryName ? `, ${item.countryName}` : "" + }`, + value: `https://www.geonames.org/${item.geonameId}`, + coordinates: [parseFloat(item.lng), parseFloat(item.lat)], + id: item.geonameId.toString(), + })), + } + : []; + }, + transformErrorResponse: () => ({ + error: i18n.t("metadata:apiFetchError", { api: "Geonames" }), + }), + }), }), }); -export const { useFetchGeonamesFreeTextQuery } = geonamesApi; +export const { useFetchGeonamesFreeTextQuery, useFetchPlaceReverseLookupQuery } = geonamesApi; diff --git a/packages/deposit/src/features/metadata/fields/Map.tsx b/packages/deposit/src/features/metadata/fields/Map.tsx index 1f88ad6b..180dbd4b 100644 --- a/packages/deposit/src/features/metadata/fields/Map.tsx +++ b/packages/deposit/src/features/metadata/fields/Map.tsx @@ -32,7 +32,7 @@ import DeleteIcon from '@mui/icons-material/Delete'; import PlaceIcon from '@mui/icons-material/Place'; import HighlightAltIcon from '@mui/icons-material/HighlightAlt'; import PentagonIcon from '@mui/icons-material/Pentagon'; -import { useFetchGeonamesFreeTextQuery } from "../api/geonames"; +import { useFetchGeonamesFreeTextQuery, useFetchPlaceReverseLookupQuery } from "../api/geonames"; import type { QueryReturnType } from "../../../types/Api"; import CircularProgress from "@mui/material/CircularProgress"; import Autocomplete from "@mui/material/Autocomplete"; @@ -41,6 +41,15 @@ import { useDebounce } from "use-debounce"; import Collapse from '@mui/material/Collapse'; import PublicIcon from '@mui/icons-material/Public'; +import Table from '@mui/material/Table'; +import TableBody from '@mui/material/TableBody'; +import TableCell from '@mui/material/TableCell'; +import TableContainer from '@mui/material/TableContainer'; +import TableHead from '@mui/material/TableHead'; +import TablePagination from '@mui/material/TablePagination'; +import TableRow from '@mui/material/TableRow'; + + /** * Map field * Lookup base location/point via Geonames. @@ -133,28 +142,138 @@ const DrawMap = ({ + {features.length > 0 && + // let's user edit features coordinates directly + // todo: how to present this?? + // also, let user select a corresponding geonames option??? + + } - {features.length > 0 && - // let's user edit features coordinates directly - // todo: how to present this?? - // also, let user select a corresponding geonames option??? - - {features.map(feature => - - {feature.geometry.type} - {feature.geometry.coordinates.map(coord => - Array.isArray(coord) ? coord.map(c => c) : coord - )} - - )} - - } ); }; export default DrawMap; +interface Column { + id: string; + label: string; + minWidth?: number; +} + +const columns: readonly Column[] = [ + { id: 'feature', label: 'Type', width: 50 }, + { id: 'coordinates', label: 'Coordinates', width: 500 }, + { id: 'geonames', label: 'Geoname reference' }, +]; + +const FeatureTable = ({ features }) => { + const { t } = useTranslation("metadata"); + + return ( + + + + + {columns.map((column) => ( + + {column.label} + + ))} + + + + {features.map((feature, i) => + + + { + feature.geometry.type === "Point" + ? + : feature.geometry.type === "LineString" + ? + : feature.geometry.type === "Polygon" + ? + : null + } + + + { + feature.geometry.type === "Point" && + + {feature.geometry.coordinates.map((coord, i) => + + )} + + } + { + feature.geometry.type === "LineString" && + feature.geometry.coordinates.map((coord, i) => + + {coord.map((c, j) => + + )} + + ) + } + { + feature.geometry.type === "Polygon" && + feature.geometry.coordinates[0].map((coord, i) => + + {coord.map((c, j) => + + )} + + ) + } + + + + + + )} + +
+
+ ) +} + const controls = ["simple_select", "draw_point", "draw_line_string", "draw_polygon"]; @@ -174,8 +293,7 @@ const DrawControls = ({ features, setFeatures }: { const onUpdate = useCallback((e: FeaturesEvent) => { console.log('update called') setFeatures(currFeatures => - // making sure here points added from a geonames lookup cannot be moved - [...new Map([...currFeatures, ...e.features.filter(f => !f.properties.geoNames)].map(item => [item.id, item])).values()] + [...new Map([...currFeatures, ...e.features].map(item => [item.id, item])).values()] ); setSelectedMode(controls[0]); }, []); @@ -185,6 +303,7 @@ const DrawControls = ({ features, setFeatures }: { setFeatures(currFeatures => currFeatures.filter(feature => !changedFeatureIds.has(feature.id)) ); + // todo: clear the geonames reference (if present) when a feature is edited setSelectedMode(controls[0]); }, []); @@ -349,6 +468,55 @@ const DrawControl = ({ return null; } +const ReverseLookupGeonamesField = ({lat, lng, disabled}) => { + // todo: fetch op open, not directly on prop change + // geonames info, where to save + const { t } = useTranslation("metadata"); + const [value, setValue] = useState(); + const [inputValue, setInputValue] = useState(""); + // Fetch data right away, based on coordinates + const { data, isFetching, isLoading } = + useFetchPlaceReverseLookupQuery({lat: lat, lng: lng}); + + return ( + ( + + )} + onChange={(_e, newValue, _reason) => setValue(newValue as OptionsType)} + filterOptions={(x) => x} + onInputChange={(e, newValue) => { + e && e.type === "change" && setInputValue(newValue); + e && (e.type === "click" || e.type === "blur") && setInputValue(""); + }} + noOptionsText={!inputValue ? t("startTyping", {api: t("geonames")}) : t("noResults")} + loading={isLoading || isFetching} + loadingText={ + + {t("loading")} + + } + forcePopupIcon + clearOnBlur + disabled={disabled} + getOptionKey={(option) => option.value} + /> + ) +} + const GeonamesApiField = ({ value, setValue, From 8b53e7685e2957a1997ba949f3ef6eaffb3b90e1 Mon Sep 17 00:00:00 2001 From: D-Unit Date: Wed, 28 Aug 2024 16:00:49 +0200 Subject: [PATCH 06/44] coupled to geonames, still to fix ts --- packages/deposit/package.json | 4 +- .../src/features/metadata/fields/Map.tsx | 117 ++++++++++++++---- pnpm-lock.yaml | 14 ++- 3 files changed, 107 insertions(+), 28 deletions(-) diff --git a/packages/deposit/package.json b/packages/deposit/package.json index 87368982..93d23706 100644 --- a/packages/deposit/package.json +++ b/packages/deposit/package.json @@ -40,6 +40,7 @@ }, "devDependencies": { "@dans-framework/pages": "workspace:*", + "@types/geojson": "^7946.0.14", "@types/jest": "^29.5.3", "@types/mapbox-gl": "^3.4.0", "@types/mapbox__mapbox-gl-draw": "^1.4.7", @@ -47,6 +48,7 @@ "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", "@types/react-transition-group": "^4.4.6", - "@types/uuid": "^9.0.2" + "@types/uuid": "^9.0.2", + "geojson": "^0.5.0" } } diff --git a/packages/deposit/src/features/metadata/fields/Map.tsx b/packages/deposit/src/features/metadata/fields/Map.tsx index 180dbd4b..a5e2ee47 100644 --- a/packages/deposit/src/features/metadata/fields/Map.tsx +++ b/packages/deposit/src/features/metadata/fields/Map.tsx @@ -46,10 +46,8 @@ import TableBody from '@mui/material/TableBody'; import TableCell from '@mui/material/TableCell'; import TableContainer from '@mui/material/TableContainer'; import TableHead from '@mui/material/TableHead'; -import TablePagination from '@mui/material/TablePagination'; import TableRow from '@mui/material/TableRow'; - /** * Map field * Lookup base location/point via Geonames. @@ -91,7 +89,7 @@ const DrawMap = ({ id: geonamesValue.id, type: "Feature", properties: { - geoNames: true, + geoNames: geonamesValue, }, geometry: { type: "Point", @@ -146,7 +144,7 @@ const DrawMap = ({ // let's user edit features coordinates directly // todo: how to present this?? // also, let user select a corresponding geonames option??? - + } @@ -158,7 +156,7 @@ export default DrawMap; interface Column { id: string; label: string; - minWidth?: number; + width?: number; } const columns: readonly Column[] = [ @@ -167,9 +165,38 @@ const columns: readonly Column[] = [ { id: 'geonames', label: 'Geoname reference' }, ]; -const FeatureTable = ({ features }) => { +const FeatureTable = ({ features, setFeatures }: { + features: Feature[]; + setFeatures: Dispatch>; +}) => { const { t } = useTranslation("metadata"); + const setCoordinates = (coord: string, indexes: number[], isFirst?: boolean) => { + // set the new coordinates + const newFeatures = [...features]; + let target = newFeatures[indexes[0]].geometry.coordinates; + for (let i = 1; i < indexes.length - 1; i++) { + target = target[indexes[i]]; + } + target[indexes[indexes.length - 1]] = parseFloat(coord); + + // For a polygon, we need to set the last coordinate pair to the first one, to close the shape + // This is not editable by the user + if (isFirst) { + const lastIndex = newFeatures[indexes[0]].geometry.coordinates[0].length - 1; + newFeatures[indexes[0]].geometry.coordinates[0][lastIndex] = target; + } + setFeatures(newFeatures); + setGeonames(undefined, indexes[0]); + } + + const setGeonames = (geonamesValue: OptionsType | undefined, index: number) => { + // set the new geonames value + const newFeatures = [...features]; + newFeatures[index].properties.geoNames = geonamesValue; + setFeatures(newFeatures); + } + return ( @@ -178,7 +205,6 @@ const FeatureTable = ({ features }) => { {columns.map((column) => ( {column.label} @@ -204,28 +230,30 @@ const FeatureTable = ({ features }) => { { feature.geometry.type === "Point" && - {feature.geometry.coordinates.map((coord, i) => + {feature.geometry.coordinates.map((coord: number, j: number) => setCoordinates(e.target.value, [i, j])} /> )} } { feature.geometry.type === "LineString" && - feature.geometry.coordinates.map((coord, i) => - - {coord.map((c, j) => + feature.geometry.coordinates.map((coord: number[], j:number) => + + {coord.map((c, k) => setCoordinates(e.target.value, [i, j, k])} /> )} @@ -233,15 +261,17 @@ const FeatureTable = ({ features }) => { } { feature.geometry.type === "Polygon" && - feature.geometry.coordinates[0].map((coord, i) => - - {coord.map((c, j) => + feature.geometry.coordinates[0].map((coord: number[], j: number) => + + {coord.map((c, k) => setCoordinates(e.target.value, [i, 0, j, k], j === 0)} /> )} @@ -250,6 +280,9 @@ const FeatureTable = ({ features }) => { { const controls = ["simple_select", "draw_point", "draw_line_string", "draw_polygon"]; interface Feature { - id?: string | number; + id: string; + geometry: { + type: string; + coordinates: number[] | number[][] | number[][][]; + }; + properties: { + geoNames?: OptionsType; + } } type FeaturesEvent = {features: Feature[], action?: string}; @@ -292,18 +332,26 @@ const DrawControls = ({ features, setFeatures }: { const onUpdate = useCallback((e: FeaturesEvent) => { console.log('update called') + + // Clear 'properties' key for each feature in the new array + // So geonames reference is removed when points change + const updatedFeatures = e.features.map(feature => ({ + ...feature, + properties: {}, + })); + setFeatures(currFeatures => - [...new Map([...currFeatures, ...e.features].map(item => [item.id, item])).values()] + [...new Map([...currFeatures, ...updatedFeatures].map(item => [item.id, item])).values()] ); setSelectedMode(controls[0]); }, []); const onDelete = useCallback((e: FeaturesEvent) => { + console.log('delete called') const changedFeatureIds = new Set(e.features.map(feature => feature.id)); setFeatures(currFeatures => currFeatures.filter(feature => !changedFeatureIds.has(feature.id)) ); - // todo: clear the geonames reference (if present) when a feature is edited setSelectedMode(controls[0]); }, []); @@ -468,20 +516,37 @@ const DrawControl = ({ return null; } -const ReverseLookupGeonamesField = ({lat, lng, disabled}) => { - // todo: fetch op open, not directly on prop change +const ReverseLookupGeonamesField = ({ + lat, + lng, + featureIndex, + value, + setValue, + disabled +}: { + lat: number; + lng: number; + featureIndex: number; + value: OptionsType | null; + setValue: (option: OptionsType | null, index: number) => void; + disabled?: boolean; +}) => { // geonames info, where to save const { t } = useTranslation("metadata"); - const [value, setValue] = useState(); const [inputValue, setInputValue] = useState(""); + // fetch on open, not directly on prop change + const [open, setOpen] = useState(false); // Fetch data right away, based on coordinates const { data, isFetching, isLoading } = - useFetchPlaceReverseLookupQuery({lat: lat, lng: lng}); + useFetchPlaceReverseLookupQuery({lat: lat, lng: lng}, {skip: !open}); return ( setOpen(true)} + onClose={() => setOpen(false)} options={data?.response || []} value={value || null} inputValue={inputValue || value?.label as string || ""} @@ -492,13 +557,13 @@ const ReverseLookupGeonamesField = ({lat, lng, disabled}) => { size="small" /> )} - onChange={(_e, newValue, _reason) => setValue(newValue as OptionsType)} + onChange={(_e, newValue, _reason) => setValue(newValue as OptionsType, featureIndex)} filterOptions={(x) => x} onInputChange={(e, newValue) => { e && e.type === "change" && setInputValue(newValue); e && (e.type === "click" || e.type === "blur") && setInputValue(""); }} - noOptionsText={!inputValue ? t("startTyping", {api: t("geonames")}) : t("noResults")} + noOptionsText={t("noResults")} loading={isLoading || isFetching} loadingText={ = 0.10'} + geotiff@2.0.7: resolution: {integrity: sha512-FKvFTNowMU5K6lHYY2f83d4lS2rsCNdpUC28AX61x9ZzzqPNaWFElWv93xj0eJFaNyOYA63ic5OzJ88dHpoA5Q==} engines: {node: '>=10.19'} @@ -5697,6 +5707,8 @@ snapshots: geojson-vt@4.0.2: {} + geojson@0.5.0: {} + geotiff@2.0.7: dependencies: '@petamoriken/float16': 3.8.4 From 0425a08019b4532c99c39376e8ebbd236303f307 Mon Sep 17 00:00:00 2001 From: D-Unit Date: Thu, 29 Aug 2024 14:09:04 +0200 Subject: [PATCH 07/44] fixalot --- .../src/config/formsections/citation.ts | 2 +- packages/deposit/package.json | 3 +- .../metadata/fields/AutocompleteAPIField.tsx | 2 +- .../metadata/fields/DateTimeField.tsx | 4 +- .../src/features/metadata/fields/Map.tsx | 359 ++++++++++-------- .../src/features/metadata/metadataHelpers.ts | 10 +- .../src/features/metadata/metadataSlice.ts | 24 +- .../src/languages/locales/en/metadata.json | 12 +- packages/deposit/src/types/MetadataFields.ts | 16 +- .../deposit/src/types/MetadataPayloads.ts | 31 +- pnpm-lock.yaml | 9 - 11 files changed, 266 insertions(+), 206 deletions(-) diff --git a/apps/digitaltwins/src/config/formsections/citation.ts b/apps/digitaltwins/src/config/formsections/citation.ts index 0d9b8c79..9ba41280 100644 --- a/apps/digitaltwins/src/config/formsections/citation.ts +++ b/apps/digitaltwins/src/config/formsections/citation.ts @@ -50,7 +50,7 @@ const section: InitialSectionType = { { type: "drawmap", label: { - en: "Find on a map and draw locations", + en: "Indicate location", nl: "Map", }, name: "map", diff --git a/packages/deposit/package.json b/packages/deposit/package.json index 93d23706..27459220 100644 --- a/packages/deposit/package.json +++ b/packages/deposit/package.json @@ -48,7 +48,6 @@ "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", "@types/react-transition-group": "^4.4.6", - "@types/uuid": "^9.0.2", - "geojson": "^0.5.0" + "@types/uuid": "^9.0.2" } } diff --git a/packages/deposit/src/features/metadata/fields/AutocompleteAPIField.tsx b/packages/deposit/src/features/metadata/fields/AutocompleteAPIField.tsx index f6463247..fb699114 100644 --- a/packages/deposit/src/features/metadata/fields/AutocompleteAPIField.tsx +++ b/packages/deposit/src/features/metadata/fields/AutocompleteAPIField.tsx @@ -421,7 +421,7 @@ export const MultiApiField = ({ setMultiApiField({ sectionIndex: sectionIndex, id: field.id, - value: e.target.value, + value: e.target.value as TypeaheadAPI, }), ); // and reset the currently selected value if there is one diff --git a/packages/deposit/src/features/metadata/fields/DateTimeField.tsx b/packages/deposit/src/features/metadata/fields/DateTimeField.tsx index fcaf6c9e..34f751cf 100644 --- a/packages/deposit/src/features/metadata/fields/DateTimeField.tsx +++ b/packages/deposit/src/features/metadata/fields/DateTimeField.tsx @@ -17,7 +17,7 @@ import type { DateFieldProps, DateRangeFieldProps } from "../../../types/Metadat import { lookupLanguageString } from "@dans-framework/utils"; import { getFormDisabled } from "../../../deposit/depositSlice"; import type { DateValidationError, TimeValidationError } from "@mui/x-date-pickers/models"; -import type { DateFieldType, DateRangeFieldType } from "../../../types/MetadataFields"; +import type { DateFieldType, DateRangeFieldType, DateTimeFormat } from "../../../types/MetadataFields"; // Date and time selection component // Allows a user to select input type (date and time, date, month and year, year) if specified in config @@ -366,7 +366,7 @@ const DateTypeWrapper = ({field, sectionIndex, currentField}: { setDateTypeField({ sectionIndex: sectionIndex, id: field.id, - value: e.target.value, + value: e.target.value as DateTimeFormat, }), ); // and reset the currently selected value if there is one diff --git a/packages/deposit/src/features/metadata/fields/Map.tsx b/packages/deposit/src/features/metadata/fields/Map.tsx index a5e2ee47..87370c02 100644 --- a/packages/deposit/src/features/metadata/fields/Map.tsx +++ b/packages/deposit/src/features/metadata/fields/Map.tsx @@ -1,16 +1,18 @@ import { useEffect, useState, useCallback, type SetStateAction, type Dispatch } from "react"; import Box from "@mui/material/Box"; import Paper from "@mui/material/Paper"; +import Card from "@mui/material/Card"; +import CardHeader from "@mui/material/CardHeader"; +import CardContent from "@mui/material/CardContent"; import Stack from "@mui/material/Stack"; import TextField from "@mui/material/TextField"; import Button from "@mui/material/Button"; -import Tooltip from "@mui/material/Tooltip"; -import { useTranslation, Trans } from "react-i18next"; +import { useTranslation } from "react-i18next"; import { useAppDispatch, useAppSelector } from "../../../redux/hooks"; import { StatusIcon } from "../../generic/Icons"; import { setField } from "../metadataSlice"; import { getFieldStatus } from "../metadataHelpers"; -import type { OptionsType } from "../../../types/MetadataFields"; +import type { OptionsType, ExtendedMapFeature, MapFeatureType } from "../../../types/MetadataFields"; import type { DrawMapFieldProps } from "../../../types/MetadataProps"; import { lookupLanguageString } from "@dans-framework/utils"; import { getFormDisabled } from "../../../deposit/depositSlice"; @@ -19,10 +21,8 @@ import MapboxDraw from '@mapbox/mapbox-gl-draw'; import 'maplibre-gl/dist/maplibre-gl.css'; import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css'; import './Map.css'; - -import InfoRoundedIcon from '@mui/icons-material/InfoRounded'; +import type { Point, Polygon } from 'geojson'; import List from '@mui/material/List'; -import ListSubheader from '@mui/material/ListSubheader'; import ListItem from '@mui/material/ListItem'; import ListItemButton from '@mui/material/ListItemButton'; import ListItemIcon from '@mui/material/ListItemIcon'; @@ -36,8 +36,7 @@ import { useFetchGeonamesFreeTextQuery, useFetchPlaceReverseLookupQuery } from " import type { QueryReturnType } from "../../../types/Api"; import CircularProgress from "@mui/material/CircularProgress"; import Autocomplete from "@mui/material/Autocomplete"; -import Typography from "@mui/material/Typography"; -import { useDebounce } from "use-debounce"; +import { useDebounce, useDebouncedCallback } from "use-debounce"; import Collapse from '@mui/material/Collapse'; import PublicIcon from '@mui/icons-material/Public'; @@ -47,6 +46,8 @@ import TableCell from '@mui/material/TableCell'; import TableContainer from '@mui/material/TableContainer'; import TableHead from '@mui/material/TableHead'; import TableRow from '@mui/material/TableRow'; +import IconButton from '@mui/material/IconButton'; +import RemoveCircleOutlineIcon from "@mui/icons-material/RemoveCircleOutline"; /** * Map field @@ -71,10 +72,34 @@ const DrawMap = ({ latitude: 52.080738, zoom: 8, }); - const [ features, setFeatures ] = useState([]); - // todo: write this to redux store, import proper geojson type from map lib + const [ features, setFeatures ] = useState(field.value || []); + + // write this to redux store with some debouncing for performance + const debouncedSaveToStore = useDebouncedCallback( + () => { + console.log('dispatching') + dispatch( + setField({ + sectionIndex: sectionIndex, + id: field.id, + value: features, + }), + ); + }, + // delay in ms + 800 + ); + + useEffect(() => { + // on features change, write this to store with a debounce + if (features.length > 0 || (features.length === 0 && field.touched)) { + debouncedSaveToStore(); + } + }, [features, field.touched]) console.log(features) + const [ selectedFeatures, setSelectedFeatures ] = useState<(string | number | undefined)[]>([]); + useEffect(() => { if (geonamesValue) { // move map to selected GeoNames value @@ -85,16 +110,15 @@ const DrawMap = ({ }); setOpenMap(true); // and add it to map if not added yet, checks geonames id - const newFeature = { + const newFeature: ExtendedMapFeature = { id: geonamesValue.id, type: "Feature", - properties: { - geoNames: geonamesValue, - }, geometry: { type: "Point", - coordinates: geonamesValue.coordinates, + coordinates: geonamesValue.coordinates as number[], }, + properties: {}, + geonames: geonamesValue, }; setFeatures( [...new Map([...features, newFeature].map(item => [item.id, item])).values()] @@ -103,51 +127,65 @@ const DrawMap = ({ }, [geonamesValue]); return ( - - - - - - - - setViewState(e.viewState)} - style={{ - width: '100%', - height: 400, - borderRadius: '5px', - border: "1px solid rgba(0,0,0,0.23)" - }} - mapStyle={`https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json`} - > - - - - - {features.length > 0 && - // let's user edit features coordinates directly - // todo: how to present this?? - // also, let user select a corresponding geonames option??? - + + - + titleTypographyProps={{ fontSize: 16 }} + subheaderTypographyProps={{ fontSize: 12 }} + sx={{ pb: 0, pl: 2.25, pr: 2.25 }} + /> + + + + + + + + + setViewState(e.viewState)} + style={{ + width: '100%', + height: 400, + borderRadius: '5px', + border: "1px solid rgba(0,0,0,0.23)" + }} + mapStyle={`https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json`} + > + + + + + {features.length > 0 && + // let's user edit features coordinates directly + // todo: how to present this?? + // also, let user select a corresponding geonames option??? + + } + + + + ); }; @@ -155,50 +193,69 @@ export default DrawMap; interface Column { id: string; - label: string; + label?: string; width?: number; } -const columns: readonly Column[] = [ - { id: 'feature', label: 'Type', width: 50 }, - { id: 'coordinates', label: 'Coordinates', width: 500 }, - { id: 'geonames', label: 'Geoname reference' }, -]; - -const FeatureTable = ({ features, setFeatures }: { - features: Feature[]; - setFeatures: Dispatch>; +const FeatureTable = ({ features, setFeatures, selectedFeatures }: { + features: ExtendedMapFeature[]; + setFeatures: Dispatch>; + selectedFeatures: (string | number | undefined)[]; }) => { const { t } = useTranslation("metadata"); - const setCoordinates = (coord: string, indexes: number[], isFirst?: boolean) => { + const columns: readonly Column[] = [ + { id: 'feature', label: t('featureType'), width: 50 }, + { id: 'coordinates', label: t('featureCoordinates'), width: 500 }, + { id: 'geonames', label: t('featureGeonameRef') }, + { id: 'delete', label: t('delete'), width: 50 }, + ]; + + const setCoordinates = (coord: string, featureIndex: number, coordIndexes: number[], isFirst?: boolean) => { // set the new coordinates - const newFeatures = [...features]; - let target = newFeatures[indexes[0]].geometry.coordinates; - for (let i = 1; i < indexes.length - 1; i++) { - target = target[indexes[i]]; + let newFeatures = [...features]; + let target: any = (newFeatures[featureIndex].geometry as MapFeatureType).coordinates; + + // Traverse the array up to the point where you're modifying a single number + for (let i = 0; i < coordIndexes.length - 1; i++) { + target = target[coordIndexes[i]]; } - target[indexes[indexes.length - 1]] = parseFloat(coord); - // For a polygon, we need to set the last coordinate pair to the first one, to close the shape - // This is not editable by the user - if (isFirst) { - const lastIndex = newFeatures[indexes[0]].geometry.coordinates[0].length - 1; - newFeatures[indexes[0]].geometry.coordinates[0][lastIndex] = target; + // Modify the specific coordinate (either lat or lng) + target[coordIndexes[coordIndexes.length - 1]] = parseFloat(coord); + + // Close the polygon if necessary + if (isFirst && (newFeatures[featureIndex].geometry as Polygon).type === 'Polygon') { + const polygon = newFeatures[featureIndex].geometry as Polygon; + const firstCoordinate = polygon.coordinates[0][0]; + polygon.coordinates[0][polygon.coordinates[0].length - 1] = [...firstCoordinate]; } + + // Update the features and geoNames setFeatures(newFeatures); - setGeonames(undefined, indexes[0]); + setGeonames(undefined, featureIndex); } const setGeonames = (geonamesValue: OptionsType | undefined, index: number) => { // set the new geonames value - const newFeatures = [...features]; - newFeatures[index].properties.geoNames = geonamesValue; - setFeatures(newFeatures); + setFeatures(features.map((feature, i) => + i === index ? { ...feature, geonames: geonamesValue } : feature + )); + } + + const deleteFeature = (index: number) => { + setFeatures(features.filter((_, i) => i !== index)); } return ( - +
@@ -214,15 +271,17 @@ const FeatureTable = ({ features, setFeatures }: { {features.map((feature, i) => - + { feature.geometry.type === "Point" - ? + ? : feature.geometry.type === "LineString" - ? + ? : feature.geometry.type === "Polygon" - ? + ? : null } @@ -230,21 +289,21 @@ const FeatureTable = ({ features, setFeatures }: { { feature.geometry.type === "Point" && - {feature.geometry.coordinates.map((coord: number, j: number) => + {feature.geometry.coordinates.map((coord, j) => setCoordinates(e.target.value, [i, j])} + label={j === 1 ? t("lat") : t("lng")} + onChange={(e) => setCoordinates(e.target.value, i, [j])} /> )} } { feature.geometry.type === "LineString" && - feature.geometry.coordinates.map((coord: number[], j:number) => + feature.geometry.coordinates.map((coord, j) => {coord.map((c, k) => setCoordinates(e.target.value, [i, j, k])} + label={k === 1 ? t("lat") : t("lng")} + onChange={(e) => setCoordinates(e.target.value, i, [j, k])} /> )} @@ -261,17 +320,17 @@ const FeatureTable = ({ features, setFeatures }: { } { feature.geometry.type === "Polygon" && - feature.geometry.coordinates[0].map((coord: number[], j: number) => + feature.geometry.coordinates[0].map((coord, j) => {coord.map((c, k) => setCoordinates(e.target.value, [i, 0, j, k], j === 0)} + label={k === 1 ? t("lat") : t("lng")} + onChange={(e) => setCoordinates(e.target.value, i, [0, j, k], j === 0)} /> )} @@ -281,24 +340,34 @@ const FeatureTable = ({ features, setFeatures }: { + + deleteFeature(i)} + > + + + )} @@ -310,22 +379,12 @@ const FeatureTable = ({ features, setFeatures }: { const controls = ["simple_select", "draw_point", "draw_line_string", "draw_polygon"]; -interface Feature { - id: string; - geometry: { - type: string; - coordinates: number[] | number[][] | number[][][]; - }; - properties: { - geoNames?: OptionsType; - } -} - -type FeaturesEvent = {features: Feature[], action?: string}; +type FeaturesEvent = {features: ExtendedMapFeature[], action?: string}; -const DrawControls = ({ features, setFeatures }: { - features: Feature[]; - setFeatures: Dispatch>; +const DrawControls = ({ features, setFeatures, setSelectedFeatures }: { + features: ExtendedMapFeature[]; + setFeatures: Dispatch>; + setSelectedFeatures: Dispatch>; }) => { const { t } = useTranslation("metadata"); const [ selectedMode, setSelectedMode ] = useState(controls[0]); @@ -337,7 +396,7 @@ const DrawControls = ({ features, setFeatures }: { // So geonames reference is removed when points change const updatedFeatures = e.features.map(feature => ({ ...feature, - properties: {}, + geonames: undefined, })); setFeatures(currFeatures => @@ -355,6 +414,13 @@ const DrawControls = ({ features, setFeatures }: { setSelectedMode(controls[0]); }, []); + const onSelectionChange = useCallback((e: FeaturesEvent) => { + console.log('selection changed'); + console.log(e) + // const changedFeatureIds = new Set(e.features.map(feature => feature.id)); + setSelectedFeatures(e.features.map(feature => feature.id)); + }, []); + // manual key listener, since delete is broken in the map libre / mapbox draw combo const handleKeyDown = useCallback((event: KeyboardEvent, drawControl: MapboxDraw) => { const selectedFeatures = drawControl.getSelected(); @@ -376,22 +442,7 @@ const DrawControls = ({ features, setFeatures }: { top: "1rem" }} > - - {t('draw')} - , - ]} - /> - }> - - - - }> + {controls.map(control => ) } -type DrawControlProps = { - onCreate: (e: FeaturesEvent) => void; - onUpdate: (e: FeaturesEvent) => void; - onDelete: (e: FeaturesEvent) => void; - mode: string; - onKeyDown: (e: KeyboardEvent, c: MapboxDraw) => void; - features: Feature[]; -}; - -// Some MapboxDraw typescript issues, changed to any type for now - const DrawControl = ({ onCreate, onUpdate, onDelete, + onSelectionChange, mode, onKeyDown, features, -}: DrawControlProps) => { +}: { + onCreate: (e: FeaturesEvent) => void; + onUpdate: (e: FeaturesEvent) => void; + onDelete: (e: FeaturesEvent) => void; + onSelectionChange: (e: FeaturesEvent) => void; + mode: string; + onKeyDown: (e: KeyboardEvent, c: MapboxDraw) => void; + features: ExtendedMapFeature[]; +}) => { const control = useControl( () => new MapboxDraw({ // remove default controls @@ -481,6 +531,7 @@ const DrawControl = ({ map.on('draw.create', onCreate); map.on('draw.update', onUpdate); map.on('draw.delete', onDelete); + map.on('draw.selectionchange', onSelectionChange); // Attach the keydown event to the map container const canvas = map.getCanvas(); @@ -494,6 +545,7 @@ const DrawControl = ({ map.off('draw.create', onCreate); map.off('draw.update', onUpdate); map.off('draw.delete', onDelete); + map.off('draw.selectionchange', onSelectionChange); // Clean up the keydown event listener const canvas = map.getCanvas(); @@ -508,8 +560,11 @@ const DrawControl = ({ useEffect(() => { // if features prop changes, reflect that on map - if (control && features.length > 0) { - features.map(f => control.add(f)) + if (control) { + control.set({ + type: 'FeatureCollection', + features: features, + }) } }, [features, control]); @@ -527,11 +582,12 @@ const ReverseLookupGeonamesField = ({ lat: number; lng: number; featureIndex: number; - value: OptionsType | null; - setValue: (option: OptionsType | null, index: number) => void; + value: OptionsType | undefined; + setValue: (option: OptionsType | undefined, index: number) => void; disabled?: boolean; }) => { - // geonames info, where to save + // TODO: we need a better reverse lookup + const { t } = useTranslation("metadata"); const [inputValue, setInputValue] = useState(""); // fetch on open, not directly on prop change @@ -555,6 +611,7 @@ const ReverseLookupGeonamesField = ({ {...params} label={t("findPlace")} size="small" + error={!value} /> )} onChange={(_e, newValue, _reason) => setValue(newValue as OptionsType, featureIndex)} diff --git a/packages/deposit/src/features/metadata/metadataHelpers.ts b/packages/deposit/src/features/metadata/metadataHelpers.ts index 4c786bfa..e0cb5a3c 100644 --- a/packages/deposit/src/features/metadata/metadataHelpers.ts +++ b/packages/deposit/src/features/metadata/metadataHelpers.ts @@ -155,7 +155,8 @@ export const getFieldStatus = (field: InputField): SectionStatus => { !field.value || (typeof field.value === "string" && !field.value.trim()) || (Array.isArray(field.value) && field.value.length === 0 ) || - (field.type === 'daterange' && Array.isArray(field.value) && field.value.every(v => v === null || v === "")); + (field.type === 'daterange' && Array.isArray(field.value) && field.value.every(v => v === null || v === "")) || + (field.type === 'drawmap' && Array.isArray(field.value) && field.value.some(v => v.geonames === null || v.geonames === undefined)); if (field.noIndicator && !field.required && fieldEmpty) { return "neutral"; @@ -187,19 +188,20 @@ export const getSectionStatus = (section: SectionStatus[]): SectionStatus => { // Check if a field conforms to validation type specified export const getValid = ( - value: string, + value: any, field: Field, ): boolean => { if (field.validation) { return validateData(field.validation, value); } else if ( - ( value && value.length !== 0 && field.type !== 'daterange' ) || + ( value && value.length !== 0 && field.type !== 'daterange' && field.type !== 'drawmap' ) || // special check for date range: start date must be before or equal to end date, // or if end date not required, end date can be empty (field.type === 'daterange' && value && ( moment(value[0], field.format).isSameOrBefore(moment(value[1], field.format)) || (field.optionalEndDate && value[0] && !value[1]) - )) + )) || + (field.type === 'drawmap' && value.every((item: any) => item.geonames !== null && item.geonames !== undefined)) ) { return true; } diff --git a/packages/deposit/src/features/metadata/metadataSlice.ts b/packages/deposit/src/features/metadata/metadataSlice.ts index 3b87045c..1a772935 100644 --- a/packages/deposit/src/features/metadata/metadataSlice.ts +++ b/packages/deposit/src/features/metadata/metadataSlice.ts @@ -1,19 +1,19 @@ import { createSlice, PayloadAction, /*current*/ } from "@reduxjs/toolkit"; import { RootState } from "../../redux/store"; import type { - SetFieldPayload, + SetFieldValuePayload, + SetFieldMultiApiPayload, + SetFieldFormatPayload, + SetFieldValidPayload, AddFieldPayload, DeleteFieldPayload, SectionStatusPayload, - FieldValue, } from "../../types/MetadataPayloads"; import type { RepeatTextFieldType, RepeatGroupedFieldType, TextFieldType, InputField, - TypeaheadAPI, - DateTimeFormat, } from "../../types/MetadataFields"; import type { InitialStateType, @@ -68,7 +68,7 @@ export const metadataSlice = createSlice({ } }, // keep track of form state - setField: (state, action: PayloadAction) => { + setField: (state, action: PayloadAction) => { const section = state.form[action.payload.sectionIndex]; const field = findByIdOrName(action.payload.id, section.fields); @@ -78,7 +78,7 @@ export const metadataSlice = createSlice({ // field is found, lets set it if (field) { - field.value = action.payload.value as FieldValue; + field.value = action.payload.value; field.touched = true; // For setting required state of 'conditional' fields, @@ -110,28 +110,28 @@ export const metadataSlice = createSlice({ // After every input, we need to update field valid status and section status as well. field.valid = getValid( - action.payload.value as string, + action.payload.value, field ); // then set the section/accordion metadataSlice.caseReducers.setSectionStatus(state, action); } }, - setMultiApiField: (state, action: PayloadAction) => { + setMultiApiField: (state, action: PayloadAction) => { const section = state.form[action.payload.sectionIndex]; const field = findByIdOrName(action.payload.id, section.fields); if (field) { - field.multiApiValue = action.payload.value as TypeaheadAPI; + field.multiApiValue = action.payload.value; } }, - setDateTypeField: (state, action: PayloadAction) => { + setDateTypeField: (state, action: PayloadAction) => { const section = state.form[action.payload.sectionIndex]; const field = findByIdOrName(action.payload.id, section.fields); if (field) { - field.format = action.payload.value as DateTimeFormat; + field.format = action.payload.value; } }, - setFieldValid: (state, action: PayloadAction) => { + setFieldValid: (state, action: PayloadAction) => { const section = state.form[action.payload.sectionIndex]; const field = findByIdOrName(action.payload.id, section.fields); if (field) { diff --git a/packages/deposit/src/languages/locales/en/metadata.json b/packages/deposit/src/languages/locales/en/metadata.json index 2fedc16e..6a6f50e2 100644 --- a/packages/deposit/src/languages/locales/en/metadata.json +++ b/packages/deposit/src/languages/locales/en/metadata.json @@ -44,12 +44,18 @@ "apiFetchError": "Could not get data from {{api}}", "generate": "Regenerate value", "generateDisabled": "Cannot generate value, as not all required fields have been filled in or are public data.", + "initialLocation": "Search on geonames and create a point on your selected location", "draw": "Draw", "simple_select": "Select", "draw_point": "Point", "draw_line_string": "Line", "draw_polygon": "Polygon", - "drawExplanation": "<0>Select a shape type and click on the map to start drawing. In case of a multipoint shape, double click or press 'Enter' to finish drawing.<0>To edit a shape, click on it to select it, and drag it around, or add or move individual points.<0>To delete a shape, select it and press 'Delete' on your keyboard.", - "delete": "Delete", - "toggleMap": "Toggle map" + "drawExplanation": "

Select a shape type and click on the map to start drawing. In case of a multipoint shape, double click or press 'Enter' to finish drawing.

To edit a shape, click on it to select it, and drag it around, or add or move individual points.

To delete a shape, select it and press 'Delete' on your keyboard.

", + "toggleMap": "Toggle map", + "featureType": "Type", + "featureCoordinates": "Coordinates", + "featureGeonameRef": "Geonames reference", + "lat": "Latitude", + "lng": "Longitude", + "findPlace": "Select corresponding location" } \ No newline at end of file diff --git a/packages/deposit/src/types/MetadataFields.ts b/packages/deposit/src/types/MetadataFields.ts index d7b3e17e..2561e864 100644 --- a/packages/deposit/src/types/MetadataFields.ts +++ b/packages/deposit/src/types/MetadataFields.ts @@ -1,5 +1,6 @@ import type { LanguageStrings } from "@dans-framework/utils"; import type { AuthProperty } from "@dans-framework/user-auth"; +import type { Feature, Point, Polygon, LineString, Geometry } from 'geojson'; // All user input field types export type InputField = @@ -166,20 +167,17 @@ export interface CheckFieldType maxDateField?: never; } -interface GeoJSON { - id: string; - type: string; - properties: Object; - geometry: { - type: string; - coordinates: string[] | string[][]; - }; +export type MapFeatureType = Point | Polygon | LineString; +export interface ExtendedMapFeature extends Feature { + geonames?: OptionsType | undefined; + label?: never; + value?: never; } export interface DrawMapFieldType extends Omit { type: "drawmap"; - value?: GeoJSON; + value?: ExtendedMapFeature[]; multiApiValue?: never; fields?: never; format?: never; diff --git a/packages/deposit/src/types/MetadataPayloads.ts b/packages/deposit/src/types/MetadataPayloads.ts index b83eb073..ec4c03ea 100644 --- a/packages/deposit/src/types/MetadataPayloads.ts +++ b/packages/deposit/src/types/MetadataPayloads.ts @@ -1,23 +1,30 @@ import type { - ValidationType, OptionsType, TypeaheadAPI, + ExtendedMapFeature, + DateTimeFormat, } from "./MetadataFields"; // Payloads and types for redux slices -export type FieldValue = - | string - | string[] - | OptionsType - | OptionsType[] - | null - | ValidationType; - -export interface SetFieldPayload { +interface Payload { sectionIndex: number; id: string; - value: FieldValue | boolean; - typeaheadApi?: TypeaheadAPI; +} + +export interface SetFieldValuePayload extends Payload { + value: string | string[] | OptionsType | OptionsType[] | ExtendedMapFeature[] | null; +} + +export interface SetFieldMultiApiPayload extends Payload { + value: TypeaheadAPI; +} + +export interface SetFieldFormatPayload extends Payload { + value: DateTimeFormat; +} + +export interface SetFieldValidPayload extends Payload { + value: boolean; } export interface AddFieldPayload { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cb18335e..7b6f3b1c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -659,9 +659,6 @@ importers: '@types/uuid': specifier: ^9.0.2 version: 9.0.2 - geojson: - specifier: ^0.5.0 - version: 0.5.0 packages/file-mapper: dependencies: @@ -2665,10 +2662,6 @@ packages: geojson-vt@4.0.2: resolution: {integrity: sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A==} - geojson@0.5.0: - resolution: {integrity: sha512-/Bx5lEn+qRF4TfQ5aLu6NH+UKtvIv7Lhc487y/c8BdludrCTpiWf9wyI0RTyqg49MFefIAvFDuEi5Dfd/zgNxQ==} - engines: {node: '>= 0.10'} - geotiff@2.0.7: resolution: {integrity: sha512-FKvFTNowMU5K6lHYY2f83d4lS2rsCNdpUC28AX61x9ZzzqPNaWFElWv93xj0eJFaNyOYA63ic5OzJ88dHpoA5Q==} engines: {node: '>=10.19'} @@ -5707,8 +5700,6 @@ snapshots: geojson-vt@4.0.2: {} - geojson@0.5.0: {} - geotiff@2.0.7: dependencies: '@petamoriken/float16': 3.8.4 From bdee27aeefeaa593b768c65bf7ed64c224341b5f Mon Sep 17 00:00:00 2001 From: Daan Janssen Date: Mon, 2 Sep 2024 09:17:09 +0200 Subject: [PATCH 08/44] updated geonames reverse lookup --- .../deposit/src/features/metadata/api/geonames.ts | 13 +++++++++++-- packages/deposit/src/types/Api.ts | 1 + pnpm-lock.yaml | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/deposit/src/features/metadata/api/geonames.ts b/packages/deposit/src/features/metadata/api/geonames.ts index dcd362cf..22df06ae 100644 --- a/packages/deposit/src/features/metadata/api/geonames.ts +++ b/packages/deposit/src/features/metadata/api/geonames.ts @@ -35,14 +35,14 @@ export const geonamesApi = createApi({ }), fetchPlaceReverseLookup: build.query({ query: ({lat, lng}) => ({ - url: `findNearbyPlaceName?lat=${lat}&lng=${lng}&radius=10&maxRows=100&username=${ + url: `extendedFindNearby?lat=${lat}&lng=${lng}&radius=1&maxRows=100&username=${ import.meta.env.VITE_GEONAMES_API_KEY }`, headers: { Accept: "application/json" }, }), transformResponse: (response: GeonamesResponse, _meta, arg) => { // Return an empty array when no results, which is what the Autocomplete field expects - return response.geonames.length > 0 ? + return response.geonames?.length > 0 ? { arg: arg, response: response.geonames.map((item) => ({ @@ -54,6 +54,15 @@ export const geonamesApi = createApi({ id: item.geonameId.toString(), })), } + : response.ocean ? + { + arg: arg, + response: [{ + label: response.ocean.name, + value: `https://www.geonames.org/${response.ocean.geonameId}`, + id: response.ocean.geonameId, + }] + } : []; }, transformErrorResponse: () => ({ diff --git a/packages/deposit/src/types/Api.ts b/packages/deposit/src/types/Api.ts index 55857a64..248df942 100644 --- a/packages/deposit/src/types/Api.ts +++ b/packages/deposit/src/types/Api.ts @@ -108,6 +108,7 @@ interface GeonamesItem { export interface GeonamesResponse { totalResultsCount: number; geonames: GeonamesItem[]; + ocean?: GeonamesItem; } export interface ProxyResponse { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7b6f3b1c..08637ce7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -813,7 +813,7 @@ importers: specifier: ^5.14.3 version: 5.14.3(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) '@mui/material': - specifier: ^5.16.7 + specifier: ^5.14.3 version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) clsx: specifier: ^2.0.0 From 20e356f819cd0879cc592d9e00742a1c22c51c95 Mon Sep 17 00:00:00 2001 From: Daan Janssen Date: Mon, 2 Sep 2024 13:33:01 +0200 Subject: [PATCH 09/44] started work on coord conversions --- .../src/features/metadata/api/maptiler.ts | 36 +++ .../src/features/metadata/fields/Map.tsx | 303 +++++++++++++----- packages/deposit/src/redux/store.ts | 3 + packages/deposit/src/types/Api.ts | 10 + packages/deposit/src/types/MetadataFields.ts | 2 + 5 files changed, 279 insertions(+), 75 deletions(-) create mode 100644 packages/deposit/src/features/metadata/api/maptiler.ts diff --git a/packages/deposit/src/features/metadata/api/maptiler.ts b/packages/deposit/src/features/metadata/api/maptiler.ts new file mode 100644 index 00000000..37b4b19a --- /dev/null +++ b/packages/deposit/src/features/metadata/api/maptiler.ts @@ -0,0 +1,36 @@ +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; +import type { MaptilerCoordinateSystemResponse } from "../../../types/Api"; +import i18n from "../../../languages/i18n"; + +export const maptilerApi = createApi({ + reducerPath: "maptiler", + baseQuery: fetchBaseQuery({ baseUrl: "https://api.maptiler.com" }), + endpoints: (build) => ({ + fetchCoordinateSystems: build.query({ + query: (value) => ({ + url: `coordinates/search/${value} kind:*.json?key=${ + import.meta.env.VITE_MAPTILER_API_KEY + }`, + headers: { Accept: "application/json" }, + }), + transformResponse: (response: MaptilerCoordinateSystemResponse, _meta, arg) => { + // Return an empty array when no results, which is what the Autocomplete field expects + return response.results.length > 0 ? + { + arg: arg, + response: response.results.map((item) => ({ + label: `${item.name} (${item.id.authority} ${item.id.code})`, + value: item.id.code, + id: `${item.id.authority}-${item.id.code}`, + })), + } + : []; + }, + transformErrorResponse: () => ({ + error: i18n.t("metadata:apiFetchError", { api: "Maptiler" }), + }), + }), + }), +}); + +export const { useFetchCoordinateSystemsQuery } = maptilerApi; diff --git a/packages/deposit/src/features/metadata/fields/Map.tsx b/packages/deposit/src/features/metadata/fields/Map.tsx index 87370c02..fb76fcca 100644 --- a/packages/deposit/src/features/metadata/fields/Map.tsx +++ b/packages/deposit/src/features/metadata/fields/Map.tsx @@ -21,7 +21,7 @@ import MapboxDraw from '@mapbox/mapbox-gl-draw'; import 'maplibre-gl/dist/maplibre-gl.css'; import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css'; import './Map.css'; -import type { Point, Polygon } from 'geojson'; +import type { Point, Polygon, LineString } from 'geojson'; import List from '@mui/material/List'; import ListItem from '@mui/material/ListItem'; import ListItemButton from '@mui/material/ListItemButton'; @@ -33,6 +33,7 @@ import PlaceIcon from '@mui/icons-material/Place'; import HighlightAltIcon from '@mui/icons-material/HighlightAlt'; import PentagonIcon from '@mui/icons-material/Pentagon'; import { useFetchGeonamesFreeTextQuery, useFetchPlaceReverseLookupQuery } from "../api/geonames"; +import { useFetchCoordinateSystemsQuery } from "../api/maptiler"; import type { QueryReturnType } from "../../../types/Api"; import CircularProgress from "@mui/material/CircularProgress"; import Autocomplete from "@mui/material/Autocomplete"; @@ -66,6 +67,7 @@ const DrawMap = ({ const { t, i18n } = useTranslation("metadata"); const formDisabled = useAppSelector(getFormDisabled); const [geonamesValue, setGeonamesValue] = useState(); + const [coordinateSystem, setCoordinateSystem] = useState(); const [openMap, setOpenMap] = useState(false); const [viewState, setViewState] = useState({ longitude: 4.342779, @@ -139,13 +141,26 @@ const DrawMap = ({ sx={{ pb: 0, pl: 2.25, pr: 2.25 }} /> - + + + } @@ -197,43 +212,83 @@ interface Column { width?: number; } -const FeatureTable = ({ features, setFeatures, selectedFeatures }: { +const FeatureTable = ({ features, setFeatures, selectedFeatures, coordinateSystem }: { features: ExtendedMapFeature[]; setFeatures: Dispatch>; selectedFeatures: (string | number | undefined)[]; + coordinateSystem?: OptionsType; }) => { const { t } = useTranslation("metadata"); const columns: readonly Column[] = [ { id: 'feature', label: t('featureType'), width: 50 }, - { id: 'coordinates', label: t('featureCoordinates'), width: 500 }, + { id: 'coordinates', label: t('featureCoordinates'), width: coordinateSystem === undefined ? 500 : 300 }, + ...(coordinateSystem !== undefined ? [{id: 'transposedCoordinates', label: t('transposedCoordinates'), width: 300}] : []), { id: 'geonames', label: t('featureGeonameRef') }, { id: 'delete', label: t('delete'), width: 50 }, ]; - const setCoordinates = (coord: string, featureIndex: number, coordIndexes: number[], isFirst?: boolean) => { + const setCoordinates = (value: number, featureIndex: number, type: string, coordinateIndex: number, groupIndex?: number) => { + // TODO: Expand this to optionally set two coord objects, with call to conversion service maptiler + // set the new coordinates - let newFeatures = [...features]; - let target: any = (newFeatures[featureIndex].geometry as MapFeatureType).coordinates; + const newFeatures = features.map((feature, index) => + index === featureIndex ? ({ + ...feature, + geometry: { + ...feature.geometry, + coordinates: + type === 'Point' ? + (feature.geometry as Point).coordinates.map((coordinate, i) => + i === coordinateIndex ? value : coordinate + ) : + type === 'LineString' ? + (feature.geometry as LineString).coordinates.map((coordinateGroup, i) => + i === groupIndex ? coordinateGroup.map((coordinate, j) => + j === coordinateIndex ? value : coordinate + ) : coordinateGroup + ) : + type === 'Polygon' ? (() => { + // First, update the first set of coordinates + const updatedCoordinates = (feature.geometry as Polygon).coordinates[0].map((coordinateGroup, i) => + i === groupIndex ? coordinateGroup.map((coordinate, j) => + j === coordinateIndex ? value : coordinate + ) : coordinateGroup + ); + // Ensure the last set of coordinates is the same as the first one + const firstSet = updatedCoordinates[0]; + updatedCoordinates[updatedCoordinates.length - 1] = firstSet; + + return [updatedCoordinates]; + })() : + (feature.geometry as any).coordinates, + }, + geonames: undefined, + }) + : feature + ); - // Traverse the array up to the point where you're modifying a single number - for (let i = 0; i < coordIndexes.length - 1; i++) { - target = target[coordIndexes[i]]; - } - // Modify the specific coordinate (either lat or lng) - target[coordIndexes[coordIndexes.length - 1]] = parseFloat(coord); + // let newFeatures = [...features]; + // let target: any = (newFeatures[featureIndex].geometry as MapFeatureType).coordinates; + + // // Traverse the array up to the point where you're modifying a single number + // for (let i = 0; i < coordIndexes.length - 1; i++) { + // target = target[coordIndexes[i]]; + // } + + // // Modify the specific coordinate (either lat or lng) + // target[coordIndexes[coordIndexes.length - 1]] = parseFloat(coord); // Close the polygon if necessary - if (isFirst && (newFeatures[featureIndex].geometry as Polygon).type === 'Polygon') { - const polygon = newFeatures[featureIndex].geometry as Polygon; - const firstCoordinate = polygon.coordinates[0][0]; - polygon.coordinates[0][polygon.coordinates[0].length - 1] = [...firstCoordinate]; - } + // if (isFirst && (newFeatures[featureIndex].geometry as Polygon).type === 'Polygon') { + // const polygon = newFeatures[featureIndex].geometry as Polygon; + // const firstCoordinate = polygon.coordinates[0][0]; + // polygon.coordinates[0][polygon.coordinates[0].length - 1] = [...firstCoordinate]; + // } // Update the features and geoNames setFeatures(newFeatures); - setGeonames(undefined, featureIndex); } const setGeonames = (geonamesValue: OptionsType | undefined, index: number) => { @@ -286,57 +341,13 @@ const FeatureTable = ({ features, setFeatures, selectedFeatures }: { } - { - feature.geometry.type === "Point" && - - {feature.geometry.coordinates.map((coord, j) => - setCoordinates(e.target.value, i, [j])} - /> - )} - - } - { - feature.geometry.type === "LineString" && - feature.geometry.coordinates.map((coord, j) => - - {coord.map((c, k) => - setCoordinates(e.target.value, i, [j, k])} - /> - )} - - ) - } - { - feature.geometry.type === "Polygon" && - feature.geometry.coordinates[0].map((coord, j) => - - {coord.map((c, k) => - setCoordinates(e.target.value, i, [0, j, k], j === 0)} - /> - )} - - ) - } + + {coordinateSystem && + + + + } void; +}) => { + const { t } = useTranslation("metadata"); + console.log(feature) + + return ( + feature.geometry.type === "Point" ? + + {feature.geometry.coordinates.map((coord, coordinateIndex) => + onChange(parseFloat(e.target.value), featureIndex, feature.geometry.type, coordinateIndex)} + /> + )} + + : feature.geometry.type === "LineString" ? + feature.geometry.coordinates.map((coordGroup, groupIndex) => + + {coordGroup.map((coord, coordinateIndex) => + onChange(parseFloat(e.target.value), featureIndex, feature.geometry.type, coordinateIndex, groupIndex)} + /> + )} + + ) + : feature.geometry.type === "Polygon" ? + feature.geometry.coordinates[0].map((coordGroup, groupIndex) => + + {coordGroup.map((coord, coordinateIndex) => + onChange(parseFloat(e.target.value), featureIndex, feature.geometry.type, coordinateIndex, groupIndex)} + /> + )} + + ) + : null + ) +} + const controls = ["simple_select", "draw_point", "draw_line_string", "draw_polygon"]; @@ -643,14 +711,15 @@ const GeonamesApiField = ({ value, setValue, disabled, - label + label, + width, }: { value?: OptionsType; setValue: (v: OptionsType) => void; disabled?: boolean; label?: string; + width?: string | number; }) => { - const { t } = useTranslation("metadata"); const [inputValue, setInputValue] = useState(""); const debouncedInputValue = useDebounce(inputValue, 500)[0]; // Fetch data on input change @@ -659,9 +728,93 @@ const GeonamesApiField = ({ skip: debouncedInputValue === "", }); + return ( + + ); +}; + +const FindCoordinateSystemField = ({ + value, + setValue, + disabled, + label, + width, +}: { + value?: OptionsType; + setValue: (v: OptionsType) => void; + disabled?: boolean; + label?: string; + width?: string | number; +}) => { + const [inputValue, setInputValue] = useState(""); + const debouncedInputValue = useDebounce(inputValue, 500)[0]; + // Fetch data on input change + const { data, isFetching, isLoading } = + useFetchCoordinateSystemsQuery(debouncedInputValue, { + skip: debouncedInputValue === "", + }); + + return ( + + ); +}; + +const TypeaheadField = ({ + inputValue, + setInputValue, + debouncedInputValue, + data, + value, + label, + setValue, + disabled, + isLoading, + isFetching, + width, +}: { + value?: OptionsType; + setValue: (v: OptionsType) => void; + disabled?: boolean; + label?: string; + width?: string | number; + inputValue?: string; + setInputValue: Dispatch> + debouncedInputValue?: string; + data: any; + isLoading: boolean; + isFetching: boolean; +}) => { + const { t } = useTranslation("metadata"); return ( option.value} /> - ); -}; \ No newline at end of file + ) +} \ No newline at end of file diff --git a/packages/deposit/src/redux/store.ts b/packages/deposit/src/redux/store.ts index 4ddc871a..3d5a9c10 100644 --- a/packages/deposit/src/redux/store.ts +++ b/packages/deposit/src/redux/store.ts @@ -16,6 +16,7 @@ import { dansUtilityApi } from "../features/files/api/dansUtility"; import { errorLogger } from "@dans-framework/utils/error"; import { licenceApi } from "../features/metadata/api/licences"; import { sshLicenceApi } from "../features/metadata/api/sshLicences"; +import { maptilerApi } from "../features/metadata/api/maptiler"; import { rdaApi } from "../features/metadata/api/rdaApi"; import { validateKeyApi } from "@dans-framework/user-auth"; @@ -37,6 +38,7 @@ export const store = configureStore({ [rdaApi.reducerPath]: rdaApi.reducer, [languagesApi.reducerPath]: languagesApi.reducer, [validateKeyApi.reducerPath]: validateKeyApi.reducer, + [maptilerApi.reducerPath]: maptilerApi.reducer, submit: submitReducer, deposit: depositReducer, }, @@ -56,6 +58,7 @@ export const store = configureStore({ .concat(rdaApi.middleware) .concat(languagesApi.middleware) .concat(validateKeyApi.middleware) + .concat(maptilerApi.middleware) .concat(errorLogger), }); diff --git a/packages/deposit/src/types/Api.ts b/packages/deposit/src/types/Api.ts index 248df942..1a2a2639 100644 --- a/packages/deposit/src/types/Api.ts +++ b/packages/deposit/src/types/Api.ts @@ -111,6 +111,16 @@ export interface GeonamesResponse { ocean?: GeonamesItem; } +export interface MaptilerCoordinateSystemResponse { + results: { + id: { + authority: string; + code: number; + }; + name: string; + }[]; +} + export interface ProxyResponse { status_code: number; text: string; diff --git a/packages/deposit/src/types/MetadataFields.ts b/packages/deposit/src/types/MetadataFields.ts index 2561e864..3140f81d 100644 --- a/packages/deposit/src/types/MetadataFields.ts +++ b/packages/deposit/src/types/MetadataFields.ts @@ -170,6 +170,8 @@ export interface CheckFieldType export type MapFeatureType = Point | Polygon | LineString; export interface ExtendedMapFeature extends Feature { geonames?: OptionsType | undefined; + originalCoordinates?: number[] | number[][] | number[][][]; + coordinateSystem?: string; label?: never; value?: never; } From 17eef8e138eeea7f4c045eb6200da62beba52270 Mon Sep 17 00:00:00 2001 From: Laurens Tobias Date: Thu, 26 Sep 2024 03:26:18 +0200 Subject: [PATCH 10/44] Updated ES endpoint --- apps/rda/src/config/elasticSearch.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/rda/src/config/elasticSearch.tsx b/apps/rda/src/config/elasticSearch.tsx index 269209a7..3b7b8e2d 100644 --- a/apps/rda/src/config/elasticSearch.tsx +++ b/apps/rda/src/config/elasticSearch.tsx @@ -24,7 +24,7 @@ const fieldConfig: Partial = { export const elasticConfig = [ { name: "RDA Catalogue", - url: "https://tiger.laurenstobias.com/rda", + url: "https://es.laurenstobias.com/rda", fullTextFields: fieldConfig.fullTextFields, fullTextHighlight: fieldConfig.fullTextHighlight, resultBodyComponent: Rda2Result, From 917e350a3b457bdb5e1acb7cb3c8e102f55b1a6c Mon Sep 17 00:00:00 2001 From: Daan Janssen Date: Mon, 7 Oct 2024 14:37:03 +0200 Subject: [PATCH 11/44] wip --- .../src/features/metadata/api/maptiler.ts | 24 ++++++++- .../src/features/metadata/fields/Map.tsx | 51 ++++++++----------- .../src/languages/locales/en/metadata.json | 6 ++- 3 files changed, 48 insertions(+), 33 deletions(-) diff --git a/packages/deposit/src/features/metadata/api/maptiler.ts b/packages/deposit/src/features/metadata/api/maptiler.ts index 37b4b19a..7076f321 100644 --- a/packages/deposit/src/features/metadata/api/maptiler.ts +++ b/packages/deposit/src/features/metadata/api/maptiler.ts @@ -27,10 +27,30 @@ export const maptilerApi = createApi({ : []; }, transformErrorResponse: () => ({ - error: i18n.t("metadata:apiFetchError", { api: "Maptiler" }), + error: i18n.t("metadata:apiFetchError", { api: "maptiler" }), + }), + }), + transformCoordinates: build.query({ + query: ({coordinates, from, to}) => ({ + url: `coordinates/transform/${coordinates}.json?s_srs=${from}&t_srs=${to}&key=${ + import.meta.env.VITE_MAPTILER_API_KEY + }`, + headers: { Accept: "application/json" }, + }), + transformResponse: (response: any, _meta, arg) => { + // Return an empty array when no results, which is what the Autocomplete field expects + return response.results.length > 0 ? + { + arg: arg, + response: response.results, + } + : []; + }, + transformErrorResponse: () => ({ + error: i18n.t("metadata:apiFetchError", { api: "maptiler" }), }), }), }), }); -export const { useFetchCoordinateSystemsQuery } = maptilerApi; +export const { useFetchCoordinateSystemsQuery, useTransformCoordinatesQuery } = maptilerApi; diff --git a/packages/deposit/src/features/metadata/fields/Map.tsx b/packages/deposit/src/features/metadata/fields/Map.tsx index fb76fcca..7a711bb3 100644 --- a/packages/deposit/src/features/metadata/fields/Map.tsx +++ b/packages/deposit/src/features/metadata/fields/Map.tsx @@ -33,7 +33,7 @@ import PlaceIcon from '@mui/icons-material/Place'; import HighlightAltIcon from '@mui/icons-material/HighlightAlt'; import PentagonIcon from '@mui/icons-material/Pentagon'; import { useFetchGeonamesFreeTextQuery, useFetchPlaceReverseLookupQuery } from "../api/geonames"; -import { useFetchCoordinateSystemsQuery } from "../api/maptiler"; +import { useFetchCoordinateSystemsQuery, useTransformCoordinatesQuery } from "../api/maptiler"; import type { QueryReturnType } from "../../../types/Api"; import CircularProgress from "@mui/material/CircularProgress"; import Autocomplete from "@mui/material/Autocomplete"; @@ -193,8 +193,6 @@ const DrawMap = ({ {features.length > 0 && // let's user edit features coordinates directly - // todo: how to present this?? - // also, let user select a corresponding geonames option??? } @@ -219,17 +217,21 @@ const FeatureTable = ({ features, setFeatures, selectedFeatures, coordinateSyste coordinateSystem?: OptionsType; }) => { const { t } = useTranslation("metadata"); + const getAltCoordinates = useTransformCoordinatesQuery(); const columns: readonly Column[] = [ { id: 'feature', label: t('featureType'), width: 50 }, { id: 'coordinates', label: t('featureCoordinates'), width: coordinateSystem === undefined ? 500 : 300 }, - ...(coordinateSystem !== undefined ? [{id: 'transposedCoordinates', label: t('transposedCoordinates'), width: 300}] : []), + ...(coordinateSystem !== undefined ? [{id: 'transposedCoordinates', label: t('transposedCoordinates', { id: coordinateSystem.id }), width: 300}] : []), { id: 'geonames', label: t('featureGeonameRef') }, { id: 'delete', label: t('delete'), width: 50 }, ]; + console.log(coordinateSystem) + const setCoordinates = (value: number, featureIndex: number, type: string, coordinateIndex: number, groupIndex?: number) => { // TODO: Expand this to optionally set two coord objects, with call to conversion service maptiler + // conversion expects a lat/lon pair. // set the new coordinates const newFeatures = features.map((feature, index) => @@ -268,25 +270,6 @@ const FeatureTable = ({ features, setFeatures, selectedFeatures, coordinateSyste : feature ); - - // let newFeatures = [...features]; - // let target: any = (newFeatures[featureIndex].geometry as MapFeatureType).coordinates; - - // // Traverse the array up to the point where you're modifying a single number - // for (let i = 0; i < coordIndexes.length - 1; i++) { - // target = target[coordIndexes[i]]; - // } - - // // Modify the specific coordinate (either lat or lng) - // target[coordIndexes[coordIndexes.length - 1]] = parseFloat(coord); - - // Close the polygon if necessary - // if (isFirst && (newFeatures[featureIndex].geometry as Polygon).type === 'Polygon') { - // const polygon = newFeatures[featureIndex].geometry as Polygon; - // const firstCoordinate = polygon.coordinates[0][0]; - // polygon.coordinates[0][polygon.coordinates[0].length - 1] = [...firstCoordinate]; - // } - // Update the features and geoNames setFeatures(newFeatures); } @@ -341,11 +324,11 @@ const FeatureTable = ({ features, setFeatures, selectedFeatures, coordinateSyste } - + {coordinateSystem && - + } @@ -387,13 +370,15 @@ const FeatureTable = ({ features, setFeatures, selectedFeatures, coordinateSyste ) } -const FeatureCoordinateCell = ({feature, onChange, featureIndex}: { +const FeatureCoordinateCell = ({feature, onChange, featureIndex, coordinateSystem, isWgs84}: { feature: ExtendedMapFeature; featureIndex: number; onChange: (value: number, featureIndex: number, type: string, coordinateIndex: number, groupIndex?: number) => void; + coordinateSystem?: any; + isCoordinateSystem?: boolean; }) => { const { t } = useTranslation("metadata"); - console.log(feature) + console.log(feature); return ( feature.geometry.type === "Point" ? @@ -405,7 +390,7 @@ const FeatureCoordinateCell = ({feature, onChange, featureIndex}: { size="small" value={coord} label={coordinateIndex === 1 ? t("lat") : t("lng")} - onChange={(e) => onChange(parseFloat(e.target.value), featureIndex, feature.geometry.type, coordinateIndex)} + onChange={(e) => onChange(parseFloat(e.target.value), featureIndex, feature.geometry.type, coordinateIndex, undefined)} /> )} @@ -444,6 +429,10 @@ const FeatureCoordinateCell = ({feature, onChange, featureIndex}: { ) } +// TODO?? Create component representing a lat/lon group, so we can convert the coordinates using an rtk (GET) query hook directly +// Keep local value in state, do conversion on state change +// then call setCoordinates with both value and converted value +// Or just do conversion in the setCoordinates function?? const controls = ["simple_select", "draw_point", "draw_line_string", "draw_polygon"]; @@ -741,6 +730,7 @@ const GeonamesApiField = ({ isLoading={isLoading} isFetching={isFetching} width={width} + api="geonames" /> ); }; @@ -779,6 +769,7 @@ const FindCoordinateSystemField = ({ isLoading={isLoading} isFetching={isFetching} width={width} + api="maptiler" /> ); }; @@ -795,6 +786,7 @@ const TypeaheadField = ({ isLoading, isFetching, width, + api }: { value?: OptionsType; setValue: (v: OptionsType) => void; @@ -807,6 +799,7 @@ const TypeaheadField = ({ data: any; isLoading: boolean; isFetching: boolean; + api: string; }) => { const { t } = useTranslation("metadata"); return ( @@ -840,7 +833,7 @@ const TypeaheadField = ({ e && e.type === "change" && setInputValue(newValue); e && (e.type === "click" || e.type === "blur") && setInputValue(""); }} - noOptionsText={!inputValue ? t("startTyping", {api: t("geonames")}) : t("noResults")} + noOptionsText={!inputValue ? t("startTyping", {api: t(api)}) : t("noResults")} loading={isLoading || isFetching || inputValue !== debouncedInputValue} loadingText={ Select a shape type and click on the map to start drawing. In case of a multipoint shape, double click or press 'Enter' to finish drawing.

To edit a shape, click on it to select it, and drag it around, or add or move individual points.

To delete a shape, select it and press 'Delete' on your keyboard.

", "toggleMap": "Toggle map", "featureType": "Type", - "featureCoordinates": "Coordinates", + "featureCoordinates": "Coordinates (WGS84)", "featureGeonameRef": "Geonames reference", "lat": "Latitude", "lng": "Longitude", - "findPlace": "Select corresponding location" + "findPlace": "Select corresponding location", + "findCoordinateSystem": "Select coordinate system", + "transposedCoordinates": "Coordinates ({{id}})" } \ No newline at end of file From 73a882d6c0511d6936fce25c0f168276b3ce732a Mon Sep 17 00:00:00 2001 From: Daan Janssen Date: Mon, 7 Oct 2024 14:46:19 +0200 Subject: [PATCH 12/44] wip --- packages/deposit/src/features/metadata/fields/Map.tsx | 3 +-- packages/deposit/src/types/MetadataFields.ts | 5 +++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/deposit/src/features/metadata/fields/Map.tsx b/packages/deposit/src/features/metadata/fields/Map.tsx index 7a711bb3..8da65676 100644 --- a/packages/deposit/src/features/metadata/fields/Map.tsx +++ b/packages/deposit/src/features/metadata/fields/Map.tsx @@ -217,7 +217,6 @@ const FeatureTable = ({ features, setFeatures, selectedFeatures, coordinateSyste coordinateSystem?: OptionsType; }) => { const { t } = useTranslation("metadata"); - const getAltCoordinates = useTransformCoordinatesQuery(); const columns: readonly Column[] = [ { id: 'feature', label: t('featureType'), width: 50 }, @@ -375,7 +374,7 @@ const FeatureCoordinateCell = ({feature, onChange, featureIndex, coordinateSyste featureIndex: number; onChange: (value: number, featureIndex: number, type: string, coordinateIndex: number, groupIndex?: number) => void; coordinateSystem?: any; - isCoordinateSystem?: boolean; + isWgs84?: boolean; }) => { const { t } = useTranslation("metadata"); console.log(feature); diff --git a/packages/deposit/src/types/MetadataFields.ts b/packages/deposit/src/types/MetadataFields.ts index 3140f81d..00218a4d 100644 --- a/packages/deposit/src/types/MetadataFields.ts +++ b/packages/deposit/src/types/MetadataFields.ts @@ -175,6 +175,11 @@ export interface ExtendedMapFeature exte label?: never; value?: never; } +export interface MapTilerCoordinateSystem { + label: string; + value: number; + id: string; +} export interface DrawMapFieldType extends Omit { From e4ba9d1396454b1e522bd3a9951cb23bad5090ca Mon Sep 17 00:00:00 2001 From: D-Unit Date: Mon, 14 Oct 2024 15:24:32 +0200 Subject: [PATCH 13/44] wip --- .../src/features/metadata/api/maptiler.ts | 66 +++++- .../src/features/metadata/fields/Map.tsx | 219 +++++++++++++----- packages/deposit/src/types/MetadataFields.ts | 7 +- 3 files changed, 214 insertions(+), 78 deletions(-) diff --git a/packages/deposit/src/features/metadata/api/maptiler.ts b/packages/deposit/src/features/metadata/api/maptiler.ts index 7076f321..f058fdb1 100644 --- a/packages/deposit/src/features/metadata/api/maptiler.ts +++ b/packages/deposit/src/features/metadata/api/maptiler.ts @@ -2,6 +2,47 @@ import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; import type { MaptilerCoordinateSystemResponse } from "../../../types/Api"; import i18n from "../../../languages/i18n"; +function geojsonToString(type, coordinates) { + switch (type) { + case 'Point': + return `${coordinates[0]},${coordinates[1]}`; + + case 'LineString': + return coordinates.map(coord => `${coord[0]},${coord[1]}`).join(';'); + + case 'Polygon': + // For polygons, we join each ring with ';' and join coordinates within each ring with ' ' + return coordinates + .map(ring => ring.map(coord => `${coord[0]},${coord[1]}`).join(';')) + .join(';'); + + default: + throw new Error('Unsupported GeoJSON type'); + } +} + +function convertToGeojsonCoordinates(coordinatesArray, type) { + // Map through the array to get the [x, y] coordinates. + const coordinates = coordinatesArray.map(({ x, y }) => [x, y]); + + switch (type) { + case 'Point': + if (coordinates.length !== 1) { + throw new Error('A Point must have exactly one coordinate pair.'); + } + return coordinates[0]; + + case 'LineString': + return coordinates; + + case 'Polygon': + return [coordinates]; + + default: + throw new Error('Unsupported GeoJSON type'); + } +} + export const maptilerApi = createApi({ reducerPath: "maptiler", baseQuery: fetchBaseQuery({ baseUrl: "https://api.maptiler.com" }), @@ -31,19 +72,20 @@ export const maptilerApi = createApi({ }), }), transformCoordinates: build.query({ - query: ({coordinates, from, to}) => ({ - url: `coordinates/transform/${coordinates}.json?s_srs=${from}&t_srs=${to}&key=${ - import.meta.env.VITE_MAPTILER_API_KEY - }`, - headers: { Accept: "application/json" }, - }), + query: ({type, coordinates, to, from}) => { + const stringCoordinates = geojsonToString(type, coordinates); + console.log(stringCoordinates) + return ({ + url: `coordinates/transform/${stringCoordinates}.json?s_srs=${from}&t_srs=${to}&key=${ + import.meta.env.VITE_MAPTILER_API_KEY + }`, + headers: { Accept: "application/json" }, + }) + }, transformResponse: (response: any, _meta, arg) => { - // Return an empty array when no results, which is what the Autocomplete field expects + // If there are results, just return the coordinates as an array. We always assume only one set of coordinates is passed along. return response.results.length > 0 ? - { - arg: arg, - response: response.results, - } + convertToGeojsonCoordinates(response.results, arg.type) : []; }, transformErrorResponse: () => ({ @@ -53,4 +95,4 @@ export const maptilerApi = createApi({ }), }); -export const { useFetchCoordinateSystemsQuery, useTransformCoordinatesQuery } = maptilerApi; +export const { useFetchCoordinateSystemsQuery, useTransformCoordinatesQuery, useLazyTransformCoordinatesQuery } = maptilerApi; diff --git a/packages/deposit/src/features/metadata/fields/Map.tsx b/packages/deposit/src/features/metadata/fields/Map.tsx index 8da65676..b12234fa 100644 --- a/packages/deposit/src/features/metadata/fields/Map.tsx +++ b/packages/deposit/src/features/metadata/fields/Map.tsx @@ -33,7 +33,7 @@ import PlaceIcon from '@mui/icons-material/Place'; import HighlightAltIcon from '@mui/icons-material/HighlightAlt'; import PentagonIcon from '@mui/icons-material/Pentagon'; import { useFetchGeonamesFreeTextQuery, useFetchPlaceReverseLookupQuery } from "../api/geonames"; -import { useFetchCoordinateSystemsQuery, useTransformCoordinatesQuery } from "../api/maptiler"; +import { useFetchCoordinateSystemsQuery, useLazyTransformCoordinatesQuery, useTransformCoordinatesQuery } from "../api/maptiler"; import type { QueryReturnType } from "../../../types/Api"; import CircularProgress from "@mui/material/CircularProgress"; import Autocomplete from "@mui/material/Autocomplete"; @@ -128,6 +128,15 @@ const DrawMap = ({ } }, [geonamesValue]); + useEffect(() => { + // update all feature's originalCoordinates value + const updatedFeatures = features.map( f => ({ + ...f, + coordinateSystem: coordinateSystem + })) + setFeatures(updatedFeatures); + }, [coordinateSystem]); + return ( - + {features.length > 0 && // let's user edit features coordinates directly - + } @@ -217,39 +236,44 @@ const FeatureTable = ({ features, setFeatures, selectedFeatures, coordinateSyste coordinateSystem?: OptionsType; }) => { const { t } = useTranslation("metadata"); + const [ getConvertedCoordinates ] = useLazyTransformCoordinatesQuery(); const columns: readonly Column[] = [ { id: 'feature', label: t('featureType'), width: 50 }, { id: 'coordinates', label: t('featureCoordinates'), width: coordinateSystem === undefined ? 500 : 300 }, - ...(coordinateSystem !== undefined ? [{id: 'transposedCoordinates', label: t('transposedCoordinates', { id: coordinateSystem.id }), width: 300}] : []), + ...(coordinateSystem ? [{id: 'transposedCoordinates', label: t('transposedCoordinates', { id: coordinateSystem.id }), width: 300}] : []), { id: 'geonames', label: t('featureGeonameRef') }, { id: 'delete', label: t('delete'), width: 50 }, ]; - console.log(coordinateSystem) - - const setCoordinates = (value: number, featureIndex: number, type: string, coordinateIndex: number, groupIndex?: number) => { + const setCoordinates = async ({value, featureIndex, coordinateIndex, groupIndex, coordinateSystem, isWgs84}: { + value: number; + featureIndex: number; + coordinateIndex: number; + groupIndex?: number; + coordinateSystem?: OptionsType; + isWgs84?: boolean; + }) => { // TODO: Expand this to optionally set two coord objects, with call to conversion service maptiler // conversion expects a lat/lon pair. + console.log('changing coordinates'); // set the new coordinates - const newFeatures = features.map((feature, index) => - index === featureIndex ? ({ - ...feature, - geometry: { - ...feature.geometry, - coordinates: - type === 'Point' ? - (feature.geometry as Point).coordinates.map((coordinate, i) => - i === coordinateIndex ? value : coordinate - ) : - type === 'LineString' ? + const newFeatures = await Promise.all( + features.map(async (feature, index) => { + if (index === featureIndex) { + const updatedCoordinates = + feature.geometry.type === 'Point' ? + (feature.geometry as Point).coordinates.map((coordinate, i) => + i === coordinateIndex ? value : coordinate + ) : + feature.geometry.type === 'LineString' ? (feature.geometry as LineString).coordinates.map((coordinateGroup, i) => i === groupIndex ? coordinateGroup.map((coordinate, j) => j === coordinateIndex ? value : coordinate ) : coordinateGroup ) : - type === 'Polygon' ? (() => { + feature.geometry.type === 'Polygon' ? (() => { // First, update the first set of coordinates const updatedCoordinates = (feature.geometry as Polygon).coordinates[0].map((coordinateGroup, i) => i === groupIndex ? coordinateGroup.map((coordinate, j) => @@ -262,13 +286,34 @@ const FeatureTable = ({ features, setFeatures, selectedFeatures, coordinateSyste return [updatedCoordinates]; })() : - (feature.geometry as any).coordinates, - }, - geonames: undefined, - }) - : feature + (feature.geometry as any).coordinates; + + // convert coords if needed + const convertedCoordinates = coordinateSystem + ? await getConvertedCoordinates({ + type: feature.geometry.type, + coordinates: updatedCoordinates, + to: isWgs84 ? coordinateSystem.value : 4326, + from: isWgs84 ? 4326 : coordinateSystem.value, + }) + : null; + + const updatedFeature = { + ...feature, + geometry: { + ...feature.geometry, + coordinates: isWgs84 ? updatedCoordinates : convertedCoordinates?.data, + }, + geonames: undefined, + originalCoordinates: isWgs84 && coordinateSystem ? convertedCoordinates?.data : updatedCoordinates, + } + return updatedFeature; + } + else { + return feature; + } + }) ); - // Update the features and geoNames setFeatures(newFeatures); } @@ -323,15 +368,26 @@ const FeatureTable = ({ features, setFeatures, selectedFeatures, coordinateSyste } - + {coordinateSystem && - + } - + />*/} void; + onChange: (object: any) => void; coordinateSystem?: any; isWgs84?: boolean; }) => { const { t } = useTranslation("metadata"); - console.log(feature); + const coordinates = isWgs84 ? feature.geometry.coordinates : feature.originalCoordinates; return ( feature.geometry.type === "Point" ? - {feature.geometry.coordinates.map((coord, coordinateIndex) => + {Array.isArray(coordinates) && coordinates.map((coord, coordinateIndex) => onChange(parseFloat(e.target.value), featureIndex, feature.geometry.type, coordinateIndex, undefined)} + label={coordinateIndex === 1 ? t(isWgs84 ? "lat" : "Y") : t(isWgs84 ? "lng" : "X")} + onChange={(e) => onChange({ + value: parseFloat(e.target.value), + featureIndex: featureIndex, + coordinateIndex: coordinateIndex, + coordinateSystem: coordinateSystem, + isWgs84: isWgs84, + })} /> )} : feature.geometry.type === "LineString" ? - feature.geometry.coordinates.map((coordGroup, groupIndex) => + Array.isArray(coordinates) && coordinates.map((coordGroup, groupIndex) => {coordGroup.map((coord, coordinateIndex) => onChange(parseFloat(e.target.value), featureIndex, feature.geometry.type, coordinateIndex, groupIndex)} + label={coordinateIndex === 1 ? t(isWgs84 ? "lat" : "Y") : t(isWgs84 ? "lng" : "X")} + onChange={(e) => onChange({ + value: parseFloat(e.target.value), + featureIndex: featureIndex, + coordinateIndex: coordinateIndex, + groupIndex: groupIndex, + coordinateSystem: coordinateSystem, + isWgs84: isWgs84, + })} /> )} ) : feature.geometry.type === "Polygon" ? - feature.geometry.coordinates[0].map((coordGroup, groupIndex) => + Array.isArray(coordinates) && coordinates[0].map((coordGroup, groupIndex) => {coordGroup.map((coord, coordinateIndex) => onChange(parseFloat(e.target.value), featureIndex, feature.geometry.type, coordinateIndex, groupIndex)} + label={coordinateIndex === 1 ? t(isWgs84 ? "lat" : "Y") : t(isWgs84 ? "lng" : "X")} + onChange={(e) => onChange({ + value: parseFloat(e.target.value), + featureIndex: featureIndex, + coordinateIndex: coordinateIndex, + groupIndex: groupIndex, + coordinateSystem: coordinateSystem, + isWgs84: isWgs84, + })} /> )} @@ -428,32 +504,51 @@ const FeatureCoordinateCell = ({feature, onChange, featureIndex, coordinateSyste ) } -// TODO?? Create component representing a lat/lon group, so we can convert the coordinates using an rtk (GET) query hook directly -// Keep local value in state, do conversion on state change -// then call setCoordinates with both value and converted value -// Or just do conversion in the setCoordinates function?? - const controls = ["simple_select", "draw_point", "draw_line_string", "draw_polygon"]; type FeaturesEvent = {features: ExtendedMapFeature[], action?: string}; -const DrawControls = ({ features, setFeatures, setSelectedFeatures }: { +const DrawControls = ({ features, setFeatures, setSelectedFeatures, coordinateSystemValue }: { features: ExtendedMapFeature[]; setFeatures: Dispatch>; setSelectedFeatures: Dispatch>; + coordinateSystemValue?: number; }) => { const { t } = useTranslation("metadata"); const [ selectedMode, setSelectedMode ] = useState(controls[0]); - - const onUpdate = useCallback((e: FeaturesEvent) => { - console.log('update called') - - // Clear 'properties' key for each feature in the new array - // So geonames reference is removed when points change - const updatedFeatures = e.features.map(feature => ({ - ...feature, - geonames: undefined, - })); + const [ getConvertedCoordinates ] = useLazyTransformCoordinatesQuery(); + + console.log(coordinateSystemValue) + + // TODO GET THIS TO WORK! + const onUpdate = useCallback(async (e: FeaturesEvent, system: number) => { + console.log('update called'); + console.log(system) + + // Clear geonames key for each feature in the new array, + // reference must be removed when points change + // Must also do a conversion to the optionally selected alternative coordinate system here + const updatedFeatures = await Promise.all( + e.features.map(async (feature) => { + console.log(feature) + const originalCoordinates = system + ? await getConvertedCoordinates({ + type: feature.geometry.type, + coordinates: feature.geometry.coordinates, + to: system, + from: 4326, + }) + : null; + + console.log(originalCoordinates); + + return ({ + ...feature, + originalCoordinates: originalCoordinates?.data, + geonames: undefined, + }) + }) + ); setFeatures(currFeatures => [...new Map([...currFeatures, ...updatedFeatures].map(item => [item.id, item])).values()] @@ -553,6 +648,7 @@ const DrawControls = ({ features, setFeatures, setSelectedFeatures }: { onKeyDown={handleKeyDown} features={features} onSelectionChange={onSelectionChange} + coordinateSystemValue={coordinateSystemValue} /> ) @@ -566,15 +662,18 @@ const DrawControl = ({ mode, onKeyDown, features, + coordinateSystemValue, }: { - onCreate: (e: FeaturesEvent) => void; - onUpdate: (e: FeaturesEvent) => void; + onCreate: (e: FeaturesEvent, system: number) => void; + onUpdate: (e: FeaturesEvent, system: number) => void; onDelete: (e: FeaturesEvent) => void; onSelectionChange: (e: FeaturesEvent) => void; mode: string; onKeyDown: (e: KeyboardEvent, c: MapboxDraw) => void; features: ExtendedMapFeature[]; + coordinateSystemValue?: number; }) => { + console.log(`systemvalue: ${coordinateSystemValue}`) const control = useControl( () => new MapboxDraw({ // remove default controls @@ -584,8 +683,8 @@ const DrawControl = ({ clickBuffer: 5, }), ({map}: {map: any}) => { - map.on('draw.create', onCreate); - map.on('draw.update', onUpdate); + map.on('draw.create', e => onCreate(e, coordinateSystemValue)); + map.on('draw.update', e => onUpdate(e, coordinateSystemValue)); map.on('draw.delete', onDelete); map.on('draw.selectionchange', onSelectionChange); diff --git a/packages/deposit/src/types/MetadataFields.ts b/packages/deposit/src/types/MetadataFields.ts index 00218a4d..6b7b1dc7 100644 --- a/packages/deposit/src/types/MetadataFields.ts +++ b/packages/deposit/src/types/MetadataFields.ts @@ -171,15 +171,10 @@ export type MapFeatureType = Point | Polygon | LineString; export interface ExtendedMapFeature extends Feature { geonames?: OptionsType | undefined; originalCoordinates?: number[] | number[][] | number[][][]; - coordinateSystem?: string; + coordinateSystem?: OptionsType; label?: never; value?: never; } -export interface MapTilerCoordinateSystem { - label: string; - value: number; - id: string; -} export interface DrawMapFieldType extends Omit { From 915e294d49bef0815f837822dcedd2a3eb67156d Mon Sep 17 00:00:00 2001 From: D-Unit Date: Wed, 16 Oct 2024 14:41:00 +0200 Subject: [PATCH 14/44] should be good to go --- .../src/features/metadata/api/maptiler.ts | 13 +- .../src/features/metadata/fields/Map.tsx | 158 ++++++++++-------- .../src/languages/locales/en/metadata.json | 9 +- packages/deposit/src/types/Api.ts | 7 + 4 files changed, 109 insertions(+), 78 deletions(-) diff --git a/packages/deposit/src/features/metadata/api/maptiler.ts b/packages/deposit/src/features/metadata/api/maptiler.ts index f058fdb1..b1e73195 100644 --- a/packages/deposit/src/features/metadata/api/maptiler.ts +++ b/packages/deposit/src/features/metadata/api/maptiler.ts @@ -1,18 +1,18 @@ import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; -import type { MaptilerCoordinateSystemResponse } from "../../../types/Api"; +import type { MaptilerCoordinateSystemResponse, MaptilerConversionResponse } from "../../../types/Api"; import i18n from "../../../languages/i18n"; -function geojsonToString(type, coordinates) { +function geojsonToString(type: string, coordinates: number[] | number[][] | number[][][]) { switch (type) { case 'Point': return `${coordinates[0]},${coordinates[1]}`; case 'LineString': - return coordinates.map(coord => `${coord[0]},${coord[1]}`).join(';'); + return (coordinates as number[][]).map(coord => `${coord[0]},${coord[1]}`).join(';'); case 'Polygon': // For polygons, we join each ring with ';' and join coordinates within each ring with ' ' - return coordinates + return (coordinates as number[][][]) .map(ring => ring.map(coord => `${coord[0]},${coord[1]}`).join(';')) .join(';'); @@ -21,7 +21,7 @@ function geojsonToString(type, coordinates) { } } -function convertToGeojsonCoordinates(coordinatesArray, type) { +function convertToGeojsonCoordinates(coordinatesArray: {x: number, y: number}[], type: string) { // Map through the array to get the [x, y] coordinates. const coordinates = coordinatesArray.map(({ x, y }) => [x, y]); @@ -74,7 +74,6 @@ export const maptilerApi = createApi({ transformCoordinates: build.query({ query: ({type, coordinates, to, from}) => { const stringCoordinates = geojsonToString(type, coordinates); - console.log(stringCoordinates) return ({ url: `coordinates/transform/${stringCoordinates}.json?s_srs=${from}&t_srs=${to}&key=${ import.meta.env.VITE_MAPTILER_API_KEY @@ -82,7 +81,7 @@ export const maptilerApi = createApi({ headers: { Accept: "application/json" }, }) }, - transformResponse: (response: any, _meta, arg) => { + transformResponse: (response: MaptilerConversionResponse, _meta, arg) => { // If there are results, just return the coordinates as an array. We always assume only one set of coordinates is passed along. return response.results.length > 0 ? convertToGeojsonCoordinates(response.results, arg.type) diff --git a/packages/deposit/src/features/metadata/fields/Map.tsx b/packages/deposit/src/features/metadata/fields/Map.tsx index b12234fa..8f9e4c91 100644 --- a/packages/deposit/src/features/metadata/fields/Map.tsx +++ b/packages/deposit/src/features/metadata/fields/Map.tsx @@ -12,7 +12,7 @@ import { useAppDispatch, useAppSelector } from "../../../redux/hooks"; import { StatusIcon } from "../../generic/Icons"; import { setField } from "../metadataSlice"; import { getFieldStatus } from "../metadataHelpers"; -import type { OptionsType, ExtendedMapFeature, MapFeatureType } from "../../../types/MetadataFields"; +import type { OptionsType, ExtendedMapFeature } from "../../../types/MetadataFields"; import type { DrawMapFieldProps } from "../../../types/MetadataProps"; import { lookupLanguageString } from "@dans-framework/utils"; import { getFormDisabled } from "../../../deposit/depositSlice"; @@ -33,7 +33,7 @@ import PlaceIcon from '@mui/icons-material/Place'; import HighlightAltIcon from '@mui/icons-material/HighlightAlt'; import PentagonIcon from '@mui/icons-material/Pentagon'; import { useFetchGeonamesFreeTextQuery, useFetchPlaceReverseLookupQuery } from "../api/geonames"; -import { useFetchCoordinateSystemsQuery, useLazyTransformCoordinatesQuery, useTransformCoordinatesQuery } from "../api/maptiler"; +import { useFetchCoordinateSystemsQuery, useLazyTransformCoordinatesQuery } from "../api/maptiler"; import type { QueryReturnType } from "../../../types/Api"; import CircularProgress from "@mui/material/CircularProgress"; import Autocomplete from "@mui/material/Autocomplete"; @@ -75,11 +75,11 @@ const DrawMap = ({ zoom: 8, }); const [ features, setFeatures ] = useState(field.value || []); + const [ getConvertedCoordinates ] = useLazyTransformCoordinatesQuery(); // write this to redux store with some debouncing for performance const debouncedSaveToStore = useDebouncedCallback( () => { - console.log('dispatching') dispatch( setField({ sectionIndex: sectionIndex, @@ -98,7 +98,6 @@ const DrawMap = ({ debouncedSaveToStore(); } }, [features, field.touched]) - console.log(features) const [ selectedFeatures, setSelectedFeatures ] = useState<(string | number | undefined)[]>([]); @@ -130,11 +129,37 @@ const DrawMap = ({ useEffect(() => { // update all feature's originalCoordinates value - const updatedFeatures = features.map( f => ({ - ...f, - coordinateSystem: coordinateSystem - })) - setFeatures(updatedFeatures); + // and calculate coordinates of existing features + const asyncFeatures = async () => { + const updatedCoordinatesFeatures = await Promise.all( + features.map( async (f) => { + const convertedCoordinates = await getConvertedCoordinates({ + type: f.geometry.type, + coordinates: (f.geometry as Point | Polygon | LineString).coordinates, + to: coordinateSystem?.value, + from: 4326, + }); + return ({ + ...f, + coordinateSystem: coordinateSystem, + originalCoordinates: convertedCoordinates?.data, + }) + }) + ); + setFeatures(updatedCoordinatesFeatures); + } + if (coordinateSystem) { + asyncFeatures(); + } + else { + setFeatures( + features.map((f) => ({ + ...f, + coordinateSystem: undefined, + originalCoordinates: undefined, + })) + ); + } }, [coordinateSystem]); return ( @@ -168,12 +193,10 @@ const DrawMap = ({ setValue={setCoordinateSystem} disabled={formDisabled || field.disabled} label={t("findCoordinateSystem")} - width="30%" />
{columns.map((column) => ( - + {column.label} ))} - {features.map((feature, i) => - + {features.map((feature, i) => ( + - { - feature.geometry.type === "Point" - ? - : feature.geometry.type === "LineString" - ? - : feature.geometry.type === "Polygon" - ? - : null - } + {feature.geometry.type === "Point" ? + + : feature.geometry.type === "LineString" ? + + : feature.geometry.type === "Polygon" ? + + : null} - - {coordinateSystem && + {coordinateSystem && ( - - } + )} - @@ -525,14 +654,20 @@ const FeatureTable = ({ features, setFeatures, selectedFeatures, coordinateSyste - )} + ))}
- ) -} + ); +}; -const FeatureCoordinateCell = ({feature, onChange, featureIndex, isWgs84, coordinateSystem}: { +const FeatureCoordinateCell = ({ + feature, + onChange, + featureIndex, + isWgs84, + coordinateSystem, +}: { feature: ExtendedMapFeature; featureIndex: number; onChange: (object: any) => void; @@ -540,49 +675,65 @@ const FeatureCoordinateCell = ({feature, onChange, featureIndex, isWgs84, coordi coordinateSystem?: OptionsType; }) => { // Check if this input box is wsg84 or a different coordinate system - const coordinates = isWgs84 ? (feature.geometry as Point | Polygon | LineString).coordinates : feature.originalCoordinates; + const coordinates = + isWgs84 ? + (feature.geometry as Point | Polygon | LineString).coordinates + : feature.originalCoordinates; return ( - feature.geometry.type === "Point" ? - : feature.geometry.type === "LineString" ? - Array.isArray(coordinates) && (coordinates as number[][]).map((coordGroup, groupIndex) => - ( + - ) + )) : feature.geometry.type === "Polygon" ? - Array.isArray(coordinates) && (coordinates as number[][][])[0].map((coordGroup, groupIndex) => - ( + - ) + )) : null - ) -} + ); +}; -const CoordinateGroup = ({ onChange, coordinates, featureIndex, isWgs84, groupIndex, disabled, coordinateSystem }: { +const CoordinateGroup = ({ + onChange, + coordinates, + featureIndex, + isWgs84, + groupIndex, + disabled, + coordinateSystem, +}: { onChange: (object: any) => void; - coordinates?: number[] | number[][] | number[][][]; + coordinates?: number[] | number[][] | number[][][]; featureIndex: number; isWgs84?: boolean; groupIndex?: number; @@ -593,42 +744,61 @@ const CoordinateGroup = ({ onChange, coordinates, featureIndex, isWgs84, groupIn return ( - {coordinates?.map((coord, coordinateIndex) => - ( + onChange({ - value: parseFloat(e.target.value), - featureIndex: featureIndex, - coordinateIndex: coordinateIndex, - groupIndex: groupIndex, - coordinateSystem: coordinateSystem, - isWgs84: isWgs84, - })} + label={ + coordinateIndex === 1 ? + t(isWgs84 ? "lat" : "Y") + : t(isWgs84 ? "lng" : "X") + } + onChange={(e) => + onChange({ + value: parseFloat(e.target.value), + featureIndex: featureIndex, + coordinateIndex: coordinateIndex, + groupIndex: groupIndex, + coordinateSystem: coordinateSystem, + isWgs84: isWgs84, + }) + } /> - )} + ))} - ) -} + ); +}; -const controls = ["simple_select", "draw_point", "draw_line_string", "draw_polygon"]; +const controls = [ + "simple_select", + "draw_point", + "draw_line_string", + "draw_polygon", +]; -type FeaturesEvent = {features: ExtendedMapFeature[], action?: string}; +type FeaturesEvent = { features: ExtendedMapFeature[]; action?: string }; -const DrawControls = ({ features, setFeatures, setSelectedFeatures, coordinateSystem }: { +const DrawControls = ({ + features, + setFeatures, + setSelectedFeatures, + coordinateSystem, +}: { features: ExtendedMapFeature[]; setFeatures: Dispatch>; - setSelectedFeatures: Dispatch>; + setSelectedFeatures: Dispatch< + SetStateAction<(string | number | undefined)[]> + >; coordinateSystem?: OptionsType; }) => { const { t } = useTranslation("metadata"); - const [ selectedMode, setSelectedMode ] = useState(controls[0]); - const [ updatedFeatures, setUpdatedFeatures ] = useState(); - const [ getConvertedCoordinates ] = useLazyTransformCoordinatesQuery(); + const [selectedMode, setSelectedMode] = useState(controls[0]); + const [updatedFeatures, setUpdatedFeatures] = + useState(); + const [getConvertedCoordinates] = useLazyTransformCoordinatesQuery(); const onUpdate = useCallback((e: FeaturesEvent) => { // Clear geonames key for each feature in the new array, @@ -645,28 +815,35 @@ const DrawControls = ({ features, setFeatures, setSelectedFeatures, coordinateSy useEffect(() => { // Have to pull this out of the useCallback function onUpdate, otherwise no access to current coordinate system // Listens to any changes in (local state) features, then applies coordinate transformation if neccessary, and updates global features. - const setNewFeatures = (updatedCoordinateFeatures: ExtendedMapFeature[]) => setFeatures(currFeatures => - [...new Map([...currFeatures, ...updatedCoordinateFeatures].map(item => [item.id, item])).values()] - ); + const setNewFeatures = (updatedCoordinateFeatures: ExtendedMapFeature[]) => + setFeatures((currFeatures) => [ + ...new Map( + [...currFeatures, ...updatedCoordinateFeatures].map((item) => [ + item.id, + item, + ]), + ).values(), + ]); const updateOriginalCoordinates = async () => { // Do a conversion to the optionally selected alternative coordinate system here const updatedCoordinateFeatures = await Promise.all( updatedFeatures!.map(async (feature) => { const originalCoordinates = await getConvertedCoordinates({ type: feature.geometry.type, - coordinates: (feature.geometry as Point | Polygon | LineString).coordinates, + coordinates: (feature.geometry as Point | Polygon | LineString) + .coordinates, to: coordinateSystem?.value, from: 4326, }); - return ({ + return { ...feature, originalCoordinates: originalCoordinates?.data, - }) - }) + }; + }), ); setNewFeatures(updatedCoordinateFeatures); - } - if ( updatedFeatures && coordinateSystem?.value ) { + }; + if (updatedFeatures && coordinateSystem?.value) { updateOriginalCoordinates(); } else if (updatedFeatures) { setNewFeatures(updatedFeatures); @@ -674,86 +851,89 @@ const DrawControls = ({ features, setFeatures, setSelectedFeatures, coordinateSy }, [updatedFeatures]); const onDelete = useCallback((e: FeaturesEvent) => { - const changedFeatureIds = new Set(e.features.map(feature => feature.id)); - setFeatures(currFeatures => - currFeatures.filter(feature => !changedFeatureIds.has(feature.id)) + const changedFeatureIds = new Set(e.features.map((feature) => feature.id)); + setFeatures((currFeatures) => + currFeatures.filter((feature) => !changedFeatureIds.has(feature.id)), ); setSelectedMode(controls[0]); }, []); const onSelectionChange = useCallback((e: FeaturesEvent) => { - setSelectedFeatures(e.features.map(feature => feature.id)); + setSelectedFeatures(e.features.map((feature) => feature.id)); }, []); // manual key listener, since delete is broken in the map libre / mapbox draw combo - const handleKeyDown = useCallback((event: KeyboardEvent, drawControl: MapboxDraw) => { - const selectedFeatures = drawControl.getSelected(); - if (event.key === 'Delete' && selectedFeatures.features.length > 0) { - event.preventDefault(); - event.stopPropagation(); - // remove features from store - onDelete(selectedFeatures); - // remove them from map - drawControl.trash(); - } - }, []); + const handleKeyDown = useCallback( + (event: KeyboardEvent, drawControl: MapboxDraw) => { + const selectedFeatures = drawControl.getSelected(); + if (event.key === "Delete" && selectedFeatures.features.length > 0) { + event.preventDefault(); + event.stopPropagation(); + // remove features from store + onDelete(selectedFeatures); + // remove them from map + drawControl.trash(); + } + }, + [], + ); return ( - {controls.map(control => + {controls.map((control) => ( - setSelectedMode(control)} selected={control === selectedMode} > - - { - control === "simple_select" - ? - : control === "draw_point" - ? - : control === "draw_line_string" - ? - : control === "draw_polygon" - ? - : null - } + + {control === "simple_select" ? + + : control === "draw_point" ? + + : control === "draw_line_string" ? + + : control === "draw_polygon" ? + + : null} - )} + ))} - { - // just simulate the delete keyboard press event on the map canvas - const target = document.querySelector('.maplibregl-canvas'); - if (target) { - const keyboardEvent = new KeyboardEvent('keydown', { - key: 'Delete', - code: 'Delete', - keyCode: 46, - charCode: 46, - bubbles: true, - cancelable: true - }); - target.dispatchEvent(keyboardEvent); - } - }}> - + { + // just simulate the delete keyboard press event on the map canvas + const target = document.querySelector(".maplibregl-canvas"); + if (target) { + const keyboardEvent = new KeyboardEvent("keydown", { + key: "Delete", + code: "Delete", + keyCode: 46, + charCode: 46, + bubbles: true, + cancelable: true, + }); + target.dispatchEvent(keyboardEvent); + } + }} + > + - + - - ) -} + ); +}; const DrawControl = ({ onCreate, @@ -784,37 +964,38 @@ const DrawControl = ({ features: ExtendedMapFeature[]; }) => { const control = useControl( - () => new MapboxDraw({ - // remove default controls - displayControlsDefault: false, - defaultMode: mode, - keybindings: true, - clickBuffer: 5, - }), - ({map}: {map: any}) => { - map.on('draw.create', onCreate); - map.on('draw.update', onUpdate); - map.on('draw.delete', onDelete); - map.on('draw.selectionchange', onSelectionChange); - + () => + new MapboxDraw({ + // remove default controls + displayControlsDefault: false, + defaultMode: mode, + keybindings: true, + clickBuffer: 5, + }), + ({ map }: { map: any }) => { + map.on("draw.create", onCreate); + map.on("draw.update", onUpdate); + map.on("draw.delete", onDelete); + map.on("draw.selectionchange", onSelectionChange); + // Attach the keydown event to the map container const canvas = map.getCanvas(); - const handleKeyDownInternal = (event: KeyboardEvent) => onKeyDown(event, control); - canvas.addEventListener('keydown', handleKeyDownInternal); + const handleKeyDownInternal = (event: KeyboardEvent) => + onKeyDown(event, control); + canvas.addEventListener("keydown", handleKeyDownInternal); // Store the reference to the internal handler for cleanup map._handleKeyDownInternal = handleKeyDownInternal; - }, - ({map}: {map: any}) => { - map.off('draw.create', onCreate); - map.off('draw.update', onUpdate); - map.off('draw.delete', onDelete); - map.off('draw.selectionchange', onSelectionChange); + ({ map }: { map: any }) => { + map.off("draw.create", onCreate); + map.off("draw.update", onUpdate); + map.off("draw.delete", onDelete); + map.off("draw.selectionchange", onSelectionChange); // Clean up the keydown event listener const canvas = map.getCanvas(); - canvas.removeEventListener('keydown', map._handleKeyDownInternal); - } + canvas.removeEventListener("keydown", map._handleKeyDownInternal); + }, ); useEffect(() => { @@ -826,25 +1007,25 @@ const DrawControl = ({ // if features prop changes, reflect that on map if (control) { control.set({ - type: 'FeatureCollection', + type: "FeatureCollection", features: features, - }) + }); } }, [features, control]); return null; -} +}; // TODO: find something else for this, as this (geonames extendedFindNearby) does not work great and does not // always find a relevant value. Also, for multipoint shapes, we can only check the nearby value of a single point, // which might not be the most relevant point. const ReverseLookupGeonamesField = ({ - lat, - lng, + lat, + lng, featureIndex, value, setValue, - disabled + disabled, }: { lat: number; lng: number; @@ -854,14 +1035,17 @@ const ReverseLookupGeonamesField = ({ disabled?: boolean; }) => { // TODO: we need a better reverse lookup - + const { t } = useTranslation("metadata"); const [inputValue, setInputValue] = useState(""); // fetch on open, not directly on prop change const [open, setOpen] = useState(false); // Fetch data right away, based on coordinates const { data, isFetching, isLoading } = - useFetchPlaceReverseLookupQuery({lat: lat, lng: lng}, {skip: !open}); + useFetchPlaceReverseLookupQuery( + { lat: lat, lng: lng }, + { skip: !open }, + ); return ( setOpen(false)} options={data?.response || []} value={value || null} - inputValue={inputValue || value?.label as string || ""} + inputValue={inputValue || (value?.label as string) || ""} renderInput={(params) => ( )} - onChange={(_e, newValue, _reason) => setValue(newValue as OptionsType, featureIndex)} + onChange={(_e, newValue, _reason) => + setValue(newValue as OptionsType, featureIndex) + } filterOptions={(x) => x} onInputChange={(e, newValue) => { e && e.type === "change" && setInputValue(newValue); @@ -890,11 +1076,7 @@ const ReverseLookupGeonamesField = ({ noOptionsText={t("noResults")} loading={isLoading || isFetching} loadingText={ - + {t("loading")} } @@ -903,8 +1085,8 @@ const ReverseLookupGeonamesField = ({ disabled={disabled} getOptionKey={(option) => option.value} /> - ) -} + ); +}; const GeonamesApiField = ({ value, @@ -928,7 +1110,7 @@ const GeonamesApiField = ({ }); return ( - (""); const debouncedInputValue = useDebounce(inputValue, 500)[0]; // Fetch data on input change - const { data, isFetching, isLoading } = - useFetchCoordinateSystemsQuery>(debouncedInputValue, { - skip: debouncedInputValue === "", - }); + const { data, isFetching, isLoading } = useFetchCoordinateSystemsQuery< + QueryReturnType + >(debouncedInputValue, { + skip: debouncedInputValue === "", + }); return ( - void; @@ -1004,7 +1187,7 @@ const TypeaheadField = ({ label?: string; width?: string | number; inputValue?: string; - setInputValue: Dispatch> + setInputValue: Dispatch>; debouncedInputValue?: string; data: any; isLoading: boolean; @@ -1030,27 +1213,20 @@ const TypeaheadField = ({ : [] } value={value || null} - inputValue={inputValue || value?.label as string || ""} - renderInput={(params) => ( - - )} + inputValue={inputValue || (value?.label as string) || ""} + renderInput={(params) => } onChange={(_e, newValue, _reason) => setValue(newValue as OptionsType)} filterOptions={(x) => x} onInputChange={(e, newValue) => { e && e.type === "change" && setInputValue(newValue); e && (e.type === "click" || e.type === "blur") && setInputValue(""); }} - noOptionsText={!inputValue ? t("startTyping", {api: t(api)}) : t("noResults")} + noOptionsText={ + !inputValue ? t("startTyping", { api: t(api) }) : t("noResults") + } loading={isLoading || isFetching || inputValue !== debouncedInputValue} loadingText={ - + {t("loading")} } @@ -1059,5 +1235,5 @@ const TypeaheadField = ({ disabled={disabled} getOptionKey={(option) => option.value} /> - ) -} \ No newline at end of file + ); +}; diff --git a/packages/deposit/src/features/metadata/fields/TextField.tsx b/packages/deposit/src/features/metadata/fields/TextField.tsx index 22c6d257..d8e46277 100644 --- a/packages/deposit/src/features/metadata/fields/TextField.tsx +++ b/packages/deposit/src/features/metadata/fields/TextField.tsx @@ -70,9 +70,13 @@ const SingleTextField = ({ // if field type is date, just convert it to DD-MM-YYYY for every value // TODO: should any other app than ohsmart want to use this, modify this where necessary : field.type === "date" ? - moment(field.value, field.format).startOf("day").format("DD-MM-YYYY") + moment(field.value, field.format) + .startOf("day") + .format("DD-MM-YYYY") : field.type === "daterange" ? - moment(field.value[0], field.format).startOf("day").format("DD-MM-YYYY") + moment(field.value[0], field.format) + .startOf("day") + .format("DD-MM-YYYY") : field.value : null ); @@ -105,7 +109,6 @@ const SingleTextField = ({ } }, [generatedValue]); - return ( )} - { const fieldEmpty = !field.value || (typeof field.value === "string" && !field.value.trim()) || - (Array.isArray(field.value) && field.value.length === 0 ) || - (field.type === 'daterange' && Array.isArray(field.value) && field.value.every(v => v === null || v === "")) || - (field.type === 'drawmap' && Array.isArray(field.value) && field.value.some(v => v.geonames === null || v.geonames === undefined)); + (Array.isArray(field.value) && field.value.length === 0) || + (field.type === "daterange" && + Array.isArray(field.value) && + field.value.every((v) => v === null || v === "")) || + (field.type === "drawmap" && + Array.isArray(field.value) && + field.value.some((v) => v.geonames === null || v.geonames === undefined)); if (field.noIndicator && !field.required && fieldEmpty) { return "neutral"; } else if ( (!field.required && fieldEmpty) || // daterange should also give a warning state if end date is optional and not filled in - (field.type === 'daterange' && field.optionalEndDate && Array.isArray(field.value) && !field.value[1] && field.valid) + (field.type === "daterange" && + field.optionalEndDate && + Array.isArray(field.value) && + !field.value[1] && + field.valid) ) { return "warning"; } else if ( (field.required && fieldEmpty) || (!fieldEmpty && field.validation && !field.valid) || - (field.type === 'daterange' && !fieldEmpty && !field.valid) + (field.type === "daterange" && !fieldEmpty && !field.valid) ) { return "error"; } else { @@ -187,21 +195,26 @@ export const getSectionStatus = (section: SectionStatus[]): SectionStatus => { }; // Check if a field conforms to validation type specified -export const getValid = ( - value: any, - field: Field, -): boolean => { +export const getValid = (value: any, field: Field): boolean => { if (field.validation) { return validateData(field.validation, value); } else if ( - ( value && value.length !== 0 && field.type !== 'daterange' && field.type !== 'drawmap' ) || + (value && + value.length !== 0 && + field.type !== "daterange" && + field.type !== "drawmap") || // special check for date range: start date must be before or equal to end date, // or if end date not required, end date can be empty - (field.type === 'daterange' && value && ( - moment(value[0], field.format).isSameOrBefore(moment(value[1], field.format)) || - (field.optionalEndDate && value[0] && !value[1]) - )) || - (field.type === 'drawmap' && value.every((item: any) => item.geonames !== null && item.geonames !== undefined)) + (field.type === "daterange" && + value && + (moment(value[0], field.format).isSameOrBefore( + moment(value[1], field.format), + ) || + (field.optionalEndDate && value[0] && !value[1]))) || + (field.type === "drawmap" && + value.every( + (item: any) => item.geonames !== null && item.geonames !== undefined, + )) ) { return true; } diff --git a/packages/deposit/src/features/metadata/metadataSlice.ts b/packages/deposit/src/features/metadata/metadataSlice.ts index 1a772935..612acd11 100644 --- a/packages/deposit/src/features/metadata/metadataSlice.ts +++ b/packages/deposit/src/features/metadata/metadataSlice.ts @@ -1,4 +1,4 @@ -import { createSlice, PayloadAction, /*current*/ } from "@reduxjs/toolkit"; +import { createSlice, PayloadAction /*current*/ } from "@reduxjs/toolkit"; import { RootState } from "../../redux/store"; import type { SetFieldValuePayload, @@ -109,15 +109,15 @@ export const metadataSlice = createSlice({ } // After every input, we need to update field valid status and section status as well. - field.valid = getValid( - action.payload.value, - field - ); + field.valid = getValid(action.payload.value, field); // then set the section/accordion metadataSlice.caseReducers.setSectionStatus(state, action); } }, - setMultiApiField: (state, action: PayloadAction) => { + setMultiApiField: ( + state, + action: PayloadAction, + ) => { const section = state.form[action.payload.sectionIndex]; const field = findByIdOrName(action.payload.id, section.fields); if (field) { diff --git a/packages/deposit/src/features/submit/Submit.tsx b/packages/deposit/src/features/submit/Submit.tsx index dcfae123..80748f2e 100644 --- a/packages/deposit/src/features/submit/Submit.tsx +++ b/packages/deposit/src/features/submit/Submit.tsx @@ -19,7 +19,7 @@ import { getSessionId, } from "../metadata/metadataSlice"; import { getFiles, resetFiles } from "../files/filesSlice"; -import { useSubmitDataMutation, /*useSubmitFilesMutation*/ } from "./submitApi"; +import { useSubmitDataMutation /*useSubmitFilesMutation*/ } from "./submitApi"; import { uploadFile } from "./submitFile"; import { setMetadataSubmitStatus, @@ -77,7 +77,11 @@ const Submit = ({ const fileStatusArray = [...new Set(filesSubmitStatus.map((f) => f.status))]; const fileStatus = fileStatusArray.indexOf("error") !== -1 ? "error" - : fileStatusArray.indexOf("submitting") !== -1 || fileStatusArray.indexOf("queued") !== -1 ? "submitting" + : ( + fileStatusArray.indexOf("submitting") !== -1 || + fileStatusArray.indexOf("queued") !== -1 + ) ? + "submitting" : fileStatusArray.indexOf("success") !== -1 ? "success" : ""; @@ -88,11 +92,7 @@ const Submit = ({ const [ submitData, - { - isLoading: isLoadingMeta, - isError: isErrorMeta, - reset: resetMeta, - }, + { isLoading: isLoadingMeta, isError: isErrorMeta, reset: resetMeta }, ] = useSubmitDataMutation(); // Access token might just be expiring, or user settings just changed @@ -141,22 +141,26 @@ const Submit = ({ user: user, actionType: actionType, id: sessionId, - metadata: metadata, + metadata: metadata, config: formConfig, files: selectedFiles, }).then((result: { data?: any; error?: any }) => { if (result.data?.status === "OK") { // if metadata has been submitted ok, we start the file submit - selectedFiles.map( file => { - const hasStatus = filesSubmitStatus.find( f => f.id === file.id); + selectedFiles.map((file) => { + const hasStatus = filesSubmitStatus.find((f) => f.id === file.id); // make sure file is not already submitted or currently submitting - return !file.submittedFile && (!hasStatus || hasStatus?.status === 'error') && dispatch( - setFilesSubmitStatus({ - id: file.id, - progress: 0, - status: "queued", - }), - ) + return ( + !file.submittedFile && + (!hasStatus || hasStatus?.status === "error") && + dispatch( + setFilesSubmitStatus({ + id: file.id, + progress: 0, + status: "queued", + }), + ) + ); }); } }), @@ -167,11 +171,11 @@ const Submit = ({ const autoSave = useDebouncedCallback(() => { // on autosave, we send along file metadata, but not the actual files if (!formDisabled && isTouched) { - submitData({ - user: auth.user, + submitData({ + user: auth.user, actionType: "save", id: sessionId, - metadata: metadata, + metadata: metadata, config: formConfig, files: selectedFiles, // set flag autoSave, so we don't show a snackbar each time @@ -228,8 +232,9 @@ const Submit = ({ { ( !metadataSubmitStatus || - (metadataSubmitStatus === "saved" && !formDisabled) && - fileStatus !== "submitting" + (metadataSubmitStatus === "saved" && + !formDisabled && + fileStatus !== "submitting") ) ? // metadata has not yet been submitted, so let's just indicate metadata completeness metadataStatus === "error" ? @@ -403,19 +408,23 @@ const FileUploader = () => { const formConfig = useAppSelector(getData); useEffect(() => { - const currentlyUploading = filesSubmitStatus.filter(file => file.status === 'submitting'); + const currentlyUploading = filesSubmitStatus.filter( + (file) => file.status === "submitting", + ); if (currentlyUploading.length < maxConcurrentUploads) { // add first file of selectedFiles that is not currently uploading to the active uploads - selectedFiles.find(file => { + selectedFiles.find((file) => { // only call the upload function if file is queued - const hasStatus = filesSubmitStatus.find( f => f.id === file.id); - return hasStatus?.status === "queued" && uploadFile(file, sessionId, formConfig.target?.envName); + const hasStatus = filesSubmitStatus.find((f) => f.id === file.id); + return ( + hasStatus?.status === "queued" && + uploadFile(file, sessionId, formConfig.target?.envName) + ); }); } - }, [filesSubmitStatus, selectedFiles, sessionId, formConfig]) + }, [filesSubmitStatus, selectedFiles, sessionId, formConfig]); return null; - }; export default Submit; diff --git a/packages/deposit/src/features/submit/submitApi.ts b/packages/deposit/src/features/submit/submitApi.ts index ad94d840..ae655280 100644 --- a/packages/deposit/src/features/submit/submitApi.ts +++ b/packages/deposit/src/features/submit/submitApi.ts @@ -19,7 +19,7 @@ export const submitApi = createApi({ endpoints: (build) => ({ submitData: build.mutation({ query: ({ user, actionType, id, metadata, config, files }) => { - console.log(metadata) + console.log(metadata); // format data const data = formatFormData(id, metadata, files, config.formTitle); console.log("Submit metadata:"); @@ -27,9 +27,7 @@ export const submitApi = createApi({ // format headers const headers = { - Authorization: `Bearer ${ - config.submitKey || user?.access_token - }`, + Authorization: `Bearer ${config.submitKey || user?.access_token}`, "user-id": user?.profile.sub, "auth-env-name": config.target?.envName, "assistant-config-name": config.target?.configName, @@ -56,18 +54,20 @@ export const submitApi = createApi({ `resubmit/${data.id}` : `dataset/${actionType === "save" ? "DRAFT" : "PUBLISH"}`; - return ({ + return { url: `inbox/${submitUrl}`, method: "POST", headers: headers, body: data, - }) + }; }, - invalidatesTags: (_res, _err, arg ) => [{ type: "Forms", id: arg.id }], + invalidatesTags: (_res, _err, arg) => [{ type: "Forms", id: arg.id }], transformResponse: (response, _meta, arg) => { - store.dispatch(setMetadataSubmitStatus( - arg.actionType === "save" ? "saved" : "submitted", - )); + store.dispatch( + setMetadataSubmitStatus( + arg.actionType === "save" ? "saved" : "submitted", + ), + ); if (arg.actionType === "save" && !arg.autoSave) { // show notice and enable form again after successful save enqueueSnackbar( @@ -87,9 +87,11 @@ export const submitApi = createApi({ store.dispatch(setMetadataSubmitStatus("error")); // enable form again, so user can try and resubmit store.dispatch(setFormDisabled(false)); - return ({ - error: i18n.t("submit:submitMetadataError", { error: response.status }) - }); + return { + error: i18n.t("submit:submitMetadataError", { + error: response.status, + }), + }; }, }), fetchSavedMetadata: build.query({ @@ -119,7 +121,4 @@ export const submitApi = createApi({ }), }); -export const { - useSubmitDataMutation, - useFetchSavedMetadataQuery -} = submitApi; +export const { useSubmitDataMutation, useFetchSavedMetadataQuery } = submitApi; diff --git a/packages/deposit/src/features/submit/submitFile.ts b/packages/deposit/src/features/submit/submitFile.ts index 27f3f598..9a515eb8 100644 --- a/packages/deposit/src/features/submit/submitFile.ts +++ b/packages/deposit/src/features/submit/submitFile.ts @@ -1,184 +1,209 @@ -import * as tus from 'tus-js-client'; -import { store } from "../../redux/store"; -import { setFilesSubmitStatus } from "./submitSlice"; -import { setFileMeta } from "../files/filesSlice"; -import { SelectedFile } from "../../types/Files"; -import { enqueueSnackbar } from "notistack"; -import { getUser } from "@dans-framework/utils/user"; -import i18n from "../../languages/i18n"; -import { sendTicket } from "@dans-framework/utils/error"; - -const manualError = async (fileName: string, fileId: string, error: any, type: string) => { - console.error("Error", error); - // Since this process is not connected to Redux, we manually - // display a message, send a Freshdesk ticket or error, and set file status to errored - let ticket; - if (import.meta.env.VITE_FRESHDESK_API_KEY) { - ticket = await sendTicket({error: error, function: type}); - } - enqueueSnackbar(`Uploading ${fileName} - ${error}`, { variant: "customError", ticket: ticket }); - store.dispatch( - setFilesSubmitStatus({ - id: fileId, - status: "error", - }), - ); -} - -// Create a new tus upload -export const uploadFile = async ( - file: SelectedFile, - sessionId: string, - target: string = '' -) => { - // set file status to submitting, to add it to actual upload queue, while we create the blob - store.dispatch( - setFilesSubmitStatus({ - id: file.id, - progress: 0, - status: "submitting", - }), - ); - - // convert file url to blob - const fetchedFile = await fetch(file.url); - - if (!fetchedFile.ok) { - throw new Error(`Failed to fetch file: ${fetchedFile.statusText}`); - store.dispatch( - setFilesSubmitStatus({ - id: file.id, - status: "error", - }), - ); - } - - const fileBlob = await fetchedFile.blob(); - - // Get the current user object to send along at start of upload, for auth - const userBeforeUpload = getUser(); - - // TUS upload logic - const upload = new tus.Upload(fileBlob, { - endpoint: `${import.meta.env.VITE_PACKAGING_TARGET}/files`, - // retry 5 times on error - retryDelays: [1000, 5000, 10000, 20000, 30000], - // optional metadata for the file - metadata: { - fileName: file.name, - fileId: file.id, - datasetId: sessionId, - }, - headers: { - Authorization: `Bearer ${userBeforeUpload?.access_token}`, - "auth-env-name": target, - }, - removeFingerprintOnSuccess: true, - onError: (error) => { - manualError(file.name, file.id, error, 'onError function in TUS upload'); - }, - onShouldRetry: (error, retryAttempt, _options) => { - console.error("Error", error) - console.log("Request", error.originalRequest) - console.log("Response", error.originalResponse) - - var status = error.originalResponse ? error.originalResponse.getStatus() : 0 - // Do not retry if the status is a 403. - if (status === 403) { - return false - } - - enqueueSnackbar( - i18n.t("uploadRetry", { - ns: "submit", - file: file.name, - attempt: retryAttempt + 2, - }), - { - variant: "warning", - }, - ); - - // For any other status code, we should retry. - return true - }, - onProgress: (bytesUploaded, bytesTotal) => { - var percentage = parseFloat(((bytesUploaded / bytesTotal) * 100).toFixed(0)) || 0; - store.dispatch( - setFilesSubmitStatus({ - id: file.id, - progress: percentage, - status: "submitting", - }), - ); - }, - onSuccess: async () => { - const tusId = upload.url?.split('/').pop(); - - // User key might have changed during upload, so let's get it again - const userAfterUpload = getUser(); - - // Due to incomplete Python TUS implementation, - // we do an extra api PATCH call to the server to signal succesful upload. - // Response might take a while, so lets display a spinner that informs the user - store.dispatch( - setFilesSubmitStatus({ - id: file.id, - status: "finalising", - }), - ); - - try { - const response = await fetch(`${import.meta.env.VITE_PACKAGING_TARGET}/inbox/files/${sessionId}/${tusId}`, { - method: 'PATCH', - headers: { - Authorization: `Bearer ${userAfterUpload?.access_token}`, - "auth-env-name": target, - }, - }); - // check if patch result is ok - if (response.status === 200) { - // set file status to success - store.dispatch( - setFileMeta({ - id: file.id, - type: "submittedFile", - value: true, - }), - ); - store.dispatch( - setFilesSubmitStatus({ - id: file.id, - status: "success", - }), - ); - enqueueSnackbar( - i18n.t("uploadSuccess", { - ns: "submit", - file: file.name, - }), - { - variant: "success", - }, - ); - } else { - manualError(file.name, file.id, 'PATCH call failed', `PATCH call gave an invalid response ${response.status}`); - } - } catch(error){ - // on error, file must be set to failed, as server can't processed it properly - manualError(file.name, file.id, error, 'error dispatching PATCH call to inbox/files/{sessionID}/{tusID}'); - }; - }, - }); - - // Check if there are any previous uploads to continue. - upload.findPreviousUploads().then(function (previousUploads) { - // Found previous uploads so we select the first one. - if (previousUploads.length) { - upload.resumeFromPreviousUpload(previousUploads[0]); - } - - // Start the upload - upload.start(); - }); -} \ No newline at end of file +import * as tus from "tus-js-client"; +import { store } from "../../redux/store"; +import { setFilesSubmitStatus } from "./submitSlice"; +import { setFileMeta } from "../files/filesSlice"; +import { SelectedFile } from "../../types/Files"; +import { enqueueSnackbar } from "notistack"; +import { getUser } from "@dans-framework/utils/user"; +import i18n from "../../languages/i18n"; +import { sendTicket } from "@dans-framework/utils/error"; + +const manualError = async ( + fileName: string, + fileId: string, + error: any, + type: string, +) => { + console.error("Error", error); + // Since this process is not connected to Redux, we manually + // display a message, send a Freshdesk ticket or error, and set file status to errored + let ticket; + if (import.meta.env.VITE_FRESHDESK_API_KEY) { + ticket = await sendTicket({ error: error, function: type }); + } + enqueueSnackbar(`Uploading ${fileName} - ${error}`, { + variant: "customError", + ticket: ticket, + }); + store.dispatch( + setFilesSubmitStatus({ + id: fileId, + status: "error", + }), + ); +}; + +// Create a new tus upload +export const uploadFile = async ( + file: SelectedFile, + sessionId: string, + target: string = "", +) => { + // set file status to submitting, to add it to actual upload queue, while we create the blob + store.dispatch( + setFilesSubmitStatus({ + id: file.id, + progress: 0, + status: "submitting", + }), + ); + + // convert file url to blob + const fetchedFile = await fetch(file.url); + + if (!fetchedFile.ok) { + throw new Error(`Failed to fetch file: ${fetchedFile.statusText}`); + store.dispatch( + setFilesSubmitStatus({ + id: file.id, + status: "error", + }), + ); + } + + const fileBlob = await fetchedFile.blob(); + + // Get the current user object to send along at start of upload, for auth + const userBeforeUpload = getUser(); + + // TUS upload logic + const upload = new tus.Upload(fileBlob, { + endpoint: `${import.meta.env.VITE_PACKAGING_TARGET}/files`, + // retry 5 times on error + retryDelays: [1000, 5000, 10000, 20000, 30000], + // optional metadata for the file + metadata: { + fileName: file.name, + fileId: file.id, + datasetId: sessionId, + }, + headers: { + Authorization: `Bearer ${userBeforeUpload?.access_token}`, + "auth-env-name": target, + }, + removeFingerprintOnSuccess: true, + onError: (error) => { + manualError(file.name, file.id, error, "onError function in TUS upload"); + }, + onShouldRetry: (error, retryAttempt, _options) => { + console.error("Error", error); + console.log("Request", error.originalRequest); + console.log("Response", error.originalResponse); + + var status = + error.originalResponse ? error.originalResponse.getStatus() : 0; + // Do not retry if the status is a 403. + if (status === 403) { + return false; + } + + enqueueSnackbar( + i18n.t("uploadRetry", { + ns: "submit", + file: file.name, + attempt: retryAttempt + 2, + }), + { + variant: "warning", + }, + ); + + // For any other status code, we should retry. + return true; + }, + onProgress: (bytesUploaded, bytesTotal) => { + var percentage = + parseFloat(((bytesUploaded / bytesTotal) * 100).toFixed(0)) || 0; + store.dispatch( + setFilesSubmitStatus({ + id: file.id, + progress: percentage, + status: "submitting", + }), + ); + }, + onSuccess: async () => { + const tusId = upload.url?.split("/").pop(); + + // User key might have changed during upload, so let's get it again + const userAfterUpload = getUser(); + + // Due to incomplete Python TUS implementation, + // we do an extra api PATCH call to the server to signal succesful upload. + // Response might take a while, so lets display a spinner that informs the user + store.dispatch( + setFilesSubmitStatus({ + id: file.id, + status: "finalising", + }), + ); + + try { + const response = await fetch( + `${ + import.meta.env.VITE_PACKAGING_TARGET + }/inbox/files/${sessionId}/${tusId}`, + { + method: "PATCH", + headers: { + Authorization: `Bearer ${userAfterUpload?.access_token}`, + "auth-env-name": target, + }, + }, + ); + // check if patch result is ok + if (response.status === 200) { + // set file status to success + store.dispatch( + setFileMeta({ + id: file.id, + type: "submittedFile", + value: true, + }), + ); + store.dispatch( + setFilesSubmitStatus({ + id: file.id, + status: "success", + }), + ); + enqueueSnackbar( + i18n.t("uploadSuccess", { + ns: "submit", + file: file.name, + }), + { + variant: "success", + }, + ); + } else { + manualError( + file.name, + file.id, + "PATCH call failed", + `PATCH call gave an invalid response ${response.status}`, + ); + } + } catch (error) { + // on error, file must be set to failed, as server can't processed it properly + manualError( + file.name, + file.id, + error, + "error dispatching PATCH call to inbox/files/{sessionID}/{tusID}", + ); + } + }, + }); + + // Check if there are any previous uploads to continue. + upload.findPreviousUploads().then(function (previousUploads) { + // Found previous uploads so we select the first one. + if (previousUploads.length) { + upload.resumeFromPreviousUpload(previousUploads[0]); + } + + // Start the upload + upload.start(); + }); +}; diff --git a/packages/deposit/src/features/submit/submitHelpers.ts b/packages/deposit/src/features/submit/submitHelpers.ts index 26f032d1..aa64a3f5 100644 --- a/packages/deposit/src/features/submit/submitHelpers.ts +++ b/packages/deposit/src/features/submit/submitHelpers.ts @@ -7,7 +7,7 @@ export const formatFormData = ( sessionId: string, metadata: SectionType[], files?: SelectedFile[], - formTitle: string = '', + formTitle: string = "", ) => { // Create the file metadata array const fileMetadata = @@ -26,20 +26,22 @@ export const formatFormData = ( // since the title field is unique, we can assume we only find one value // so lets return that let foundTitle = false; - const title = metadata.map(section => { - if (foundTitle) return false; - const toFind = findByIdOrName(formTitle, section.fields, "name")?.value; - if (toFind) { - foundTitle = true; - } - return toFind; - }).filter(Boolean)[0]; + const title = metadata + .map((section) => { + if (foundTitle) return false; + const toFind = findByIdOrName(formTitle, section.fields, "name")?.value; + if (toFind) { + foundTitle = true; + } + return toFind; + }) + .filter(Boolean)[0]; return { id: sessionId, metadata: metadata, "file-metadata": fileMetadata, - title: title || '', + title: title || "", }; }; @@ -68,4 +70,4 @@ export const formatFileData = async ( )); return fileData; -}; \ No newline at end of file +}; diff --git a/packages/deposit/src/languages/locales/en/files.json b/packages/deposit/src/languages/locales/en/files.json index 73dd6d0b..28ef5cd2 100644 --- a/packages/deposit/src/languages/locales/en/files.json +++ b/packages/deposit/src/languages/locales/en/files.json @@ -47,5 +47,6 @@ "dateInvalid": "Invalid date", "fileTooLarge": "Files over {{ size }} GB cannot be processed by the target repository", "fileNoSize": "Cannot upload files of 0 bytes", - "fileForbiddenCharacters": "File name contains forbidden characters: /:*?\"<>|;#" + "fileForbiddenCharacters": "File name contains forbidden characters: /:*?\"<>|;#", + "termsMapped": "Terms mapped" } \ No newline at end of file diff --git a/packages/deposit/src/languages/locales/nl/files.json b/packages/deposit/src/languages/locales/nl/files.json index 5f1f1dc2..e298deeb 100644 --- a/packages/deposit/src/languages/locales/nl/files.json +++ b/packages/deposit/src/languages/locales/nl/files.json @@ -47,5 +47,6 @@ "dateInvalid": "Ongeldige datum", "fileTooLarge": "Bestanden groter dan {{ size }} GB kunnen niet worden verwerkt door het doelrepository", "fileNoSize": "Kan geen bestanden van 0 bytes uploaden", - "fileForbiddenCharacters": "Bestandsnaam bevat tekens die niet zijn toegestaan: /:*?\"<>|;#" + "fileForbiddenCharacters": "Bestandsnaam bevat tekens die niet zijn toegestaan: /:*?\"<>|;#", + "termsMapped": "Terms mapped" } \ No newline at end of file diff --git a/packages/deposit/src/types/Api.ts b/packages/deposit/src/types/Api.ts index 08fb6344..744f182e 100644 --- a/packages/deposit/src/types/Api.ts +++ b/packages/deposit/src/types/Api.ts @@ -127,7 +127,7 @@ export interface MaptilerConversionResponse { results: { x: number; y: number; - }[] + }[]; } export interface ProxyResponse { @@ -187,4 +187,4 @@ export interface BiodiversityItem { export interface BiodiversityResponse { resultSet: BiodiversityItem[]; -} \ No newline at end of file +} diff --git a/packages/deposit/src/types/Files.ts b/packages/deposit/src/types/Files.ts index 75210cf8..609d8ef7 100644 --- a/packages/deposit/src/types/Files.ts +++ b/packages/deposit/src/types/Files.ts @@ -42,6 +42,10 @@ export interface SelectedFile { submittedFile?: boolean; errors?: never; file?: never; + // for translating xls/csv file columns + mapping?: { + [key: string]: any; + }; } interface FileError { diff --git a/packages/deposit/src/types/MetadataFields.ts b/packages/deposit/src/types/MetadataFields.ts index f9ef6f58..b96eb2cc 100644 --- a/packages/deposit/src/types/MetadataFields.ts +++ b/packages/deposit/src/types/MetadataFields.ts @@ -1,6 +1,6 @@ import type { LanguageStrings } from "@dans-framework/utils"; import type { AuthProperty } from "@dans-framework/user-auth"; -import type { Feature, Point, Polygon, LineString, Geometry } from 'geojson'; +import type { Feature, Point, Polygon, LineString, Geometry } from "geojson"; import type { LngLatBoundsLike } from "react-map-gl"; // All user input field types @@ -71,7 +71,8 @@ export interface DateFieldType extends BasisFieldType { maxDateField?: string; } -export interface DateRangeFieldType extends Omit { +export interface DateRangeFieldType + extends Omit { type: "daterange"; value?: (string | null)[]; optionalEndDate?: boolean; @@ -169,7 +170,8 @@ export interface CheckFieldType } export type MapFeatureType = Point | Polygon | LineString; -export interface ExtendedMapFeature extends Feature { +export interface ExtendedMapFeature + extends Feature { geonames?: OptionsType | undefined; originalCoordinates?: number[] | number[][] | number[][][]; coordinateSystem?: OptionsType; @@ -181,8 +183,7 @@ export interface CoordinateSystem extends OptionsType { bbox?: LngLatBoundsLike; } -export interface DrawMapFieldType - extends Omit { +export interface DrawMapFieldType extends Omit { type: "drawmap"; value?: ExtendedMapFeature[]; wmsLayers?: { diff --git a/packages/deposit/src/types/MetadataPayloads.ts b/packages/deposit/src/types/MetadataPayloads.ts index ec4c03ea..363688ab 100644 --- a/packages/deposit/src/types/MetadataPayloads.ts +++ b/packages/deposit/src/types/MetadataPayloads.ts @@ -12,7 +12,13 @@ interface Payload { } export interface SetFieldValuePayload extends Payload { - value: string | string[] | OptionsType | OptionsType[] | ExtendedMapFeature[] | null; + value: + | string + | string[] + | OptionsType + | OptionsType[] + | ExtendedMapFeature[] + | null; } export interface SetFieldMultiApiPayload extends Payload { diff --git a/packages/file-mapper/lib/index.tsx b/packages/file-mapper/lib/index.tsx index 4d81704c..1d94a0d5 100644 --- a/packages/file-mapper/lib/index.tsx +++ b/packages/file-mapper/lib/index.tsx @@ -1,2 +1,2 @@ -export { default as FileMapper } from "../src"; -export { default as i18n } from "../src/languages/i18n"; +export { default as FileMapper } from "../src"; +export { default as i18n } from "../src/languages/i18n"; diff --git a/packages/file-mapper/package.json b/packages/file-mapper/package.json index 1cb4a84c..ac36e94e 100644 --- a/packages/file-mapper/package.json +++ b/packages/file-mapper/package.json @@ -5,6 +5,7 @@ "private": true, "version": "1.0.0", "dependencies": { + "@dans-framework/deposit": "workspace:*", "@dans-framework/utils": "workspace:*", "@mui/icons-material": "^5.14.3", "@mui/material": "^5.16.7", @@ -17,12 +18,14 @@ "react-dropzone": "^14.2.3", "react-i18next": "^13.0.3", "react-redux": "^8.1.2", + "react-router-dom": "^6.14.2", + "uuid": "^9.0.0", "xlsx": "^0.18.5" }, "devDependencies": { - "@dans-framework/deposit": "workspace:*", "@dans-framework/pages": "workspace:*", "@types/react": "^18.2.15", - "@types/react-dom": "^18.2.7" + "@types/react-dom": "^18.2.7", + "@types/uuid": "^9.0.2" } } diff --git a/packages/file-mapper/src/features/FileMapper.tsx b/packages/file-mapper/src/features/FileMapper.tsx index 20bd8e93..372ee8fc 100644 --- a/packages/file-mapper/src/features/FileMapper.tsx +++ b/packages/file-mapper/src/features/FileMapper.tsx @@ -1,133 +1,186 @@ -import { useEffect, type Dispatch, type SetStateAction } from "react"; -import Container from "@mui/material/Container"; -import Grid from "@mui/material/Unstable_Grid2"; -import Box from "@mui/material/Box"; -import Stack from "@mui/material/Stack"; -import Paper from "@mui/material/Paper"; -import Button from "@mui/material/Button"; -import Stepper from '@mui/material/Stepper'; -import Step from '@mui/material/Step'; -import StepLabel from '@mui/material/StepLabel'; -import { useTranslation } from "react-i18next"; -import SelectFile from './SelectFile'; -import SetMapping from './SetMapping'; -import SaveMapping from './SaveMapping'; -import { getActiveStep, setActiveStep, getFile, getSavedMap, getMapping, getFileError } from './fileMapperSlice'; -import { useSubmitMapMutation } from './fileMapperApi'; -import { useAppSelector, useAppDispatch } from "../redux/hooks"; -import CircularProgress from '@mui/material/CircularProgress'; -import { useSiteTitle, setSiteTitle } from "@dans-framework/utils/sitetitle"; -import { lookupLanguageString } from "@dans-framework/utils/language"; -import { type Page } from "@dans-framework/pages"; -import type { FormConfig } from "@dans-framework/deposit"; -import { steps } from "./Steps"; - -const FileMapper = ({setMappedForm, page}: { - setMappedForm: Dispatch>; - page: Page; -}) => { - const dispatch = useAppDispatch(); - const siteTitle = useSiteTitle(); - const { t, i18n } = useTranslation("steps"); - const activeStep = useAppSelector(getActiveStep); - const file = useAppSelector(getFile); - const savedMap = useAppSelector(getSavedMap); - const mapping = useAppSelector(getMapping); - const fileError = useAppSelector(getFileError); - const [ submitMap, { isLoading, data } ] = useSubmitMapMutation(); - - // set page title - useEffect(() => { - setSiteTitle(siteTitle, lookupLanguageString(page.name, i18n.language)); - }, [siteTitle, page.name]); - - useEffect(() => { - // save server return data to state - setMappedForm(data); - }, [data]); - - const handleNext = () => { - if (activeStep !== steps.length - 1 && (!file || !savedMap)) { - dispatch(setActiveStep(activeStep + 1)); - } else if ( file ) { - (async () => { - const fetchedFile = await fetch(file.url); - const blob = await fetchedFile.blob(); - submitMap({ - savedMap: savedMap, - newMap: mapping, - file: blob, - }); - })(); - } - }; - - const handleBack = () => { - dispatch(setActiveStep(activeStep - 1)); - }; - - return ( - - - - - - {steps.map((label) => { - const stepProps: { completed?: boolean } = {}; - return ( - - {t(label)} - - ); - })} - - { - activeStep === 0 - ? - : activeStep === 1 - ? - : - } - - - - - - - - - - ) -}; - -export default FileMapper; +import { useEffect /*type Dispatch, type SetStateAction*/ } from "react"; +import Container from "@mui/material/Container"; +import Grid from "@mui/material/Unstable_Grid2"; +import Box from "@mui/material/Box"; +// import Stack from "@mui/material/Stack"; +import Paper from "@mui/material/Paper"; +import Button from "@mui/material/Button"; +import Stepper from "@mui/material/Stepper"; +import Step from "@mui/material/Step"; +import StepLabel from "@mui/material/StepLabel"; +import { useTranslation } from "react-i18next"; +import SelectFile from "./SelectFile"; +import SetMapping from "./SetMapping"; +import SaveMapping from "./SaveMapping"; +import { + getActiveStep, + setActiveStep, + getFile, + getSavedMap, + getMapping, + getFileError, + reset, +} from "./fileMapperSlice"; +// import { useSubmitMapMutation } from './fileMapperApi'; +import { useAppSelector, useAppDispatch } from "../redux/hooks"; +// import CircularProgress from '@mui/material/CircularProgress'; +import { useSiteTitle, setSiteTitle } from "@dans-framework/utils/sitetitle"; +import { lookupLanguageString } from "@dans-framework/utils/language"; +import type { Page } from "@dans-framework/pages"; +import { + addFiles, + initForm, + depositStore, + type FormConfig, + type FileLocation, +} from "@dans-framework/deposit"; +import { steps } from "./Steps"; +import { v4 as uuidv4 } from "uuid"; +import { useNavigate } from "react-router-dom"; + +const FileMapper = ({ + config, + /*setMappedForm,*/ page, + depositPageSlug, +}: { + config: FormConfig; + // setMappedForm?: Dispatch>; + page: Page; + depositPageSlug?: string; +}) => { + const dispatch = useAppDispatch(); + const siteTitle = useSiteTitle(); + const { t, i18n } = useTranslation("steps"); + const activeStep = useAppSelector(getActiveStep); + const file = useAppSelector(getFile); + const savedMap = useAppSelector(getSavedMap); + const mapping = useAppSelector(getMapping); + const fileError = useAppSelector(getFileError); + const navigate = useNavigate(); + + // submit to server, disabled for now + // const [ submitMap, { isLoading, data } ] = useSubmitMapMutation(); + + // set page title + useEffect(() => { + setSiteTitle(siteTitle, lookupLanguageString(page.name, i18n.language)); + }, [siteTitle, page.name]); + + // useEffect(() => { + // // save server returned data to state + // setMappedForm(data); + // }, [data]); + + const handleNext = () => { + if (activeStep !== steps.length - 1 && (!file || !savedMap)) { + dispatch(setActiveStep(activeStep + 1)); + } else if (file) { + // submit to server + // let's disable this for now, and just load the file and the selected mapping into the Deposit package redux store + // (async () => { + // const fetchedFile = await fetch(file.url); + // const blob = await fetchedFile.blob(); + // submitMap({ + // savedMap: savedMap, + // newMap: mapping, + // file: blob, + // }); + // })(); + + // add file to deposit form directly + const serializedFile = { + id: uuidv4(), + name: file.name, + size: file.size, + type: file.name.substring(file.name.lastIndexOf(".") + 1), + location: "local" as FileLocation, + url: file.url, + private: false, + lastModified: 0, + mapping: mapping, + }; + + // must initialize the form here, otherwise files will get overwritten + depositStore.dispatch(initForm(config.form)); + // add files to initialized form + depositStore.dispatch(addFiles([serializedFile])); + // navigate to form + depositPageSlug && navigate(depositPageSlug); + // reset file mapper + dispatch(reset()); + } + }; + + const handleBack = () => { + dispatch(setActiveStep(activeStep - 1)); + }; + + return ( + + + + + + {steps.map((label) => { + const stepProps: { completed?: boolean } = {}; + return ( + + {t(label)} + + ); + })} + + {activeStep === 0 ? + + : activeStep === 1 ? + + : } + + + + + + + + + + ); +}; + +export default FileMapper; diff --git a/packages/file-mapper/src/features/SaveMapping.tsx b/packages/file-mapper/src/features/SaveMapping.tsx index 9e822ef8..d44e40fb 100644 --- a/packages/file-mapper/src/features/SaveMapping.tsx +++ b/packages/file-mapper/src/features/SaveMapping.tsx @@ -1,17 +1,20 @@ -import { useTranslation } from "react-i18next"; -import TextField from '@mui/material/TextField'; -import Typography from "@mui/material/Typography"; -import { StepWrap } from "./Steps"; - -export const SaveMapping = () => { - const { t } = useTranslation("steps"); - - return ( - - {t("saveMappingExtra")} - - - ) -} - -export default SaveMapping; \ No newline at end of file +import { useTranslation } from "react-i18next"; +import TextField from "@mui/material/TextField"; +import Typography from "@mui/material/Typography"; +import { StepWrap } from "./Steps"; + +export const SaveMapping = () => { + const { t } = useTranslation("steps"); + + return ( + + {t("saveMappingExtra")} + + + ); +}; + +export default SaveMapping; diff --git a/packages/file-mapper/src/features/SelectFile.tsx b/packages/file-mapper/src/features/SelectFile.tsx index c387480c..95b9eb65 100644 --- a/packages/file-mapper/src/features/SelectFile.tsx +++ b/packages/file-mapper/src/features/SelectFile.tsx @@ -1,136 +1,148 @@ -import { useDropzone } from "react-dropzone"; -import Box from "@mui/material/Box"; -import Stack from "@mui/material/Stack"; -import Typography from "@mui/material/Typography"; -import Alert from "@mui/material/Alert"; -import { useTranslation } from "react-i18next"; -import List from '@mui/material/List'; -import ListItem from '@mui/material/ListItem'; -import ListItemButton from '@mui/material/ListItemButton'; -import ListItemText from '@mui/material/ListItemText'; -import ListItemIcon from '@mui/material/ListItemIcon'; -import Checkbox from '@mui/material/Checkbox'; -import Divider from '@mui/material/Divider'; -import useMediaQuery from '@mui/material/useMediaQuery'; -import { useTheme } from '@mui/material/styles'; -import type { Saves, SerializedFile } from "../types"; -import { - getFile, - setFile, - getSavedMap, - setSavedMap, - resetMapping, - getFileError, - resetFileError, - resetFileData, -} from './fileMapperSlice'; -import { useAppSelector, useAppDispatch } from "../redux/hooks"; -import { StepWrap, maxRows, saves } from "./Steps"; - -const SelectFile = () => { - const { t } = useTranslation("steps"); - const theme = useTheme(); - const matches = useMediaQuery(theme.breakpoints.up('md')); - const dispatch = useAppDispatch(); - const file = useAppSelector(getFile); - const savedMap = useAppSelector(getSavedMap); - const fileError = useAppSelector(getFileError); - - const onDrop = async (files: File[]) => { - // serialize files to store in redux - const serializedFile: SerializedFile = { - name: files[0].name, - size: files[0].size, - url: URL.createObjectURL(files[0]), - }; - - dispatch(setFile(serializedFile)); - - // reset saved mapping and column values after selecting a different file - dispatch(resetMapping()); - dispatch(resetFileData()); - dispatch(resetFileError()); - } - - const { - getRootProps, - getInputProps, - isDragActive, - } = useDropzone({ - onDrop, - multiple: false, - accept: { - "text/csv": [".csv"], - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": [".xlsx"], - }, - }); - - return ( - - } - > - - {t("uploadNew")} - - - - {isDragActive ? t("dropNow") : t("drop")} - - - { file && - - - {t("selectedFile", { name: file.name, size: (file.size / 1024).toFixed(0) })} - - {fileError && - - {t(fileError, {max: maxRows})} - - } - - } - - {saves.length > 0 && - - {t("selectSave")} - - {saves.map( (save: Saves) => - - dispatch(setSavedMap(savedMap === save.id ? "" : save.id))} dense> - - - - - - - )} - - - } - - - ) -} - -export default SelectFile; \ No newline at end of file +import { useDropzone } from "react-dropzone"; +import Box from "@mui/material/Box"; +import Stack from "@mui/material/Stack"; +import Typography from "@mui/material/Typography"; +import Alert from "@mui/material/Alert"; +import { useTranslation } from "react-i18next"; +import List from "@mui/material/List"; +import ListItem from "@mui/material/ListItem"; +import ListItemButton from "@mui/material/ListItemButton"; +import ListItemText from "@mui/material/ListItemText"; +import ListItemIcon from "@mui/material/ListItemIcon"; +import Checkbox from "@mui/material/Checkbox"; +import Divider from "@mui/material/Divider"; +import useMediaQuery from "@mui/material/useMediaQuery"; +import { useTheme } from "@mui/material/styles"; +import type { Saves, SerializedFile } from "../types"; +import { + getFile, + setFile, + getSavedMap, + setSavedMap, + resetMapping, + getFileError, + resetFileError, + resetFileData, +} from "./fileMapperSlice"; +import { useAppSelector, useAppDispatch } from "../redux/hooks"; +import { StepWrap, maxRows, saves } from "./Steps"; + +const SelectFile = () => { + const { t } = useTranslation("steps"); + const theme = useTheme(); + const matches = useMediaQuery(theme.breakpoints.up("md")); + const dispatch = useAppDispatch(); + const file = useAppSelector(getFile); + const savedMap = useAppSelector(getSavedMap); + const fileError = useAppSelector(getFileError); + + const onDrop = async (files: File[]) => { + // serialize files to store in redux + const serializedFile: SerializedFile = { + name: files[0].name, + size: files[0].size, + url: URL.createObjectURL(files[0]), + }; + + dispatch(setFile(serializedFile)); + + // reset saved mapping and column values after selecting a different file + dispatch(resetMapping()); + dispatch(resetFileData()); + dispatch(resetFileError()); + }; + + const { getRootProps, getInputProps, isDragActive } = useDropzone({ + onDrop, + multiple: false, + accept: { + "text/csv": [".csv"], + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": [ + ".xlsx", + ], + }, + }); + + return ( + + + } + > + + {t("uploadNew")} + + + + {isDragActive ? t("dropNow") : t("drop")} + + + {file && ( + + + {t("selectedFile", { + name: file.name, + size: (file.size / 1024).toFixed(0), + })} + + {fileError && ( + {t(fileError, { max: maxRows })} + )} + + )} + + {saves.length > 0 && ( + + + {t("selectSave")} + + + {saves.map((save: Saves) => ( + + + dispatch(setSavedMap(savedMap === save.id ? "" : save.id)) + } + dense + > + + + + + + + ))} + + + )} + + + ); +}; + +export default SelectFile; diff --git a/packages/file-mapper/src/features/SetMapping.tsx b/packages/file-mapper/src/features/SetMapping.tsx index 38034fb9..abec4c51 100644 --- a/packages/file-mapper/src/features/SetMapping.tsx +++ b/packages/file-mapper/src/features/SetMapping.tsx @@ -1,189 +1,241 @@ -import { useState, useEffect } from "react"; -import Typography from "@mui/material/Typography"; -import Paper from "@mui/material/Paper"; -import Alert from "@mui/material/Alert"; -import { useTranslation } from "react-i18next"; -import TableContainer from '@mui/material/TableContainer'; -import Table from '@mui/material/Table'; -import TableBody from '@mui/material/TableBody'; -import TableCell from '@mui/material/TableCell'; -import TableHead from '@mui/material/TableHead'; -import TableRow from '@mui/material/TableRow'; -import TextField from '@mui/material/TextField'; -import Autocomplete from '@mui/material/Autocomplete'; -import CircularProgress from '@mui/material/CircularProgress'; -import IconButton from '@mui/material/IconButton'; -import Collapse from '@mui/material/Collapse'; -import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; -import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp'; -import type { DarwinOptions, FileError, SheetData } from "../types"; -import { - getFile, - getMapping, - setMapping, - getFileError, - setFileError, - setFileData, - getFileData, -} from './fileMapperSlice'; -import { useFetchDarwinTermsQuery } from "./fileMapperApi"; -import { useAppSelector, useAppDispatch } from "../redux/hooks"; -import { StepWrap, maxRows } from "./Steps"; - -export const SetMapping = () => { - const { t } = useTranslation("steps"); - const dispatch = useAppDispatch(); - const file = useAppSelector(getFile); - const fileData = useAppSelector(getFileData); - const fileError = useAppSelector(getFileError); - // loading indicator only if new file needs to be read - const [ loading, setLoading ] = useState( !Array.isArray(fileData) && !fileError ); - - useEffect(() => { - const loadXLSX = async () => { - const XLSX = await import('xlsx'); // Lazy load the library here - - const reader = new FileReader(); - reader.onload = (event) => { - // parse the xlsx/csv file - const workbook = XLSX.read(event.target?.result, { type: 'binary' }); - const sheetName = workbook.SheetNames[0]; - const sheet = workbook.Sheets[sheetName]; - const sheetData: SheetData[] = XLSX.utils.sheet_to_json(sheet, { header: "A" }); - // check to see if sheet doesn't have too many rows (first row is headers, so doesn't count) - const rowCount = sheetData.length - 1; - if (rowCount > maxRows) { - dispatch(setFileError("tooManyRows")); - } else { - // save sheet data so we only need to load and parse once - dispatch(setFileData(sheetData)); - } - setLoading(false); - }; - - if (file && !fileData && !fileError) { - dispatch(setFileError(undefined)); - // if no file loaded yet, convert file url back to blob - const fetchedFile = await fetch(file.url); - const blob = await fetchedFile.blob(); - if (blob) { - reader.readAsBinaryString(blob); - } - } - }; - - loadXLSX(); // Call the lazy loading function - }, [file, fileData, fileError, dispatch]); - - return ( - - - - - - - {t("dataValue")} - {t("mapTo")} - - - - { ( loading || fileError ) && - - - { - loading ? - : - - {t(fileError as FileError, {max: maxRows})} - - } - - - } - {fileData && Object.entries(fileData[0]).map(([key, value]) => - - )} - -
-
-
- ) -} - -export default SetMapping; - -const Row = ({rowKey, row}: {rowKey: string; row: string;}) => { - const { t } = useTranslation("steps"); - const [inputValue, setInputValue] = useState(''); - const mapping = useAppSelector(getMapping); - const dispatch = useAppDispatch(); - const fileData = useAppSelector(getFileData); - const columnData = fileData && fileData.slice(1).map( data => data[rowKey]) - const [ open, setOpen ] = useState(false); - console.log(columnData) - - const { data, isLoading } = useFetchDarwinTermsQuery(''); - - const selectValue = (row: string, value: DarwinOptions | null) => { - if (value === null) { - // Create a new object excluding the [row] key - const { [row]: _, ...rest } = mapping; - dispatch(setMapping(rest)); - } else { - dispatch(setMapping({ - ...mapping, - [row]: value, - })); - } - }; - - return ( - <> - - - setOpen(!open)} - > - {open ? : } - - - - {row} - - - option.label} - groupBy={(option) => option.header} - sx={{ width: 300 }} - renderInput={(params) => } - onChange={(_e, value) => selectValue(row, value)} - value={(mapping.hasOwnProperty(row) && mapping[row]) || null} - inputValue={inputValue} - isOptionEqualToValue={(option, value) => option.term_localName === value.term_localName} - onInputChange={(_e, newInputValue) => { - setInputValue(newInputValue); - }} - loading={isLoading} - size="small" - /> - - - {columnData && - - - - - {t('dataHeader')} - {columnData.map((item, i) => - {item} - )} - - - - } - - ) -} +import { useState, useEffect } from "react"; +import Typography from "@mui/material/Typography"; +import Paper from "@mui/material/Paper"; +import Alert from "@mui/material/Alert"; +import { useTranslation } from "react-i18next"; +import TableContainer from "@mui/material/TableContainer"; +import Table from "@mui/material/Table"; +import TableBody from "@mui/material/TableBody"; +import TableCell from "@mui/material/TableCell"; +import TableHead from "@mui/material/TableHead"; +import TableRow from "@mui/material/TableRow"; +import TextField from "@mui/material/TextField"; +import Autocomplete from "@mui/material/Autocomplete"; +import CircularProgress from "@mui/material/CircularProgress"; +import IconButton from "@mui/material/IconButton"; +import Collapse from "@mui/material/Collapse"; +import Tooltip from "@mui/material/Tooltip"; +import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; +import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"; +import type { DarwinOptions, FileError, SheetData } from "../types"; +import { + getFile, + getMapping, + setMapping, + getFileError, + setFileError, + setFileData, + getFileData, +} from "./fileMapperSlice"; +import { useFetchDarwinTermsQuery } from "./fileMapperApi"; +import { useAppSelector, useAppDispatch } from "../redux/hooks"; +import { StepWrap, maxRows } from "./Steps"; +import LaunchIcon from "@mui/icons-material/Launch"; +import InputAdornment from "@mui/material/InputAdornment"; + +export const SetMapping = () => { + const { t } = useTranslation("steps"); + const dispatch = useAppDispatch(); + const file = useAppSelector(getFile); + const fileData = useAppSelector(getFileData); + const fileError = useAppSelector(getFileError); + // loading indicator only if new file needs to be read + const [loading, setLoading] = useState( + !Array.isArray(fileData) && !fileError, + ); + + useEffect(() => { + const loadXLSX = async () => { + const XLSX = await import("xlsx"); // Lazy load the library here + + const reader = new FileReader(); + reader.onload = (event) => { + // parse the xlsx/csv file + const workbook = XLSX.read(event.target?.result, { type: "binary" }); + const sheetName = workbook.SheetNames[0]; + const sheet = workbook.Sheets[sheetName]; + const sheetData: SheetData[] = XLSX.utils.sheet_to_json(sheet, { + header: "A", + }); + // check to see if sheet doesn't have too many rows (first row is headers, so doesn't count) + const rowCount = sheetData.length - 1; + if (rowCount > maxRows) { + dispatch(setFileError("tooManyRows")); + } else { + // save sheet data so we only need to load and parse once + dispatch(setFileData(sheetData)); + } + setLoading(false); + }; + + if (file && !fileData && !fileError) { + dispatch(setFileError(undefined)); + // if no file loaded yet, convert file url back to blob + const fetchedFile = await fetch(file.url); + const blob = await fetchedFile.blob(); + if (blob) { + reader.readAsBinaryString(blob); + } + } + }; + + loadXLSX(); // Call the lazy loading function + }, [file, fileData, fileError, dispatch]); + + return ( + + + + + + + {t("dataValue")} + {t("mapTo")} + + + + {(loading || fileError) && ( + + + {loading ? + + : + {t(fileError as FileError, { max: maxRows })} + + } + + + )} + {fileData && + Object.entries(fileData[0]).map(([key, value]) => ( + + ))} + +
+
+
+ ); +}; + +export default SetMapping; + +const Row = ({ rowKey, row }: { rowKey: string; row: string }) => { + const { t } = useTranslation("steps"); + const [inputValue, setInputValue] = useState(""); + const mapping = useAppSelector(getMapping); + const dispatch = useAppDispatch(); + const fileData = useAppSelector(getFileData); + const columnData = fileData && fileData.slice(1).map((data) => data[rowKey]); + const [open, setOpen] = useState(false); + + const { data, isLoading } = useFetchDarwinTermsQuery(""); + + const selectValue = (row: string, value: DarwinOptions | null) => { + if (value === null) { + // Create a new object excluding the [row] key + const { [row]: _, ...rest } = mapping; + dispatch(setMapping(rest)); + } else { + dispatch( + setMapping({ + ...mapping, + [row]: value, + }), + ); + } + }; + + return ( + <> + + + setOpen(!open)} + > + {open ? + + : } + + + {row} + + option.label} + groupBy={(option) => option.header} + sx={{ width: 300 }} + renderInput={(params) => ( + + + + : undefined, + }} + /> + )} + onChange={(_e, value) => selectValue(row, value)} + value={(mapping.hasOwnProperty(row) && mapping[row]) || null} + inputValue={inputValue} + isOptionEqualToValue={(option, value) => + option.term_localName === value.term_localName + } + onInputChange={(_e, newInputValue) => { + setInputValue(newInputValue); + }} + loading={isLoading} + size="small" + renderOption={(props, option) => ( +
  • + + {option.label} +
  • + )} + /> +
    +
    + {columnData && ( + + + + + {t("dataHeader")} + {columnData.map((item, i) => ( + + {item} + + ))} + + + + )} + + ); +}; + +const InfoLink = ({ url, margin }: { url: string; margin?: boolean }) => { + const { t } = useTranslation("steps"); + + return ( + + + + + + ); +}; diff --git a/packages/file-mapper/src/features/Steps.tsx b/packages/file-mapper/src/features/Steps.tsx index 8447d821..ae488221 100644 --- a/packages/file-mapper/src/features/Steps.tsx +++ b/packages/file-mapper/src/features/Steps.tsx @@ -1,30 +1,37 @@ -import type { ReactNode } from "react"; -import Box from "@mui/material/Box"; -import Typography from "@mui/material/Typography"; - -// some fake placeholder saves. todo. -export const saves = [ - { - name: "Fake save #1", - date: "8-8-2024", - id: "someUniqueId1", - }, - { - name: "Fake save #2", - date: "7-8-2024", - id: "someUniqueId2", - }, -]; - -// define max number of rows a file selected for processing can contain -export const maxRows = 10; - -// define steps -export const steps = ['selectFile', 'createMapping', 'finish']; - -// wrapper for individual steps -export const StepWrap = ({ title, children }: { title: string; children: ReactNode }) => - - {title} - {children} - \ No newline at end of file +import type { ReactNode } from "react"; +import Box from "@mui/material/Box"; +import Typography from "@mui/material/Typography"; + +// some fake placeholder saves. todo. +export const saves = [ + /*{ + name: "Fake save #1", + date: "8-8-2024", + id: "someUniqueId1", + }, + { + name: "Fake save #2", + date: "7-8-2024", + id: "someUniqueId2", + },*/ +]; + +// define max number of rows a file selected for processing can contain +export const maxRows = 10; + +// define steps +export const steps = ["selectFile", "createMapping" /*'finish'*/]; + +// wrapper for individual steps +export const StepWrap = ({ + title, + children, +}: { + title: string; + children: ReactNode; +}) => ( + + {title} + {children} + +); diff --git a/packages/file-mapper/src/features/fileMapperApi.ts b/packages/file-mapper/src/features/fileMapperApi.ts index 9ab6684d..9711d5e7 100644 --- a/packages/file-mapper/src/features/fileMapperApi.ts +++ b/packages/file-mapper/src/features/fileMapperApi.ts @@ -1,81 +1,88 @@ -import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; -import type { DarwinOptions } from "../types"; -import { getUser } from "@dans-framework/utils/user"; - -export const darwinCoreApi = createApi({ - reducerPath: "darwinCoreApi", - baseQuery: fetchBaseQuery({ baseUrl: "https://raw.githubusercontent.com/tdwg/rs.tdwg.org/master" }), - endpoints: (build) => ({ - fetchDarwinTerms: build.query({ - query: () => ({ - url: "terms/terms.csv", - responseHandler: (response) => response.text(), - }), - transformResponse: async (response, _meta, _arg) => { - // Dynamically import XLSX - const XLSX = await import("xlsx"); // Lazy load the library here - - // Convert CSV text string to JSON - const workbook = XLSX.read(response, { type: 'binary' }); - const sheetName = workbook.SheetNames[0]; - const sheet = workbook.Sheets[sheetName]; - const sheetData: DarwinOptions[] = XLSX.utils.sheet_to_json(sheet); - - const filteredData = sheetData - .filter(d => !d.term_deprecated) - .map(d => ({...d, header: d.tdwgutility_organizedInClass?.split('/').pop() || 'Dataset'})) - .sort((a, b) => a.header?.localeCompare(b.header)); - - return filteredData || []; - }, - transformErrorResponse: () => ({ - error: "Could not fetch terms", - }), - }), - }), -}); - -export const { useFetchDarwinTermsQuery } = darwinCoreApi; - -export const submitMappingApi = createApi({ - reducerPath: "submitMappingApi", - baseQuery: fetchBaseQuery({ - baseUrl: `${import.meta.env.VITE_MAPPER_URI}`, - }), - endpoints: (build) => ({ - submitMap: build.mutation({ - query: ({ savedMap, newMap, file }) => { - const user = getUser(); - // format headers - const headers = { - Authorization: `Bearer ${user?.access_token}`, - "auth-env-name": import.meta.env.VITE_ENV_NAME, - }; - - let formData = new FormData(); - formData.append("file", file); - formData.append("savedMap", savedMap); - formData.append("map", JSON.stringify(newMap)); - - console.log(`sending data:`) - console.log(formData.get('file')) - console.log(formData.get('savedMap')) - console.log(formData.get('map')) - - return ({ - url: 'mapper', - method: "POST", - headers: headers, - body: formData, - }); - }, - transformErrorResponse: () => { - return ({ - error: "Error connecting to server" - }); - }, - }), - }), -}); - -export const { useSubmitMapMutation } = submitMappingApi; +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; +import type { DarwinOptions } from "../types"; +import { getUser } from "@dans-framework/utils/user"; + +export const darwinCoreApi = createApi({ + reducerPath: "darwinCoreApi", + baseQuery: fetchBaseQuery({ + baseUrl: "https://raw.githubusercontent.com/tdwg/rs.tdwg.org/master", + }), + endpoints: (build) => ({ + fetchDarwinTerms: build.query({ + query: () => ({ + url: "terms/terms.csv", + responseHandler: (response) => response.text(), + }), + transformResponse: async (response, _meta, _arg) => { + // Dynamically import XLSX + const XLSX = await import("xlsx"); // Lazy load the library here + + // Convert CSV text string to JSON + const workbook = XLSX.read(response, { type: "binary" }); + const sheetName = workbook.SheetNames[0]; + const sheet = workbook.Sheets[sheetName]; + const sheetData: DarwinOptions[] = XLSX.utils.sheet_to_json(sheet); + + const filteredData = sheetData + .filter((d) => !d.term_deprecated) + .map((d) => ({ + ...d, + header: + d.tdwgutility_organizedInClass?.split("/").pop() || "Dataset", + url: `https://dwc.tdwg.org/list/#dwc_${d.term_localName}`, + })) + .sort((a, b) => a.header?.localeCompare(b.header)); + + return filteredData || []; + }, + transformErrorResponse: () => ({ + error: "Could not fetch terms", + }), + }), + }), +}); + +export const { useFetchDarwinTermsQuery } = darwinCoreApi; + +export const submitMappingApi = createApi({ + reducerPath: "submitMappingApi", + baseQuery: fetchBaseQuery({ + baseUrl: `${import.meta.env.VITE_MAPPER_URI}`, + }), + endpoints: (build) => ({ + submitMap: build.mutation({ + query: ({ savedMap, newMap, file }) => { + const user = getUser(); + // format headers + const headers = { + Authorization: `Bearer ${user?.access_token}`, + "auth-env-name": import.meta.env.VITE_ENV_NAME, + }; + + let formData = new FormData(); + formData.append("file", file); + formData.append("savedMap", savedMap); + formData.append("map", JSON.stringify(newMap)); + + console.log(`sending data:`); + console.log(formData.get("file")); + console.log(formData.get("savedMap")); + console.log(formData.get("map")); + + return { + url: "mapper", + method: "POST", + headers: headers, + body: formData, + }; + }, + transformErrorResponse: () => { + return { + error: "Error connecting to server", + }; + }, + }), + }), +}); + +export const { useSubmitMapMutation } = submitMappingApi; diff --git a/packages/file-mapper/src/features/fileMapperSlice.ts b/packages/file-mapper/src/features/fileMapperSlice.ts index 277bcfde..8d440dd5 100644 --- a/packages/file-mapper/src/features/fileMapperSlice.ts +++ b/packages/file-mapper/src/features/fileMapperSlice.ts @@ -1,82 +1,84 @@ -import { createSlice, type PayloadAction } from "@reduxjs/toolkit"; -import { RootState } from "../redux/store"; -import type { SerializedFile, Mapping, FileError, SheetData } from "../types"; -import type { FormConfig } from "@dans-framework/deposit"; - -const initialState: { - activeStep: number; - mapping: Mapping; - file: SerializedFile | undefined; - savedMap: string; - form: FormConfig | undefined; - fileError: string | undefined; - fileData: SheetData[] | undefined; -} = { - activeStep: 0, - mapping: {}, - file: undefined, - savedMap: '', - form: undefined, - fileError: undefined, - fileData: undefined, -}; - -export const fileMapperSlice = createSlice({ - name: "fileMapper", - initialState, - reducers: { - setActiveStep: (state, action: PayloadAction) => { - state.activeStep = action.payload; - }, - setMapping: (state, action: PayloadAction) => { - state.mapping = action.payload; - }, - resetMapping: (state) => { - state.mapping = initialState.mapping; - }, - setSavedMap: (state, action: PayloadAction) => { - state.savedMap = action.payload; - }, - setFile: (state, action: PayloadAction) => { - state.file = action.payload; - }, - saveData: (state, action) => { - state.form = action.payload; - }, - setFileData: (state, action: PayloadAction) => { - state.fileData = action.payload; - }, - resetFileData: (state) => { - state.fileData = initialState.fileData; - }, - setFileError: (state, action: PayloadAction) => { - state.fileError = action.payload; - }, - resetFileError: (state) => { - state.fileError = initialState.fileError; - }, - }, -}); - -export const { - setActiveStep, - setMapping, - resetMapping, - setSavedMap, - setFile, - saveData, - setFileData, - resetFileData, - setFileError, - resetFileError, -} = fileMapperSlice.actions; - -export const getActiveStep = (state: RootState) => state.fileMapper.activeStep; -export const getMapping = (state: RootState) => state.fileMapper.mapping; -export const getSavedMap = (state: RootState) => state.fileMapper.savedMap; -export const getFile = (state: RootState) => state.fileMapper.file; -export const getForm = (state: RootState) => state.fileMapper.form; -export const getFileData = (state: RootState) => state.fileMapper.fileData; -export const getFileError = (state: RootState) => state.fileMapper.fileError; - -export default fileMapperSlice.reducer; +import { createSlice, type PayloadAction } from "@reduxjs/toolkit"; +import { RootState } from "../redux/store"; +import type { SerializedFile, Mapping, FileError, SheetData } from "../types"; +import type { FormConfig } from "@dans-framework/deposit"; + +const initialState: { + activeStep: number; + mapping: Mapping; + file: SerializedFile | undefined; + savedMap: string; + form: FormConfig | undefined; + fileError: string | undefined; + fileData: SheetData[] | undefined; +} = { + activeStep: 0, + mapping: {}, + file: undefined, + savedMap: "", + form: undefined, + fileError: undefined, + fileData: undefined, +}; + +export const fileMapperSlice = createSlice({ + name: "fileMapper", + initialState, + reducers: { + setActiveStep: (state, action: PayloadAction) => { + state.activeStep = action.payload; + }, + setMapping: (state, action: PayloadAction) => { + state.mapping = action.payload; + }, + resetMapping: (state) => { + state.mapping = initialState.mapping; + }, + setSavedMap: (state, action: PayloadAction) => { + state.savedMap = action.payload; + }, + setFile: (state, action: PayloadAction) => { + state.file = action.payload; + }, + saveData: (state, action) => { + state.form = action.payload; + }, + setFileData: (state, action: PayloadAction) => { + state.fileData = action.payload; + }, + resetFileData: (state) => { + state.fileData = initialState.fileData; + }, + setFileError: (state, action: PayloadAction) => { + state.fileError = action.payload; + }, + resetFileError: (state) => { + state.fileError = initialState.fileError; + }, + reset: () => initialState, + }, +}); + +export const { + setActiveStep, + setMapping, + resetMapping, + setSavedMap, + setFile, + saveData, + setFileData, + resetFileData, + setFileError, + resetFileError, + reset, +} = fileMapperSlice.actions; + +export const getActiveStep = (state: RootState) => state.fileMapper.activeStep; +export const getMapping = (state: RootState) => state.fileMapper.mapping; +export const getSavedMap = (state: RootState) => state.fileMapper.savedMap; +export const getFile = (state: RootState) => state.fileMapper.file; +export const getForm = (state: RootState) => state.fileMapper.form; +export const getFileData = (state: RootState) => state.fileMapper.fileData; +export const getFileError = (state: RootState) => state.fileMapper.fileError; + +export default fileMapperSlice.reducer; diff --git a/packages/file-mapper/src/index.tsx b/packages/file-mapper/src/index.tsx index 4992c91f..ccebf8af 100644 --- a/packages/file-mapper/src/index.tsx +++ b/packages/file-mapper/src/index.tsx @@ -1,20 +1,31 @@ -import { type Dispatch, type SetStateAction } from "react"; -import { I18nextProvider } from "react-i18next"; -import i18nProvider from "./languages/i18n"; -import FileMapper from "./features/FileMapper"; -import { Provider as ReduxProvider } from "react-redux"; -import { store } from './redux/store'; -import type { Page } from "@dans-framework/pages"; -import type { FormConfig } from "@dans-framework/deposit"; - -export const MapWrapper = ({setMappedForm, page}: { - setMappedForm: Dispatch>; - page: Page; -}) => - - - - - - -export default MapWrapper; \ No newline at end of file +// import { type Dispatch, type SetStateAction } from "react"; +import { I18nextProvider } from "react-i18next"; +import i18nProvider from "./languages/i18n"; +import FileMapper from "./features/FileMapper"; +import { Provider as ReduxProvider } from "react-redux"; +import { store } from "./redux/store"; +import type { Page } from "@dans-framework/pages"; +import type { FormConfig } from "@dans-framework/deposit"; + +export const MapWrapper = ({ + config, + /*setMappedForm,*/ page, + depositPageSlug, +}: { + config: FormConfig; + // setMappedForm?: Dispatch>; + page: Page; + depositPageSlug?: string; +}) => ( + + + + + +); + +export default MapWrapper; diff --git a/packages/file-mapper/src/languages/i18n.ts b/packages/file-mapper/src/languages/i18n.ts index 3fc475e0..0e05e228 100644 --- a/packages/file-mapper/src/languages/i18n.ts +++ b/packages/file-mapper/src/languages/i18n.ts @@ -1,22 +1,22 @@ -import resourcesToBackend from "i18next-resources-to-backend"; -import { createInstance } from "i18next"; -import { initReactI18next } from "react-i18next"; - -const i18n = createInstance({ - fallbackLng: "en", - interpolation: { - escapeValue: false, // not needed for react as it escapes by default - }, -}); - -i18n - .use( - resourcesToBackend( - (language: string, namespace: string) => - import(`./locales/${language}/${namespace}.json`), - ), - ) - .use(initReactI18next) - .init(); - -export default i18n; +import resourcesToBackend from "i18next-resources-to-backend"; +import { createInstance } from "i18next"; +import { initReactI18next } from "react-i18next"; + +const i18n = createInstance({ + fallbackLng: "en", + interpolation: { + escapeValue: false, // not needed for react as it escapes by default + }, +}); + +i18n + .use( + resourcesToBackend( + (language: string, namespace: string) => + import(`./locales/${language}/${namespace}.json`), + ), + ) + .use(initReactI18next) + .init(); + +export default i18n; diff --git a/packages/file-mapper/src/languages/locales/en/steps.json b/packages/file-mapper/src/languages/locales/en/steps.json index ce1f5bd3..8fe35a4c 100644 --- a/packages/file-mapper/src/languages/locales/en/steps.json +++ b/packages/file-mapper/src/languages/locales/en/steps.json @@ -19,5 +19,6 @@ "saveMappingExtra": "You can save your mapping for future datasets for easy reference. Please enter a name below.", "isLoading": "Loading...", "tooManyRows": "Your data file contains too many rows to process using this tool. Make sure your file has less than {{max}} rows.", - "dataHeader": "Sheet data for this column" + "dataHeader": "Sheet data for this column", + "moreInfo": "Read more about this term" } \ No newline at end of file diff --git a/packages/file-mapper/src/languages/locales/nl/steps.json b/packages/file-mapper/src/languages/locales/nl/steps.json index fbac7560..3a720f46 100644 --- a/packages/file-mapper/src/languages/locales/nl/steps.json +++ b/packages/file-mapper/src/languages/locales/nl/steps.json @@ -19,5 +19,6 @@ "saveMappingExtra": "You can save your mapping for future datasets for easy reference. Please enter a name below.", "isLoading": "Loading...", "tooManyRows": "Je data file contains too many rows to process using this tool. Make sure your file has less than {{max}} rows.", - "dataHeader": "Sheet data for this column" + "dataHeader": "Sheet data for this column", + "moreInfo": "Read more about this term" } \ No newline at end of file diff --git a/packages/file-mapper/src/redux/hooks.ts b/packages/file-mapper/src/redux/hooks.ts index f0c6116f..36b5ea2f 100644 --- a/packages/file-mapper/src/redux/hooks.ts +++ b/packages/file-mapper/src/redux/hooks.ts @@ -1,6 +1,6 @@ -import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux"; -import type { RootState, AppDispatch } from "./store"; - -// Use throughout your app instead of plain `useDispatch` and `useSelector` -export const useAppDispatch = () => useDispatch(); -export const useAppSelector: TypedUseSelectorHook = useSelector; +import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux"; +import type { RootState, AppDispatch } from "./store"; + +// Use throughout your app instead of plain `useDispatch` and `useSelector` +export const useAppDispatch = () => useDispatch(); +export const useAppSelector: TypedUseSelectorHook = useSelector; diff --git a/packages/file-mapper/src/redux/store.ts b/packages/file-mapper/src/redux/store.ts index 0bcf2bcd..32e847ea 100644 --- a/packages/file-mapper/src/redux/store.ts +++ b/packages/file-mapper/src/redux/store.ts @@ -1,20 +1,20 @@ -import { configureStore } from "@reduxjs/toolkit"; -import { errorLogger } from "@dans-framework/utils/error"; -import fileMapperReducer from "../features/fileMapperSlice"; -import { darwinCoreApi, submitMappingApi } from "../features/fileMapperApi"; - -export const store = configureStore({ - reducer: { - fileMapper: fileMapperReducer, - [darwinCoreApi.reducerPath]: darwinCoreApi.reducer, - [submitMappingApi.reducerPath]: submitMappingApi.reducer, - }, - middleware: (getDefaultMiddleware) => - getDefaultMiddleware() - .concat(darwinCoreApi.middleware) - .concat(submitMappingApi.middleware) - .concat(errorLogger) -}); - -export type AppDispatch = typeof store.dispatch; -export type RootState = ReturnType; +import { configureStore } from "@reduxjs/toolkit"; +import { errorLogger } from "@dans-framework/utils/error"; +import fileMapperReducer from "../features/fileMapperSlice"; +import { darwinCoreApi, submitMappingApi } from "../features/fileMapperApi"; + +export const store = configureStore({ + reducer: { + fileMapper: fileMapperReducer, + [darwinCoreApi.reducerPath]: darwinCoreApi.reducer, + [submitMappingApi.reducerPath]: submitMappingApi.reducer, + }, + middleware: (getDefaultMiddleware) => + getDefaultMiddleware() + .concat(darwinCoreApi.middleware) + .concat(submitMappingApi.middleware) + .concat(errorLogger), +}); + +export type AppDispatch = typeof store.dispatch; +export type RootState = ReturnType; diff --git a/packages/file-mapper/src/types/index.ts b/packages/file-mapper/src/types/index.ts index d98b5218..8839f7e9 100644 --- a/packages/file-mapper/src/types/index.ts +++ b/packages/file-mapper/src/types/index.ts @@ -1,33 +1,35 @@ -export type DarwinTerms = - | "term_localName" - | "tdwgutility_organizedInClass" - | "label" - | "header" - | "term_deprecated"; - -export type DarwinOptions = { - [key in DarwinTerms]: string; -} - -export interface Mapping { - [key: string]: DarwinOptions; -} - -export interface Saves { - name: string; - date: string; - id: string; -} - -export interface SerializedFile { - name: string; - size: number; - url: string; -} - -export type FileError = - | "tooManyRows"; - -export interface SheetData { - [key: string]: string; -} \ No newline at end of file +export type DarwinTerms = + | "term_localName" + | "tdwgutility_organizedInClass" + | "label" + | "header" + | "term_deprecated" + | "term_isDefinedBy" + | "term_localName" + | "url"; + +export type DarwinOptions = { + [key in DarwinTerms]: string; +}; + +export interface Mapping { + [key: string]: DarwinOptions; +} + +export interface Saves { + name: string; + date: string; + id: string; +} + +export interface SerializedFile { + name: string; + size: number; + url: string; +} + +export type FileError = "tooManyRows"; + +export interface SheetData { + [key: string]: string; +} diff --git a/packages/layout/src/MenuBar.tsx b/packages/layout/src/MenuBar.tsx index 716dedd3..a820c474 100644 --- a/packages/layout/src/MenuBar.tsx +++ b/packages/layout/src/MenuBar.tsx @@ -91,7 +91,7 @@ const MenuBar = ({ {lookupLanguageString(page.menuTitle, i18n.language)} - ) + ), )} {lookupLanguageString(page.menuTitle, i18n.language)} - ) + ), )} diff --git a/packages/repo-advisor/lib/index.tsx b/packages/repo-advisor/lib/index.tsx index 12b97216..35415eb3 100644 --- a/packages/repo-advisor/lib/index.tsx +++ b/packages/repo-advisor/lib/index.tsx @@ -1,4 +1,3 @@ -export { default as RepoAdvisor } from "../src"; -export { default as i18n } from "../src/languages/i18n"; -export { RepoBar, NoRepoSelected } from "../src/features/Layout"; - +export { default as RepoAdvisor } from "../src"; +export { default as i18n } from "../src/languages/i18n"; +export { RepoBar, NoRepoSelected } from "../src/features/Layout"; diff --git a/packages/repo-advisor/src/features/Components.tsx b/packages/repo-advisor/src/features/Components.tsx index 1bf4a910..3e5583bc 100644 --- a/packages/repo-advisor/src/features/Components.tsx +++ b/packages/repo-advisor/src/features/Components.tsx @@ -1,167 +1,177 @@ -import { useState } from "react"; -import Stack from '@mui/material/Stack'; -import CircularProgress from '@mui/material/CircularProgress'; -import Box from '@mui/material/Box'; -import { useDebounce } from "use-debounce"; -import InputLabel from '@mui/material/InputLabel'; -import MenuItem from '@mui/material/MenuItem'; -import FormControl from '@mui/material/FormControl'; -import Select, { SelectChangeEvent } from '@mui/material/Select'; -import TextField from '@mui/material/TextField'; -import Autocomplete from '@mui/material/Autocomplete'; -import { useFetchRorByNameQuery, useFetchDatastationsTermQuery, type OptionsType, type QueryReturnType } from "@dans-framework/deposit"; -import { useTranslation } from "react-i18next"; -import { useAppSelector, useAppDispatch } from "../redux/hooks"; -import { getRor, getNarcis, setRor, setNarcis } from "./repoAdvisorSlice"; -import type { AutocompleteProps } from "../types"; - -type Option = { - value: string; - label: string; -}; - -export const SelectField = ({label, value, onChange, options, disabled}: { - label: string; - value: string; - onChange: (val: string) => void; - options: Option[]; - disabled?: boolean; -}) => - - - {label} - - - - -// Derived from the API field in the Deposit package -export const RorField = () => { - const { t } = useTranslation("steps"); - const dispatch = useAppDispatch(); - const [inputValue, setInputValue] = useState(""); - const debouncedInputValue = useDebounce(inputValue, 500)[0]; - // Fetch data on input change - const { data, isFetching, isLoading } = - useFetchRorByNameQuery(debouncedInputValue, { - skip: debouncedInputValue === "", - }); - const value = useAppSelector(getRor); - - return ( - dispatch(setRor(v))} - value={value} - /> - ); -}; - -export const NarcisField = () => { - const { t, i18n } = useTranslation("steps"); - const dispatch = useAppDispatch(); - const [inputValue, setInputValue] = useState(""); - const debouncedInputValue = useDebounce(inputValue, 500)[0]; - // Fetch data on input change - const { data, isFetching, isLoading } = - useFetchDatastationsTermQuery( - { - vocabulary: "narcis", - lang: i18n.language, - query: debouncedInputValue, - }, - { skip: debouncedInputValue === "" }, - ); - const value = useAppSelector(getNarcis); - - return ( - dispatch(setNarcis(v))} - value={value} - /> - ); -}; - -const ApiField = ({ - inputValue, - setInputValue, - debouncedInputValue, - data, - isLoading, - isFetching, - label, - setValue, - value, - disabled, -}: AutocompleteProps ) => { - const { t } = useTranslation("steps"); - - return ( - - ( - - )} - onChange={(_e, newValue, _reason) => setValue(newValue as OptionsType)} - filterOptions={(x) => x} - onInputChange={(e, newValue) => { - e && e.type === "change" && setInputValue(newValue); - e && (e.type === "click" || e.type === "blur") && setInputValue(""); - }} - noOptionsText={!inputValue ? t("startTyping") : t("noResults")} - loading={isLoading || isFetching || inputValue !== debouncedInputValue} - loadingText={ - - {t("isLoading")} - - } - forcePopupIcon - // isOptionEqualToValue={(option, value) => option.value === value.value} - clearOnBlur - disabled={disabled} - /> - - ); -}; +import { useState } from "react"; +import Stack from "@mui/material/Stack"; +import CircularProgress from "@mui/material/CircularProgress"; +import Box from "@mui/material/Box"; +import { useDebounce } from "use-debounce"; +import InputLabel from "@mui/material/InputLabel"; +import MenuItem from "@mui/material/MenuItem"; +import FormControl from "@mui/material/FormControl"; +import Select, { SelectChangeEvent } from "@mui/material/Select"; +import TextField from "@mui/material/TextField"; +import Autocomplete from "@mui/material/Autocomplete"; +import { + useFetchRorByNameQuery, + useFetchDatastationsTermQuery, + type OptionsType, + type QueryReturnType, +} from "@dans-framework/deposit"; +import { useTranslation } from "react-i18next"; +import { useAppSelector, useAppDispatch } from "../redux/hooks"; +import { getRor, getNarcis, setRor, setNarcis } from "./repoAdvisorSlice"; +import type { AutocompleteProps } from "../types"; + +type Option = { + value: string; + label: string; +}; + +export const SelectField = ({ + label, + value, + onChange, + options, + disabled, +}: { + label: string; + value: string; + onChange: (val: string) => void; + options: Option[]; + disabled?: boolean; +}) => ( + + + {label} + + + +); + +// Derived from the API field in the Deposit package +export const RorField = () => { + const { t } = useTranslation("steps"); + const dispatch = useAppDispatch(); + const [inputValue, setInputValue] = useState(""); + const debouncedInputValue = useDebounce(inputValue, 500)[0]; + // Fetch data on input change + const { data, isFetching, isLoading } = + useFetchRorByNameQuery(debouncedInputValue, { + skip: debouncedInputValue === "", + }); + const value = useAppSelector(getRor); + + return ( + dispatch(setRor(v))} + value={value} + /> + ); +}; + +export const NarcisField = () => { + const { t, i18n } = useTranslation("steps"); + const dispatch = useAppDispatch(); + const [inputValue, setInputValue] = useState(""); + const debouncedInputValue = useDebounce(inputValue, 500)[0]; + // Fetch data on input change + const { data, isFetching, isLoading } = + useFetchDatastationsTermQuery( + { + vocabulary: "narcis", + lang: i18n.language, + query: debouncedInputValue, + }, + { skip: debouncedInputValue === "" }, + ); + const value = useAppSelector(getNarcis); + + return ( + dispatch(setNarcis(v))} + value={value} + /> + ); +}; + +const ApiField = ({ + inputValue, + setInputValue, + debouncedInputValue, + data, + isLoading, + isFetching, + label, + setValue, + value, + disabled, +}: AutocompleteProps) => { + const { t } = useTranslation("steps"); + + return ( + + ( + + )} + onChange={(_e, newValue, _reason) => setValue(newValue as OptionsType)} + filterOptions={(x) => x} + onInputChange={(e, newValue) => { + e && e.type === "change" && setInputValue(newValue); + e && (e.type === "click" || e.type === "blur") && setInputValue(""); + }} + noOptionsText={!inputValue ? t("startTyping") : t("noResults")} + loading={isLoading || isFetching || inputValue !== debouncedInputValue} + loadingText={ + + {t("isLoading")} + + } + forcePopupIcon + // isOptionEqualToValue={(option, value) => option.value === value.value} + clearOnBlur + disabled={disabled} + /> + + ); +}; diff --git a/packages/repo-advisor/src/features/Layout.tsx b/packages/repo-advisor/src/features/Layout.tsx index b5869086..abc10915 100644 --- a/packages/repo-advisor/src/features/Layout.tsx +++ b/packages/repo-advisor/src/features/Layout.tsx @@ -1,58 +1,72 @@ -import Container from "@mui/material/Container"; -import Box from "@mui/material/Box"; -import Grid from "@mui/material/Unstable_Grid2"; -import Typography from "@mui/material/Typography"; -import { lookupLanguageString, type LanguageStrings } from "@dans-framework/utils/language"; -import { I18nextProvider, useTranslation, Trans } from "react-i18next"; -import Link from '@mui/material/Link'; -import { Link as RouterLink } from "react-router-dom"; -import i18n from "../languages/i18n"; - -export const RepoBar = ({repo}: {repo?: LanguageStrings | string}) => - - - - -const RepoBarInner = ({repo}: {repo?: LanguageStrings | string}) => { - const { i18n, t } = useTranslation("repobar"); - return ( - - - - - - {t("activeRepo", { repo: lookupLanguageString(repo, i18n.language) })} - - - - - - ); -} - -export const NoRepoSelected = ({advisorLocation}: {advisorLocation: string}) => - - - - -const NoRepoSelectedInner = ({advisorLocation}: {advisorLocation: string}) => { - const { t } = useTranslation("repobar"); - return ( - - - - {t("selectRepoFirst")} - - , - ]} - /> - - - - - ); -} - +import Container from "@mui/material/Container"; +import Box from "@mui/material/Box"; +import Grid from "@mui/material/Unstable_Grid2"; +import Typography from "@mui/material/Typography"; +import { + lookupLanguageString, + type LanguageStrings, +} from "@dans-framework/utils/language"; +import { I18nextProvider, useTranslation, Trans } from "react-i18next"; +import Link from "@mui/material/Link"; +import { Link as RouterLink } from "react-router-dom"; +import i18n from "../languages/i18n"; + +export const RepoBar = ({ repo }: { repo?: LanguageStrings | string }) => ( + + + +); + +const RepoBarInner = ({ repo }: { repo?: LanguageStrings | string }) => { + const { i18n, t } = useTranslation("repobar"); + return ( + + + + + + {t("activeRepo", { + repo: lookupLanguageString(repo, i18n.language), + })} + + + + + + ); +}; + +export const NoRepoSelected = ({ + advisorLocation, +}: { + advisorLocation: string; +}) => ( + + + +); + +const NoRepoSelectedInner = ({ + advisorLocation, +}: { + advisorLocation: string; +}) => { + const { t } = useTranslation("repobar"); + return ( + + + + {t("selectRepoFirst")} + + , + ]} + /> + + + + + ); +}; diff --git a/packages/repo-advisor/src/features/RepoAdvisor.tsx b/packages/repo-advisor/src/features/RepoAdvisor.tsx index c3e67dd8..15e57ceb 100644 --- a/packages/repo-advisor/src/features/RepoAdvisor.tsx +++ b/packages/repo-advisor/src/features/RepoAdvisor.tsx @@ -1,124 +1,128 @@ -import { useEffect, type Dispatch, type SetStateAction } from "react"; -import { useNavigate } from "react-router-dom"; -import Paper from '@mui/material/Paper'; -import Box from '@mui/material/Box'; -import Button from '@mui/material/Button'; -import Grid from "@mui/material/Unstable_Grid2"; -import Container from "@mui/material/Container"; -import Stepper from '@mui/material/Stepper'; -import Step from '@mui/material/Step'; -import StepLabel from '@mui/material/StepLabel'; -import { useTranslation } from "react-i18next"; -import { useAppSelector, useAppDispatch } from "../redux/hooks"; -import { getActiveStep, getRor, getNarcis, getFileType, getDepositType, setActiveStep, getRepo } from './repoAdvisorSlice'; -import { Step1, Step2 } from './Steps'; -import { useSiteTitle, setSiteTitle } from "@dans-framework/utils/sitetitle"; -import { lookupLanguageString } from "@dans-framework/utils/language"; -import type { Page } from "@dans-framework/pages"; -import type { FormConfig } from "@dans-framework/deposit"; - -const steps = ['defineDataset', 'recommendations']; - -const RepoAdvisor = ({setRepoConfig, page, depositLocation}: { - setRepoConfig: Dispatch>; - page: Page; - depositLocation: string; -}) => { - const dispatch = useAppDispatch(); - const siteTitle = useSiteTitle(); - const ror = useAppSelector(getRor); - const narcis = useAppSelector(getNarcis); - const fileType = useAppSelector(getFileType); - const depositType = useAppSelector(getDepositType); - const repo = useAppSelector(getRepo); - const navigate = useNavigate(); - const activeStep = useAppSelector(getActiveStep); - const { t, i18n } = useTranslation('steps'); - - // set page title - useEffect(() => { - setSiteTitle(siteTitle, lookupLanguageString(page.name, i18n.language)); - }, [siteTitle, page.name]); - - const handleNext = () => { - if (activeStep !== steps.length - 1) { - dispatch(setActiveStep(activeStep + 1)); - } - else if (repo && repo.external) { - window.location.href = repo.external; - } - else { - setRepoConfig(repo); - navigate(depositLocation); - window.scrollTo({top: 0, behavior: "smooth"}); - } - }; - - const handleBack = () => { - dispatch(setActiveStep(activeStep - 1)); - }; - - const dataMissing = - !ror || - !narcis || - !depositType || - (depositType === 'dataset' && !fileType); - - return ( - - - - - - {steps.map((label) => { - const stepProps: { completed?: boolean } = {}; - return ( - - {t(label)} - - ); - })} - - { - activeStep === 0 - ? - : - } - - - - - - - - - - ); -}; - -export default RepoAdvisor; +import { useEffect, type Dispatch, type SetStateAction } from "react"; +import { useNavigate } from "react-router-dom"; +import Paper from "@mui/material/Paper"; +import Box from "@mui/material/Box"; +import Button from "@mui/material/Button"; +import Grid from "@mui/material/Unstable_Grid2"; +import Container from "@mui/material/Container"; +import Stepper from "@mui/material/Stepper"; +import Step from "@mui/material/Step"; +import StepLabel from "@mui/material/StepLabel"; +import { useTranslation } from "react-i18next"; +import { useAppSelector, useAppDispatch } from "../redux/hooks"; +import { + getActiveStep, + getRor, + getNarcis, + getFileType, + getDepositType, + setActiveStep, + getRepo, +} from "./repoAdvisorSlice"; +import { Step1, Step2 } from "./Steps"; +import { useSiteTitle, setSiteTitle } from "@dans-framework/utils/sitetitle"; +import { lookupLanguageString } from "@dans-framework/utils/language"; +import type { Page } from "@dans-framework/pages"; +import type { FormConfig } from "@dans-framework/deposit"; + +const steps = ["defineDataset", "recommendations"]; + +const RepoAdvisor = ({ + setRepoConfig, + page, + depositLocation, +}: { + setRepoConfig: Dispatch>; + page: Page; + depositLocation: string; +}) => { + const dispatch = useAppDispatch(); + const siteTitle = useSiteTitle(); + const ror = useAppSelector(getRor); + const narcis = useAppSelector(getNarcis); + const fileType = useAppSelector(getFileType); + const depositType = useAppSelector(getDepositType); + const repo = useAppSelector(getRepo); + const navigate = useNavigate(); + const activeStep = useAppSelector(getActiveStep); + const { t, i18n } = useTranslation("steps"); + + // set page title + useEffect(() => { + setSiteTitle(siteTitle, lookupLanguageString(page.name, i18n.language)); + }, [siteTitle, page.name]); + + const handleNext = () => { + if (activeStep !== steps.length - 1) { + dispatch(setActiveStep(activeStep + 1)); + } else if (repo && repo.external) { + window.location.href = repo.external; + } else { + setRepoConfig(repo); + navigate(depositLocation); + window.scrollTo({ top: 0, behavior: "smooth" }); + } + }; + + const handleBack = () => { + dispatch(setActiveStep(activeStep - 1)); + }; + + const dataMissing = + !ror || !narcis || !depositType || (depositType === "dataset" && !fileType); + + return ( + + + + + + {steps.map((label) => { + const stepProps: { completed?: boolean } = {}; + return ( + + {t(label)} + + ); + })} + + {activeStep === 0 ? + + : } + + + + + + + + + + ); +}; + +export default RepoAdvisor; diff --git a/packages/repo-advisor/src/features/Steps.tsx b/packages/repo-advisor/src/features/Steps.tsx index 3d628eeb..5b9302d2 100644 --- a/packages/repo-advisor/src/features/Steps.tsx +++ b/packages/repo-advisor/src/features/Steps.tsx @@ -1,156 +1,199 @@ -import { type ReactNode } from "react"; -import Box from "@mui/material/Box"; -import Typography from "@mui/material/Typography"; -import { useTranslation } from "react-i18next"; -import CircularProgress from '@mui/material/CircularProgress'; -import List from '@mui/material/List'; -import ListItem from '@mui/material/ListItem'; -import ListItemButton from '@mui/material/ListItemButton'; -import ListItemText from '@mui/material/ListItemText'; -import ListItemIcon from '@mui/material/ListItemIcon'; -import Checkbox from '@mui/material/Checkbox'; -import Alert from '@mui/material/Alert'; -import Button from '@mui/material/Button'; -import { useAppSelector, useAppDispatch } from "../redux/hooks"; -import { getRor, getNarcis, getDepositType, getFileType, setFileType, setDepositType, getRepo, setRepo } from "./repoAdvisorSlice"; -import { useFetchDataQuery } from "./repoAdvisorApi"; -import { RorField, NarcisField, SelectField } from "./Components"; -import { AnimatePresence, motion } from "framer-motion"; -import { lookupLanguageString, type LanguageStrings } from "@dans-framework/utils/language"; -import type { FormConfig } from "@dans-framework/deposit"; - -const StepWrap = ({ title, children, subtitle }: { title: string; children: ReactNode, subtitle?: string; }) => - - {title} - {subtitle && {subtitle}} - {children} - - -export const Step1 = () => { - const { t } = useTranslation("steps"); - const depositType = useAppSelector(getDepositType); - const fileType = useAppSelector(getFileType); - const dispatch = useAppDispatch(); - - return ( - - - - dispatch(setDepositType(value))} - options={[ - {label: t("dataset"), value: "dataset"}, - {label: t("code"), value: "code"}, - {label: t("report"), value: "report"}, - {label: t("publication"), value: "publication"}, - ]} - /> - - {depositType === 'dataset' && - - dispatch(setFileType(value))} - options={[ - {label: t("audiovisual_materials"), value: "audiovisual_materials"}, - {label: t("statistical_data"), value: "statistical_data"}, - {label: t("geospatial_data_files"), value: "geospatial_data_files"}, - {label: t("netcdf_and_hdf_files"), value: "netcdf_and_hdf_files"}, - {label: t("darwin_core_and_ecological_markup_language_files"), value: "darwin_core_and_ecological_markup_language_files"}, - {label: t("other"), value: "other"}, - ]} - /> - - } - - - ) -} - -export const Step2 = () => { - const { t, i18n } = useTranslation("steps"); - const ror = useAppSelector(getRor); - const narcis = useAppSelector(getNarcis); - const depositType = useAppSelector(getDepositType); - const fileType = useAppSelector(getFileType); - const repo = useAppSelector(getRepo); - const dispatch = useAppDispatch(); - - const { data, isLoading, isError, refetch } = useFetchDataQuery<{ - data: FormConfig[]; - isLoading: boolean; - isError: boolean; - refetch: () => void; - }>({ - ror: ror, - narcis: narcis, - depositType: depositType, - fileType: fileType, - }); - - return ( - - {data && data.length > 0 ? - - {data.map( (rec, i) => - - dispatch(setRepo(rec))} dense> - - - - - {rec.external && - {t("externalRepo")} - } - {lookupLanguageString(rec.description, i18n.language)} - - } - sx={{pr: 6}} - /> - - - )} - - : isLoading ? - - : isError ? - - {t("fetchError")} - - - : - {t("noRepoFound")} - } - - ) -} \ No newline at end of file +import { type ReactNode } from "react"; +import Box from "@mui/material/Box"; +import Typography from "@mui/material/Typography"; +import { useTranslation } from "react-i18next"; +import CircularProgress from "@mui/material/CircularProgress"; +import List from "@mui/material/List"; +import ListItem from "@mui/material/ListItem"; +import ListItemButton from "@mui/material/ListItemButton"; +import ListItemText from "@mui/material/ListItemText"; +import ListItemIcon from "@mui/material/ListItemIcon"; +import Checkbox from "@mui/material/Checkbox"; +import Alert from "@mui/material/Alert"; +import Button from "@mui/material/Button"; +import { useAppSelector, useAppDispatch } from "../redux/hooks"; +import { + getRor, + getNarcis, + getDepositType, + getFileType, + setFileType, + setDepositType, + getRepo, + setRepo, +} from "./repoAdvisorSlice"; +import { useFetchDataQuery } from "./repoAdvisorApi"; +import { RorField, NarcisField, SelectField } from "./Components"; +import { AnimatePresence, motion } from "framer-motion"; +import { + lookupLanguageString, + type LanguageStrings, +} from "@dans-framework/utils/language"; +import type { FormConfig } from "@dans-framework/deposit"; + +const StepWrap = ({ + title, + children, + subtitle, +}: { + title: string; + children: ReactNode; + subtitle?: string; +}) => ( + + {title} + {subtitle && ( + + {subtitle} + + )} + {children} + +); + +export const Step1 = () => { + const { t } = useTranslation("steps"); + const depositType = useAppSelector(getDepositType); + const fileType = useAppSelector(getFileType); + const dispatch = useAppDispatch(); + + return ( + + + + dispatch(setDepositType(value))} + options={[ + { label: t("dataset"), value: "dataset" }, + { label: t("code"), value: "code" }, + { label: t("report"), value: "report" }, + { label: t("publication"), value: "publication" }, + ]} + /> + + {depositType === "dataset" && ( + + dispatch(setFileType(value))} + options={[ + { + label: t("audiovisual_materials"), + value: "audiovisual_materials", + }, + { label: t("statistical_data"), value: "statistical_data" }, + { + label: t("geospatial_data_files"), + value: "geospatial_data_files", + }, + { + label: t("netcdf_and_hdf_files"), + value: "netcdf_and_hdf_files", + }, + { + label: t("darwin_core_and_ecological_markup_language_files"), + value: "darwin_core_and_ecological_markup_language_files", + }, + { label: t("other"), value: "other" }, + ]} + /> + + )} + + + ); +}; + +export const Step2 = () => { + const { t, i18n } = useTranslation("steps"); + const ror = useAppSelector(getRor); + const narcis = useAppSelector(getNarcis); + const depositType = useAppSelector(getDepositType); + const fileType = useAppSelector(getFileType); + const repo = useAppSelector(getRepo); + const dispatch = useAppDispatch(); + + const { data, isLoading, isError, refetch } = useFetchDataQuery<{ + data: FormConfig[]; + isLoading: boolean; + isError: boolean; + refetch: () => void; + }>({ + ror: ror, + narcis: narcis, + depositType: depositType, + fileType: fileType, + }); + + return ( + + {data && data.length > 0 ? + + {data.map((rec, i) => ( + + dispatch(setRepo(rec))} + dense + > + + + + + {rec.external && ( + + {t("externalRepo")} + + )} + {lookupLanguageString(rec.description, i18n.language)} + + } + sx={{ pr: 6 }} + /> + + + ))} + + : isLoading ? + + : isError ? + + {t("fetchError")} + + + : {t("noRepoFound")}} + + ); +}; diff --git a/packages/repo-advisor/src/features/repoAdvisorApi.ts b/packages/repo-advisor/src/features/repoAdvisorApi.ts index 7a584199..ac4006ae 100644 --- a/packages/repo-advisor/src/features/repoAdvisorApi.ts +++ b/packages/repo-advisor/src/features/repoAdvisorApi.ts @@ -1,42 +1,42 @@ -import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; -import { getUser } from "@dans-framework/utils/user"; -import type { RepoResponse } from "../types"; - -export const repoAdvisorApi = createApi({ - reducerPath: "repoAdvisorApi", - baseQuery: fetchBaseQuery({ - baseUrl: import.meta.env.VITE_ADVISOR_URL, - }), - endpoints: (build) => ({ - fetchData: build.query({ - query: ({ ror, narcis, depositType, fileType }) => { - const user = getUser(); - const headers = { - "Content-Type": "application/json", - Authorization: `Bearer ${user?.access_token}`, - "auth-env-name": import.meta.env.VITE_ENV_NAME, - }; - - return ({ - url: 'seek-advice', - method: "POST", - headers: headers, - body: JSON.stringify({ - affiliation: ror.value, - domain: narcis.value, - "deposit-type": depositType, - ...(fileType && { "file-type": fileType }), - }), - }); - }, - transformResponse: (response: RepoResponse) => response.advice, - transformErrorResponse: () => { - return ({ - error: "Error connecting to server" - }); - }, - }), - }), -}); - -export const { useFetchDataQuery } = repoAdvisorApi; \ No newline at end of file +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; +import { getUser } from "@dans-framework/utils/user"; +import type { RepoResponse } from "../types"; + +export const repoAdvisorApi = createApi({ + reducerPath: "repoAdvisorApi", + baseQuery: fetchBaseQuery({ + baseUrl: import.meta.env.VITE_ADVISOR_URL, + }), + endpoints: (build) => ({ + fetchData: build.query({ + query: ({ ror, narcis, depositType, fileType }) => { + const user = getUser(); + const headers = { + "Content-Type": "application/json", + Authorization: `Bearer ${user?.access_token}`, + "auth-env-name": import.meta.env.VITE_ENV_NAME, + }; + + return { + url: "seek-advice", + method: "POST", + headers: headers, + body: JSON.stringify({ + affiliation: ror.value, + domain: narcis.value, + "deposit-type": depositType, + ...(fileType && { "file-type": fileType }), + }), + }; + }, + transformResponse: (response: RepoResponse) => response.advice, + transformErrorResponse: () => { + return { + error: "Error connecting to server", + }; + }, + }), + }), +}); + +export const { useFetchDataQuery } = repoAdvisorApi; diff --git a/packages/repo-advisor/src/features/repoAdvisorSlice.ts b/packages/repo-advisor/src/features/repoAdvisorSlice.ts index b0b4078b..588a2e66 100644 --- a/packages/repo-advisor/src/features/repoAdvisorSlice.ts +++ b/packages/repo-advisor/src/features/repoAdvisorSlice.ts @@ -1,55 +1,63 @@ -import { createSlice, type PayloadAction } from "@reduxjs/toolkit"; -import { RootState } from "../redux/store"; -import type { OptionsType, FormConfig } from "@dans-framework/deposit"; - -const initialState: { - activeStep: number; - ror: OptionsType | null; - narcis: OptionsType | null; - depositType: string; - fileType: string; - repo: FormConfig | undefined; -} = { - activeStep: 0, - ror: null, - narcis: null, - depositType: '', - fileType: '', - repo: undefined, -}; - -export const repoAdvisorSlice = createSlice({ - name: "repoAdvisor", - initialState, - reducers: { - setActiveStep: (state, action: PayloadAction) => { - state.activeStep = action.payload; - }, - setRor: (state, action: PayloadAction) => { - state.ror = action.payload; - }, - setNarcis: (state, action: PayloadAction) => { - state.narcis = action.payload; - }, - setDepositType: (state, action: PayloadAction) => { - state.depositType = action.payload; - }, - setFileType: (state, action: PayloadAction) => { - state.fileType = action.payload; - }, - setRepo: (state, action: PayloadAction) => { - state.repo = action.payload; - } - }, -}); - -export const { setActiveStep, setRor, setNarcis, setFileType, setDepositType, setRepo } = repoAdvisorSlice.actions; - -export const getActiveStep = (state: RootState) => state.repoAdvisor.activeStep; -export const getRor = (state: RootState) => state.repoAdvisor.ror; -export const getNarcis = (state: RootState) => state.repoAdvisor.narcis; -export const getDepositType = (state: RootState) => state.repoAdvisor.depositType; -export const getFileType = (state: RootState) => state.repoAdvisor.fileType; -export const getRepo = (state: RootState) => state.repoAdvisor.repo; - -export default repoAdvisorSlice.reducer; +import { createSlice, type PayloadAction } from "@reduxjs/toolkit"; +import { RootState } from "../redux/store"; +import type { OptionsType, FormConfig } from "@dans-framework/deposit"; + +const initialState: { + activeStep: number; + ror: OptionsType | null; + narcis: OptionsType | null; + depositType: string; + fileType: string; + repo: FormConfig | undefined; +} = { + activeStep: 0, + ror: null, + narcis: null, + depositType: "", + fileType: "", + repo: undefined, +}; + +export const repoAdvisorSlice = createSlice({ + name: "repoAdvisor", + initialState, + reducers: { + setActiveStep: (state, action: PayloadAction) => { + state.activeStep = action.payload; + }, + setRor: (state, action: PayloadAction) => { + state.ror = action.payload; + }, + setNarcis: (state, action: PayloadAction) => { + state.narcis = action.payload; + }, + setDepositType: (state, action: PayloadAction) => { + state.depositType = action.payload; + }, + setFileType: (state, action: PayloadAction) => { + state.fileType = action.payload; + }, + setRepo: (state, action: PayloadAction) => { + state.repo = action.payload; + }, + }, +}); + +export const { + setActiveStep, + setRor, + setNarcis, + setFileType, + setDepositType, + setRepo, +} = repoAdvisorSlice.actions; + +export const getActiveStep = (state: RootState) => state.repoAdvisor.activeStep; +export const getRor = (state: RootState) => state.repoAdvisor.ror; +export const getNarcis = (state: RootState) => state.repoAdvisor.narcis; +export const getDepositType = (state: RootState) => + state.repoAdvisor.depositType; +export const getFileType = (state: RootState) => state.repoAdvisor.fileType; +export const getRepo = (state: RootState) => state.repoAdvisor.repo; + +export default repoAdvisorSlice.reducer; diff --git a/packages/repo-advisor/src/index.tsx b/packages/repo-advisor/src/index.tsx index d0a036b9..98dcf742 100644 --- a/packages/repo-advisor/src/index.tsx +++ b/packages/repo-advisor/src/index.tsx @@ -1,21 +1,30 @@ -import type { Dispatch, SetStateAction } from "react"; -import { I18nextProvider } from "react-i18next"; -import i18nProvider from "./languages/i18n"; -import RepoAdvisor from "./features/RepoAdvisor"; -import { Provider as ReduxProvider } from "react-redux"; -import { store } from './redux/store'; -import type { Page } from "@dans-framework/pages"; -import type { FormConfig } from "@dans-framework/deposit"; - -export const AdvisorWrapper = ({setRepoConfig, page, depositLocation}: { - setRepoConfig: Dispatch>; - page: Page; - depositLocation: string; -}) => - - - - - - -export default AdvisorWrapper; \ No newline at end of file +import type { Dispatch, SetStateAction } from "react"; +import { I18nextProvider } from "react-i18next"; +import i18nProvider from "./languages/i18n"; +import RepoAdvisor from "./features/RepoAdvisor"; +import { Provider as ReduxProvider } from "react-redux"; +import { store } from "./redux/store"; +import type { Page } from "@dans-framework/pages"; +import type { FormConfig } from "@dans-framework/deposit"; + +export const AdvisorWrapper = ({ + setRepoConfig, + page, + depositLocation, +}: { + setRepoConfig: Dispatch>; + page: Page; + depositLocation: string; +}) => ( + + + + + +); + +export default AdvisorWrapper; diff --git a/packages/repo-advisor/src/languages/i18n.ts b/packages/repo-advisor/src/languages/i18n.ts index 3fc475e0..0e05e228 100644 --- a/packages/repo-advisor/src/languages/i18n.ts +++ b/packages/repo-advisor/src/languages/i18n.ts @@ -1,22 +1,22 @@ -import resourcesToBackend from "i18next-resources-to-backend"; -import { createInstance } from "i18next"; -import { initReactI18next } from "react-i18next"; - -const i18n = createInstance({ - fallbackLng: "en", - interpolation: { - escapeValue: false, // not needed for react as it escapes by default - }, -}); - -i18n - .use( - resourcesToBackend( - (language: string, namespace: string) => - import(`./locales/${language}/${namespace}.json`), - ), - ) - .use(initReactI18next) - .init(); - -export default i18n; +import resourcesToBackend from "i18next-resources-to-backend"; +import { createInstance } from "i18next"; +import { initReactI18next } from "react-i18next"; + +const i18n = createInstance({ + fallbackLng: "en", + interpolation: { + escapeValue: false, // not needed for react as it escapes by default + }, +}); + +i18n + .use( + resourcesToBackend( + (language: string, namespace: string) => + import(`./locales/${language}/${namespace}.json`), + ), + ) + .use(initReactI18next) + .init(); + +export default i18n; diff --git a/packages/repo-advisor/src/redux/hooks.ts b/packages/repo-advisor/src/redux/hooks.ts index d0ceb8b7..36b5ea2f 100644 --- a/packages/repo-advisor/src/redux/hooks.ts +++ b/packages/repo-advisor/src/redux/hooks.ts @@ -1,6 +1,6 @@ -import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux"; -import type { RootState, AppDispatch } from "./store"; - -// Use throughout your app instead of plain `useDispatch` and `useSelector` -export const useAppDispatch = () => useDispatch(); -export const useAppSelector: TypedUseSelectorHook = useSelector; \ No newline at end of file +import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux"; +import type { RootState, AppDispatch } from "./store"; + +// Use throughout your app instead of plain `useDispatch` and `useSelector` +export const useAppDispatch = () => useDispatch(); +export const useAppSelector: TypedUseSelectorHook = useSelector; diff --git a/packages/repo-advisor/src/redux/store.ts b/packages/repo-advisor/src/redux/store.ts index 7c634da7..908ee134 100644 --- a/packages/repo-advisor/src/redux/store.ts +++ b/packages/repo-advisor/src/redux/store.ts @@ -1,23 +1,23 @@ -import { configureStore } from "@reduxjs/toolkit"; -import { errorLogger } from "@dans-framework/utils/error"; -import repoAdvisorReducer from "../features/repoAdvisorSlice"; -import { repoAdvisorApi } from "../features/repoAdvisorApi"; -import { datastationsApi, rorApi } from "@dans-framework/deposit"; - -export const store = configureStore({ - reducer: { - repoAdvisor: repoAdvisorReducer, - [repoAdvisorApi.reducerPath]: repoAdvisorApi.reducer, - [datastationsApi.reducerPath]: datastationsApi.reducer, - [rorApi.reducerPath]: rorApi.reducer, - }, - middleware: (getDefaultMiddleware) => - getDefaultMiddleware() - .concat(repoAdvisorApi.middleware) - .concat(datastationsApi.middleware) - .concat(rorApi.middleware) - .concat(errorLogger) -}); - -export type AppDispatch = typeof store.dispatch; -export type RootState = ReturnType; +import { configureStore } from "@reduxjs/toolkit"; +import { errorLogger } from "@dans-framework/utils/error"; +import repoAdvisorReducer from "../features/repoAdvisorSlice"; +import { repoAdvisorApi } from "../features/repoAdvisorApi"; +import { datastationsApi, rorApi } from "@dans-framework/deposit"; + +export const store = configureStore({ + reducer: { + repoAdvisor: repoAdvisorReducer, + [repoAdvisorApi.reducerPath]: repoAdvisorApi.reducer, + [datastationsApi.reducerPath]: datastationsApi.reducer, + [rorApi.reducerPath]: rorApi.reducer, + }, + middleware: (getDefaultMiddleware) => + getDefaultMiddleware() + .concat(repoAdvisorApi.middleware) + .concat(datastationsApi.middleware) + .concat(rorApi.middleware) + .concat(errorLogger), +}); + +export type AppDispatch = typeof store.dispatch; +export type RootState = ReturnType; diff --git a/packages/repo-advisor/src/types/index.ts b/packages/repo-advisor/src/types/index.ts index 5f0d0f78..2b54f7de 100644 --- a/packages/repo-advisor/src/types/index.ts +++ b/packages/repo-advisor/src/types/index.ts @@ -1,19 +1,20 @@ -import type { LanguageStrings } from "@dans-framework/utils/language"; -import type { AutocompleteAPIFieldProps } from "@dans-framework/deposit"; -import type { OptionsType, FormConfig } from "@dans-framework/deposit"; - -export interface RepoResponse { - advice: { - displayName: LanguageStrings; - description: LanguageStrings; - form?: FormConfig; - external?: string; - }[] -} - -export interface AutocompleteProps extends Omit { - disabled?: boolean; - label: string; - setValue: (val: OptionsType | null) => void; - value: OptionsType | null; -} \ No newline at end of file +import type { LanguageStrings } from "@dans-framework/utils/language"; +import type { AutocompleteAPIFieldProps } from "@dans-framework/deposit"; +import type { OptionsType, FormConfig } from "@dans-framework/deposit"; + +export interface RepoResponse { + advice: { + displayName: LanguageStrings; + description: LanguageStrings; + form?: FormConfig; + external?: string; + }[]; +} + +export interface AutocompleteProps + extends Omit { + disabled?: boolean; + label: string; + setValue: (val: OptionsType | null) => void; + value: OptionsType | null; +} diff --git a/packages/user-auth/src/auth/Auth.tsx b/packages/user-auth/src/auth/Auth.tsx index 8da34845..dce9311e 100644 --- a/packages/user-auth/src/auth/Auth.tsx +++ b/packages/user-auth/src/auth/Auth.tsx @@ -12,7 +12,7 @@ import i18nProvider from "../languages/i18n"; import type { AuthProviderConfig } from "../types"; import { store } from "../redux/store"; import { LoginPage } from "./Login"; -import { WebStorageStateStore } from 'oidc-client-ts'; +import { WebStorageStateStore } from "oidc-client-ts"; export const AuthWrapper = ({ authProvider, @@ -25,8 +25,8 @@ export const AuthWrapper = ({ const authProviderConfig = { ...authProvider, userStore: new WebStorageStateStore({ store: window.sessionStorage }), - monitorSession: true // this allows cross tab login/logout detection - } + monitorSession: true, // this allows cross tab login/logout detection + }; return ( diff --git a/packages/user-auth/src/auth/Login.tsx b/packages/user-auth/src/auth/Login.tsx index 3e700bbc..783a3842 100644 --- a/packages/user-auth/src/auth/Login.tsx +++ b/packages/user-auth/src/auth/Login.tsx @@ -8,13 +8,13 @@ import { LoginButton } from "../user/Buttons"; import { useSearchParams } from "react-router-dom"; export const LoginPage = () => { - const [ searchParams ] = useSearchParams(); + const [searchParams] = useSearchParams(); useEffect(() => { // save data params to session storage to get them back after Keycloak login const data = searchParams.get("data"); if (data) { - sessionStorage.setItem('preloadData', data); + sessionStorage.setItem("preloadData", data); } }, [searchParams]); diff --git a/packages/user-auth/src/types/index.ts b/packages/user-auth/src/types/index.ts index 8b84ce97..41b09981 100644 --- a/packages/user-auth/src/types/index.ts +++ b/packages/user-auth/src/types/index.ts @@ -10,7 +10,10 @@ export interface AuthProviderConfig { } // Define the types of targets here, so we can use this in the key checking API -export type AuthKeys = "dataverse_api_key" | "zenodo_api_key" | "dataverse_nl_api_key"; +export type AuthKeys = + | "dataverse_api_key" + | "zenodo_api_key" + | "dataverse_nl_api_key"; export interface Target { name: string; diff --git a/packages/user-auth/src/user/Buttons.tsx b/packages/user-auth/src/user/Buttons.tsx index c81e68c2..ed04dad5 100644 --- a/packages/user-auth/src/user/Buttons.tsx +++ b/packages/user-auth/src/user/Buttons.tsx @@ -34,7 +34,7 @@ export const LoginButton = ({ variant }: { variant?: "contained" }) => { enqueueSnackbar("Error redirecting to sign-in server", { variant: "customError", }), - ) + ); } } > diff --git a/packages/user-auth/src/user/UserMenu.tsx b/packages/user-auth/src/user/UserMenu.tsx index 3275230e..6c4ee2f4 100644 --- a/packages/user-auth/src/user/UserMenu.tsx +++ b/packages/user-auth/src/user/UserMenu.tsx @@ -26,7 +26,13 @@ export const UserMenu = ({ // keep user signed in, and try to sign in automatically const [hasTriedSignin, setHasTriedSignin] = useState(false); useEffect(() => { - if (!hasAuthParams() && !auth.isAuthenticated && !auth.activeNavigator && !auth.isLoading && !hasTriedSignin) { + if ( + !hasAuthParams() && + !auth.isAuthenticated && + !auth.activeNavigator && + !auth.isLoading && + !hasTriedSignin + ) { auth.signinSilent(); setHasTriedSignin(true); } @@ -35,7 +41,7 @@ export const UserMenu = ({ // if we get an error renewing the token, just sign the user out useEffect(() => { auth.events.addSilentRenewError(() => { - console.error('Auth event: silent renew error. Signing user out.'); + console.error("Auth event: silent renew error. Signing user out."); auth.removeUser(); }); }, [auth.events, auth.removeUser]); diff --git a/packages/user-auth/src/user/UserSettings.tsx b/packages/user-auth/src/user/UserSettings.tsx index d3f3715a..e0753393 100644 --- a/packages/user-auth/src/user/UserSettings.tsx +++ b/packages/user-auth/src/user/UserSettings.tsx @@ -71,7 +71,11 @@ export const UserSettings = ({ - - - - - - - - ) -}; - -export default FileMapper; +import { useEffect, type Dispatch, type SetStateAction } from "react"; +import Container from "@mui/material/Container"; +import Grid from "@mui/material/Unstable_Grid2"; +import Box from "@mui/material/Box"; +import Stack from "@mui/material/Stack"; +import Paper from "@mui/material/Paper"; +import Button from "@mui/material/Button"; +import Stepper from "@mui/material/Stepper"; +import Step from "@mui/material/Step"; +import StepLabel from "@mui/material/StepLabel"; +import { useTranslation } from "react-i18next"; +import SelectFile from "./SelectFile"; +import SetMapping from "./SetMapping"; +import SaveMapping from "./SaveMapping"; +import { + getActiveStep, + setActiveStep, + getFile, + getSavedMap, + getMapping, + getFileError, +} from "./fileMapperSlice"; +import { useSubmitMapMutation } from "./fileMapperApi"; +import { useAppSelector, useAppDispatch } from "../redux/hooks"; +import CircularProgress from "@mui/material/CircularProgress"; +import { useSiteTitle, setSiteTitle } from "@dans-framework/utils/sitetitle"; +import { lookupLanguageString } from "@dans-framework/utils/language"; +import { type Page } from "@dans-framework/pages"; +import type { FormConfig } from "@dans-framework/deposit"; +import { steps } from "./Steps"; + +const FileMapper = ({ + setMappedForm, + page, +}: { + setMappedForm: Dispatch>; + page: Page; +}) => { + const dispatch = useAppDispatch(); + const siteTitle = useSiteTitle(); + const { t, i18n } = useTranslation("steps"); + const activeStep = useAppSelector(getActiveStep); + const file = useAppSelector(getFile); + const savedMap = useAppSelector(getSavedMap); + const mapping = useAppSelector(getMapping); + const fileError = useAppSelector(getFileError); + const [submitMap, { isLoading, data }] = useSubmitMapMutation(); + + // set page title + useEffect(() => { + setSiteTitle(siteTitle, lookupLanguageString(page.name, i18n.language)); + }, [siteTitle, page.name]); + + useEffect(() => { + // save server return data to state + setMappedForm(data); + }, [data]); + + const handleNext = () => { + if (activeStep !== steps.length - 1 && (!file || !savedMap)) { + dispatch(setActiveStep(activeStep + 1)); + } else if (file) { + (async () => { + const fetchedFile = await fetch(file.url); + const blob = await fetchedFile.blob(); + submitMap({ + savedMap: savedMap, + newMap: mapping, + file: blob, + }); + })(); + } + }; + + const handleBack = () => { + dispatch(setActiveStep(activeStep - 1)); + }; + + return ( + + + + + + {steps.map((label) => { + const stepProps: { completed?: boolean } = {}; + return ( + + {t(label)} + + ); + })} + + {activeStep === 0 ? + + : activeStep === 1 ? + + : } + + + + + + + + + + ); +}; + +export default FileMapper; diff --git a/packages/file-mapper/src/features/SaveMapping.tsx b/packages/file-mapper/src/features/SaveMapping.tsx index 9e822ef8..d44e40fb 100644 --- a/packages/file-mapper/src/features/SaveMapping.tsx +++ b/packages/file-mapper/src/features/SaveMapping.tsx @@ -1,17 +1,20 @@ -import { useTranslation } from "react-i18next"; -import TextField from '@mui/material/TextField'; -import Typography from "@mui/material/Typography"; -import { StepWrap } from "./Steps"; - -export const SaveMapping = () => { - const { t } = useTranslation("steps"); - - return ( - - {t("saveMappingExtra")} - - - ) -} - -export default SaveMapping; \ No newline at end of file +import { useTranslation } from "react-i18next"; +import TextField from "@mui/material/TextField"; +import Typography from "@mui/material/Typography"; +import { StepWrap } from "./Steps"; + +export const SaveMapping = () => { + const { t } = useTranslation("steps"); + + return ( + + {t("saveMappingExtra")} + + + ); +}; + +export default SaveMapping; diff --git a/packages/file-mapper/src/features/SelectFile.tsx b/packages/file-mapper/src/features/SelectFile.tsx index c387480c..95b9eb65 100644 --- a/packages/file-mapper/src/features/SelectFile.tsx +++ b/packages/file-mapper/src/features/SelectFile.tsx @@ -1,136 +1,148 @@ -import { useDropzone } from "react-dropzone"; -import Box from "@mui/material/Box"; -import Stack from "@mui/material/Stack"; -import Typography from "@mui/material/Typography"; -import Alert from "@mui/material/Alert"; -import { useTranslation } from "react-i18next"; -import List from '@mui/material/List'; -import ListItem from '@mui/material/ListItem'; -import ListItemButton from '@mui/material/ListItemButton'; -import ListItemText from '@mui/material/ListItemText'; -import ListItemIcon from '@mui/material/ListItemIcon'; -import Checkbox from '@mui/material/Checkbox'; -import Divider from '@mui/material/Divider'; -import useMediaQuery from '@mui/material/useMediaQuery'; -import { useTheme } from '@mui/material/styles'; -import type { Saves, SerializedFile } from "../types"; -import { - getFile, - setFile, - getSavedMap, - setSavedMap, - resetMapping, - getFileError, - resetFileError, - resetFileData, -} from './fileMapperSlice'; -import { useAppSelector, useAppDispatch } from "../redux/hooks"; -import { StepWrap, maxRows, saves } from "./Steps"; - -const SelectFile = () => { - const { t } = useTranslation("steps"); - const theme = useTheme(); - const matches = useMediaQuery(theme.breakpoints.up('md')); - const dispatch = useAppDispatch(); - const file = useAppSelector(getFile); - const savedMap = useAppSelector(getSavedMap); - const fileError = useAppSelector(getFileError); - - const onDrop = async (files: File[]) => { - // serialize files to store in redux - const serializedFile: SerializedFile = { - name: files[0].name, - size: files[0].size, - url: URL.createObjectURL(files[0]), - }; - - dispatch(setFile(serializedFile)); - - // reset saved mapping and column values after selecting a different file - dispatch(resetMapping()); - dispatch(resetFileData()); - dispatch(resetFileError()); - } - - const { - getRootProps, - getInputProps, - isDragActive, - } = useDropzone({ - onDrop, - multiple: false, - accept: { - "text/csv": [".csv"], - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": [".xlsx"], - }, - }); - - return ( - - } - > - - {t("uploadNew")} - - - - {isDragActive ? t("dropNow") : t("drop")} - - - { file && - - - {t("selectedFile", { name: file.name, size: (file.size / 1024).toFixed(0) })} - - {fileError && - - {t(fileError, {max: maxRows})} - - } - - } - - {saves.length > 0 && - - {t("selectSave")} - - {saves.map( (save: Saves) => - - dispatch(setSavedMap(savedMap === save.id ? "" : save.id))} dense> - - - - - - - )} - - - } - - - ) -} - -export default SelectFile; \ No newline at end of file +import { useDropzone } from "react-dropzone"; +import Box from "@mui/material/Box"; +import Stack from "@mui/material/Stack"; +import Typography from "@mui/material/Typography"; +import Alert from "@mui/material/Alert"; +import { useTranslation } from "react-i18next"; +import List from "@mui/material/List"; +import ListItem from "@mui/material/ListItem"; +import ListItemButton from "@mui/material/ListItemButton"; +import ListItemText from "@mui/material/ListItemText"; +import ListItemIcon from "@mui/material/ListItemIcon"; +import Checkbox from "@mui/material/Checkbox"; +import Divider from "@mui/material/Divider"; +import useMediaQuery from "@mui/material/useMediaQuery"; +import { useTheme } from "@mui/material/styles"; +import type { Saves, SerializedFile } from "../types"; +import { + getFile, + setFile, + getSavedMap, + setSavedMap, + resetMapping, + getFileError, + resetFileError, + resetFileData, +} from "./fileMapperSlice"; +import { useAppSelector, useAppDispatch } from "../redux/hooks"; +import { StepWrap, maxRows, saves } from "./Steps"; + +const SelectFile = () => { + const { t } = useTranslation("steps"); + const theme = useTheme(); + const matches = useMediaQuery(theme.breakpoints.up("md")); + const dispatch = useAppDispatch(); + const file = useAppSelector(getFile); + const savedMap = useAppSelector(getSavedMap); + const fileError = useAppSelector(getFileError); + + const onDrop = async (files: File[]) => { + // serialize files to store in redux + const serializedFile: SerializedFile = { + name: files[0].name, + size: files[0].size, + url: URL.createObjectURL(files[0]), + }; + + dispatch(setFile(serializedFile)); + + // reset saved mapping and column values after selecting a different file + dispatch(resetMapping()); + dispatch(resetFileData()); + dispatch(resetFileError()); + }; + + const { getRootProps, getInputProps, isDragActive } = useDropzone({ + onDrop, + multiple: false, + accept: { + "text/csv": [".csv"], + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": [ + ".xlsx", + ], + }, + }); + + return ( + + + } + > + + {t("uploadNew")} + + + + {isDragActive ? t("dropNow") : t("drop")} + + + {file && ( + + + {t("selectedFile", { + name: file.name, + size: (file.size / 1024).toFixed(0), + })} + + {fileError && ( + {t(fileError, { max: maxRows })} + )} + + )} + + {saves.length > 0 && ( + + + {t("selectSave")} + + + {saves.map((save: Saves) => ( + + + dispatch(setSavedMap(savedMap === save.id ? "" : save.id)) + } + dense + > + + + + + + + ))} + + + )} + + + ); +}; + +export default SelectFile; diff --git a/packages/file-mapper/src/features/SetMapping.tsx b/packages/file-mapper/src/features/SetMapping.tsx index 38034fb9..f48770fb 100644 --- a/packages/file-mapper/src/features/SetMapping.tsx +++ b/packages/file-mapper/src/features/SetMapping.tsx @@ -1,189 +1,201 @@ -import { useState, useEffect } from "react"; -import Typography from "@mui/material/Typography"; -import Paper from "@mui/material/Paper"; -import Alert from "@mui/material/Alert"; -import { useTranslation } from "react-i18next"; -import TableContainer from '@mui/material/TableContainer'; -import Table from '@mui/material/Table'; -import TableBody from '@mui/material/TableBody'; -import TableCell from '@mui/material/TableCell'; -import TableHead from '@mui/material/TableHead'; -import TableRow from '@mui/material/TableRow'; -import TextField from '@mui/material/TextField'; -import Autocomplete from '@mui/material/Autocomplete'; -import CircularProgress from '@mui/material/CircularProgress'; -import IconButton from '@mui/material/IconButton'; -import Collapse from '@mui/material/Collapse'; -import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; -import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp'; -import type { DarwinOptions, FileError, SheetData } from "../types"; -import { - getFile, - getMapping, - setMapping, - getFileError, - setFileError, - setFileData, - getFileData, -} from './fileMapperSlice'; -import { useFetchDarwinTermsQuery } from "./fileMapperApi"; -import { useAppSelector, useAppDispatch } from "../redux/hooks"; -import { StepWrap, maxRows } from "./Steps"; - -export const SetMapping = () => { - const { t } = useTranslation("steps"); - const dispatch = useAppDispatch(); - const file = useAppSelector(getFile); - const fileData = useAppSelector(getFileData); - const fileError = useAppSelector(getFileError); - // loading indicator only if new file needs to be read - const [ loading, setLoading ] = useState( !Array.isArray(fileData) && !fileError ); - - useEffect(() => { - const loadXLSX = async () => { - const XLSX = await import('xlsx'); // Lazy load the library here - - const reader = new FileReader(); - reader.onload = (event) => { - // parse the xlsx/csv file - const workbook = XLSX.read(event.target?.result, { type: 'binary' }); - const sheetName = workbook.SheetNames[0]; - const sheet = workbook.Sheets[sheetName]; - const sheetData: SheetData[] = XLSX.utils.sheet_to_json(sheet, { header: "A" }); - // check to see if sheet doesn't have too many rows (first row is headers, so doesn't count) - const rowCount = sheetData.length - 1; - if (rowCount > maxRows) { - dispatch(setFileError("tooManyRows")); - } else { - // save sheet data so we only need to load and parse once - dispatch(setFileData(sheetData)); - } - setLoading(false); - }; - - if (file && !fileData && !fileError) { - dispatch(setFileError(undefined)); - // if no file loaded yet, convert file url back to blob - const fetchedFile = await fetch(file.url); - const blob = await fetchedFile.blob(); - if (blob) { - reader.readAsBinaryString(blob); - } - } - }; - - loadXLSX(); // Call the lazy loading function - }, [file, fileData, fileError, dispatch]); - - return ( - - - - - - - {t("dataValue")} - {t("mapTo")} - - - - { ( loading || fileError ) && - - - { - loading ? - : - - {t(fileError as FileError, {max: maxRows})} - - } - - - } - {fileData && Object.entries(fileData[0]).map(([key, value]) => - - )} - -
    -
    -
    - ) -} - -export default SetMapping; - -const Row = ({rowKey, row}: {rowKey: string; row: string;}) => { - const { t } = useTranslation("steps"); - const [inputValue, setInputValue] = useState(''); - const mapping = useAppSelector(getMapping); - const dispatch = useAppDispatch(); - const fileData = useAppSelector(getFileData); - const columnData = fileData && fileData.slice(1).map( data => data[rowKey]) - const [ open, setOpen ] = useState(false); - console.log(columnData) - - const { data, isLoading } = useFetchDarwinTermsQuery(''); - - const selectValue = (row: string, value: DarwinOptions | null) => { - if (value === null) { - // Create a new object excluding the [row] key - const { [row]: _, ...rest } = mapping; - dispatch(setMapping(rest)); - } else { - dispatch(setMapping({ - ...mapping, - [row]: value, - })); - } - }; - - return ( - <> - - - setOpen(!open)} - > - {open ? : } - - - - {row} - - - option.label} - groupBy={(option) => option.header} - sx={{ width: 300 }} - renderInput={(params) => } - onChange={(_e, value) => selectValue(row, value)} - value={(mapping.hasOwnProperty(row) && mapping[row]) || null} - inputValue={inputValue} - isOptionEqualToValue={(option, value) => option.term_localName === value.term_localName} - onInputChange={(_e, newInputValue) => { - setInputValue(newInputValue); - }} - loading={isLoading} - size="small" - /> - - - {columnData && - - - - - {t('dataHeader')} - {columnData.map((item, i) => - {item} - )} - - - - } - - ) -} +import { useState, useEffect } from "react"; +import Typography from "@mui/material/Typography"; +import Paper from "@mui/material/Paper"; +import Alert from "@mui/material/Alert"; +import { useTranslation } from "react-i18next"; +import TableContainer from "@mui/material/TableContainer"; +import Table from "@mui/material/Table"; +import TableBody from "@mui/material/TableBody"; +import TableCell from "@mui/material/TableCell"; +import TableHead from "@mui/material/TableHead"; +import TableRow from "@mui/material/TableRow"; +import TextField from "@mui/material/TextField"; +import Autocomplete from "@mui/material/Autocomplete"; +import CircularProgress from "@mui/material/CircularProgress"; +import IconButton from "@mui/material/IconButton"; +import Collapse from "@mui/material/Collapse"; +import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; +import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"; +import type { DarwinOptions, FileError, SheetData } from "../types"; +import { + getFile, + getMapping, + setMapping, + getFileError, + setFileError, + setFileData, + getFileData, +} from "./fileMapperSlice"; +import { useFetchDarwinTermsQuery } from "./fileMapperApi"; +import { useAppSelector, useAppDispatch } from "../redux/hooks"; +import { StepWrap, maxRows } from "./Steps"; + +export const SetMapping = () => { + const { t } = useTranslation("steps"); + const dispatch = useAppDispatch(); + const file = useAppSelector(getFile); + const fileData = useAppSelector(getFileData); + const fileError = useAppSelector(getFileError); + // loading indicator only if new file needs to be read + const [loading, setLoading] = useState( + !Array.isArray(fileData) && !fileError, + ); + + useEffect(() => { + const loadXLSX = async () => { + const XLSX = await import("xlsx"); // Lazy load the library here + + const reader = new FileReader(); + reader.onload = (event) => { + // parse the xlsx/csv file + const workbook = XLSX.read(event.target?.result, { type: "binary" }); + const sheetName = workbook.SheetNames[0]; + const sheet = workbook.Sheets[sheetName]; + const sheetData: SheetData[] = XLSX.utils.sheet_to_json(sheet, { + header: "A", + }); + // check to see if sheet doesn't have too many rows (first row is headers, so doesn't count) + const rowCount = sheetData.length - 1; + if (rowCount > maxRows) { + dispatch(setFileError("tooManyRows")); + } else { + // save sheet data so we only need to load and parse once + dispatch(setFileData(sheetData)); + } + setLoading(false); + }; + + if (file && !fileData && !fileError) { + dispatch(setFileError(undefined)); + // if no file loaded yet, convert file url back to blob + const fetchedFile = await fetch(file.url); + const blob = await fetchedFile.blob(); + if (blob) { + reader.readAsBinaryString(blob); + } + } + }; + + loadXLSX(); // Call the lazy loading function + }, [file, fileData, fileError, dispatch]); + + return ( + + + + + + + {t("dataValue")} + {t("mapTo")} + + + + {(loading || fileError) && ( + + + {loading ? + + : + {t(fileError as FileError, { max: maxRows })} + + } + + + )} + {fileData && + Object.entries(fileData[0]).map(([key, value]) => ( + + ))} + +
    +
    +
    + ); +}; + +export default SetMapping; + +const Row = ({ rowKey, row }: { rowKey: string; row: string }) => { + const { t } = useTranslation("steps"); + const [inputValue, setInputValue] = useState(""); + const mapping = useAppSelector(getMapping); + const dispatch = useAppDispatch(); + const fileData = useAppSelector(getFileData); + const columnData = fileData && fileData.slice(1).map((data) => data[rowKey]); + const [open, setOpen] = useState(false); + console.log(columnData); + + const { data, isLoading } = useFetchDarwinTermsQuery(""); + + const selectValue = (row: string, value: DarwinOptions | null) => { + if (value === null) { + // Create a new object excluding the [row] key + const { [row]: _, ...rest } = mapping; + dispatch(setMapping(rest)); + } else { + dispatch( + setMapping({ + ...mapping, + [row]: value, + }), + ); + } + }; + + return ( + <> + + + setOpen(!open)} + > + {open ? + + : } + + + {row} + + option.label} + groupBy={(option) => option.header} + sx={{ width: 300 }} + renderInput={(params) => ( + + )} + onChange={(_e, value) => selectValue(row, value)} + value={(mapping.hasOwnProperty(row) && mapping[row]) || null} + inputValue={inputValue} + isOptionEqualToValue={(option, value) => + option.term_localName === value.term_localName + } + onInputChange={(_e, newInputValue) => { + setInputValue(newInputValue); + }} + loading={isLoading} + size="small" + /> + + + {columnData && ( + + + + + {t("dataHeader")} + {columnData.map((item, i) => ( + + {item} + + ))} + + + + )} + + ); +}; diff --git a/packages/file-mapper/src/features/Steps.tsx b/packages/file-mapper/src/features/Steps.tsx index 8447d821..64f3dcaa 100644 --- a/packages/file-mapper/src/features/Steps.tsx +++ b/packages/file-mapper/src/features/Steps.tsx @@ -1,30 +1,37 @@ -import type { ReactNode } from "react"; -import Box from "@mui/material/Box"; -import Typography from "@mui/material/Typography"; - -// some fake placeholder saves. todo. -export const saves = [ - { - name: "Fake save #1", - date: "8-8-2024", - id: "someUniqueId1", - }, - { - name: "Fake save #2", - date: "7-8-2024", - id: "someUniqueId2", - }, -]; - -// define max number of rows a file selected for processing can contain -export const maxRows = 10; - -// define steps -export const steps = ['selectFile', 'createMapping', 'finish']; - -// wrapper for individual steps -export const StepWrap = ({ title, children }: { title: string; children: ReactNode }) => - - {title} - {children} - \ No newline at end of file +import type { ReactNode } from "react"; +import Box from "@mui/material/Box"; +import Typography from "@mui/material/Typography"; + +// some fake placeholder saves. todo. +export const saves = [ + { + name: "Fake save #1", + date: "8-8-2024", + id: "someUniqueId1", + }, + { + name: "Fake save #2", + date: "7-8-2024", + id: "someUniqueId2", + }, +]; + +// define max number of rows a file selected for processing can contain +export const maxRows = 10; + +// define steps +export const steps = ["selectFile", "createMapping", "finish"]; + +// wrapper for individual steps +export const StepWrap = ({ + title, + children, +}: { + title: string; + children: ReactNode; +}) => ( + + {title} + {children} + +); diff --git a/packages/file-mapper/src/features/fileMapperApi.ts b/packages/file-mapper/src/features/fileMapperApi.ts index 9ab6684d..941435ba 100644 --- a/packages/file-mapper/src/features/fileMapperApi.ts +++ b/packages/file-mapper/src/features/fileMapperApi.ts @@ -1,81 +1,87 @@ -import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; -import type { DarwinOptions } from "../types"; -import { getUser } from "@dans-framework/utils/user"; - -export const darwinCoreApi = createApi({ - reducerPath: "darwinCoreApi", - baseQuery: fetchBaseQuery({ baseUrl: "https://raw.githubusercontent.com/tdwg/rs.tdwg.org/master" }), - endpoints: (build) => ({ - fetchDarwinTerms: build.query({ - query: () => ({ - url: "terms/terms.csv", - responseHandler: (response) => response.text(), - }), - transformResponse: async (response, _meta, _arg) => { - // Dynamically import XLSX - const XLSX = await import("xlsx"); // Lazy load the library here - - // Convert CSV text string to JSON - const workbook = XLSX.read(response, { type: 'binary' }); - const sheetName = workbook.SheetNames[0]; - const sheet = workbook.Sheets[sheetName]; - const sheetData: DarwinOptions[] = XLSX.utils.sheet_to_json(sheet); - - const filteredData = sheetData - .filter(d => !d.term_deprecated) - .map(d => ({...d, header: d.tdwgutility_organizedInClass?.split('/').pop() || 'Dataset'})) - .sort((a, b) => a.header?.localeCompare(b.header)); - - return filteredData || []; - }, - transformErrorResponse: () => ({ - error: "Could not fetch terms", - }), - }), - }), -}); - -export const { useFetchDarwinTermsQuery } = darwinCoreApi; - -export const submitMappingApi = createApi({ - reducerPath: "submitMappingApi", - baseQuery: fetchBaseQuery({ - baseUrl: `${import.meta.env.VITE_MAPPER_URI}`, - }), - endpoints: (build) => ({ - submitMap: build.mutation({ - query: ({ savedMap, newMap, file }) => { - const user = getUser(); - // format headers - const headers = { - Authorization: `Bearer ${user?.access_token}`, - "auth-env-name": import.meta.env.VITE_ENV_NAME, - }; - - let formData = new FormData(); - formData.append("file", file); - formData.append("savedMap", savedMap); - formData.append("map", JSON.stringify(newMap)); - - console.log(`sending data:`) - console.log(formData.get('file')) - console.log(formData.get('savedMap')) - console.log(formData.get('map')) - - return ({ - url: 'mapper', - method: "POST", - headers: headers, - body: formData, - }); - }, - transformErrorResponse: () => { - return ({ - error: "Error connecting to server" - }); - }, - }), - }), -}); - -export const { useSubmitMapMutation } = submitMappingApi; +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; +import type { DarwinOptions } from "../types"; +import { getUser } from "@dans-framework/utils/user"; + +export const darwinCoreApi = createApi({ + reducerPath: "darwinCoreApi", + baseQuery: fetchBaseQuery({ + baseUrl: "https://raw.githubusercontent.com/tdwg/rs.tdwg.org/master", + }), + endpoints: (build) => ({ + fetchDarwinTerms: build.query({ + query: () => ({ + url: "terms/terms.csv", + responseHandler: (response) => response.text(), + }), + transformResponse: async (response, _meta, _arg) => { + // Dynamically import XLSX + const XLSX = await import("xlsx"); // Lazy load the library here + + // Convert CSV text string to JSON + const workbook = XLSX.read(response, { type: "binary" }); + const sheetName = workbook.SheetNames[0]; + const sheet = workbook.Sheets[sheetName]; + const sheetData: DarwinOptions[] = XLSX.utils.sheet_to_json(sheet); + + const filteredData = sheetData + .filter((d) => !d.term_deprecated) + .map((d) => ({ + ...d, + header: + d.tdwgutility_organizedInClass?.split("/").pop() || "Dataset", + })) + .sort((a, b) => a.header?.localeCompare(b.header)); + + return filteredData || []; + }, + transformErrorResponse: () => ({ + error: "Could not fetch terms", + }), + }), + }), +}); + +export const { useFetchDarwinTermsQuery } = darwinCoreApi; + +export const submitMappingApi = createApi({ + reducerPath: "submitMappingApi", + baseQuery: fetchBaseQuery({ + baseUrl: `${import.meta.env.VITE_MAPPER_URI}`, + }), + endpoints: (build) => ({ + submitMap: build.mutation({ + query: ({ savedMap, newMap, file }) => { + const user = getUser(); + // format headers + const headers = { + Authorization: `Bearer ${user?.access_token}`, + "auth-env-name": import.meta.env.VITE_ENV_NAME, + }; + + let formData = new FormData(); + formData.append("file", file); + formData.append("savedMap", savedMap); + formData.append("map", JSON.stringify(newMap)); + + console.log(`sending data:`); + console.log(formData.get("file")); + console.log(formData.get("savedMap")); + console.log(formData.get("map")); + + return { + url: "mapper", + method: "POST", + headers: headers, + body: formData, + }; + }, + transformErrorResponse: () => { + return { + error: "Error connecting to server", + }; + }, + }), + }), +}); + +export const { useSubmitMapMutation } = submitMappingApi; diff --git a/packages/file-mapper/src/features/fileMapperSlice.ts b/packages/file-mapper/src/features/fileMapperSlice.ts index 277bcfde..d0ba2bd2 100644 --- a/packages/file-mapper/src/features/fileMapperSlice.ts +++ b/packages/file-mapper/src/features/fileMapperSlice.ts @@ -1,82 +1,82 @@ -import { createSlice, type PayloadAction } from "@reduxjs/toolkit"; -import { RootState } from "../redux/store"; -import type { SerializedFile, Mapping, FileError, SheetData } from "../types"; -import type { FormConfig } from "@dans-framework/deposit"; - -const initialState: { - activeStep: number; - mapping: Mapping; - file: SerializedFile | undefined; - savedMap: string; - form: FormConfig | undefined; - fileError: string | undefined; - fileData: SheetData[] | undefined; -} = { - activeStep: 0, - mapping: {}, - file: undefined, - savedMap: '', - form: undefined, - fileError: undefined, - fileData: undefined, -}; - -export const fileMapperSlice = createSlice({ - name: "fileMapper", - initialState, - reducers: { - setActiveStep: (state, action: PayloadAction) => { - state.activeStep = action.payload; - }, - setMapping: (state, action: PayloadAction) => { - state.mapping = action.payload; - }, - resetMapping: (state) => { - state.mapping = initialState.mapping; - }, - setSavedMap: (state, action: PayloadAction) => { - state.savedMap = action.payload; - }, - setFile: (state, action: PayloadAction) => { - state.file = action.payload; - }, - saveData: (state, action) => { - state.form = action.payload; - }, - setFileData: (state, action: PayloadAction) => { - state.fileData = action.payload; - }, - resetFileData: (state) => { - state.fileData = initialState.fileData; - }, - setFileError: (state, action: PayloadAction) => { - state.fileError = action.payload; - }, - resetFileError: (state) => { - state.fileError = initialState.fileError; - }, - }, -}); - -export const { - setActiveStep, - setMapping, - resetMapping, - setSavedMap, - setFile, - saveData, - setFileData, - resetFileData, - setFileError, - resetFileError, -} = fileMapperSlice.actions; - -export const getActiveStep = (state: RootState) => state.fileMapper.activeStep; -export const getMapping = (state: RootState) => state.fileMapper.mapping; -export const getSavedMap = (state: RootState) => state.fileMapper.savedMap; -export const getFile = (state: RootState) => state.fileMapper.file; -export const getForm = (state: RootState) => state.fileMapper.form; -export const getFileData = (state: RootState) => state.fileMapper.fileData; -export const getFileError = (state: RootState) => state.fileMapper.fileError; - -export default fileMapperSlice.reducer; +import { createSlice, type PayloadAction } from "@reduxjs/toolkit"; +import { RootState } from "../redux/store"; +import type { SerializedFile, Mapping, FileError, SheetData } from "../types"; +import type { FormConfig } from "@dans-framework/deposit"; + +const initialState: { + activeStep: number; + mapping: Mapping; + file: SerializedFile | undefined; + savedMap: string; + form: FormConfig | undefined; + fileError: string | undefined; + fileData: SheetData[] | undefined; +} = { + activeStep: 0, + mapping: {}, + file: undefined, + savedMap: "", + form: undefined, + fileError: undefined, + fileData: undefined, +}; + +export const fileMapperSlice = createSlice({ + name: "fileMapper", + initialState, + reducers: { + setActiveStep: (state, action: PayloadAction) => { + state.activeStep = action.payload; + }, + setMapping: (state, action: PayloadAction) => { + state.mapping = action.payload; + }, + resetMapping: (state) => { + state.mapping = initialState.mapping; + }, + setSavedMap: (state, action: PayloadAction) => { + state.savedMap = action.payload; + }, + setFile: (state, action: PayloadAction) => { + state.file = action.payload; + }, + saveData: (state, action) => { + state.form = action.payload; + }, + setFileData: (state, action: PayloadAction) => { + state.fileData = action.payload; + }, + resetFileData: (state) => { + state.fileData = initialState.fileData; + }, + setFileError: (state, action: PayloadAction) => { + state.fileError = action.payload; + }, + resetFileError: (state) => { + state.fileError = initialState.fileError; + }, + }, +}); + +export const { + setActiveStep, + setMapping, + resetMapping, + setSavedMap, + setFile, + saveData, + setFileData, + resetFileData, + setFileError, + resetFileError, +} = fileMapperSlice.actions; + +export const getActiveStep = (state: RootState) => state.fileMapper.activeStep; +export const getMapping = (state: RootState) => state.fileMapper.mapping; +export const getSavedMap = (state: RootState) => state.fileMapper.savedMap; +export const getFile = (state: RootState) => state.fileMapper.file; +export const getForm = (state: RootState) => state.fileMapper.form; +export const getFileData = (state: RootState) => state.fileMapper.fileData; +export const getFileError = (state: RootState) => state.fileMapper.fileError; + +export default fileMapperSlice.reducer; diff --git a/packages/file-mapper/src/index.tsx b/packages/file-mapper/src/index.tsx index 4992c91f..68f3ca77 100644 --- a/packages/file-mapper/src/index.tsx +++ b/packages/file-mapper/src/index.tsx @@ -1,20 +1,24 @@ -import { type Dispatch, type SetStateAction } from "react"; -import { I18nextProvider } from "react-i18next"; -import i18nProvider from "./languages/i18n"; -import FileMapper from "./features/FileMapper"; -import { Provider as ReduxProvider } from "react-redux"; -import { store } from './redux/store'; -import type { Page } from "@dans-framework/pages"; -import type { FormConfig } from "@dans-framework/deposit"; - -export const MapWrapper = ({setMappedForm, page}: { - setMappedForm: Dispatch>; - page: Page; -}) => - - - - - - -export default MapWrapper; \ No newline at end of file +import { type Dispatch, type SetStateAction } from "react"; +import { I18nextProvider } from "react-i18next"; +import i18nProvider from "./languages/i18n"; +import FileMapper from "./features/FileMapper"; +import { Provider as ReduxProvider } from "react-redux"; +import { store } from "./redux/store"; +import type { Page } from "@dans-framework/pages"; +import type { FormConfig } from "@dans-framework/deposit"; + +export const MapWrapper = ({ + setMappedForm, + page, +}: { + setMappedForm: Dispatch>; + page: Page; +}) => ( + + + + + +); + +export default MapWrapper; diff --git a/packages/file-mapper/src/languages/i18n.ts b/packages/file-mapper/src/languages/i18n.ts index 3fc475e0..0e05e228 100644 --- a/packages/file-mapper/src/languages/i18n.ts +++ b/packages/file-mapper/src/languages/i18n.ts @@ -1,22 +1,22 @@ -import resourcesToBackend from "i18next-resources-to-backend"; -import { createInstance } from "i18next"; -import { initReactI18next } from "react-i18next"; - -const i18n = createInstance({ - fallbackLng: "en", - interpolation: { - escapeValue: false, // not needed for react as it escapes by default - }, -}); - -i18n - .use( - resourcesToBackend( - (language: string, namespace: string) => - import(`./locales/${language}/${namespace}.json`), - ), - ) - .use(initReactI18next) - .init(); - -export default i18n; +import resourcesToBackend from "i18next-resources-to-backend"; +import { createInstance } from "i18next"; +import { initReactI18next } from "react-i18next"; + +const i18n = createInstance({ + fallbackLng: "en", + interpolation: { + escapeValue: false, // not needed for react as it escapes by default + }, +}); + +i18n + .use( + resourcesToBackend( + (language: string, namespace: string) => + import(`./locales/${language}/${namespace}.json`), + ), + ) + .use(initReactI18next) + .init(); + +export default i18n; diff --git a/packages/file-mapper/src/redux/hooks.ts b/packages/file-mapper/src/redux/hooks.ts index f0c6116f..36b5ea2f 100644 --- a/packages/file-mapper/src/redux/hooks.ts +++ b/packages/file-mapper/src/redux/hooks.ts @@ -1,6 +1,6 @@ -import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux"; -import type { RootState, AppDispatch } from "./store"; - -// Use throughout your app instead of plain `useDispatch` and `useSelector` -export const useAppDispatch = () => useDispatch(); -export const useAppSelector: TypedUseSelectorHook = useSelector; +import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux"; +import type { RootState, AppDispatch } from "./store"; + +// Use throughout your app instead of plain `useDispatch` and `useSelector` +export const useAppDispatch = () => useDispatch(); +export const useAppSelector: TypedUseSelectorHook = useSelector; diff --git a/packages/file-mapper/src/redux/store.ts b/packages/file-mapper/src/redux/store.ts index 0bcf2bcd..32e847ea 100644 --- a/packages/file-mapper/src/redux/store.ts +++ b/packages/file-mapper/src/redux/store.ts @@ -1,20 +1,20 @@ -import { configureStore } from "@reduxjs/toolkit"; -import { errorLogger } from "@dans-framework/utils/error"; -import fileMapperReducer from "../features/fileMapperSlice"; -import { darwinCoreApi, submitMappingApi } from "../features/fileMapperApi"; - -export const store = configureStore({ - reducer: { - fileMapper: fileMapperReducer, - [darwinCoreApi.reducerPath]: darwinCoreApi.reducer, - [submitMappingApi.reducerPath]: submitMappingApi.reducer, - }, - middleware: (getDefaultMiddleware) => - getDefaultMiddleware() - .concat(darwinCoreApi.middleware) - .concat(submitMappingApi.middleware) - .concat(errorLogger) -}); - -export type AppDispatch = typeof store.dispatch; -export type RootState = ReturnType; +import { configureStore } from "@reduxjs/toolkit"; +import { errorLogger } from "@dans-framework/utils/error"; +import fileMapperReducer from "../features/fileMapperSlice"; +import { darwinCoreApi, submitMappingApi } from "../features/fileMapperApi"; + +export const store = configureStore({ + reducer: { + fileMapper: fileMapperReducer, + [darwinCoreApi.reducerPath]: darwinCoreApi.reducer, + [submitMappingApi.reducerPath]: submitMappingApi.reducer, + }, + middleware: (getDefaultMiddleware) => + getDefaultMiddleware() + .concat(darwinCoreApi.middleware) + .concat(submitMappingApi.middleware) + .concat(errorLogger), +}); + +export type AppDispatch = typeof store.dispatch; +export type RootState = ReturnType; diff --git a/packages/file-mapper/src/types/index.ts b/packages/file-mapper/src/types/index.ts index d98b5218..25a39e96 100644 --- a/packages/file-mapper/src/types/index.ts +++ b/packages/file-mapper/src/types/index.ts @@ -1,33 +1,32 @@ -export type DarwinTerms = - | "term_localName" - | "tdwgutility_organizedInClass" - | "label" - | "header" - | "term_deprecated"; - -export type DarwinOptions = { - [key in DarwinTerms]: string; -} - -export interface Mapping { - [key: string]: DarwinOptions; -} - -export interface Saves { - name: string; - date: string; - id: string; -} - -export interface SerializedFile { - name: string; - size: number; - url: string; -} - -export type FileError = - | "tooManyRows"; - -export interface SheetData { - [key: string]: string; -} \ No newline at end of file +export type DarwinTerms = + | "term_localName" + | "tdwgutility_organizedInClass" + | "label" + | "header" + | "term_deprecated"; + +export type DarwinOptions = { + [key in DarwinTerms]: string; +}; + +export interface Mapping { + [key: string]: DarwinOptions; +} + +export interface Saves { + name: string; + date: string; + id: string; +} + +export interface SerializedFile { + name: string; + size: number; + url: string; +} + +export type FileError = "tooManyRows"; + +export interface SheetData { + [key: string]: string; +} diff --git a/packages/layout/src/MenuBar.tsx b/packages/layout/src/MenuBar.tsx index 716dedd3..a820c474 100644 --- a/packages/layout/src/MenuBar.tsx +++ b/packages/layout/src/MenuBar.tsx @@ -91,7 +91,7 @@ const MenuBar = ({ {lookupLanguageString(page.menuTitle, i18n.language)} - ) + ), )} {lookupLanguageString(page.menuTitle, i18n.language)} - ) + ), )} diff --git a/packages/repo-advisor/lib/index.tsx b/packages/repo-advisor/lib/index.tsx index 12b97216..35415eb3 100644 --- a/packages/repo-advisor/lib/index.tsx +++ b/packages/repo-advisor/lib/index.tsx @@ -1,4 +1,3 @@ -export { default as RepoAdvisor } from "../src"; -export { default as i18n } from "../src/languages/i18n"; -export { RepoBar, NoRepoSelected } from "../src/features/Layout"; - +export { default as RepoAdvisor } from "../src"; +export { default as i18n } from "../src/languages/i18n"; +export { RepoBar, NoRepoSelected } from "../src/features/Layout"; diff --git a/packages/repo-advisor/src/features/Components.tsx b/packages/repo-advisor/src/features/Components.tsx index 1bf4a910..3e5583bc 100644 --- a/packages/repo-advisor/src/features/Components.tsx +++ b/packages/repo-advisor/src/features/Components.tsx @@ -1,167 +1,177 @@ -import { useState } from "react"; -import Stack from '@mui/material/Stack'; -import CircularProgress from '@mui/material/CircularProgress'; -import Box from '@mui/material/Box'; -import { useDebounce } from "use-debounce"; -import InputLabel from '@mui/material/InputLabel'; -import MenuItem from '@mui/material/MenuItem'; -import FormControl from '@mui/material/FormControl'; -import Select, { SelectChangeEvent } from '@mui/material/Select'; -import TextField from '@mui/material/TextField'; -import Autocomplete from '@mui/material/Autocomplete'; -import { useFetchRorByNameQuery, useFetchDatastationsTermQuery, type OptionsType, type QueryReturnType } from "@dans-framework/deposit"; -import { useTranslation } from "react-i18next"; -import { useAppSelector, useAppDispatch } from "../redux/hooks"; -import { getRor, getNarcis, setRor, setNarcis } from "./repoAdvisorSlice"; -import type { AutocompleteProps } from "../types"; - -type Option = { - value: string; - label: string; -}; - -export const SelectField = ({label, value, onChange, options, disabled}: { - label: string; - value: string; - onChange: (val: string) => void; - options: Option[]; - disabled?: boolean; -}) => - - - {label} - - - - -// Derived from the API field in the Deposit package -export const RorField = () => { - const { t } = useTranslation("steps"); - const dispatch = useAppDispatch(); - const [inputValue, setInputValue] = useState(""); - const debouncedInputValue = useDebounce(inputValue, 500)[0]; - // Fetch data on input change - const { data, isFetching, isLoading } = - useFetchRorByNameQuery(debouncedInputValue, { - skip: debouncedInputValue === "", - }); - const value = useAppSelector(getRor); - - return ( - dispatch(setRor(v))} - value={value} - /> - ); -}; - -export const NarcisField = () => { - const { t, i18n } = useTranslation("steps"); - const dispatch = useAppDispatch(); - const [inputValue, setInputValue] = useState(""); - const debouncedInputValue = useDebounce(inputValue, 500)[0]; - // Fetch data on input change - const { data, isFetching, isLoading } = - useFetchDatastationsTermQuery( - { - vocabulary: "narcis", - lang: i18n.language, - query: debouncedInputValue, - }, - { skip: debouncedInputValue === "" }, - ); - const value = useAppSelector(getNarcis); - - return ( - dispatch(setNarcis(v))} - value={value} - /> - ); -}; - -const ApiField = ({ - inputValue, - setInputValue, - debouncedInputValue, - data, - isLoading, - isFetching, - label, - setValue, - value, - disabled, -}: AutocompleteProps ) => { - const { t } = useTranslation("steps"); - - return ( - - ( - - )} - onChange={(_e, newValue, _reason) => setValue(newValue as OptionsType)} - filterOptions={(x) => x} - onInputChange={(e, newValue) => { - e && e.type === "change" && setInputValue(newValue); - e && (e.type === "click" || e.type === "blur") && setInputValue(""); - }} - noOptionsText={!inputValue ? t("startTyping") : t("noResults")} - loading={isLoading || isFetching || inputValue !== debouncedInputValue} - loadingText={ - - {t("isLoading")} - - } - forcePopupIcon - // isOptionEqualToValue={(option, value) => option.value === value.value} - clearOnBlur - disabled={disabled} - /> - - ); -}; +import { useState } from "react"; +import Stack from "@mui/material/Stack"; +import CircularProgress from "@mui/material/CircularProgress"; +import Box from "@mui/material/Box"; +import { useDebounce } from "use-debounce"; +import InputLabel from "@mui/material/InputLabel"; +import MenuItem from "@mui/material/MenuItem"; +import FormControl from "@mui/material/FormControl"; +import Select, { SelectChangeEvent } from "@mui/material/Select"; +import TextField from "@mui/material/TextField"; +import Autocomplete from "@mui/material/Autocomplete"; +import { + useFetchRorByNameQuery, + useFetchDatastationsTermQuery, + type OptionsType, + type QueryReturnType, +} from "@dans-framework/deposit"; +import { useTranslation } from "react-i18next"; +import { useAppSelector, useAppDispatch } from "../redux/hooks"; +import { getRor, getNarcis, setRor, setNarcis } from "./repoAdvisorSlice"; +import type { AutocompleteProps } from "../types"; + +type Option = { + value: string; + label: string; +}; + +export const SelectField = ({ + label, + value, + onChange, + options, + disabled, +}: { + label: string; + value: string; + onChange: (val: string) => void; + options: Option[]; + disabled?: boolean; +}) => ( + + + {label} + + + +); + +// Derived from the API field in the Deposit package +export const RorField = () => { + const { t } = useTranslation("steps"); + const dispatch = useAppDispatch(); + const [inputValue, setInputValue] = useState(""); + const debouncedInputValue = useDebounce(inputValue, 500)[0]; + // Fetch data on input change + const { data, isFetching, isLoading } = + useFetchRorByNameQuery(debouncedInputValue, { + skip: debouncedInputValue === "", + }); + const value = useAppSelector(getRor); + + return ( + dispatch(setRor(v))} + value={value} + /> + ); +}; + +export const NarcisField = () => { + const { t, i18n } = useTranslation("steps"); + const dispatch = useAppDispatch(); + const [inputValue, setInputValue] = useState(""); + const debouncedInputValue = useDebounce(inputValue, 500)[0]; + // Fetch data on input change + const { data, isFetching, isLoading } = + useFetchDatastationsTermQuery( + { + vocabulary: "narcis", + lang: i18n.language, + query: debouncedInputValue, + }, + { skip: debouncedInputValue === "" }, + ); + const value = useAppSelector(getNarcis); + + return ( + dispatch(setNarcis(v))} + value={value} + /> + ); +}; + +const ApiField = ({ + inputValue, + setInputValue, + debouncedInputValue, + data, + isLoading, + isFetching, + label, + setValue, + value, + disabled, +}: AutocompleteProps) => { + const { t } = useTranslation("steps"); + + return ( + + ( + + )} + onChange={(_e, newValue, _reason) => setValue(newValue as OptionsType)} + filterOptions={(x) => x} + onInputChange={(e, newValue) => { + e && e.type === "change" && setInputValue(newValue); + e && (e.type === "click" || e.type === "blur") && setInputValue(""); + }} + noOptionsText={!inputValue ? t("startTyping") : t("noResults")} + loading={isLoading || isFetching || inputValue !== debouncedInputValue} + loadingText={ + + {t("isLoading")} + + } + forcePopupIcon + // isOptionEqualToValue={(option, value) => option.value === value.value} + clearOnBlur + disabled={disabled} + /> + + ); +}; diff --git a/packages/repo-advisor/src/features/Layout.tsx b/packages/repo-advisor/src/features/Layout.tsx index b5869086..abc10915 100644 --- a/packages/repo-advisor/src/features/Layout.tsx +++ b/packages/repo-advisor/src/features/Layout.tsx @@ -1,58 +1,72 @@ -import Container from "@mui/material/Container"; -import Box from "@mui/material/Box"; -import Grid from "@mui/material/Unstable_Grid2"; -import Typography from "@mui/material/Typography"; -import { lookupLanguageString, type LanguageStrings } from "@dans-framework/utils/language"; -import { I18nextProvider, useTranslation, Trans } from "react-i18next"; -import Link from '@mui/material/Link'; -import { Link as RouterLink } from "react-router-dom"; -import i18n from "../languages/i18n"; - -export const RepoBar = ({repo}: {repo?: LanguageStrings | string}) => - - - - -const RepoBarInner = ({repo}: {repo?: LanguageStrings | string}) => { - const { i18n, t } = useTranslation("repobar"); - return ( - - - - - - {t("activeRepo", { repo: lookupLanguageString(repo, i18n.language) })} - - - - - - ); -} - -export const NoRepoSelected = ({advisorLocation}: {advisorLocation: string}) => - - - - -const NoRepoSelectedInner = ({advisorLocation}: {advisorLocation: string}) => { - const { t } = useTranslation("repobar"); - return ( - - - - {t("selectRepoFirst")} - - , - ]} - /> - - - - - ); -} - +import Container from "@mui/material/Container"; +import Box from "@mui/material/Box"; +import Grid from "@mui/material/Unstable_Grid2"; +import Typography from "@mui/material/Typography"; +import { + lookupLanguageString, + type LanguageStrings, +} from "@dans-framework/utils/language"; +import { I18nextProvider, useTranslation, Trans } from "react-i18next"; +import Link from "@mui/material/Link"; +import { Link as RouterLink } from "react-router-dom"; +import i18n from "../languages/i18n"; + +export const RepoBar = ({ repo }: { repo?: LanguageStrings | string }) => ( + + + +); + +const RepoBarInner = ({ repo }: { repo?: LanguageStrings | string }) => { + const { i18n, t } = useTranslation("repobar"); + return ( + + + + + + {t("activeRepo", { + repo: lookupLanguageString(repo, i18n.language), + })} + + + + + + ); +}; + +export const NoRepoSelected = ({ + advisorLocation, +}: { + advisorLocation: string; +}) => ( + + + +); + +const NoRepoSelectedInner = ({ + advisorLocation, +}: { + advisorLocation: string; +}) => { + const { t } = useTranslation("repobar"); + return ( + + + + {t("selectRepoFirst")} + + , + ]} + /> + + + + + ); +}; diff --git a/packages/repo-advisor/src/features/RepoAdvisor.tsx b/packages/repo-advisor/src/features/RepoAdvisor.tsx index c3e67dd8..15e57ceb 100644 --- a/packages/repo-advisor/src/features/RepoAdvisor.tsx +++ b/packages/repo-advisor/src/features/RepoAdvisor.tsx @@ -1,124 +1,128 @@ -import { useEffect, type Dispatch, type SetStateAction } from "react"; -import { useNavigate } from "react-router-dom"; -import Paper from '@mui/material/Paper'; -import Box from '@mui/material/Box'; -import Button from '@mui/material/Button'; -import Grid from "@mui/material/Unstable_Grid2"; -import Container from "@mui/material/Container"; -import Stepper from '@mui/material/Stepper'; -import Step from '@mui/material/Step'; -import StepLabel from '@mui/material/StepLabel'; -import { useTranslation } from "react-i18next"; -import { useAppSelector, useAppDispatch } from "../redux/hooks"; -import { getActiveStep, getRor, getNarcis, getFileType, getDepositType, setActiveStep, getRepo } from './repoAdvisorSlice'; -import { Step1, Step2 } from './Steps'; -import { useSiteTitle, setSiteTitle } from "@dans-framework/utils/sitetitle"; -import { lookupLanguageString } from "@dans-framework/utils/language"; -import type { Page } from "@dans-framework/pages"; -import type { FormConfig } from "@dans-framework/deposit"; - -const steps = ['defineDataset', 'recommendations']; - -const RepoAdvisor = ({setRepoConfig, page, depositLocation}: { - setRepoConfig: Dispatch>; - page: Page; - depositLocation: string; -}) => { - const dispatch = useAppDispatch(); - const siteTitle = useSiteTitle(); - const ror = useAppSelector(getRor); - const narcis = useAppSelector(getNarcis); - const fileType = useAppSelector(getFileType); - const depositType = useAppSelector(getDepositType); - const repo = useAppSelector(getRepo); - const navigate = useNavigate(); - const activeStep = useAppSelector(getActiveStep); - const { t, i18n } = useTranslation('steps'); - - // set page title - useEffect(() => { - setSiteTitle(siteTitle, lookupLanguageString(page.name, i18n.language)); - }, [siteTitle, page.name]); - - const handleNext = () => { - if (activeStep !== steps.length - 1) { - dispatch(setActiveStep(activeStep + 1)); - } - else if (repo && repo.external) { - window.location.href = repo.external; - } - else { - setRepoConfig(repo); - navigate(depositLocation); - window.scrollTo({top: 0, behavior: "smooth"}); - } - }; - - const handleBack = () => { - dispatch(setActiveStep(activeStep - 1)); - }; - - const dataMissing = - !ror || - !narcis || - !depositType || - (depositType === 'dataset' && !fileType); - - return ( - - - - - - {steps.map((label) => { - const stepProps: { completed?: boolean } = {}; - return ( - - {t(label)} - - ); - })} - - { - activeStep === 0 - ? - : - } - - - - - - - - - - ); -}; - -export default RepoAdvisor; +import { useEffect, type Dispatch, type SetStateAction } from "react"; +import { useNavigate } from "react-router-dom"; +import Paper from "@mui/material/Paper"; +import Box from "@mui/material/Box"; +import Button from "@mui/material/Button"; +import Grid from "@mui/material/Unstable_Grid2"; +import Container from "@mui/material/Container"; +import Stepper from "@mui/material/Stepper"; +import Step from "@mui/material/Step"; +import StepLabel from "@mui/material/StepLabel"; +import { useTranslation } from "react-i18next"; +import { useAppSelector, useAppDispatch } from "../redux/hooks"; +import { + getActiveStep, + getRor, + getNarcis, + getFileType, + getDepositType, + setActiveStep, + getRepo, +} from "./repoAdvisorSlice"; +import { Step1, Step2 } from "./Steps"; +import { useSiteTitle, setSiteTitle } from "@dans-framework/utils/sitetitle"; +import { lookupLanguageString } from "@dans-framework/utils/language"; +import type { Page } from "@dans-framework/pages"; +import type { FormConfig } from "@dans-framework/deposit"; + +const steps = ["defineDataset", "recommendations"]; + +const RepoAdvisor = ({ + setRepoConfig, + page, + depositLocation, +}: { + setRepoConfig: Dispatch>; + page: Page; + depositLocation: string; +}) => { + const dispatch = useAppDispatch(); + const siteTitle = useSiteTitle(); + const ror = useAppSelector(getRor); + const narcis = useAppSelector(getNarcis); + const fileType = useAppSelector(getFileType); + const depositType = useAppSelector(getDepositType); + const repo = useAppSelector(getRepo); + const navigate = useNavigate(); + const activeStep = useAppSelector(getActiveStep); + const { t, i18n } = useTranslation("steps"); + + // set page title + useEffect(() => { + setSiteTitle(siteTitle, lookupLanguageString(page.name, i18n.language)); + }, [siteTitle, page.name]); + + const handleNext = () => { + if (activeStep !== steps.length - 1) { + dispatch(setActiveStep(activeStep + 1)); + } else if (repo && repo.external) { + window.location.href = repo.external; + } else { + setRepoConfig(repo); + navigate(depositLocation); + window.scrollTo({ top: 0, behavior: "smooth" }); + } + }; + + const handleBack = () => { + dispatch(setActiveStep(activeStep - 1)); + }; + + const dataMissing = + !ror || !narcis || !depositType || (depositType === "dataset" && !fileType); + + return ( + + + + + + {steps.map((label) => { + const stepProps: { completed?: boolean } = {}; + return ( + + {t(label)} + + ); + })} + + {activeStep === 0 ? + + : } + + + + + + + + + + ); +}; + +export default RepoAdvisor; diff --git a/packages/repo-advisor/src/features/Steps.tsx b/packages/repo-advisor/src/features/Steps.tsx index 3d628eeb..5b9302d2 100644 --- a/packages/repo-advisor/src/features/Steps.tsx +++ b/packages/repo-advisor/src/features/Steps.tsx @@ -1,156 +1,199 @@ -import { type ReactNode } from "react"; -import Box from "@mui/material/Box"; -import Typography from "@mui/material/Typography"; -import { useTranslation } from "react-i18next"; -import CircularProgress from '@mui/material/CircularProgress'; -import List from '@mui/material/List'; -import ListItem from '@mui/material/ListItem'; -import ListItemButton from '@mui/material/ListItemButton'; -import ListItemText from '@mui/material/ListItemText'; -import ListItemIcon from '@mui/material/ListItemIcon'; -import Checkbox from '@mui/material/Checkbox'; -import Alert from '@mui/material/Alert'; -import Button from '@mui/material/Button'; -import { useAppSelector, useAppDispatch } from "../redux/hooks"; -import { getRor, getNarcis, getDepositType, getFileType, setFileType, setDepositType, getRepo, setRepo } from "./repoAdvisorSlice"; -import { useFetchDataQuery } from "./repoAdvisorApi"; -import { RorField, NarcisField, SelectField } from "./Components"; -import { AnimatePresence, motion } from "framer-motion"; -import { lookupLanguageString, type LanguageStrings } from "@dans-framework/utils/language"; -import type { FormConfig } from "@dans-framework/deposit"; - -const StepWrap = ({ title, children, subtitle }: { title: string; children: ReactNode, subtitle?: string; }) => - - {title} - {subtitle && {subtitle}} - {children} - - -export const Step1 = () => { - const { t } = useTranslation("steps"); - const depositType = useAppSelector(getDepositType); - const fileType = useAppSelector(getFileType); - const dispatch = useAppDispatch(); - - return ( - - - - dispatch(setDepositType(value))} - options={[ - {label: t("dataset"), value: "dataset"}, - {label: t("code"), value: "code"}, - {label: t("report"), value: "report"}, - {label: t("publication"), value: "publication"}, - ]} - /> - - {depositType === 'dataset' && - - dispatch(setFileType(value))} - options={[ - {label: t("audiovisual_materials"), value: "audiovisual_materials"}, - {label: t("statistical_data"), value: "statistical_data"}, - {label: t("geospatial_data_files"), value: "geospatial_data_files"}, - {label: t("netcdf_and_hdf_files"), value: "netcdf_and_hdf_files"}, - {label: t("darwin_core_and_ecological_markup_language_files"), value: "darwin_core_and_ecological_markup_language_files"}, - {label: t("other"), value: "other"}, - ]} - /> - - } - - - ) -} - -export const Step2 = () => { - const { t, i18n } = useTranslation("steps"); - const ror = useAppSelector(getRor); - const narcis = useAppSelector(getNarcis); - const depositType = useAppSelector(getDepositType); - const fileType = useAppSelector(getFileType); - const repo = useAppSelector(getRepo); - const dispatch = useAppDispatch(); - - const { data, isLoading, isError, refetch } = useFetchDataQuery<{ - data: FormConfig[]; - isLoading: boolean; - isError: boolean; - refetch: () => void; - }>({ - ror: ror, - narcis: narcis, - depositType: depositType, - fileType: fileType, - }); - - return ( - - {data && data.length > 0 ? - - {data.map( (rec, i) => - - dispatch(setRepo(rec))} dense> - - - - - {rec.external && - {t("externalRepo")} - } - {lookupLanguageString(rec.description, i18n.language)} - - } - sx={{pr: 6}} - /> - - - )} - - : isLoading ? - - : isError ? - - {t("fetchError")} - - - : - {t("noRepoFound")} - } - - ) -} \ No newline at end of file +import { type ReactNode } from "react"; +import Box from "@mui/material/Box"; +import Typography from "@mui/material/Typography"; +import { useTranslation } from "react-i18next"; +import CircularProgress from "@mui/material/CircularProgress"; +import List from "@mui/material/List"; +import ListItem from "@mui/material/ListItem"; +import ListItemButton from "@mui/material/ListItemButton"; +import ListItemText from "@mui/material/ListItemText"; +import ListItemIcon from "@mui/material/ListItemIcon"; +import Checkbox from "@mui/material/Checkbox"; +import Alert from "@mui/material/Alert"; +import Button from "@mui/material/Button"; +import { useAppSelector, useAppDispatch } from "../redux/hooks"; +import { + getRor, + getNarcis, + getDepositType, + getFileType, + setFileType, + setDepositType, + getRepo, + setRepo, +} from "./repoAdvisorSlice"; +import { useFetchDataQuery } from "./repoAdvisorApi"; +import { RorField, NarcisField, SelectField } from "./Components"; +import { AnimatePresence, motion } from "framer-motion"; +import { + lookupLanguageString, + type LanguageStrings, +} from "@dans-framework/utils/language"; +import type { FormConfig } from "@dans-framework/deposit"; + +const StepWrap = ({ + title, + children, + subtitle, +}: { + title: string; + children: ReactNode; + subtitle?: string; +}) => ( + + {title} + {subtitle && ( + + {subtitle} + + )} + {children} + +); + +export const Step1 = () => { + const { t } = useTranslation("steps"); + const depositType = useAppSelector(getDepositType); + const fileType = useAppSelector(getFileType); + const dispatch = useAppDispatch(); + + return ( + + + + dispatch(setDepositType(value))} + options={[ + { label: t("dataset"), value: "dataset" }, + { label: t("code"), value: "code" }, + { label: t("report"), value: "report" }, + { label: t("publication"), value: "publication" }, + ]} + /> + + {depositType === "dataset" && ( + + dispatch(setFileType(value))} + options={[ + { + label: t("audiovisual_materials"), + value: "audiovisual_materials", + }, + { label: t("statistical_data"), value: "statistical_data" }, + { + label: t("geospatial_data_files"), + value: "geospatial_data_files", + }, + { + label: t("netcdf_and_hdf_files"), + value: "netcdf_and_hdf_files", + }, + { + label: t("darwin_core_and_ecological_markup_language_files"), + value: "darwin_core_and_ecological_markup_language_files", + }, + { label: t("other"), value: "other" }, + ]} + /> + + )} + + + ); +}; + +export const Step2 = () => { + const { t, i18n } = useTranslation("steps"); + const ror = useAppSelector(getRor); + const narcis = useAppSelector(getNarcis); + const depositType = useAppSelector(getDepositType); + const fileType = useAppSelector(getFileType); + const repo = useAppSelector(getRepo); + const dispatch = useAppDispatch(); + + const { data, isLoading, isError, refetch } = useFetchDataQuery<{ + data: FormConfig[]; + isLoading: boolean; + isError: boolean; + refetch: () => void; + }>({ + ror: ror, + narcis: narcis, + depositType: depositType, + fileType: fileType, + }); + + return ( + + {data && data.length > 0 ? + + {data.map((rec, i) => ( + + dispatch(setRepo(rec))} + dense + > + + + + + {rec.external && ( + + {t("externalRepo")} + + )} + {lookupLanguageString(rec.description, i18n.language)} + + } + sx={{ pr: 6 }} + /> + + + ))} + + : isLoading ? + + : isError ? + + {t("fetchError")} + + + : {t("noRepoFound")}} + + ); +}; diff --git a/packages/repo-advisor/src/features/repoAdvisorApi.ts b/packages/repo-advisor/src/features/repoAdvisorApi.ts index 7a584199..ac4006ae 100644 --- a/packages/repo-advisor/src/features/repoAdvisorApi.ts +++ b/packages/repo-advisor/src/features/repoAdvisorApi.ts @@ -1,42 +1,42 @@ -import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; -import { getUser } from "@dans-framework/utils/user"; -import type { RepoResponse } from "../types"; - -export const repoAdvisorApi = createApi({ - reducerPath: "repoAdvisorApi", - baseQuery: fetchBaseQuery({ - baseUrl: import.meta.env.VITE_ADVISOR_URL, - }), - endpoints: (build) => ({ - fetchData: build.query({ - query: ({ ror, narcis, depositType, fileType }) => { - const user = getUser(); - const headers = { - "Content-Type": "application/json", - Authorization: `Bearer ${user?.access_token}`, - "auth-env-name": import.meta.env.VITE_ENV_NAME, - }; - - return ({ - url: 'seek-advice', - method: "POST", - headers: headers, - body: JSON.stringify({ - affiliation: ror.value, - domain: narcis.value, - "deposit-type": depositType, - ...(fileType && { "file-type": fileType }), - }), - }); - }, - transformResponse: (response: RepoResponse) => response.advice, - transformErrorResponse: () => { - return ({ - error: "Error connecting to server" - }); - }, - }), - }), -}); - -export const { useFetchDataQuery } = repoAdvisorApi; \ No newline at end of file +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; +import { getUser } from "@dans-framework/utils/user"; +import type { RepoResponse } from "../types"; + +export const repoAdvisorApi = createApi({ + reducerPath: "repoAdvisorApi", + baseQuery: fetchBaseQuery({ + baseUrl: import.meta.env.VITE_ADVISOR_URL, + }), + endpoints: (build) => ({ + fetchData: build.query({ + query: ({ ror, narcis, depositType, fileType }) => { + const user = getUser(); + const headers = { + "Content-Type": "application/json", + Authorization: `Bearer ${user?.access_token}`, + "auth-env-name": import.meta.env.VITE_ENV_NAME, + }; + + return { + url: "seek-advice", + method: "POST", + headers: headers, + body: JSON.stringify({ + affiliation: ror.value, + domain: narcis.value, + "deposit-type": depositType, + ...(fileType && { "file-type": fileType }), + }), + }; + }, + transformResponse: (response: RepoResponse) => response.advice, + transformErrorResponse: () => { + return { + error: "Error connecting to server", + }; + }, + }), + }), +}); + +export const { useFetchDataQuery } = repoAdvisorApi; diff --git a/packages/repo-advisor/src/features/repoAdvisorSlice.ts b/packages/repo-advisor/src/features/repoAdvisorSlice.ts index b0b4078b..588a2e66 100644 --- a/packages/repo-advisor/src/features/repoAdvisorSlice.ts +++ b/packages/repo-advisor/src/features/repoAdvisorSlice.ts @@ -1,55 +1,63 @@ -import { createSlice, type PayloadAction } from "@reduxjs/toolkit"; -import { RootState } from "../redux/store"; -import type { OptionsType, FormConfig } from "@dans-framework/deposit"; - -const initialState: { - activeStep: number; - ror: OptionsType | null; - narcis: OptionsType | null; - depositType: string; - fileType: string; - repo: FormConfig | undefined; -} = { - activeStep: 0, - ror: null, - narcis: null, - depositType: '', - fileType: '', - repo: undefined, -}; - -export const repoAdvisorSlice = createSlice({ - name: "repoAdvisor", - initialState, - reducers: { - setActiveStep: (state, action: PayloadAction) => { - state.activeStep = action.payload; - }, - setRor: (state, action: PayloadAction) => { - state.ror = action.payload; - }, - setNarcis: (state, action: PayloadAction) => { - state.narcis = action.payload; - }, - setDepositType: (state, action: PayloadAction) => { - state.depositType = action.payload; - }, - setFileType: (state, action: PayloadAction) => { - state.fileType = action.payload; - }, - setRepo: (state, action: PayloadAction) => { - state.repo = action.payload; - } - }, -}); - -export const { setActiveStep, setRor, setNarcis, setFileType, setDepositType, setRepo } = repoAdvisorSlice.actions; - -export const getActiveStep = (state: RootState) => state.repoAdvisor.activeStep; -export const getRor = (state: RootState) => state.repoAdvisor.ror; -export const getNarcis = (state: RootState) => state.repoAdvisor.narcis; -export const getDepositType = (state: RootState) => state.repoAdvisor.depositType; -export const getFileType = (state: RootState) => state.repoAdvisor.fileType; -export const getRepo = (state: RootState) => state.repoAdvisor.repo; - -export default repoAdvisorSlice.reducer; +import { createSlice, type PayloadAction } from "@reduxjs/toolkit"; +import { RootState } from "../redux/store"; +import type { OptionsType, FormConfig } from "@dans-framework/deposit"; + +const initialState: { + activeStep: number; + ror: OptionsType | null; + narcis: OptionsType | null; + depositType: string; + fileType: string; + repo: FormConfig | undefined; +} = { + activeStep: 0, + ror: null, + narcis: null, + depositType: "", + fileType: "", + repo: undefined, +}; + +export const repoAdvisorSlice = createSlice({ + name: "repoAdvisor", + initialState, + reducers: { + setActiveStep: (state, action: PayloadAction) => { + state.activeStep = action.payload; + }, + setRor: (state, action: PayloadAction) => { + state.ror = action.payload; + }, + setNarcis: (state, action: PayloadAction) => { + state.narcis = action.payload; + }, + setDepositType: (state, action: PayloadAction) => { + state.depositType = action.payload; + }, + setFileType: (state, action: PayloadAction) => { + state.fileType = action.payload; + }, + setRepo: (state, action: PayloadAction) => { + state.repo = action.payload; + }, + }, +}); + +export const { + setActiveStep, + setRor, + setNarcis, + setFileType, + setDepositType, + setRepo, +} = repoAdvisorSlice.actions; + +export const getActiveStep = (state: RootState) => state.repoAdvisor.activeStep; +export const getRor = (state: RootState) => state.repoAdvisor.ror; +export const getNarcis = (state: RootState) => state.repoAdvisor.narcis; +export const getDepositType = (state: RootState) => + state.repoAdvisor.depositType; +export const getFileType = (state: RootState) => state.repoAdvisor.fileType; +export const getRepo = (state: RootState) => state.repoAdvisor.repo; + +export default repoAdvisorSlice.reducer; diff --git a/packages/repo-advisor/src/index.tsx b/packages/repo-advisor/src/index.tsx index d0a036b9..98dcf742 100644 --- a/packages/repo-advisor/src/index.tsx +++ b/packages/repo-advisor/src/index.tsx @@ -1,21 +1,30 @@ -import type { Dispatch, SetStateAction } from "react"; -import { I18nextProvider } from "react-i18next"; -import i18nProvider from "./languages/i18n"; -import RepoAdvisor from "./features/RepoAdvisor"; -import { Provider as ReduxProvider } from "react-redux"; -import { store } from './redux/store'; -import type { Page } from "@dans-framework/pages"; -import type { FormConfig } from "@dans-framework/deposit"; - -export const AdvisorWrapper = ({setRepoConfig, page, depositLocation}: { - setRepoConfig: Dispatch>; - page: Page; - depositLocation: string; -}) => - - - - - - -export default AdvisorWrapper; \ No newline at end of file +import type { Dispatch, SetStateAction } from "react"; +import { I18nextProvider } from "react-i18next"; +import i18nProvider from "./languages/i18n"; +import RepoAdvisor from "./features/RepoAdvisor"; +import { Provider as ReduxProvider } from "react-redux"; +import { store } from "./redux/store"; +import type { Page } from "@dans-framework/pages"; +import type { FormConfig } from "@dans-framework/deposit"; + +export const AdvisorWrapper = ({ + setRepoConfig, + page, + depositLocation, +}: { + setRepoConfig: Dispatch>; + page: Page; + depositLocation: string; +}) => ( + + + + + +); + +export default AdvisorWrapper; diff --git a/packages/repo-advisor/src/languages/i18n.ts b/packages/repo-advisor/src/languages/i18n.ts index 3fc475e0..0e05e228 100644 --- a/packages/repo-advisor/src/languages/i18n.ts +++ b/packages/repo-advisor/src/languages/i18n.ts @@ -1,22 +1,22 @@ -import resourcesToBackend from "i18next-resources-to-backend"; -import { createInstance } from "i18next"; -import { initReactI18next } from "react-i18next"; - -const i18n = createInstance({ - fallbackLng: "en", - interpolation: { - escapeValue: false, // not needed for react as it escapes by default - }, -}); - -i18n - .use( - resourcesToBackend( - (language: string, namespace: string) => - import(`./locales/${language}/${namespace}.json`), - ), - ) - .use(initReactI18next) - .init(); - -export default i18n; +import resourcesToBackend from "i18next-resources-to-backend"; +import { createInstance } from "i18next"; +import { initReactI18next } from "react-i18next"; + +const i18n = createInstance({ + fallbackLng: "en", + interpolation: { + escapeValue: false, // not needed for react as it escapes by default + }, +}); + +i18n + .use( + resourcesToBackend( + (language: string, namespace: string) => + import(`./locales/${language}/${namespace}.json`), + ), + ) + .use(initReactI18next) + .init(); + +export default i18n; diff --git a/packages/repo-advisor/src/redux/hooks.ts b/packages/repo-advisor/src/redux/hooks.ts index d0ceb8b7..36b5ea2f 100644 --- a/packages/repo-advisor/src/redux/hooks.ts +++ b/packages/repo-advisor/src/redux/hooks.ts @@ -1,6 +1,6 @@ -import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux"; -import type { RootState, AppDispatch } from "./store"; - -// Use throughout your app instead of plain `useDispatch` and `useSelector` -export const useAppDispatch = () => useDispatch(); -export const useAppSelector: TypedUseSelectorHook = useSelector; \ No newline at end of file +import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux"; +import type { RootState, AppDispatch } from "./store"; + +// Use throughout your app instead of plain `useDispatch` and `useSelector` +export const useAppDispatch = () => useDispatch(); +export const useAppSelector: TypedUseSelectorHook = useSelector; diff --git a/packages/repo-advisor/src/redux/store.ts b/packages/repo-advisor/src/redux/store.ts index 7c634da7..908ee134 100644 --- a/packages/repo-advisor/src/redux/store.ts +++ b/packages/repo-advisor/src/redux/store.ts @@ -1,23 +1,23 @@ -import { configureStore } from "@reduxjs/toolkit"; -import { errorLogger } from "@dans-framework/utils/error"; -import repoAdvisorReducer from "../features/repoAdvisorSlice"; -import { repoAdvisorApi } from "../features/repoAdvisorApi"; -import { datastationsApi, rorApi } from "@dans-framework/deposit"; - -export const store = configureStore({ - reducer: { - repoAdvisor: repoAdvisorReducer, - [repoAdvisorApi.reducerPath]: repoAdvisorApi.reducer, - [datastationsApi.reducerPath]: datastationsApi.reducer, - [rorApi.reducerPath]: rorApi.reducer, - }, - middleware: (getDefaultMiddleware) => - getDefaultMiddleware() - .concat(repoAdvisorApi.middleware) - .concat(datastationsApi.middleware) - .concat(rorApi.middleware) - .concat(errorLogger) -}); - -export type AppDispatch = typeof store.dispatch; -export type RootState = ReturnType; +import { configureStore } from "@reduxjs/toolkit"; +import { errorLogger } from "@dans-framework/utils/error"; +import repoAdvisorReducer from "../features/repoAdvisorSlice"; +import { repoAdvisorApi } from "../features/repoAdvisorApi"; +import { datastationsApi, rorApi } from "@dans-framework/deposit"; + +export const store = configureStore({ + reducer: { + repoAdvisor: repoAdvisorReducer, + [repoAdvisorApi.reducerPath]: repoAdvisorApi.reducer, + [datastationsApi.reducerPath]: datastationsApi.reducer, + [rorApi.reducerPath]: rorApi.reducer, + }, + middleware: (getDefaultMiddleware) => + getDefaultMiddleware() + .concat(repoAdvisorApi.middleware) + .concat(datastationsApi.middleware) + .concat(rorApi.middleware) + .concat(errorLogger), +}); + +export type AppDispatch = typeof store.dispatch; +export type RootState = ReturnType; diff --git a/packages/repo-advisor/src/types/index.ts b/packages/repo-advisor/src/types/index.ts index 5f0d0f78..2b54f7de 100644 --- a/packages/repo-advisor/src/types/index.ts +++ b/packages/repo-advisor/src/types/index.ts @@ -1,19 +1,20 @@ -import type { LanguageStrings } from "@dans-framework/utils/language"; -import type { AutocompleteAPIFieldProps } from "@dans-framework/deposit"; -import type { OptionsType, FormConfig } from "@dans-framework/deposit"; - -export interface RepoResponse { - advice: { - displayName: LanguageStrings; - description: LanguageStrings; - form?: FormConfig; - external?: string; - }[] -} - -export interface AutocompleteProps extends Omit { - disabled?: boolean; - label: string; - setValue: (val: OptionsType | null) => void; - value: OptionsType | null; -} \ No newline at end of file +import type { LanguageStrings } from "@dans-framework/utils/language"; +import type { AutocompleteAPIFieldProps } from "@dans-framework/deposit"; +import type { OptionsType, FormConfig } from "@dans-framework/deposit"; + +export interface RepoResponse { + advice: { + displayName: LanguageStrings; + description: LanguageStrings; + form?: FormConfig; + external?: string; + }[]; +} + +export interface AutocompleteProps + extends Omit { + disabled?: boolean; + label: string; + setValue: (val: OptionsType | null) => void; + value: OptionsType | null; +} diff --git a/packages/user-auth/src/auth/Auth.tsx b/packages/user-auth/src/auth/Auth.tsx index 8da34845..dce9311e 100644 --- a/packages/user-auth/src/auth/Auth.tsx +++ b/packages/user-auth/src/auth/Auth.tsx @@ -12,7 +12,7 @@ import i18nProvider from "../languages/i18n"; import type { AuthProviderConfig } from "../types"; import { store } from "../redux/store"; import { LoginPage } from "./Login"; -import { WebStorageStateStore } from 'oidc-client-ts'; +import { WebStorageStateStore } from "oidc-client-ts"; export const AuthWrapper = ({ authProvider, @@ -25,8 +25,8 @@ export const AuthWrapper = ({ const authProviderConfig = { ...authProvider, userStore: new WebStorageStateStore({ store: window.sessionStorage }), - monitorSession: true // this allows cross tab login/logout detection - } + monitorSession: true, // this allows cross tab login/logout detection + }; return ( diff --git a/packages/user-auth/src/auth/Login.tsx b/packages/user-auth/src/auth/Login.tsx index 3e700bbc..783a3842 100644 --- a/packages/user-auth/src/auth/Login.tsx +++ b/packages/user-auth/src/auth/Login.tsx @@ -8,13 +8,13 @@ import { LoginButton } from "../user/Buttons"; import { useSearchParams } from "react-router-dom"; export const LoginPage = () => { - const [ searchParams ] = useSearchParams(); + const [searchParams] = useSearchParams(); useEffect(() => { // save data params to session storage to get them back after Keycloak login const data = searchParams.get("data"); if (data) { - sessionStorage.setItem('preloadData', data); + sessionStorage.setItem("preloadData", data); } }, [searchParams]); diff --git a/packages/user-auth/src/types/index.ts b/packages/user-auth/src/types/index.ts index 8b84ce97..41b09981 100644 --- a/packages/user-auth/src/types/index.ts +++ b/packages/user-auth/src/types/index.ts @@ -10,7 +10,10 @@ export interface AuthProviderConfig { } // Define the types of targets here, so we can use this in the key checking API -export type AuthKeys = "dataverse_api_key" | "zenodo_api_key" | "dataverse_nl_api_key"; +export type AuthKeys = + | "dataverse_api_key" + | "zenodo_api_key" + | "dataverse_nl_api_key"; export interface Target { name: string; diff --git a/packages/user-auth/src/user/Buttons.tsx b/packages/user-auth/src/user/Buttons.tsx index c81e68c2..ed04dad5 100644 --- a/packages/user-auth/src/user/Buttons.tsx +++ b/packages/user-auth/src/user/Buttons.tsx @@ -34,7 +34,7 @@ export const LoginButton = ({ variant }: { variant?: "contained" }) => { enqueueSnackbar("Error redirecting to sign-in server", { variant: "customError", }), - ) + ); } } > diff --git a/packages/user-auth/src/user/UserMenu.tsx b/packages/user-auth/src/user/UserMenu.tsx index 3275230e..6c4ee2f4 100644 --- a/packages/user-auth/src/user/UserMenu.tsx +++ b/packages/user-auth/src/user/UserMenu.tsx @@ -26,7 +26,13 @@ export const UserMenu = ({ // keep user signed in, and try to sign in automatically const [hasTriedSignin, setHasTriedSignin] = useState(false); useEffect(() => { - if (!hasAuthParams() && !auth.isAuthenticated && !auth.activeNavigator && !auth.isLoading && !hasTriedSignin) { + if ( + !hasAuthParams() && + !auth.isAuthenticated && + !auth.activeNavigator && + !auth.isLoading && + !hasTriedSignin + ) { auth.signinSilent(); setHasTriedSignin(true); } @@ -35,7 +41,7 @@ export const UserMenu = ({ // if we get an error renewing the token, just sign the user out useEffect(() => { auth.events.addSilentRenewError(() => { - console.error('Auth event: silent renew error. Signing user out.'); + console.error("Auth event: silent renew error. Signing user out."); auth.removeUser(); }); }, [auth.events, auth.removeUser]); diff --git a/packages/user-auth/src/user/UserSettings.tsx b/packages/user-auth/src/user/UserSettings.tsx index d3f3715a..e0753393 100644 --- a/packages/user-auth/src/user/UserSettings.tsx +++ b/packages/user-auth/src/user/UserSettings.tsx @@ -71,7 +71,11 @@ export const UserSettings = ({ + ) + } + + ); +} + +function useValues(props: ListFacetProps, page: number) { + const [values, setValues] = React.useState< + ListFacetProps["values"]["values"] + >([]); + + // An effect is needed to update the values when the page changes, + // because a page change triggers a render before the values have been updated. + // When the values are not updated, page is at for example 2, but the values + // are still from page 1 (for example Array(10)), slicing an empty array, + // causing a flicker in the rendering. + React.useEffect(() => { + if (props.values == null) return; + + // Don't set the values if the pagination is enabled and the values + // have not been fetched yet + if (props.viewState.pagination) { + // Calculate the number of pages (total: 28 / size: 10 = 2.8 => 3 pages) + const pageCount = Math.ceil( + props.values.total / props.facet.config.size!, + ); + + // Check if the values have the required length (ie the values have been fetched and updated) + if ( + // The last page can be smaller than the configured size, so the length of the values + // is checked against the total values number retuned by the search API + // For example, when page = 3, values.length = 20, values.total = 28, + // wait until values are fetched and values.length becomes 28 + (page === pageCount && + props.values.values.length !== props.values.total) || + // The other pages should have the configured size + // For example, when page = 2, values.length = 10, config.size = 10, + // wait until values are fetched and values.length becomes 20 + (page !== pageCount && + props.values.values.length !== page * props.facet.config.size!) + ) { + return; + } + } + + const from = props.facet.config.size! * (page - 1); + const _values = props.values.values.slice(from, props.facetState.size); + + setValues(_values); + }, [props.values, page]); + + return values; +} + +function usePage( + props: ListFacetProps, + dispatch: React.Dispatch, +) { + const [page, setPage] = React.useState(props.facetState.page); + + // Update the page in the facetState when the page changes, + // but check if the page is not the same, this happens after + // the facetState and page are just synced (see next useEffect) + React.useEffect(() => { + if (props.facetState.page === page) return; + + dispatch({ + type: "UPDATE_FACET_STATE", + subType: "LIST_FACET_SET_PAGE", + facetID: props.facet.ID, + page, + }); + }, [page]); + + // Update the page from the facetState. For example when the user selects a value, + // the page is reset to 1 + React.useEffect(() => { + if (props.facetState.page !== page) { + setPage(props.facetState.page); + } + }, [props.facetState.page]); + + return [page, setPage] as const; +} diff --git a/packages/rdt-search-ui/src/facets/list/view/more-less-buttons.tsx b/packages/rdt-search-ui/src/facets/list/view/more-less-buttons.tsx new file mode 100644 index 00000000..bb746132 --- /dev/null +++ b/packages/rdt-search-ui/src/facets/list/view/more-less-buttons.tsx @@ -0,0 +1,42 @@ +import type { ListFacetProps } from "."; + +import React from "react"; +import styled from "styled-components"; + +import { MoreLessButton } from "../../../views/ui/button"; + +import { SearchPropsContext } from "../../../context/props"; +import { useTranslation } from "react-i18next"; + +// Add margin to the right of the "View More" button, +// so that it doesn't touch the "View Less" button. +const MoreButton = styled(MoreLessButton)` + margin-right: 1rem; +`; + +export default function (props: ListFacetProps) { + const { style } = React.useContext(SearchPropsContext); + const facetConfig = props.facet.config; + const { t } = useTranslation("facets"); + + return ( + <> + {props.values.total > 0 && props.values.total > props.facetState.size && ( + props.facet.actions.viewMore()} + spotColor={style.spotColor} + > + {t("viewMore", { value: props.values.total - props.facetState.size })} + + )} + {facetConfig.size! < props.facetState.size && ( + props.facet.actions.viewLess()} + spotColor={style.spotColor} + > + {t("viewLess")} + + )} + + ); +} diff --git a/packages/rdt-search-ui/src/facets/list/view/options.tsx b/packages/rdt-search-ui/src/facets/list/view/options.tsx new file mode 100644 index 00000000..59c48782 --- /dev/null +++ b/packages/rdt-search-ui/src/facets/list/view/options.tsx @@ -0,0 +1,179 @@ +import React from "react"; +import debounce from "lodash.debounce"; + +import type { ListFacetProps } from "."; +import { SearchPropsContext } from "../../../context/props"; +import { SortBy, SortDirection } from "../../../enum"; +import TextField from "@mui/material/TextField"; +import Stack from "@mui/material/Stack"; +import IconButton from "@mui/material/IconButton"; +import { useTranslation } from "react-i18next"; + +function Options(props: ListFacetProps) { + const { style } = React.useContext(SearchPropsContext); + const [filterInputValue, setFilterInputValue] = React.useState(""); + const { t } = useTranslation("facets"); + + const setQuery = debounce((value: string) => { + // props.facet.actions.setQuery(value) + props.dispatch({ + type: "UPDATE_FACET_STATE", + subType: "LIST_FACET_SET_QUERY", + facetID: props.facet.ID, + query: value, + }); + }, 600); + + const handleFilterInputChange = React.useCallback( + (ev: React.ChangeEvent) => { + setFilterInputValue(ev.target.value); + setQuery(ev.target.value); + }, + [], + ); + + const sortByKey = props.facetState.sort.by === SortBy.Key; + const sortByCount = props.facetState.sort.by === SortBy.Count; + const ascending = props.facetState.sort.direction === SortDirection.Asc; + + return ( + + + + { + props.dispatch({ + type: "UPDATE_FACET_STATE", + subType: "LIST_FACET_SET_SORT", + facetID: props.facet.ID, + sort: { + by: SortBy.Key, + direction: ascending ? SortDirection.Desc : SortDirection.Asc, + }, + }); + }} + > + {sortByKey && ascending ? + + : } + + { + props.dispatch({ + type: "UPDATE_FACET_STATE", + subType: "LIST_FACET_SET_SORT", + facetID: props.facet.ID, + sort: { + by: SortBy.Count, + direction: + props.facetState.sort.direction === SortDirection.Asc ? + SortDirection.Desc + : SortDirection.Asc, + }, + }); + }} + > + {sortByCount && ascending ? + + : + } + + + + ); +} + +export default React.memo(Options); + +function SortAlphaAscIcon({ color = "#444" }: { color: string }) { + const { t } = useTranslation("facets"); + return ( + + {t("sortAz")} + + + + + ); +} + +function SortAlphaDescIcon({ color = "#444" }: { color: string }) { + const { t } = useTranslation("facets"); + return ( + + {t("sortAz")} + + + + + ); +} + +function SortNumericAscIcon({ color = "#444" }: { color: string }) { + const { t } = useTranslation("facets"); + return ( + + {t("sortCount")} + + + + + ); +} + +function SortNumericDescIcon({ color = "#444" }: { color: string }) { + const { t } = useTranslation("facets"); + return ( + + {t("sortCount")} + + + + + ); +} diff --git a/packages/rdt-search-ui/src/facets/list/view/state.ts b/packages/rdt-search-ui/src/facets/list/view/state.ts new file mode 100644 index 00000000..676a109d --- /dev/null +++ b/packages/rdt-search-ui/src/facets/list/view/state.ts @@ -0,0 +1,71 @@ +import { ListFacetConfig, ListFacetState, ListFacetValues } from "../state"; +import { LIST_FACET_SCROLL_CUT_OFF } from "./list-view"; + +export interface ListFacetViewState { + pagination: boolean; + scroll: boolean; + scrollButton: boolean; + query: boolean; +} + +export const listFacetViewStates: Record = { + /** Without query */ + + // total < size + 0: { pagination: false, scroll: false, scrollButton: false, query: false }, + + // total < LIST_FACET_SCROLL_CUT_OFF + 1: { pagination: false, scroll: false, scrollButton: true, query: false }, + + // size === total && total <= LIST_FACET_SCROLL_CUT_OFF + 2: { pagination: false, scroll: true, scrollButton: false, query: false }, + + // total > LIST_FACET_SCROLL_CUT_OFF + 3: { pagination: true, scroll: false, scrollButton: false, query: false }, + + /** With query */ + + 4: { pagination: false, scroll: false, scrollButton: false, query: true }, + + // values.length === size + 5: { pagination: false, scroll: false, scrollButton: true, query: true }, + + // config.size < values.length <= LIST_FACET_SCROLL_CUT_OFF + 6: { pagination: false, scroll: true, scrollButton: false, query: true }, +}; + +// const total = props.facetState.query ? props.values.bucketsCount : props.values.total +// total, props.facet.config.size!, props.facetState.size, props.facetState.query) +// console.log(viewState) + +export function getViewState( + values: ListFacetValues, + state: ListFacetState, + config: ListFacetConfig, +) { + if (values == null) return listFacetViewStates[0]; + + const total = state.query ? values.bucketsCount : values.total; + + if (state.query?.length) { + if (total < config.size!) return listFacetViewStates[4]; + else if (total > config.size!) return listFacetViewStates[6]; + else if (total === config.size!) return listFacetViewStates[5]; + else + throw new Error( + `[viewState not set] Unexpected total (${total}) for query "${state.query}"`, + ); + } + + if (total < config.size!) { + return listFacetViewStates[0]; + } else if (total <= LIST_FACET_SCROLL_CUT_OFF) { + return state.size === total ? + listFacetViewStates[2] + : listFacetViewStates[1]; + } else if (total > LIST_FACET_SCROLL_CUT_OFF) { + return listFacetViewStates[3]; + } else { + throw new Error(`[viewState not set] unexpected total (${total})`); + } +} diff --git a/packages/rdt-search-ui/src/facets/list/view/value.tsx b/packages/rdt-search-ui/src/facets/list/view/value.tsx new file mode 100644 index 00000000..1afd4ebf --- /dev/null +++ b/packages/rdt-search-ui/src/facets/list/view/value.tsx @@ -0,0 +1,50 @@ +import React from "react"; +import { KeyCount, ListFacetState } from "../state"; +import Stack from "@mui/material/Stack"; +import Typography from "@mui/material/Typography"; +import parse from "html-react-parser"; +interface Props { + active: boolean; + keyFormatter: (key: string | number, query?: string) => string; + query: ListFacetState["query"]; + toggleFilter: (ev: React.MouseEvent) => void; + value: KeyCount; +} + +function ListFacetValueView(props: Props) { + const style = { + cursor: "pointer", + "&:hover > p": { + fontWeight: "bold", + }, + "& > p": { + fontWeight: props.active ? "bold" : "normal", + }, + }; + return ( +
    + + + {parse(props.keyFormatter(props.value.key, props.query))} + + {props.value.count} + +
    + ); +} + +ListFacetValueView.defaultProps = { + // TODO use keyFormatter higher up the tree? now everytime the facet value is rendered, + // the keyFormatter function is run + keyFormatter: (value: string, query?: ListFacetState["query"]) => { + value = value.trim().length > 0 ? value : "<empty>"; + + if (query?.length) { + value = value.replace(new RegExp(`(${query})`, "gi"), "$1"); + } + + return value; + }, +}; + +export default ListFacetValueView; diff --git a/packages/rdt-search-ui/src/facets/map/actions.ts b/packages/rdt-search-ui/src/facets/map/actions.ts new file mode 100644 index 00000000..80a34426 --- /dev/null +++ b/packages/rdt-search-ui/src/facets/map/actions.ts @@ -0,0 +1,20 @@ +import { + UpdateFacetFilter, + UpdateFacetState, +} from "../../context/state/actions"; +import { MapFacetFilter } from "./state"; + +// +interface MapFacetToggleSearchOnZoom extends UpdateFacetState { + subType: "MAP_FACET_TOGGLE_SEARCH_ON_ZOOM"; +} +// <\UPDATE_FACET_STATE> + +// +interface MapFacetSetFilter extends UpdateFacetFilter { + subType: "MAP_FACET_SET_FILTER"; + value: MapFacetFilter; +} +// + +export type MapFacetAction = MapFacetToggleSearchOnZoom | MapFacetSetFilter; diff --git a/packages/rdt-search-ui/src/facets/map/controller.ts b/packages/rdt-search-ui/src/facets/map/controller.ts new file mode 100644 index 00000000..d889c4fd --- /dev/null +++ b/packages/rdt-search-ui/src/facets/map/controller.ts @@ -0,0 +1,163 @@ +import type { Bucket } from "../../context/state/use-search/response-with-facets-parser"; +import type { + MapFacetState, + MapFacetConfig, + MapFacetValue, + MapFacetFilter, +} from "./state"; +import type { FacetFilterObject } from "../../context/state/facets"; +import type { ElasticSearchResponse } from "../../context/state/use-search/types"; + +import ngeohash from "ngeohash"; + +import { addFilter } from "../../context/state/use-search/request-with-facets-creator"; +import { MapFacet } from "./view"; +import { FacetController } from "../controller"; +import { SearchState } from "../../context/state"; +import { FacetsDataReducerAction } from "../../context/state/actions"; + +function capitalize(str: string) { + return str.charAt(0).toUpperCase() + str.slice(1); +} + +export class MapFacetController extends FacetController< + MapFacetConfig, + MapFacetState, + MapFacetFilter +> { + View = MapFacet; + + reducer(state: SearchState, action: FacetsDataReducerAction): SearchState { + const facetState = state.facetStates.get(this.ID) as MapFacetState; + const nextState = { ...facetState }; + + // + if ( + action.type === "UPDATE_FACET_STATE" && + action.subType === "MAP_FACET_TOGGLE_SEARCH_ON_ZOOM" + ) { + nextState.searchOnZoom = !nextState.searchOnZoom; + return this.updateFacetState(nextState, state); + } + // <\STATE> + + const facetFilter = state.facetFilters.get(this.ID) as + | FacetFilterObject + | undefined; + + // + if (action.type === "REMOVE_FILTER") { + return this.updateFacetFilter(undefined, state); + } + + if ( + action.type === "UPDATE_FACET_FILTER" && + action.subType === "MAP_FACET_SET_FILTER" + ) { + // Only update the filter when it has changed, + // this happens when the filter is not yet set (undefined) + // and the user triggers a reset (again undefined) + const isUpdate = facetFilter?.value !== action.value; + + // Dispatch the change if the filter has changed + // and the searchOnZoom is enabled + if (isUpdate && facetState.searchOnZoom) { + return this.updateFacetFilter(action.value, state); + } + } + // <\FILTER> + + return state; + } + + // private dispatchChange() { + // const detail = { ID: this.ID, state: { ...this.state } } + + // this.dispatchEvent( + // new CustomEvent(EventName.FacetStateChange, { detail }) + // ) + // } + + // Config + protected initConfig(config: MapFacetConfig): MapFacetConfig { + return { + title: capitalize(config.field), + zoom: config.zoom || 0, + ...config, + }; + } + + // State + initState(): MapFacetState { + return { + collapse: this.config.collapse || false, + searchOnZoom: this.config.searchOnZoom || true, + }; + } + + formatFilter(filter: MapFacetFilter) { + if (filter?.bounds == null) return []; + return [filter.bounds.map((f) => f.toFixed(2)).join(", ")]; + } + + // Search request + createPostFilter(filter: MapFacetFilter) { + let bounds = undefined; + if (filter != null) { + let [lonmin, latmax, lonmax, latmin] = filter.bounds as [ + number, + number, + number, + number, + ]; + if (lonmin < -180) lonmin = -180; + if (lonmax > 180) lonmax = 180; + if (latmax < -90) latmax = -90; + if (latmin > 90) latmin = 90; + bounds = { + top_left: `${latmin}, ${lonmin}`, + bottom_right: `${latmax}, ${lonmax}`, + }; + } + + if (bounds == null) return; + + return { + geo_bounding_box: { + [this.config.field]: bounds, + }, + }; + } + + createAggregation(postFilters: any, filter: MapFacetFilter) { + // if filter is not set, use the zoom set in the config + const zoom = filter?.zoom == null ? this.config.zoom : filter.zoom; + + let precision = Math.ceil(zoom || 0); + if (precision < 1) precision = 1; + if (precision > 12) precision = 12; + + const values = { + geohash_grid: { + field: this.config.field, + precision, + }, + }; + + return addFilter(this.ID, values, postFilters); + } + + // Search response + responseParser( + buckets: Bucket[], + _response: ElasticSearchResponse, + ): MapFacetValue[] { + return buckets.map((bucket) => { + const point = ngeohash.decode(bucket.key as string); + return { + point: [point.latitude, point.longitude], + count: bucket.doc_count, + }; + }); + } +} diff --git a/packages/rdt-search-ui/src/facets/map/state.ts b/packages/rdt-search-ui/src/facets/map/state.ts new file mode 100644 index 00000000..1fea85f0 --- /dev/null +++ b/packages/rdt-search-ui/src/facets/map/state.ts @@ -0,0 +1,25 @@ +import type { + BaseFacetConfig, + BaseFacetState, +} from "../../context/state/facets"; + +export interface MapFacetConfig extends BaseFacetConfig { + searchOnZoom?: boolean; + zoom?: number; + center?: { lon: number; lat: number }; +} + +export interface MapFacetState extends BaseFacetState { + // filter: MapFacetFilter | undefined + searchOnZoom: boolean; +} + +export interface MapFacetValue { + point: [number, number]; // [lat, lon] + count: number; +} + +export interface MapFacetFilter { + bounds: [number, number, number, number] | undefined; // [latmin, lonmin, latmax, lonmax] + zoom: number; +} diff --git a/packages/rdt-search-ui/src/facets/map/view/index.tsx b/packages/rdt-search-ui/src/facets/map/view/index.tsx new file mode 100644 index 00000000..7f857aa9 --- /dev/null +++ b/packages/rdt-search-ui/src/facets/map/view/index.tsx @@ -0,0 +1,67 @@ +import type { + MapFacetConfig, + MapFacetFilter, + MapFacetState, + MapFacetValue, +} from "../state"; + +import React from "react"; + +import FacetWrapper from "../../wrapper"; +import { MapFacetController } from "../controller"; +import { MapView } from "./map"; +import { isConfig } from "../../common"; +import styled from "styled-components"; +import { FACETS_WIDTH } from "../../../constants"; +import type { FacetsDataReducerAction } from "../../../context/state/actions"; + +const MapFacetWrapper = styled(FacetWrapper)` + .inner-container { + display: grid; + grid-template-rows: 1fr fit-content(0); + height: 100%; + min-height: ${FACETS_WIDTH * 0.75}px; + } +`; + +// TODO extend a FacetProps { dispatch, facet, state, filter, values } +export interface MapFacetProps { + dispatch: React.Dispatch; + facet: MapFacetController; + facetState: MapFacetState; + filter: MapFacetFilter; + values: MapFacetValue[]; +} + +export function MapFacet(props: { config: MapFacetConfig } | MapFacetProps) { + if (isConfig(props)) return null; + return <_MapFacet {...props} />; +} +MapFacet.controller = MapFacetController; + +function _MapFacet(props: MapFacetProps) { + if (props.facetState == null) return; + + return ( + +
    + +
    + { + props.dispatch({ + type: "UPDATE_FACET_STATE", + subType: "MAP_FACET_TOGGLE_SEARCH_ON_ZOOM", + facetID: props.facet.ID, + }); + }} + /> + +
    +
    +
    + ); +} diff --git a/packages/rdt-search-ui/src/facets/map/view/map-instance.ts b/packages/rdt-search-ui/src/facets/map/view/map-instance.ts new file mode 100644 index 00000000..d5603211 --- /dev/null +++ b/packages/rdt-search-ui/src/facets/map/view/map-instance.ts @@ -0,0 +1,129 @@ +import OLMap from "ol/Map"; +import View from "ol/View"; +import TileLayer from "ol/layer/WebGLTile"; +import Style from "ol/style/Style"; +import CircleStyle from "ol/style/Circle"; +import Stroke from "ol/style/Stroke"; +import Fill from "ol/style/Fill"; +import Text from "ol/style/Text"; +import OSM from "ol/source/OSM"; +import Feature from "ol/Feature"; +import { transformExtent } from "ol/proj"; + +// export function getAnnotationCoordinate(annotation: Annotation) { +// const [lat, lon] = annotation.value.coordinates +// return fromLonLat([lon, lat]) +// } + +const style = new Style({ + image: new CircleStyle({ + radius: 0, + stroke: new Stroke({ + color: "black", + width: 0.5, + }), + fill: new Fill({ + // color: '#FF0000' + // color: '#0b6aff' + color: "#3382ff", + }), + }), + text: new Text({ + fill: new Fill({ + color: "#fff", + }), + stroke: new Stroke({ + color: "white", + width: 1, + }), + }), +}); + +export const markerStyle = (feature: Feature) => { + let radius: number = feature.get("count") + 6; + if (radius > 12) radius = 12; + + (style.getImage() as CircleStyle).setRadius(radius); + style + .getText() + .setText( + feature.get("count") > 1 ? feature.get("count").toString() : undefined, + ); + + return style; +}; + +// export const markerStyle = (feature: Feature) => { +// let radius = feature.get('count') + 6 +// if (radius > 12) radius = 12 + +// return new Style({ +// image: new CircleStyle({ +// // radius: 8, +// radius, +// stroke: new Stroke({ +// color: 'black', +// width: .5, +// }), +// fill: new Fill({ +// // color: '#FF0000' +// // color: '#0b6aff' +// color: '#3382ff' +// }), +// }), +// text: new Text({ +// text: feature.get('count') > 1 ? feature.get('count').toString() : undefined, +// fill: new Fill({ +// color: '#fff', +// }), +// stroke: new Stroke({ +// color: 'white', +// width: 1, +// }), +// }), +// }) +// } + +export function getMapInstance(target?: HTMLElement) { + return new OLMap({ + controls: [], + target, + layers: [ + // new VectorTileLayer({ + // source: new VectorTile({ + // format: new MVT(), + // url: `https://basemaps-api.arcgis.com/arcgis/rest/services/World_Basemap_v2/VectorTileServer/tile/{z}/{y}/{x}.pbf` //?token= + // }) + // }), + new TileLayer({ + // source: new Stamen({ + // layer: 'watercolor', + // }) + // source: new XYZ({ + // url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png' + // }) + + source: new OSM(), + + // source: new XYZ({ + // attributions: + // 'Tiles © ArcGIS', + // url: + // 'https://server.arcgisonline.com/ArcGIS/rest/services/' + + // 'World_Topo_Map/MapServer/tile/{z}/{y}/{x}', + // }), + }), + ], + // overlays: [popupOverlay], + view: new View({ + center: [0, 0], + zoom: 0, + extent: transformExtent( + [-180, -90, 180, 90], + "EPSG:4326", + "EPSG:3857", + ) as [number, number, number, number], + }), + }); +} diff --git a/packages/rdt-search-ui/src/facets/map/view/map.tsx b/packages/rdt-search-ui/src/facets/map/view/map.tsx new file mode 100644 index 00000000..291babad --- /dev/null +++ b/packages/rdt-search-ui/src/facets/map/view/map.tsx @@ -0,0 +1,169 @@ +import type { MapFacetProps } from "."; + +import React from "react"; + +import { getMapInstance, markerStyle } from "./map-instance"; +import OLMap from "ol/Map"; +import Feature from "ol/Feature"; +import Point from "ol/geom/Point"; +import { fromLonLat, transformExtent } from "ol/proj"; +import VectorLayer from "ol/layer/Vector"; +import VectorSource from "ol/source/Vector"; +import styled from "styled-components"; +import { MapFacetFilter } from "../state"; +import { MapFacetAction } from "../actions"; +// import { FACETS_WIDTH } from '../../../constants' + +// height: ${FACETS_WIDTH * .75}px; +const Wrapper = styled.div` + width: 100%; +`; + +export function MapView( + props: MapFacetProps & { dispatch: React.Dispatch }, +) { + const initialZoom = React.useRef(0); + const [vectorSource, setVectorSource] = React.useState(); + const [map, setMap] = React.useState(); + const mapRef = React.useRef(null); + + React.useEffect(() => { + if (map != null) return; + const div = mapRef.current; + if (!div) return; + + const _map = getMapInstance(div); + + const vectorSource = new VectorSource({ + features: [], + }); + + const vectorLayer = new VectorLayer({ + source: vectorSource, + // @ts-ignore + style: markerStyle, + }); + + _map.addLayer(vectorLayer); + + // this.popupOverlay = new Overlay({ + // element: this.popupEl, + // autoPan: { animation: { duration: 250 } } + // }) + // map.addOverlay(this.popupOverlay) + + // this.clickInteraction = new Select() + // this.clickInteraction.on('select', e => { + // if (!e.selected.length) return + + // store.dispatch({ + // type: AppActions.SetActiveAnnotation, + // payload: { + // id: e.selected[0].get('annotation_id') + // } + // }) + + // const coordinate =e.selected[0].get('coordinate') + // if (coordinate) this.popupOverlay.setPosition(coordinate) + // }) + // map.addInteraction(this.clickInteraction) + + // Wrap moveend in rendercomplete to avoid setting the filter + // when the map is first initialized. + _map.once("rendercomplete", () => { + const view = _map.getView(); + initialZoom.current = view.getZoom()!; + + _map.on("moveend", () => { + const zoom = view.getZoom()!; + + let payload: MapFacetFilter | undefined = undefined; + + // Only set the filter if the zoom is not the initial zoom. + if (zoom != initialZoom.current) { + const extent = view.calculateExtent(); + const bounds = transformExtent(extent, "EPSG:3857", "EPSG:4326") as [ + number, + number, + number, + number, + ]; + payload = { bounds, zoom }; + + props.dispatch({ + type: "UPDATE_FACET_FILTER", + subType: "MAP_FACET_SET_FILTER", + facetID: props.facet.ID, + value: payload, + }); + } + }); + }); + + setVectorSource(vectorSource); + setMap(_map); + + return () => _map.dispose(); + }, []); + + // When the facet is reset to the initial state, + // reset the map view (zoom and bounds). + React.useEffect(() => { + const view = map?.getView()!; + if (props.filter == null && view != null) { + // Reset the zoom to the initial zoom + view.setZoom(initialZoom.current); + + // Reset the bounds to the full extent + const bounds = transformExtent( + [-180, -90, 180, 90], + "EPSG:4326", + "EPSG:3857", + ); + view.fit(bounds); + } + }, [props.filter]); + + // Effect for restoring the view (zoom and bounds) of the map + // when the facet is re-expanded. + React.useEffect(() => { + const view = map?.getView(); + + if ( + view == null || + view.getZoom() == null || + props.filter?.zoom == null || + props.filter?.bounds == null + ) + return; + + if (!props.facetState.collapse && props.filter.zoom !== view.getZoom()) { + view.setZoom(props.filter.zoom); + view.fit(transformExtent(props.filter.bounds, "EPSG:4326", "EPSG:3857")); + } + }, [props.facetState.collapse, props.filter, map]); + + // Draw features (markers) on the map. + // This effect is mainly used to update features on the map when + // the facet values change. But also when the map is re-initialized, + // for example when the user collapses and re-expands the facet. + React.useEffect(() => { + if (vectorSource == null || map == null || props.values == null) return; + + const features: Feature[] = []; + for (const value of props.values) { + const coordinate = fromLonLat([value.point[1], value.point[0]]); + const feat = new Feature({ + geometry: new Point(coordinate), + }); + feat.set("coordinate", coordinate); + feat.set("count", value.count); + features.push(feat); + } + + vectorSource.clear(); + vectorSource.addFeatures(features); + }, [props.values, map, vectorSource]); + + return ; +} diff --git a/packages/rdt-search-ui/src/facets/wrapper.module.css b/packages/rdt-search-ui/src/facets/wrapper.module.css new file mode 100644 index 00000000..ed694853 --- /dev/null +++ b/packages/rdt-search-ui/src/facets/wrapper.module.css @@ -0,0 +1,62 @@ +.wrapper { + color: #444; + display: grid; + height: 100%; +} + +.wrapper:hover .helpDropDown, +.wrapper:hover h3:before { + opacity: 1; +} + +.header { + display: grid; + grid-template-columns: 1fr fit-content(0); + margin-bottom: .5rem; +} + +.helpDropDown { + justify-content: end; + opacity: 0; +} + +.h3 { + cursor: pointer; + display: inline-block; + font-size: 1rem; + margin: 0; + user-select: none; + white-space: nowrap; +} + +.h3:before { + color: var(--rdt-spot-color); + content: '>'; + font-size: 0.5rem; + line-height: 1.5rem; + margin-left: -1rem; + opacity: 0; + position: absolute; + transform: rotate(90deg) scale(0.75, 2); +} + +.h3 small { + color: #888; + font-size: .7rem; + font-weight: normal; + margin-left: .5rem; +} + +/* // | \\ */ +/* //// | \\\ */ +/* STATES */ +/* \\\\ | //// */ +/* \\ | // */ + +.wrapper.stateCollapsed h3:before { + transform: rotate(0deg) scale(0.75, 2); +} + +.wrapper.stateCollapsed .body { + display: none; +} diff --git a/packages/rdt-search-ui/src/facets/wrapper.tsx b/packages/rdt-search-ui/src/facets/wrapper.tsx new file mode 100644 index 00000000..b45a2863 --- /dev/null +++ b/packages/rdt-search-ui/src/facets/wrapper.tsx @@ -0,0 +1,66 @@ +import type { + BaseFacetConfig, + BaseFacetState, + FacetFilter, +} from "../context/state/facets"; +import React from "react"; +import { FacetController } from "./controller"; +import { FacetsDataReducerAction } from "../context/state/actions"; +import { HelpDropDown } from "../views/ui/drop-down/help"; +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import Typography from "@mui/material/Typography"; +import { useTranslation } from "react-i18next"; +import { lookupLanguageString } from "@dans-framework/utils"; + +interface Props< + FacetConfig extends BaseFacetConfig, + FacetState extends BaseFacetState, + Filter extends FacetFilter, +> { + children: React.ReactNode; + dispatch: React.Dispatch; + facet: FacetController; + facetState: FacetState; + filter: Filter; + values: any; + className?: string; +} +function FacetWrapper< + FacetConfig extends BaseFacetConfig, + FacetState extends BaseFacetState, + Filter extends FacetFilter, +>(props: Props) { + const { i18n } = useTranslation(); + + return ( + + + + {lookupLanguageString(props.facet.config.title, i18n.language)} + {props.facetState?.collapse && ( + filter={props.filter} /> + )} + + {props.facet.config.description} + {props.children} + + + ); +} + +export default React.memo(FacetWrapper); + +// TODO handle different kinds of filters (like MapFacetFilter) +function ActiveIndicator(props: { + filter: FacetFilter | undefined; +}) { + const { t } = useTranslation("facets"); + + if (props.filter == null) return null; + const size = props.filter != null ? 1 : 0; + + if (size === 0) return null; + + return {t("active", { value: size })}; +} diff --git a/packages/rdt-search-ui/src/global.d.ts b/packages/rdt-search-ui/src/global.d.ts new file mode 100644 index 00000000..1eabbb42 --- /dev/null +++ b/packages/rdt-search-ui/src/global.d.ts @@ -0,0 +1 @@ +declare module "*.module.css"; diff --git a/packages/rdt-search-ui/src/index.tsx b/packages/rdt-search-ui/src/index.tsx new file mode 100644 index 00000000..b1f5dccb --- /dev/null +++ b/packages/rdt-search-ui/src/index.tsx @@ -0,0 +1,306 @@ +import React, { Children, isValidElement } from "react"; +import { + SearchStateContext, + SearchStateDispatchContext, + intialSearchState, +} from "./context/state"; +import { searchStateReducer } from "./context/state/reducer"; +import App from "./app"; +import { Dashboard } from "./dashboard"; +import { + SearchProps, + SearchPropsContext, + type ExternalSearchProps, + defaultSearchProps, + type EndpointProps, +} from "./context/props"; +import { + FacetControllersContext, + type FacetControllers, +} from "./context/controllers"; +import { useSearch } from "./context/state/use-search"; +import type { FacetController } from "./facets/controller"; + +import Stack from "@mui/material/Stack"; +import Container from "@mui/material/Container"; +import Typography from "@mui/material/Typography"; +import LinearProgress from "@mui/material/LinearProgress"; +import { I18nextProvider } from "react-i18next"; +import i18nProvider from "./languages/i18n"; +import { useTranslation } from "react-i18next"; +import { + serializeObject, + deserializeObject, +} from "./views/active-filters/save-search/use-saved-searches"; +import { EndpointSelector } from "./views/ui/endpoints"; +import { useNavigate } from "react-router-dom"; +import type { Result } from "./context/state/use-search/types"; +import { motion, AnimatePresence } from "framer-motion"; +import { FacetedSearchContext } from "./context/Provider"; +import LZString from "lz-string"; + +export function FacetedSearch(props: ExternalSearchProps) { + const [children, setChildren] = React.useState(undefined); + const [searchProps, setSearchProps] = React.useState( + undefined, + ); + + React.useEffect(() => { + // Only set children once + if (props.children == null || children != null) return; + + const _children = + // Make sure it is an element and not a string, number, ... + ( + isValidElement(props.children) && + // If children is a fragment, get the children of the fragment + props.children.type.toString() === + Symbol.for("react.fragment").toString() + ) ? + props.children.props.children + : props.children; + + setChildren(_children); + }, [props.children, props.url]); + + // After children have been set, set the search props. + // Everytime the props change, the search props will be updated + React.useEffect(() => { + if (children == null) return; + + // Extend the search props with default values + const sp: SearchProps = { + ...defaultSearchProps, + ...props, + url: `${props.url}/_search`, + style: { + ...defaultSearchProps.style, + ...props.style, + }, + shareRoutes: { + dashboard: "/", + results: "/search", + }, + }; + + Object.keys(sp.style).forEach((key) => { + const value = (sp.style as any)[key]; + document.documentElement.style.setProperty( + `--rdt-${camelCaseToKebabCase(key)}`, + value, + ); + }); + + setSearchProps(sp); + }, [props, children]); + + const controllers = useControllers(children); + + if (searchProps == null || controllers.size === 0) return; + + return ( + + + {children} + + + ); +} + +interface AppLoaderProps { + children: React.ReactNode; + controllers: FacetControllers; + searchProps: SearchProps; +} + +function AppLoader({ children, controllers, searchProps }: AppLoaderProps) { + // Check to see if there's a search query present in the url + const queryParams = Object.fromEntries( + new URLSearchParams(window.location.search).entries(), + ); + const searchParams = + queryParams.search && + LZString.decompressFromEncodedURIComponent(queryParams.search); + // Get the state from session storage or search params if available. Search params has priority + const storageState = deserializeObject( + searchParams || + (sessionStorage.getItem( + `rdt-search-state-${window.location.origin}-${searchProps.url}`, + ) as string), + ); + const [state, dispatch] = React.useReducer( + searchStateReducer(controllers), + // set storageState if available + { ...intialSearchState, ...storageState }, + ); + + useSearch({ + props: searchProps, + state, + dispatch, + controllers, + }); + + const Component = searchProps.dashboard ? Dashboard : App; + const { t } = useTranslation("app"); + + React.useEffect(() => { + if (!controllers.size) return; + const facetStates = new Map(); + for (const [id, controller] of controllers.entries()) { + facetStates.set(id, controller.initState()); + } + + dispatch({ + type: "SET_FACET_STATES", + facetStates, + }); + + // clear uri search string + const url = new URL(window.location.href); + url.search = ""; + history.replaceState(null, "", url); + }, [controllers]); + + React.useEffect(() => { + // Save to session storage on state change, to retrieve when component is remounted + sessionStorage.setItem( + `rdt-search-state-${window.location.origin}-${searchProps.url}`, + serializeObject({ + facetFilters: state.facetFilters, + query: state.query, + }), + ); + }, [state.facetFilters, state.query]); + + return ( + + + + {state.loading && ( + + )} + { + state.error ? + + + {t("error.header")} + + {t("error.p1", { message: state.error.message })} + + {t("error.p2")} + + + // no error, show components + : + {children} + + + } + + + + ); +} + +/** + * Initializes and returns a map of facet controllers based on the `children` prop. + */ +function useControllers(children: React.ReactNode): FacetControllers { + const [controllers, setControllers] = React.useState( + new Map(), + ); + + React.useEffect(() => { + if (children == null || controllers.size > 0) return; + + // Initialise the facet controllers + const facets = Children.map( + children, + (child: any) => new child.type.controller(child.props.config), + ); + + setControllers( + new Map(facets.map((f: FacetController) => [f.ID, f])), + ); + }, [children, controllers]); + + return controllers; +} + +/** + * Converts a string from camelCase to kebab-case. + * @example camelCaseToKebabCase('camelCase') => 'camel-case' + */ +function camelCaseToKebabCase(str: string) { + return str.replace(/([A-Z])/g, "-$1").toLowerCase(); +} + +/* Wrapper for the faceted search that makes multiple endpoint selection possible */ +export const FacetedWrapper = ({ + dashboard, + dashRoute, + resultRoute, +}: { + dashboard?: boolean; + dashRoute?: string; + resultRoute?: string; +}) => { + const { config, endpoint } = React.useContext(FacetedSearchContext); + const navigate = useNavigate(); + const currentConfig = config.find((e) => e.url === endpoint) as EndpointProps; + + return ( + + + {config.length > 1 && ( + // show selector if there's more than 1 endpoint + + )} + + + + navigate(`/${currentConfig.onClickResultPath}/${result.id}`) + } + ResultBodyComponent={currentConfig.resultBodyComponent} + url={currentConfig.url} + shareRoutes={{ + results: resultRoute, + dashboard: dashRoute, + }} + > + {currentConfig?.dashboard.map((node, i) => + React.cloneElement(node, { key: i }), + )} + + + + + + ); +}; diff --git a/packages/rdt-search-ui/src/languages/i18n.ts b/packages/rdt-search-ui/src/languages/i18n.ts new file mode 100644 index 00000000..0e05e228 --- /dev/null +++ b/packages/rdt-search-ui/src/languages/i18n.ts @@ -0,0 +1,22 @@ +import resourcesToBackend from "i18next-resources-to-backend"; +import { createInstance } from "i18next"; +import { initReactI18next } from "react-i18next"; + +const i18n = createInstance({ + fallbackLng: "en", + interpolation: { + escapeValue: false, // not needed for react as it escapes by default + }, +}); + +i18n + .use( + resourcesToBackend( + (language: string, namespace: string) => + import(`./locales/${language}/${namespace}.json`), + ), + ) + .use(initReactI18next) + .init(); + +export default i18n; diff --git a/packages/rdt-search-ui/src/languages/locales/en/app.json b/packages/rdt-search-ui/src/languages/locales/en/app.json new file mode 100644 index 00000000..e646d246 --- /dev/null +++ b/packages/rdt-search-ui/src/languages/locales/en/app.json @@ -0,0 +1,9 @@ +{ + "error": { + "header": "Uh oh", + "p1": "We got an unexpected error: {{message}}", + "p2": "Please refresh your browser to try again. If the problem persists, contact DANS." + }, + "swipeUp": "Swipe up for filters", + "swipeDown": "Swipe down to close" +} \ No newline at end of file diff --git a/packages/rdt-search-ui/src/languages/locales/en/facets.json b/packages/rdt-search-ui/src/languages/locales/en/facets.json new file mode 100644 index 00000000..5a6bfb97 --- /dev/null +++ b/packages/rdt-search-ui/src/languages/locales/en/facets.json @@ -0,0 +1,9 @@ +{ + "active": "{{value}} active", + "viewMore": "More ({{value}})", + "viewLess": "Less", + "filter": "Filter", + "noData": "No data found", + "sortAz": "Sort alphabetically", + "sortCount": "Sort by count" +} \ No newline at end of file diff --git a/packages/rdt-search-ui/src/languages/locales/en/views.json b/packages/rdt-search-ui/src/languages/locales/en/views.json new file mode 100644 index 00000000..cd9a10cb --- /dev/null +++ b/packages/rdt-search-ui/src/languages/locales/en/views.json @@ -0,0 +1,27 @@ +{ + "fullTextQuery": "Full text query", + "facetFilterValue": "Facet filter value: {{value}}", + "savedAs": "Search saved as:", + "saveSearch": "Save search", + "shareSearch": "Share this search", + "facetView": "Search results view", + "dashboardView": "Dashboard view", + "copiedShareUrl": "{{value}} URL copied to clipboard", + "enterName": "Enter a name", + "saveSearchAs": "Save search as", + "loadSearch": "Load search", + "fullTextSearchHelp": "Search for words in the full text of the documents", + "clearSearch": "Clear search", + "resultCount_zero": "{{count}} results", + "resultCount_one": "{{count}} result", + "resultCount_other": "{{from}} - {{to}} of {{count}} results", + "searchDocuments": "Search documents", + "sortBy_zero": "Sort by", + "sortBy_one": "Sort by ({{count}})", + "sortBy_other": "Sort by ({{count}})", + "detailedView": "Detailed view", + "noResults": "Sorry, no results found", + "activeFilters": "Active filters", + "dataset": "Dataset", + "selectDataset": "Select your dataset" +} \ No newline at end of file diff --git a/packages/rdt-search-ui/src/languages/locales/nl/app.json b/packages/rdt-search-ui/src/languages/locales/nl/app.json new file mode 100644 index 00000000..42d3d569 --- /dev/null +++ b/packages/rdt-search-ui/src/languages/locales/nl/app.json @@ -0,0 +1,9 @@ +{ + "error": { + "header": "Uh oh", + "p1": "Onverwachte fout: {{message}}", + "p2": "Herlaad de pagina om het nog eens te proberen. Blijft de fout aanwezig, contacteer dan DANS." + }, + "swipeUp": "Swipe omhoog om te filteren", + "swipeDown": "Swipe omlaag om te sluiten" +} \ No newline at end of file diff --git a/packages/rdt-search-ui/src/languages/locales/nl/facets.json b/packages/rdt-search-ui/src/languages/locales/nl/facets.json new file mode 100644 index 00000000..161fd44b --- /dev/null +++ b/packages/rdt-search-ui/src/languages/locales/nl/facets.json @@ -0,0 +1,9 @@ +{ + "active": "{{value}} actief", + "viewMore": "Meer ({{value}})", + "viewLess": "Minder", + "filter": "Filter", + "noData": "Niets gevonden", + "sortAz": "Sorteer alfabetisch", + "sortCount": "Sorteer op aantal" +} \ No newline at end of file diff --git a/packages/rdt-search-ui/src/languages/locales/nl/views.json b/packages/rdt-search-ui/src/languages/locales/nl/views.json new file mode 100644 index 00000000..c569a86d --- /dev/null +++ b/packages/rdt-search-ui/src/languages/locales/nl/views.json @@ -0,0 +1,27 @@ +{ + "fullTextQuery": "Zoek in alle tekst", + "facetFilterValue": "Facet filter waarde: {{value}}", + "savedAs": "Zoekactie opgeslagen als:", + "saveSearch": "Sla zoekactie op", + "shareSearch": "Deel deze zoekactie", + "facetView": "Zoekresultatenoverzicht", + "dashboardView": "Dashboard", + "copiedShareUrl": "{{value}} URL gekopieerd", + "enterName": "Voer een naam in", + "saveSearchAs": "Sla zoekactie op als", + "loadSearch": "Laad zoekactie", + "fullTextSearchHelp": "Zoek naar woorden in alle tekst van het document", + "clearSearch": "Zoekactie leegmaken", + "resultCount_zero": "{{count}} resultaten", + "resultCount_one": "{{count}} resultaat", + "resultCount_other": "{{from}} - {{to}} van {{count}} resultaten", + "searchDocuments": "Zoek documenten", + "sortBy_zero": "Sorteer", + "sortBy_one": "Sorteer ({{count}})", + "sortBy_other": "Sorteer ({{count}})", + "detailedView": "Meer details", + "noResults": "Sorry, niets gevonden", + "activeFilters": "Actieve filters", + "dataset": "Dataset", + "selectDataset": "Selecteer je dataset" +} \ No newline at end of file diff --git a/packages/rdt-search-ui/src/views/active-filters/index.tsx b/packages/rdt-search-ui/src/views/active-filters/index.tsx new file mode 100644 index 00000000..dcc860e0 --- /dev/null +++ b/packages/rdt-search-ui/src/views/active-filters/index.tsx @@ -0,0 +1,106 @@ +import React from "react"; + +import { ActiveFilterValue } from "./value"; +import { SearchPropsContext } from "../../context/props"; + +import { + SearchStateContext, + SearchStateDispatchContext, +} from "../../context/state"; +import { FacetControllersContext } from "../../context/controllers"; +import { SaveSearch } from "./save-search/save-search"; + +import Typography from "@mui/material/Typography"; +import Stack from "@mui/material/Stack"; +import Paper from "@mui/material/Paper"; +import Button from "@mui/material/Button"; +import Box from "@mui/material/Box"; + +import { useTranslation } from "react-i18next"; + +export function ActiveFilters() { + const controllers = React.useContext(FacetControllersContext); + const { url } = React.useContext(SearchPropsContext); + const state = React.useContext(SearchStateContext); + const dispatch = React.useContext(SearchStateDispatchContext); + + const reset = React.useCallback(() => { + dispatch({ type: "RESET" }); + }, [controllers]); + + const removeFilter = React.useCallback((ev: React.MouseEvent) => { + dispatch({ + type: "REMOVE_FILTER", + facetID: ev.currentTarget.getAttribute("data-facet-id")!, + value: ev.currentTarget.getAttribute("data-value")!, + }); + }, []); + + const { t } = useTranslation("views"); + + return ( + + {t("activeFilters")} + + {state.query?.length > 0 && ( + + dispatch({ type: "SET_QUERY", value: "" })} + title={t("fullTextQuery")} + value={state.query} + /> + + )} + {Array.from(state.facetFilters.entries()).map(([facetID, filter]) => ( + + {filter.formatted.map((value) => ( + + ))} + + ))} + + + + + + + + + ); +} + +interface ItemProps { + children: React.ReactNode; + title: string; +} +function ActiveFilterItem({ children, title }: ItemProps) { + return ( + + + {title} + + {children} + + ); +} diff --git a/packages/rdt-search-ui/src/views/active-filters/save-search/load-search.tsx b/packages/rdt-search-ui/src/views/active-filters/save-search/load-search.tsx new file mode 100644 index 00000000..88aeff91 --- /dev/null +++ b/packages/rdt-search-ui/src/views/active-filters/save-search/load-search.tsx @@ -0,0 +1,48 @@ +import React from "react"; +import { DropDown } from "../../ui/drop-down"; +import { SearchProps } from "../../../context/props"; +import { SearchStateDispatchContext } from "../../../context/state"; +import { SavedSearch, useSavedSearches } from "./use-saved-searches"; +import ListItemText from "@mui/material/ListItemText"; +import MenuItem from "@mui/material/MenuItem"; +import { useTranslation } from "react-i18next"; + +export function LoadSearch(props: { url: SearchProps["url"] }) { + const [savedSearches] = useSavedSearches(props.url); + const { t } = useTranslation("views"); + + if (savedSearches.length === 0) return null; + + return ( + + + + ); +} + +const LoadSearches = (props: { savedSearches: SavedSearch[] }) => { + const dispatch = React.useContext(SearchStateDispatchContext); + + const loadSearch = (savedSearch: SavedSearch) => { + console.log(savedSearch); + dispatch({ + type: "LOAD_SEARCH", + filters: savedSearch.filters, + query: savedSearch.query, + }); + }; + + return props.savedSearches.map((savedSearch, i) => ( + loadSearch(savedSearch)}> + + + )); +}; + +// Show date without time +function dateString(date: string) { + return date.slice(0, (/\d\d\d\d/.exec(date)?.index || 0) + 4); +} diff --git a/packages/rdt-search-ui/src/views/active-filters/save-search/save-search.tsx b/packages/rdt-search-ui/src/views/active-filters/save-search/save-search.tsx new file mode 100644 index 00000000..1f974fd7 --- /dev/null +++ b/packages/rdt-search-ui/src/views/active-filters/save-search/save-search.tsx @@ -0,0 +1,248 @@ +import { useState, useContext, useCallback, useEffect } from "react"; +import md5 from "md5"; +import { DropDown } from "../../ui/drop-down"; +import { SearchProps } from "../../../context/props"; +import { SearchState } from "../../../context/state"; +import { serializeObject, useSavedSearches } from "./use-saved-searches"; +import Box from "@mui/material/Box"; +import Stack from "@mui/material/Stack"; +import Typography from "@mui/material/Typography"; +import Button from "@mui/material/Button"; +import TextField from "@mui/material/TextField"; +import { useTranslation } from "react-i18next"; +import IconButton from "@mui/material/IconButton"; +import ShareIcon from "@mui/icons-material/Share"; +import CloseIcon from "@mui/icons-material/Close"; +import Tooltip from "@mui/material/Tooltip"; +import Dialog from "@mui/material/Dialog"; +import DialogContent from "@mui/material/DialogContent"; +import DialogTitle from "@mui/material/DialogTitle"; +import Alert from "@mui/material/Alert"; +import Fade from "@mui/material/Fade"; +import LZString from "lz-string"; +import { SearchPropsContext } from "../../../context/props"; + +export interface SearchFilters { + filters: SearchState["facetFilters"]; + query: string; +} + +export function SaveSearch(props: { + url: SearchProps["url"]; + activeFilters: SearchFilters; +}) { + const [savedSearches, saveSearch] = useSavedSearches(props.url); + const hash = useHash(props.activeFilters); + const [open, setOpen] = useState(false); + + const savedSearch = savedSearches.find((ss) => ss.hash === hash); + const { t } = useTranslation("views"); + + if (savedSearch) { + return ( + + + + + {t("savedAs")} + + + {savedSearch.name || savedSearch.hash} + + + + setOpen(true)}> + + + + + + + ); + } + + return ( + + + + ); +} + +const SavedSearches = (props: { + activeFilters: SearchFilters; + hash: string | undefined; + savedSearches: ReturnType[0]; + saveSearch: ReturnType[1]; +}) => { + const [name, setName] = useState(); + const { t } = useTranslation("views"); + + const save = useCallback(async () => { + if (props.hash == null) return; + + props.saveSearch({ + name, + hash: props.hash, + date: new Date().toUTCString(), + ...props.activeFilters, + }); + }, [name, props.hash, props.activeFilters]); + + if (props.hash == null) return null; + + return ( + + {t("saveSearchAs")} + + setName(ev.currentTarget.value)} + onKeyDown={(ev) => { + if (ev.key === "Enter") save(); + }} + label={t("enterName")} + placeholder={props.hash} + type="text" + value={name || ""} + InputLabelProps={{ shrink: true }} + fullWidth + size="small" + /> + + + + ); +}; + +function useHash(activeFilters: SearchFilters | undefined) { + const [hash, setHash] = useState(); + + useEffect(() => { + if (activeFilters == null) return; + const activeFilterString = serializeObject(activeFilters); + const hash = md5(activeFilterString); + setHash(hash); + }, [activeFilters]); + + return hash; +} + +const ShareDialog = ({ + open, + setOpen, + activeFilters, +}: { + open: boolean; + setOpen: (arg: boolean) => void; + activeFilters: SearchFilters; +}) => { + const { shareRoutes } = useContext(SearchPropsContext); + const { filters, ...rest } = activeFilters; + const formattedFilters = { + ...rest, + facetFilters: filters, + }; + const searchString = `?search=${LZString.compressToEncodedURIComponent( + serializeObject(formattedFilters), + )}`; + const [facetValue] = useState( + `${window.location.origin}${shareRoutes?.results}${searchString}`, + ); + const [dashboardValue] = useState( + `${window.location.origin}${shareRoutes?.dashboard}${searchString}`, + ); + const [copy, setCopy] = useState(""); + const { t } = useTranslation("views"); + const close = () => { + setOpen(false); + setCopy(""); + }; + + return ( + + + + + {t("shareSearch")} + + {t("dashboardView")} + + + + + {t("facetView")} + + + + + + {copy && ( + + + {t("copiedShareUrl", { value: t(copy) })} + + + )} + + ); +}; diff --git a/packages/rdt-search-ui/src/views/active-filters/save-search/use-saved-searches.tsx b/packages/rdt-search-ui/src/views/active-filters/save-search/use-saved-searches.tsx new file mode 100644 index 00000000..29780891 --- /dev/null +++ b/packages/rdt-search-ui/src/views/active-filters/save-search/use-saved-searches.tsx @@ -0,0 +1,79 @@ +import React from "react"; +import { SearchFilters } from "./save-search"; + +export interface SavedSearch extends SearchFilters { + name: string | undefined; + hash: string; + date: string; // UTC string +} + +export function useSavedSearches( + url: string, +): [SavedSearch[], (ss: SavedSearch) => void] { + const [savedSearches, setSavedSearches] = React.useState([]); + + const saveSearch = React.useCallback( + (savedSearch: SavedSearch) => { + const nextSavedSearches = [...savedSearches]; + nextSavedSearches.unshift(savedSearch); + localStorage.setItem( + getStorageKey(url), + serializeObject(nextSavedSearches), + ); + setSavedSearches(nextSavedSearches); + }, + [url, savedSearches], + ); + + React.useEffect(() => { + const _savedSearches = localStorage.getItem(getStorageKey(url)); + if (_savedSearches == null) return; + setSavedSearches(deserializeObject(_savedSearches)); + }, [url]); + + return [savedSearches, saveSearch]; +} + +export function getStorageKey(url: string) { + return `rdt-search__ss__${url}`; +} + +function replacer(_key: string, value: any) { + if (value instanceof Map) { + return { + dataType: "Map", + value: [...value], + }; + } + + if (value instanceof Set) { + return { + dataType: "Set", + value: [...value], + }; + } + + return value; +} + +function reviver(_key: string, value: any) { + if (typeof value === "object" && value !== null) { + if (value.dataType === "Map") { + return new Map(value.value); + } + + if (value.dataType === "Set") { + return new Set(value.value); + } + } + + return value; +} + +export function serializeObject(object: any) { + return JSON.stringify(object, replacer); +} + +export function deserializeObject(filters: string) { + return JSON.parse(filters, reviver); +} diff --git a/packages/rdt-search-ui/src/views/active-filters/value.tsx b/packages/rdt-search-ui/src/views/active-filters/value.tsx new file mode 100644 index 00000000..0fa01bb2 --- /dev/null +++ b/packages/rdt-search-ui/src/views/active-filters/value.tsx @@ -0,0 +1,22 @@ +import type { MouseEvent } from "react"; +import Chip from "@mui/material/Chip"; +import CancelIcon from "@mui/icons-material/Cancel"; + +export function ActiveFilterValue(props: { + facetID?: string; + removeFilter: (ev: MouseEvent) => void; + title: string; + value: string; +}) { + return ( + } + /> + ); +} diff --git a/packages/rdt-search-ui/src/views/full-text-search/auto-suggest.tsx b/packages/rdt-search-ui/src/views/full-text-search/auto-suggest.tsx new file mode 100644 index 00000000..cbab1872 --- /dev/null +++ b/packages/rdt-search-ui/src/views/full-text-search/auto-suggest.tsx @@ -0,0 +1,143 @@ +import React from "react"; +import styled from "styled-components"; +import debounce from "lodash.debounce"; + +const SuggestionsDropDownBody = styled.div` + border-top: 0; + margin-top: 1px; +`; + +interface Props { + autoSuggest: (query: string) => Promise; + onClick: (query: string) => void; + value: string; +} + +const cache: { [key: string]: string[] } = {}; + +export function AutoSuggest(props: Props) { + const [suggestions, setSuggestions] = useSuggestions(props); + + return ( + + {suggestions.map((suggestion, index) => ( +
    { + setSuggestions([]); + props.onClick(suggestion); + }} + > + {suggestion} +
    + ))} +
    + ); +} + +function useSuggestions(props: Props): [string[], React.Dispatch] { + const [suggestions, setSuggestions] = React.useState([]); + + /** + * Debounced callback function for updating the suggestions. + * + * When the user types in the input value, the autoSuggest function + * is not fired on every keyDown, but calls autoSuggest with the + * combined keyDowns 300ms after the last keyDown event + */ + const updateSuggestions = React.useCallback( + debounce((value) => { + if (cache.hasOwnProperty(value)) { + setSuggestions(cache[value]); + } else { + props.autoSuggest(value).then((suggestions) => { + // If there is only one suggestions which is equal + // to the input value, show nothing. + if ( + suggestions.length === 1 && + suggestions[0].toLowerCase() === value.toLowerCase() + ) { + suggestions = []; + } + + cache[value] = suggestions; + setSuggestions(suggestions); + }); + } + }, 300), + [], + ); + + // Update the suggestions whenever the input value changes + React.useEffect(() => { + updateSuggestions(props.value); + }, [props.value]); + + return [suggestions, setSuggestions]; +} + +// interface State { +// suggestions: string[] +// } +// export default class AutoSuggest extends React.PureComponent { +// private cache: {[key: string]: string[]} = {} +// state: State = { +// suggestions: [] +// } + +// async componentDidUpdate(prevProps: Props, prevState: State) { +// // The update came from a suggestion click +// if (prevState.suggestions.length && !this.state.suggestions.length) return + +// if (prevProps.value !== this.props.value) { +// this.requestAutoSuggest() +// } +// } + +// render() { +// return ( +// 0} +// > +// { +// this.state.suggestions.map((suggestion, index) => +//
    { +// this.setState({ suggestions: [] }) +// this.props.onClick(suggestion) +// }} +// > +// {suggestion} +//
    +// ) +// } +//
    +// ) +// } + +// private autoSuggest = async () => { +// let suggestions: string[] + +// if (this.cache.hasOwnProperty(this.props.value)) { +// suggestions = this.cache[this.props.value] +// } else { +// suggestions = await this.props.autoSuggest(this.props.value) +// this.cache[this.props.value] = suggestions +// } + +// /** +// * If there is only one suggestions which is equal to the input value, +// * show nothing. +// */ +// if ( +// suggestions.length === 1 && +// suggestions[0].toLowerCase() === this.props.value.toLowerCase() +// ) { +// suggestions = [] +// } + +// this.setState({ suggestions }) +// } +// private requestAutoSuggest = debounce(this.autoSuggest, 300) +// } diff --git a/packages/rdt-search-ui/src/views/full-text-search/index.tsx b/packages/rdt-search-ui/src/views/full-text-search/index.tsx new file mode 100644 index 00000000..a17c814e --- /dev/null +++ b/packages/rdt-search-ui/src/views/full-text-search/index.tsx @@ -0,0 +1,58 @@ +import { useContext, useState, useCallback, useEffect } from "react"; +import debounce from "lodash.debounce"; +import { AutoSuggest } from "./auto-suggest"; +import { InputWrapper } from "./input"; +import { SearchPropsContext } from "../../context/props"; +import { + SearchStateContext, + SearchStateDispatchContext, +} from "../../context/state"; + +export * from "./input"; + +export function FullTextSearch() { + const { autoSuggest } = useContext(SearchPropsContext); + const state = useContext(SearchStateContext); + const dispatch = useContext(SearchStateDispatchContext); + const [loader, showLoader] = useState(false); + const [suggestActive, setSuggestActive] = useState(false); + const [inputValue, setInputValue] = useState(""); + const setQuery = debounce((value: string) => { + dispatch({ type: "SET_QUERY", value }); + showLoader(false); + }, 1000); + const handleInputChange = useCallback( + (ev: React.ChangeEvent) => { + setSuggestActive(autoSuggest != null); // Set suggestActive state only to true if props.autoSuggest exists + setInputValue(ev.target.value); + setQuery(ev.target.value); + showLoader(true); + }, + [], + ); + + useEffect(() => { + if (state.query !== inputValue) setInputValue(state.query); + }, [state.query]); + + return ( + <> + + {suggestActive && ( + { + setInputValue(query); + setQuery(query); + }} + value={inputValue} + /> + )} + + ); +} diff --git a/packages/rdt-search-ui/src/views/full-text-search/input.tsx b/packages/rdt-search-ui/src/views/full-text-search/input.tsx new file mode 100644 index 00000000..033f8825 --- /dev/null +++ b/packages/rdt-search-ui/src/views/full-text-search/input.tsx @@ -0,0 +1,50 @@ +import { useCallback, KeyboardEvent } from "react"; +import TextField from "@mui/material/TextField"; +import InputAdornment from "@mui/material/InputAdornment"; +import Tooltip from "@mui/material/Tooltip"; +import HelpIcon from "@mui/icons-material/Help"; +import CircularProgress from "@mui/material/CircularProgress"; +import { useTranslation } from "react-i18next"; + +interface Props { + handleInputChange: any; + inputValue: string; + setSuggestActive: any; + loader?: boolean; +} +export function InputWrapper(props: Props) { + const handleKeyDown = useCallback((ev: KeyboardEvent) => { + if ( + ev.code === "Enter" || // Enter + ev.code === "Escape" // Escape + ) { + props.setSuggestActive(false); + } + }, []); + + const { t } = useTranslation("views"); + + return ( + props.setSuggestActive(false)} + onChange={props.handleInputChange} + onKeyDown={handleKeyDown} + fullWidth + sx={{ mb: 2 }} + InputProps={{ + endAdornment: ( + + {props.loader ? + + : + + + } + + ), + }} + /> + ); +} diff --git a/packages/rdt-search-ui/src/views/header/index.tsx b/packages/rdt-search-ui/src/views/header/index.tsx new file mode 100644 index 00000000..47af1db8 --- /dev/null +++ b/packages/rdt-search-ui/src/views/header/index.tsx @@ -0,0 +1,56 @@ +import type { FSResponse } from "../../context/state/use-search/types"; + +import React from "react"; + +import { Pagination } from "../pagination"; +import { ResultCount } from "./result-count"; + +import { SearchState, SearchStateDispatchContext } from "../../context/state"; +import { SortBy } from "./result-count/order-by"; +import { LoadSearch } from "../active-filters/save-search/load-search"; +import { SearchPropsContext } from "../../context/props"; + +import Stack from "@mui/material/Stack"; + +interface Props { + currentPage: SearchState["currentPage"]; + searchResult: FSResponse | undefined; + sortOrder: SearchState["sortOrder"]; +} +export const ResultHeader = function Header(props: Props) { + const { url } = React.useContext(SearchPropsContext); + const dispatch = React.useContext(SearchStateDispatchContext); + if (props.searchResult == null) return null; + + return ( + <> + 0 ? 2 : 8} + > + + + + {props.searchResult.total > 0 && ( + + + + + )} + + ); +}; diff --git a/packages/rdt-search-ui/src/views/header/result-count/index.tsx b/packages/rdt-search-ui/src/views/header/result-count/index.tsx new file mode 100644 index 00000000..ca96d9e3 --- /dev/null +++ b/packages/rdt-search-ui/src/views/header/result-count/index.tsx @@ -0,0 +1,41 @@ +import type { SearchState } from "../../../context/state"; +import type { FSResponse } from "../../../context/state/use-search/types"; + +import React from "react"; + +import { SearchPropsContext } from "../../../context/props"; +import Typography from "@mui/material/Typography"; +import { useTranslation } from "react-i18next"; + +interface Props { + currentPage: SearchState["currentPage"]; + searchResult: FSResponse; +} +export function ResultCount(props: Props) { + const { resultsPerPage } = React.useContext(SearchPropsContext); + const [fromTo, setFromTo] = React.useState<[number, number]>(); + const { t } = useTranslation("views"); + + React.useEffect(() => { + let nextFrom = (props.currentPage - 1) * resultsPerPage + 1; + if (nextFrom > props.searchResult.total) + nextFrom = props.searchResult.total; + + let nextTo = nextFrom + resultsPerPage - 1; + if (nextTo > props.searchResult.total) nextTo = props.searchResult.total; + + setFromTo([nextFrom, nextTo]); + }, [props.currentPage, resultsPerPage, props.searchResult.total]); + + if (fromTo == null) return null; + + return ( + + {t("resultCount", { + from: fromTo[0], + to: fromTo[1], + count: props.searchResult.total, + })} + + ); +} diff --git a/packages/rdt-search-ui/src/views/header/result-count/order-by/index.tsx b/packages/rdt-search-ui/src/views/header/result-count/order-by/index.tsx new file mode 100644 index 00000000..fd025fc2 --- /dev/null +++ b/packages/rdt-search-ui/src/views/header/result-count/order-by/index.tsx @@ -0,0 +1,22 @@ +import React from "react"; +import { DropDown } from "../../../ui/drop-down"; +import OrderOption from "./option"; +import { FacetControllersContext } from "../../../../context/controllers"; +import { SortOrder } from "../../../../context/state/use-search/types"; +import { useTranslation } from "react-i18next"; + +interface Props { + sortOrder: SortOrder; +} +export const SortBy = React.memo(function SortBy(props: Props) { + const controllers = React.useContext(FacetControllersContext); + const { t } = useTranslation("views"); + + return ( + + {Array.from(controllers.values()).map((facet) => ( + + ))} + + ); +}); diff --git a/packages/rdt-search-ui/src/views/header/result-count/order-by/option.tsx b/packages/rdt-search-ui/src/views/header/result-count/order-by/option.tsx new file mode 100644 index 00000000..1a6e26cb --- /dev/null +++ b/packages/rdt-search-ui/src/views/header/result-count/order-by/option.tsx @@ -0,0 +1,188 @@ +import React from "react"; +import { SearchStateDispatchContext } from "../../../../context/state"; +import { FacetController } from "../../../../facets/controller"; +import { SortDirection } from "../../../../enum"; +import { SortOrder } from "../../../../context/state/use-search/types"; +import MenuItem from "@mui/material/MenuItem"; +import ListItemText from "@mui/material/ListItemText"; +import ListItemIcon from "@mui/material/ListItemIcon"; +import SortIcon from "@mui/icons-material/Sort"; +import { lookupLanguageString } from "@dans-framework/utils"; +import { useTranslation } from "react-i18next"; + +function updateSortOrder( + sortOrder: SortOrder, + field: string, + direction: SortDirection = SortDirection.Desc, +) { + if (sortOrder.has(field) && sortOrder.get(field) === direction) + sortOrder.delete(field); + else sortOrder.set(field, direction); + + return new Map(sortOrder); +} + +interface Props { + facet: FacetController; + sortOrder: SortOrder; +} +function OrderOption(props: Props) { + const dispatch = React.useContext(SearchStateDispatchContext); + const { i18n } = useTranslation(); + + const setDirection = React.useCallback( + (ev: React.MouseEvent) => { + ev.stopPropagation(); + + const nextDirection = + props.sortOrder.get(props.facet.config.field) === SortDirection.Desc ? + SortDirection.Asc + : SortDirection.Desc; + + const sortOrder = updateSortOrder( + props.sortOrder, + props.facet.config.field, + nextDirection, + ); + dispatch({ type: "SET_SORT_ORDER", sortOrder }); + }, + [props.sortOrder], + ); + + const setFacetId = React.useCallback( + (ev: React.MouseEvent) => { + ev.stopPropagation(); + const direction = props.sortOrder.get(props.facet.config.field); + const sortOrder = updateSortOrder( + props.sortOrder, + props.facet.config.field, + direction, + ); + + dispatch({ type: "SET_SORT_ORDER", sortOrder }); + }, + [props.sortOrder], + ); + + const direction = props.sortOrder.get(props.facet.config.field); + + return ( + + {direction != null && ( + + + + )} + + {lookupLanguageString(props.facet.config.title, i18n.language)} + + + ); +} + +export default React.memo(OrderOption); + +export function Asc({ + title = "Ascending", + color = "#444", +}: { + title?: string; + color?: string; +}) { + return ( + + {title} + + + + + + ); +} + +export function Desc({ + title = "Descending", + color = "#444", +}: { + title?: string; + color?: string; +}) { + return ( + + {title} + + + + + + ); +} diff --git a/packages/rdt-search-ui/src/views/pagination/index.tsx b/packages/rdt-search-ui/src/views/pagination/index.tsx new file mode 100644 index 00000000..093cb6ae --- /dev/null +++ b/packages/rdt-search-ui/src/views/pagination/index.tsx @@ -0,0 +1,46 @@ +import React from "react"; + +import { SearchPropsContext } from "../../context/props"; +import { FacetsDataReducerAction } from "../../context/state/actions"; + +import MuiPagination from "@mui/material/Pagination"; + +export interface PaginationProps { + currentPage: number; + dispatch: React.Dispatch; + resultsPerPage?: number; + total: number; + setCurrentPage?: (page: number) => void; + siblingCount?: number; +} + +export function Pagination(props: PaginationProps) { + const context = React.useContext(SearchPropsContext); + + let setCurrentPage = React.useCallback((page: number) => { + props.dispatch({ type: "SET_PAGE", page }); + }, []); + + // Override the setCurrentPage function if it was passed in as a prop + // For example, the list facet overrides this function + setCurrentPage = props.setCurrentPage || setCurrentPage; + + const pageCount = Math.ceil( + props.total / (props.resultsPerPage || context.resultsPerPage), + ); + + if (isNaN(pageCount) || pageCount === 1) return null; + + return ( + setCurrentPage(v)} + siblingCount={ + typeof props.siblingCount === "number" ? props.siblingCount : 1 + } + size={props.siblingCount === 0 ? "small" : "medium"} + /> + ); +} diff --git a/packages/rdt-search-ui/src/views/pagination/page-number.tsx b/packages/rdt-search-ui/src/views/pagination/page-number.tsx new file mode 100644 index 00000000..28448860 --- /dev/null +++ b/packages/rdt-search-ui/src/views/pagination/page-number.tsx @@ -0,0 +1,53 @@ +import React from "react"; +import styled from "styled-components"; + +import { SearchProps, SearchPropsContext } from "../../context/props"; +import { PaginationProps } from "."; + +export const PaginationButton = styled.button` + background: none; + border: none; + color: ${(props: { + disabled?: boolean; + color?: string; + _style?: SearchProps["style"]; + }) => props.color || props._style?.spotColor}; + cursor: ${(props) => (props.disabled ? "default" : "pointer")}; + outline: none; + padding: 0; +`; + +interface PnProps { + active: boolean; + _style: SearchProps["style"]; +} +const PageNumberWrapper = styled(PaginationButton)` + background-color: ${(props: PnProps) => + props.active ? props._style.buttonBackground : "none"}; + border-radius: 0.25em; + color: ${(props: PnProps) => (props.active ? "#444" : "inherit")}; + font-weight: ${(props: PnProps) => (props.active ? "bold" : "normal")}; + padding: 0.35em; + text-align: center; +`; + +interface Props extends Pick { + pageNumber: number; + setCurrentPage: (page: number) => void; +} +export function PageNumber(props: Props) { + const { style } = React.useContext(SearchPropsContext); + const active = props.pageNumber === props.currentPage; + + return ( + props.setCurrentPage(props.pageNumber)} + _style={style} + > + {props.pageNumber} + + ); +} diff --git a/packages/rdt-search-ui/src/views/pagination/use-pages.ts b/packages/rdt-search-ui/src/views/pagination/use-pages.ts new file mode 100644 index 00000000..5b1744cc --- /dev/null +++ b/packages/rdt-search-ui/src/views/pagination/use-pages.ts @@ -0,0 +1,47 @@ +import React from "react"; + +function getRange(start: number, end: number) { + return Array.from({ length: end - start + 1 }, (_value, key) => key + start); +} + +// Hook to calculate the page numbers to display +// The page numbers are split into three groups: +// - first: the first 3 page numbers, e.g. [1, 2, 3] +// - current: the current (page 5, the prev and next) page numbers, e.g. [4, 5, 6] +// - last: the last 3 page numbers, e.g. [7, 8, 9] +export function usePages(currentPage: number, pageCount: number) { + const [first, setFirst] = React.useState([]); + const [current, setCurrent] = React.useState([]); + const [last, setLast] = React.useState([]); + + React.useEffect(() => { + if (isNaN(pageCount) || pageCount === 1) return; + + let first: number[] = []; + let current: number[] = []; + let last: number[] = []; + + // If there are less than 7 pages, all page numbers are displayed + if (pageCount < 7) { + current = getRange(1, pageCount); + } else { + first = [1]; + last = [pageCount]; + + if (currentPage < 4) { + first = getRange(1, 4); + } else if (currentPage > pageCount - 3) { + last = getRange(pageCount - 3, pageCount); + } else { + // The current group is filled with the current page number and the two adjacent page numbers + current = getRange(currentPage - 1, currentPage + 1); + } + } + + setFirst(first); + setCurrent(current); + setLast(last); + }, [currentPage, pageCount]); + + return { first, current, last }; +} diff --git a/packages/rdt-search-ui/src/views/search-result/index.tsx b/packages/rdt-search-ui/src/views/search-result/index.tsx new file mode 100644 index 00000000..994c790d --- /dev/null +++ b/packages/rdt-search-ui/src/views/search-result/index.tsx @@ -0,0 +1,112 @@ +import type { SearchProps } from "../../context/props"; +import type { FSResponse } from "../../context/state/use-search/types"; + +import React from "react"; +import { Pagination } from "../pagination"; +import { SearchState, SearchStateDispatchContext } from "../../context/state"; + +import Stack from "@mui/material/Stack"; +import Button from "@mui/material/Button"; +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import CardActions from "@mui/material/CardActions"; +import Typography from "@mui/material/Typography"; +import { useTranslation } from "react-i18next"; + +/* Layout for content is defined in the app and passed as props to this component */ + +interface Props { + currentPage: SearchState["currentPage"]; + ResultBodyComponent: SearchProps["ResultBodyComponent"]; + onClickResult: SearchProps["onClickResult"]; + resultBodyProps: SearchProps["resultBodyProps"]; + searchResult: FSResponse | undefined; +} +export function SearchResult(props: Props) { + const dispatch = React.useContext(SearchStateDispatchContext); + const { t } = useTranslation("views"); + if (props.searchResult == null) return null; + + return ( + <> + {props.searchResult.results.length > 0 ? + props.searchResult.results.map((hit, i) => ( + + + + + + + + + )) + : + + + {t("noResults")} + + + } + {props.searchResult.results.length > 0 && ( + + + + )} + + ); +} + +const NoResultsSvg = () => ( + + + + + + + + + + + + + + + +); diff --git a/packages/rdt-search-ui/src/views/ui/drop-down/help.tsx b/packages/rdt-search-ui/src/views/ui/drop-down/help.tsx new file mode 100644 index 00000000..0e84e6bd --- /dev/null +++ b/packages/rdt-search-ui/src/views/ui/drop-down/help.tsx @@ -0,0 +1,15 @@ +import { DropDown } from "."; + +interface Props { + children: string | undefined; + label?: string; +} +export function HelpDropDown({ children, label = "?" }: Props) { + if (children == null || !children.length) return null; + + return ( + + {children} + + ); +} diff --git a/packages/rdt-search-ui/src/views/ui/drop-down/index.tsx b/packages/rdt-search-ui/src/views/ui/drop-down/index.tsx new file mode 100644 index 00000000..068b53ae --- /dev/null +++ b/packages/rdt-search-ui/src/views/ui/drop-down/index.tsx @@ -0,0 +1,51 @@ +import React from "react"; + +import Button from "@mui/material/Button"; +import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; +import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"; +import Popover from "@mui/material/Popover"; + +interface Props { + children: React.ReactNode; + label: string; + small?: boolean; +} +export const DropDown = React.memo(function DropDown({ + children, + label, + small = false, +}: Props) { + const [anchorEl, setAnchorEl] = React.useState(null); + const open = Boolean(anchorEl); + const handleClick = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + const handleClose = () => { + setAnchorEl(null); + }; + + return ( +
    + + + {children} + +
    + ); +}); diff --git a/packages/rdt-search-ui/src/views/ui/endpoints/index.tsx b/packages/rdt-search-ui/src/views/ui/endpoints/index.tsx new file mode 100644 index 00000000..3ade92d3 --- /dev/null +++ b/packages/rdt-search-ui/src/views/ui/endpoints/index.tsx @@ -0,0 +1,42 @@ +import { useContext } from "react"; +import InputLabel from "@mui/material/InputLabel"; +import MenuItem from "@mui/material/MenuItem"; +import FormControl from "@mui/material/FormControl"; +import Select, { type SelectChangeEvent } from "@mui/material/Select"; +import Stack from "@mui/material/Stack"; +import Typography from "@mui/material/Typography"; +import { useTranslation } from "react-i18next"; +import { FacetedSearchContext } from "../../../context/Provider"; + +export const EndpointSelector = () => { + const { t } = useTranslation("views"); + const { config, endpoint, setEndpoint } = useContext(FacetedSearchContext); + + const handleSelect = (e: SelectChangeEvent) => { + setEndpoint(e.target.value); + }; + + return ( + + + {t("selectDataset")} + + + {t("dataset")} + + + + ); +}; diff --git a/packages/rdt-search-ui/tsconfig.json b/packages/rdt-search-ui/tsconfig.json new file mode 100644 index 00000000..b8ece96a --- /dev/null +++ b/packages/rdt-search-ui/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "target": "esnext", + "allowJs": false, + "strict": true, + "noImplicitReturns": true, + "noUnusedLocals": false, + "esModuleInterop": false, + "experimentalDecorators": true, + "jsx": "react-jsx", + "module": "ESNext", + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "isolatedModules": true, + "lib": ["DOM", "ES2019", "DOM.Iterable"], + "skipLibCheck": true, + "downlevelIteration": true, + "useDefineForClassFields": false, + "outDir": "build", + "types": ["vite/client"] + }, + "include": [ + "vite-env.d.ts", + "src/global.d.ts", + "src/index.tsx", + "src/facets/chart/view/index.tsx", + "src/facets/map/view/index.tsx", + "src/facets/list/view/index.tsx" + ] +} diff --git a/packages/rdt-search-ui/vite-env.d.ts b/packages/rdt-search-ui/vite-env.d.ts new file mode 100644 index 00000000..11f02fe2 --- /dev/null +++ b/packages/rdt-search-ui/vite-env.d.ts @@ -0,0 +1 @@ +/// From 405b219c6a0bc533f9c5b20ac7093aa33c8b9386 Mon Sep 17 00:00:00 2001 From: D-Unit Date: Tue, 3 Dec 2024 15:15:22 +0100 Subject: [PATCH 37/44] updated userSubmissions call to include target credentials --- apps/ohsmart/src/App.tsx | 2 +- .../deposit/src/features/submit/submitApi.ts | 3 ++- .../src/languages/locales/en/submit.json | 3 ++- .../src/languages/locales/nl/submit.json | 3 ++- packages/user-auth/src/user/UserSubmissions.tsx | 15 +++++++++++---- packages/user-auth/src/user/userApi.ts | 17 ++++++++++++++++- 6 files changed, 34 insertions(+), 9 deletions(-) diff --git a/apps/ohsmart/src/App.tsx b/apps/ohsmart/src/App.tsx index 59ae74d3..accd06ef 100644 --- a/apps/ohsmart/src/App.tsx +++ b/apps/ohsmart/src/App.tsx @@ -61,7 +61,7 @@ const App = () => { path="user-submissions" element={ - + } /> diff --git a/packages/deposit/src/features/submit/submitApi.ts b/packages/deposit/src/features/submit/submitApi.ts index ae655280..78e0b366 100644 --- a/packages/deposit/src/features/submit/submitApi.ts +++ b/packages/deposit/src/features/submit/submitApi.ts @@ -87,9 +87,10 @@ export const submitApi = createApi({ store.dispatch(setMetadataSubmitStatus("error")); // enable form again, so user can try and resubmit store.dispatch(setFormDisabled(false)); + console.log(response) return { error: i18n.t("submit:submitMetadataError", { - error: response.status, + error: response.status === "FETCH_ERROR" ? i18n.t("submit:serverConnectionError") : response.status, }), }; }, diff --git a/packages/deposit/src/languages/locales/en/submit.json b/packages/deposit/src/languages/locales/en/submit.json index f65902a4..5f1e9ddf 100644 --- a/packages/deposit/src/languages/locales/en/submit.json +++ b/packages/deposit/src/languages/locales/en/submit.json @@ -22,5 +22,6 @@ "saveFileErrorNotification": "Failed to save files - {{error}}", "submitFileErrorNotification": "Failed to submit files - {{error}}", "submitMetadataError": "Failed to send metadata to the server - {{error}}", - "submitFileError": "Failed to send files to the server - {{error}}" + "submitFileError": "Failed to send files to the server - {{error}}", + "serverConnectionError": "Couldn't connect, please try again in a few moments." } \ No newline at end of file diff --git a/packages/deposit/src/languages/locales/nl/submit.json b/packages/deposit/src/languages/locales/nl/submit.json index 19ce0a63..a2a3b043 100644 --- a/packages/deposit/src/languages/locales/nl/submit.json +++ b/packages/deposit/src/languages/locales/nl/submit.json @@ -22,5 +22,6 @@ "saveFileErrorNotification": "Kan bestanden niet opslaan - {{error}}", "submitFileErrorNotification": "Kan bestanden niet submitten - {{error}}", "submitMetadataError": "Fout bij versturen metadata naar de server - {{error}}", - "submitFileError": "Fout bij versturen bestanden naar de server - {{error}}" + "submitFileError": "Fout bij versturen bestanden naar de server - {{error}}", + "serverConnectionError": "Kan niet verbinden, probeer het nog eens." } \ No newline at end of file diff --git a/packages/user-auth/src/user/UserSubmissions.tsx b/packages/user-auth/src/user/UserSubmissions.tsx index 34c1b5af..d761ddad 100644 --- a/packages/user-auth/src/user/UserSubmissions.tsx +++ b/packages/user-auth/src/user/UserSubmissions.tsx @@ -74,16 +74,23 @@ const depositStatus: DepositStatus = { success: ["finish", "accepted", "success"], }; -export const UserSubmissions = ({ depositSlug }: { depositSlug?: string }) => { +export const UserSubmissions = ({ + depositSlug, + targetCredentials +}: { + depositSlug?: string; + targetCredentials?: { repo: string; auth: string; authKey: string; }[]; +}) => { const { t } = useTranslation("user"); const siteTitle = useSiteTitle(); const auth = useAuth(); const dispatch = useAppDispatch(); // Fetch the users submitted/saved forms, every 10 sec, to update submission status - const { data, isLoading } = useFetchUserSubmissionsQuery( - auth.user?.profile.sub, - ); + const { data, isLoading } = useFetchUserSubmissionsQuery({ + userId: auth.user?.profile.sub, + targetCredentials: targetCredentials, + }); // are there any targets that have been submitted not complete yet? const allTargetsComplete = diff --git a/packages/user-auth/src/user/userApi.ts b/packages/user-auth/src/user/userApi.ts index 3dfac8f0..33968937 100644 --- a/packages/user-auth/src/user/userApi.ts +++ b/packages/user-auth/src/user/userApi.ts @@ -60,11 +60,26 @@ export const userSubmissionsApi = createApi({ tagTypes: ["Submissions"], endpoints: (build) => ({ fetchUserSubmissions: build.query({ - query: (userId) => { + query: ({userId: userId, targetCredentials: targetCredentials}) => { + // TODO: we need to pass on endpoint api keys with this call, like submitApi.ts does + const user = getUser(); + const targets = targetCredentials.map((t: { repo: string; auth: string; authKey: string; }) => ({ + "target-repo-name": t.repo, + credentials: { + username: t.auth, + password: Object.assign( + {}, + ...targetCredentials.map((t: { authKey: string }) => ({ + [t.authKey]: user?.profile[t.authKey], + })), + )[t.authKey], + }, + })); return { url: `progress-state/${userId}`, headers: { Accept: "application/json", + "targets-credentials": JSON.stringify(targets), }, }; }, From 1c03fe27340ddd6344d4b4bb54e84c3b92f1f6b3 Mon Sep 17 00:00:00 2001 From: D-Unit Date: Tue, 3 Dec 2024 15:18:55 +0100 Subject: [PATCH 38/44] added comment --- packages/user-auth/src/user/userApi.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/user-auth/src/user/userApi.ts b/packages/user-auth/src/user/userApi.ts index 33968937..36da3f77 100644 --- a/packages/user-auth/src/user/userApi.ts +++ b/packages/user-auth/src/user/userApi.ts @@ -61,7 +61,8 @@ export const userSubmissionsApi = createApi({ endpoints: (build) => ({ fetchUserSubmissions: build.query({ query: ({userId: userId, targetCredentials: targetCredentials}) => { - // TODO: we need to pass on endpoint api keys with this call, like submitApi.ts does + // We need to pass on endpoint api keys with this call, like submitApi.ts does, + // for server to compare data with data on target repo const user = getUser(); const targets = targetCredentials.map((t: { repo: string; auth: string; authKey: string; }) => ({ "target-repo-name": t.repo, From e80fc84689181176a86af41f42058a020ca8fee1 Mon Sep 17 00:00:00 2001 From: D-Unit Date: Wed, 4 Dec 2024 10:42:41 +0100 Subject: [PATCH 39/44] updated packages, removed redundant modules, fixed typescript --- apps/4tu/package.json | 4 +- apps/cat/package.json | 3 +- apps/digitaltwins/package.json | 5 +- apps/ohsmart/package.json | 4 +- apps/rda/package.json | 3 +- apps/rda/src/config/elasticSearch.tsx | 3 +- apps/swh/package.json | 3 +- package.json | 7 +- packages/config-eslint/package.json | 10 +- packages/config-typescript/package.json | 3 + packages/deposit/package.json | 7 +- .../src/features/files/FilesUpload.tsx | 2 +- .../src/features/metadata/fields/Map.tsx | 4 +- packages/deposit/src/types/Files.ts | 10 +- packages/deposit/src/types/Submit.ts | 10 - packages/rdt-search-ui/README.md | 43 - packages/rdt-search-ui/package-lock.json | 899 ---- packages/rdt-search-ui/package.json | 14 +- packages/rdt-search-ui/scripts/build.js | 37 - packages/rdt-search-ui/scripts/link-rda.sh | 6 - packages/rdt-search-ui/scripts/watch.js | 39 - .../rdt-search-ui/src/context/props/index.ts | 6 +- packages/rdt-search-ui/tsconfig.json | 30 - packages/rdt-search-ui/vite-env.d.ts | 1 - pnpm-lock.yaml | 4144 ++++++++--------- 25 files changed, 1982 insertions(+), 3315 deletions(-) delete mode 100644 packages/rdt-search-ui/package-lock.json delete mode 100644 packages/rdt-search-ui/scripts/build.js delete mode 100755 packages/rdt-search-ui/scripts/link-rda.sh delete mode 100644 packages/rdt-search-ui/scripts/watch.js delete mode 100644 packages/rdt-search-ui/tsconfig.json delete mode 100644 packages/rdt-search-ui/vite-env.d.ts diff --git a/apps/4tu/package.json b/apps/4tu/package.json index 1431e3bd..04826e5a 100644 --- a/apps/4tu/package.json +++ b/apps/4tu/package.json @@ -33,12 +33,10 @@ "web-vitals": "^3.4.0" }, "devDependencies": { - "@types/node": "^20.11.27", "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", "@vitejs/plugin-react": "^4.0.3", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.4.3", + "eslint-plugin-react-hooks": "^5.0.0", "vite": "^4.4.5", "vite-plugin-checker": "^0.6.2" } diff --git a/apps/cat/package.json b/apps/cat/package.json index 7c42a5ba..7712d600 100644 --- a/apps/cat/package.json +++ b/apps/cat/package.json @@ -34,8 +34,7 @@ "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", "@vitejs/plugin-react": "^4.0.3", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.4.3", + "eslint-plugin-react-hooks": "^5.0.0", "vite": "^4.4.5", "vite-plugin-checker": "^0.6.2" } diff --git a/apps/digitaltwins/package.json b/apps/digitaltwins/package.json index 89548518..2da267de 100644 --- a/apps/digitaltwins/package.json +++ b/apps/digitaltwins/package.json @@ -29,13 +29,10 @@ "web-vitals": "^3.4.0" }, "devDependencies": { - "@types/node": "^20.11.27", "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", "@vitejs/plugin-react": "^4.0.3", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.4.3", - "rollup-plugin-visualizer": "^5.12.0", + "eslint-plugin-react-hooks": "^5.0.0", "vite": "^4.4.5", "vite-plugin-checker": "^0.6.2" } diff --git a/apps/ohsmart/package.json b/apps/ohsmart/package.json index d72a78fd..fbb04365 100644 --- a/apps/ohsmart/package.json +++ b/apps/ohsmart/package.json @@ -29,12 +29,10 @@ }, "devDependencies": { "@playwright/test": "^1.42.1", - "@types/node": "^20.11.27", "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", "@vitejs/plugin-react": "^4.0.3", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.4.3", + "eslint-plugin-react-hooks": "^5.0.0", "vite": "^4.4.5", "vite-plugin-checker": "^0.6.2" } diff --git a/apps/rda/package.json b/apps/rda/package.json index bda0e7df..d3a280b6 100644 --- a/apps/rda/package.json +++ b/apps/rda/package.json @@ -35,8 +35,7 @@ "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", "@vitejs/plugin-react": "^4.0.3", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.4.3", + "eslint-plugin-react-hooks": "^5.0.0", "vite": "^4.4.5", "vite-plugin-checker": "^0.6.2" } diff --git a/apps/rda/src/config/elasticSearch.tsx b/apps/rda/src/config/elasticSearch.tsx index 50c4e69f..9f7775a1 100644 --- a/apps/rda/src/config/elasticSearch.tsx +++ b/apps/rda/src/config/elasticSearch.tsx @@ -3,6 +3,7 @@ import { PieChartFacet, ListFacet, type RDTSearchUIProps, + type EndpointProps, } from "@dans-framework/rdt-search-ui"; import { Rda2Result } from "../pages/search/result"; @@ -21,7 +22,7 @@ const fieldConfig: Partial = { * The config is for larger screens. For mobile, we use half width and full width cols. */ -export const elasticConfig = [ +export const elasticConfig: EndpointProps[] = [ { name: "RDA Catalogue", url: "https://es.laurenstobias.com/rda", diff --git a/apps/swh/package.json b/apps/swh/package.json index 3874bff7..f9b19b84 100644 --- a/apps/swh/package.json +++ b/apps/swh/package.json @@ -31,8 +31,7 @@ "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", "@vitejs/plugin-react": "^4.0.3", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.4.3", + "eslint-plugin-react-hooks": "^5.0.0", "vite": "^4.4.5", "vite-plugin-checker": "^0.6.2" } diff --git a/package.json b/package.json index 539119da..797f8194 100644 --- a/package.json +++ b/package.json @@ -27,11 +27,8 @@ "devDependencies": { "@dans-framework/eslint-config": "workspace:*", "@dans-framework/typescript-config": "workspace:*", - "@types/node": "^18.0.6", - "eslint": "^8.54.0", - "prettier": "^3.1.0", - "turbo": "^1.10.16", - "typescript": "^5.1.6" + "@types/node": "^20.11.27", + "turbo": "^1.13.4" }, "packageManager": "pnpm@8.6.12" } diff --git a/packages/config-eslint/package.json b/packages/config-eslint/package.json index 46c45961..1a128bb2 100644 --- a/packages/config-eslint/package.json +++ b/packages/config-eslint/package.json @@ -3,10 +3,12 @@ "version": "0.0.0", "main": "index.js", "license": "MIT", - "dependencies": { - "@typescript-eslint/eslint-plugin": "^6.12.0", - "@typescript-eslint/parser": "^6.12.0", - "eslint-config-prettier": "^9.0.0" + "devDependencies": { + "@typescript-eslint/eslint-plugin": "^8.17.0", + "@typescript-eslint/parser": "^8.17.0", + "eslint": "^9.16.0", + "eslint-config-prettier": "^9.1.0", + "prettier": "^3.4.2" }, "publishConfig": { "access": "public" diff --git a/packages/config-typescript/package.json b/packages/config-typescript/package.json index fee85bde..b2a08ae1 100644 --- a/packages/config-typescript/package.json +++ b/packages/config-typescript/package.json @@ -5,5 +5,8 @@ "license": "MIT", "publishConfig": { "access": "public" + }, + "devDependencies": { + "typescript": "^5.7.2" } } \ No newline at end of file diff --git a/packages/deposit/package.json b/packages/deposit/package.json index 27459220..09b0d4e2 100644 --- a/packages/deposit/package.json +++ b/packages/deposit/package.json @@ -14,20 +14,18 @@ "@mui/material": "^5.16.7", "@mui/x-date-pickers": "^6.11.0", "@reduxjs/toolkit": "^1.9.5", - "axios": "^1.6.0", "fast-xml-parser": "^4.2.7", "framer-motion": "^10.15.0", "html-react-parser": "^4.2.2", "i18next": "^23.4.1", "i18next-browser-languagedetector": "^7.1.0", "i18next-resources-to-backend": "^1.1.4", - "mapbox-gl": "^3.6.0", - "maplibre-gl": "^4.5.2", + "maplibre-gl": "^4.7.1", "moment": "^2.29.4", "notistack": "^3.0.1", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-dropzone": "^14.2.3", + "react-dropzone": "^14.3.5", "react-i18next": "^13.0.3", "react-map-gl": "^7.1.7", "react-oidc-context": "^2.2.2", @@ -42,7 +40,6 @@ "@dans-framework/pages": "workspace:*", "@types/geojson": "^7946.0.14", "@types/jest": "^29.5.3", - "@types/mapbox-gl": "^3.4.0", "@types/mapbox__mapbox-gl-draw": "^1.4.7", "@types/node": "^20.4.7", "@types/react": "^18.2.15", diff --git a/packages/deposit/src/features/files/FilesUpload.tsx b/packages/deposit/src/features/files/FilesUpload.tsx index a07c57db..2593cb07 100644 --- a/packages/deposit/src/features/files/FilesUpload.tsx +++ b/packages/deposit/src/features/files/FilesUpload.tsx @@ -231,7 +231,7 @@ const FileAlert = ({ }: { color: "warning" | "error"; title: string; - files: SelectedFile[] | RejectedFiles[]; + files: SelectedFile[] | readonly RejectedFiles[]; description?: string; }) => { const [open, setOpen] = useState(true); diff --git a/packages/deposit/src/features/metadata/fields/Map.tsx b/packages/deposit/src/features/metadata/fields/Map.tsx index 91b9724b..794b065d 100644 --- a/packages/deposit/src/features/metadata/fields/Map.tsx +++ b/packages/deposit/src/features/metadata/fields/Map.tsx @@ -227,7 +227,7 @@ const DrawMap = ({ field, sectionIndex }: DrawMapFieldProps) => { console.log(coordinateSystem.bbox); asyncFeatures(); // set bounding box of the selected coordinate system - setViewState({ bounds: coordinateSystem.bbox }); + setViewState({ bounds: coordinateSystem.bbox as LngLatBoundsLike }); } else { setFeatures( features.map((f) => ({ @@ -293,7 +293,7 @@ const DrawMap = ({ field, sectionIndex }: DrawMapFieldProps) => { border: "1px solid rgba(0,0,0,0.23)", }} mapStyle={`https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json`} - maxBounds={coordinateSystem?.bbox} + maxBounds={coordinateSystem?.bbox as LngLatBoundsLike} onClick={async (e) => { /* Gets shape info for active WMS layers when clicked on. diff --git a/packages/deposit/src/types/Files.ts b/packages/deposit/src/types/Files.ts index 609d8ef7..5f4f6f78 100644 --- a/packages/deposit/src/types/Files.ts +++ b/packages/deposit/src/types/Files.ts @@ -1,4 +1,5 @@ import type { LanguageStrings } from "@dans-framework/utils"; +import type { FileRejection } from "react-dropzone"; export interface FileActions { label: string | LanguageStrings; @@ -48,14 +49,7 @@ export interface SelectedFile { }; } -interface FileError { - code: string; - message: string; -} - -export interface RejectedFiles { - file: File; - errors: FileError[]; +export interface RejectedFiles extends FileRejection { name?: never; } diff --git a/packages/deposit/src/types/Submit.ts b/packages/deposit/src/types/Submit.ts index f87a1d46..5a455a91 100644 --- a/packages/deposit/src/types/Submit.ts +++ b/packages/deposit/src/types/Submit.ts @@ -1,5 +1,4 @@ import type { Target } from "@dans-framework/user-auth"; -import type { AxiosHeaders } from "axios"; import type { SelectedFile } from "./Files"; import type { SectionType, FormConfig } from "./Metadata"; @@ -50,15 +49,6 @@ export interface HeaderData { title?: string; } -export interface SubmitHeaders extends AxiosHeaders { - Authorization: string; - "user-id": string; - "auth-env-name": string; - "assistant-config-name": string; - "targets-credentials": string; - title?: string; -} - export interface SubmitData { metadata: { form: SectionType[]; diff --git a/packages/rdt-search-ui/README.md b/packages/rdt-search-ui/README.md index 35686399..c3cf68d8 100644 --- a/packages/rdt-search-ui/README.md +++ b/packages/rdt-search-ui/README.md @@ -2,49 +2,6 @@ ## Usage -### Installing Packages - -First, install the required packages by running the following command: - -```bash -npm install -``` - -### Local Development - -For local development, you can start the development server by running: - -```bash -npm run watch -``` - -### Production Build - -If you only need to generate the production build, use: - -```bash -npm run build -``` - -## Integrating with Other Projects - -### As a Git Submodule - -If the parent project specifies this repository as a submodule, you can clone both simultaneously using: - -```bash -git clone --recursive https://github.com/YOURREPO -``` - -### Without Using as a Submodule - -If you prefer not to use this as a submodule, navigate to the directory where you want to install the package. Then run: - -```bash -npm install -npm run build -``` - ## TODO - move facet values to Facet classes. This way we can finegrain the way the values are handled, for example after a reset when the ListFacet values have been set to 'show all', we want to show all the values instead of the initial config.size amount. diff --git a/packages/rdt-search-ui/package-lock.json b/packages/rdt-search-ui/package-lock.json deleted file mode 100644 index 0d85eb2b..00000000 --- a/packages/rdt-search-ui/package-lock.json +++ /dev/null @@ -1,899 +0,0 @@ -{ - "name": "@dans-framework/rdt-search-ui", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "@dans-framework/rdt-search-ui", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "@elastic/elasticsearch": "^8.10.0", - "clsx": "^2.0.0", - "echarts": "^5.4.2", - "lodash.debounce": "^4.0.8", - "md5": "^2.3.0", - "ngeohash": "^0.6.3", - "ol": "^7.3.0" - }, - "devDependencies": { - "@types/lodash.debounce": "^4.0.7", - "@types/md5": "^2.3.2", - "@types/ngeohash": "^0.6.4", - "@types/react": "^18.0.33", - "@types/styled-components": "^5.1.26", - "esbuild": "^0.17.15", - "esbuild-css-modules-plugin": "^3.0.2", - "tslib": "^2.5.0", - "typescript": "^5.0.3" - }, - "peerDependencies": { - "react": "^18.2.0", - "styled-components": "^5.3.10" - } - }, - "../knaw/dans/rda-client/node_modules/react": { - "version": "18.2.0", - "license": "MIT", - "peer": true, - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "../knaw/dans/rda-client/node_modules/styled-components": { - "version": "5.3.11", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/traverse": "^7.4.5", - "@emotion/is-prop-valid": "^1.1.0", - "@emotion/stylis": "^0.8.4", - "@emotion/unitless": "^0.7.4", - "babel-plugin-styled-components": ">= 1.12.0", - "css-to-react-native": "^3.0.0", - "hoist-non-react-statics": "^3.0.0", - "shallowequal": "^1.1.0", - "supports-color": "^5.5.0" - }, - "devDependencies": { - "@babel/cli": "^7.0.0", - "@babel/core": "^7.0.0", - "@babel/plugin-proposal-object-rest-spread": "^7.0.0", - "@babel/preset-env": "^7.0.0", - "@babel/preset-flow": "^7.0.0", - "@babel/preset-react": "^7.0.0", - "babel-eslint": "^10.0.1", - "eslint-plugin-flowtype": "^5.2.0", - "eslint-plugin-import": "^2.22.0", - "eslint-plugin-react": "^7.20.6", - "flow-bin": "^0.132.0", - "jest-serializer-html": "^7.0.0", - "js-beautify": "^1.13.0", - "prop-types": "^15.7.2", - "react": "^16.8.6", - "react-dom": "^16.8.6", - "react-frame-component": "^4.0.2", - "react-is": "^16.8.6", - "react-native": "^0.63.4", - "react-primitives": "^0.8.0", - "react-test-renderer": "^16.8.6", - "rollup": "^1.13.1", - "rollup-plugin-babel": "^4.3.2", - "rollup-plugin-terser": "^5.0.0", - "stylis-plugin-rtl": "^1.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/styled-components" - }, - "peerDependencies": { - "react": ">= 16.8.0", - "react-dom": ">= 16.8.0", - "react-is": ">= 16.8.0" - } - }, - "../knaw/dans/rda-client/node_modules/styled-components/node_modules/@emotion/is-prop-valid": { - "version": "1.2.1", - "license": "MIT", - "peer": true, - "dependencies": { - "@emotion/memoize": "^0.8.1" - } - }, - "../knaw/dans/rda-client/node_modules/styled-components/node_modules/@emotion/memoize": { - "version": "0.8.1", - "license": "MIT", - "peer": true - }, - "node_modules/@elastic/elasticsearch": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/@elastic/elasticsearch/-/elasticsearch-8.10.0.tgz", - "integrity": "sha512-RIEyqz0D18bz/dK+wJltaak+7wKaxDELxuiwOJhuMrvbrBsYDFnEoTdP/TZ0YszHBgnRPGqBDBgH/FHNgHObiQ==", - "dependencies": { - "@elastic/transport": "^8.3.4", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@elastic/transport": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/@elastic/transport/-/transport-8.3.4.tgz", - "integrity": "sha512-+0o8o74sbzu3BO7oOZiP9ycjzzdOt4QwmMEjFc1zfO7M0Fh7QX1xrpKqZbSd8vBwihXNlSq/EnMPfgD2uFEmFg==", - "dependencies": { - "debug": "^4.3.4", - "hpagent": "^1.0.0", - "ms": "^2.1.3", - "secure-json-parse": "^2.4.0", - "tslib": "^2.4.0", - "undici": "^5.22.1" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.17.19", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@mapbox/jsonlint-lines-primitives": { - "version": "2.0.2", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@mapbox/mapbox-gl-style-spec": { - "version": "13.28.0", - "license": "ISC", - "dependencies": { - "@mapbox/jsonlint-lines-primitives": "~2.0.2", - "@mapbox/point-geometry": "^0.1.0", - "@mapbox/unitbezier": "^0.0.0", - "csscolorparser": "~1.0.2", - "json-stringify-pretty-compact": "^2.0.0", - "minimist": "^1.2.6", - "rw": "^1.3.3", - "sort-object": "^0.3.2" - }, - "bin": { - "gl-style-composite": "bin/gl-style-composite.js", - "gl-style-format": "bin/gl-style-format.js", - "gl-style-migrate": "bin/gl-style-migrate.js", - "gl-style-validate": "bin/gl-style-validate.js" - } - }, - "node_modules/@mapbox/point-geometry": { - "version": "0.1.0", - "license": "ISC" - }, - "node_modules/@mapbox/unitbezier": { - "version": "0.0.0", - "license": "BSD-2-Clause" - }, - "node_modules/@petamoriken/float16": { - "version": "3.8.1", - "license": "MIT" - }, - "node_modules/@types/hoist-non-react-statics": { - "version": "3.3.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0" - } - }, - "node_modules/@types/lodash": { - "version": "4.14.195", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/lodash.debounce": { - "version": "4.0.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/lodash": "*" - } - }, - "node_modules/@types/md5": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@types/md5/-/md5-2.3.2.tgz", - "integrity": "sha512-v+JFDu96+UYJ3/UWzB0mEglIS//MZXgRaJ4ubUPwOM0gvLc/kcQ3TWNYwENEK7/EcXGQVrW8h/XqednSjBd/Og==", - "dev": true - }, - "node_modules/@types/ngeohash": { - "version": "0.6.4", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/prop-types": { - "version": "15.7.5", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/react": { - "version": "18.2.14", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/scheduler": { - "version": "0.16.3", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/styled-components": { - "version": "5.1.26", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/hoist-non-react-statics": "*", - "@types/react": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, - "node_modules/charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", - "engines": { - "node": "*" - } - }, - "node_modules/clsx": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", - "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", - "engines": { - "node": ">=6" - } - }, - "node_modules/crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", - "engines": { - "node": "*" - } - }, - "node_modules/csscolorparser": { - "version": "1.0.3", - "license": "MIT" - }, - "node_modules/csstype": { - "version": "3.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "dev": true, - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/earcut": { - "version": "2.2.4", - "license": "ISC" - }, - "node_modules/echarts": { - "version": "5.4.2", - "license": "Apache-2.0", - "dependencies": { - "tslib": "2.3.0", - "zrender": "5.4.3" - } - }, - "node_modules/echarts/node_modules/tslib": { - "version": "2.3.0", - "license": "0BSD" - }, - "node_modules/esbuild": { - "version": "0.17.19", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.17.19", - "@esbuild/android-arm64": "0.17.19", - "@esbuild/android-x64": "0.17.19", - "@esbuild/darwin-arm64": "0.17.19", - "@esbuild/darwin-x64": "0.17.19", - "@esbuild/freebsd-arm64": "0.17.19", - "@esbuild/freebsd-x64": "0.17.19", - "@esbuild/linux-arm": "0.17.19", - "@esbuild/linux-arm64": "0.17.19", - "@esbuild/linux-ia32": "0.17.19", - "@esbuild/linux-loong64": "0.17.19", - "@esbuild/linux-mips64el": "0.17.19", - "@esbuild/linux-ppc64": "0.17.19", - "@esbuild/linux-riscv64": "0.17.19", - "@esbuild/linux-s390x": "0.17.19", - "@esbuild/linux-x64": "0.17.19", - "@esbuild/netbsd-x64": "0.17.19", - "@esbuild/openbsd-x64": "0.17.19", - "@esbuild/sunos-x64": "0.17.19", - "@esbuild/win32-arm64": "0.17.19", - "@esbuild/win32-ia32": "0.17.19", - "@esbuild/win32-x64": "0.17.19" - } - }, - "node_modules/esbuild-css-modules-plugin": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/esbuild-css-modules-plugin/-/esbuild-css-modules-plugin-3.0.2.tgz", - "integrity": "sha512-Ru5NKnbA3m7E79ZIs9o+ZVqzsVGjSyI1fKAPXRT4zQeSSKty9KasIDcLNuFmDGhFZdooARA6cd3I0GGhHAdW8Q==", - "dev": true, - "dependencies": { - "lightningcss": "^1.21.7", - "lodash": "^4.17.21", - "lodash-es": "^4.17.21" - }, - "engines": { - "node": ">= 16.20.0" - }, - "peerDependencies": { - "esbuild": "*" - } - }, - "node_modules/geotiff": { - "version": "2.0.7", - "license": "MIT", - "dependencies": { - "@petamoriken/float16": "^3.4.7", - "lerc": "^3.0.0", - "pako": "^2.0.4", - "parse-headers": "^2.0.2", - "quick-lru": "^6.1.1", - "web-worker": "^1.2.0", - "xml-utils": "^1.0.2" - }, - "engines": { - "node": ">=10.19" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/hpagent": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-1.2.0.tgz", - "integrity": "sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==", - "engines": { - "node": ">=14" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "node_modules/json-stringify-pretty-compact": { - "version": "2.0.0", - "license": "MIT" - }, - "node_modules/lerc": { - "version": "3.0.0", - "license": "Apache-2.0" - }, - "node_modules/lightningcss": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.22.0.tgz", - "integrity": "sha512-+z0qvwRVzs4XGRXelnWRNwqsXUx8k3bSkbP8vD42kYKSk3z9OM2P3e/gagT7ei/gwh8DTS80LZOFZV6lm8Z8Fg==", - "dev": true, - "dependencies": { - "detect-libc": "^1.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-darwin-arm64": "1.22.0", - "lightningcss-darwin-x64": "1.22.0", - "lightningcss-freebsd-x64": "1.22.0", - "lightningcss-linux-arm-gnueabihf": "1.22.0", - "lightningcss-linux-arm64-gnu": "1.22.0", - "lightningcss-linux-arm64-musl": "1.22.0", - "lightningcss-linux-x64-gnu": "1.22.0", - "lightningcss-linux-x64-musl": "1.22.0", - "lightningcss-win32-x64-msvc": "1.22.0" - } - }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.22.0.tgz", - "integrity": "sha512-aH2be3nNny+It5YEVm8tBSSdRlBVWQV8m2oJ7dESiYRzyY/E/bQUe2xlw5caaMuhlM9aoTMtOH25yzMhir0qPg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.22.0.tgz", - "integrity": "sha512-9KHRFA0Y6mNxRHeoQMp0YaI0R0O2kOgUlYPRjuasU4d+pI8NRhVn9bt0yX9VPs5ibWX1RbDViSPtGJvYYrfVAQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.22.0.tgz", - "integrity": "sha512-xaYL3xperGwD85rQioDb52ozF3NAJb+9wrge3jD9lxGffplu0Mn35rXMptB8Uc2N9Mw1i3Bvl7+z1evlqVl7ww==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.22.0.tgz", - "integrity": "sha512-epQGvXIjOuxrZpMpMnRjK54ZqzhiHhCPLtHvw2fb6NeK2kK9YtF0wqmeTBiQ1AkbWfnnXGTstYaFNiadNK+StQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.22.0.tgz", - "integrity": "sha512-AArGtKSY4DGTA8xP8SDyNyKtpsUl1Rzq6FW4JomeyUQ4nBrR71uPChksTpj3gmWuGhZeRKLeCUI1DBid/zhChg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.22.0.tgz", - "integrity": "sha512-RRraNgP8hnBPhInTTUdlFm+z16C/ghbxBG51Sw00hd7HUyKmEUKRozyc5od+/N6pOrX/bIh5vIbtMXIxsos0lg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.22.0.tgz", - "integrity": "sha512-grdrhYGRi2KrR+bsXJVI0myRADqyA7ekprGxiuK5QRNkv7kj3Yq1fERDNyzZvjisHwKUi29sYMClscbtl+/Zpw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.22.0.tgz", - "integrity": "sha512-t5f90X+iQUtIyR56oXIHMBUyQFX/zwmPt72E6Dane3P8KNGlkijTg2I75XVQS860gNoEFzV7Mm5ArRRA7u5CAQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.22.0.tgz", - "integrity": "sha512-64HTDtOOZE9PUCZJiZZQpyqXBbdby1lnztBccnqh+NtbKxjnGzP92R2ngcgeuqMPecMNqNWxgoWgTGpC+yN5Sw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", - "dev": true - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "license": "MIT" - }, - "node_modules/mapbox-to-css-font": { - "version": "2.4.2", - "license": "BSD-2-Clause" - }, - "node_modules/md5": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", - "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", - "dependencies": { - "charenc": "0.0.2", - "crypt": "0.0.2", - "is-buffer": "~1.1.6" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/ngeohash": { - "version": "0.6.3", - "license": "MIT", - "engines": { - "node": ">=v0.2.0" - } - }, - "node_modules/ol": { - "version": "7.4.0", - "license": "BSD-2-Clause", - "dependencies": { - "earcut": "^2.2.3", - "geotiff": "^2.0.7", - "ol-mapbox-style": "^10.1.0", - "pbf": "3.2.1", - "rbush": "^3.0.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/openlayers" - } - }, - "node_modules/ol-mapbox-style": { - "version": "10.6.0", - "license": "BSD-2-Clause", - "dependencies": { - "@mapbox/mapbox-gl-style-spec": "^13.23.1", - "mapbox-to-css-font": "^2.4.1", - "ol": "^7.3.0" - } - }, - "node_modules/pako": { - "version": "2.1.0", - "license": "(MIT AND Zlib)" - }, - "node_modules/parse-headers": { - "version": "2.0.5", - "license": "MIT" - }, - "node_modules/pbf": { - "version": "3.2.1", - "license": "BSD-3-Clause", - "dependencies": { - "ieee754": "^1.1.12", - "resolve-protobuf-schema": "^2.1.0" - }, - "bin": { - "pbf": "bin/pbf" - } - }, - "node_modules/protocol-buffers-schema": { - "version": "3.6.0", - "license": "MIT" - }, - "node_modules/quick-lru": { - "version": "6.1.1", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/quickselect": { - "version": "2.0.0", - "license": "ISC" - }, - "node_modules/rbush": { - "version": "3.0.1", - "license": "MIT", - "dependencies": { - "quickselect": "^2.0.0" - } - }, - "node_modules/react": { - "resolved": "../knaw/dans/rda-client/node_modules/react", - "link": true - }, - "node_modules/react-is": { - "version": "16.13.1", - "dev": true, - "license": "MIT" - }, - "node_modules/resolve-protobuf-schema": { - "version": "2.1.0", - "license": "MIT", - "dependencies": { - "protocol-buffers-schema": "^3.3.1" - } - }, - "node_modules/rw": { - "version": "1.3.3", - "license": "BSD-3-Clause" - }, - "node_modules/secure-json-parse": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", - "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==" - }, - "node_modules/sort-asc": { - "version": "0.1.0", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sort-desc": { - "version": "0.1.1", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sort-object": { - "version": "0.3.2", - "dependencies": { - "sort-asc": "^0.1.0", - "sort-desc": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/styled-components": { - "resolved": "../knaw/dans/rda-client/node_modules/styled-components", - "link": true - }, - "node_modules/tslib": { - "version": "2.6.0", - "license": "0BSD" - }, - "node_modules/typescript": { - "version": "5.1.6", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici": { - "version": "5.25.2", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.25.2.tgz", - "integrity": "sha512-tch8RbCfn1UUH1PeVCXva4V8gDpGAud/w0WubD6sHC46vYQ3KDxL+xv1A2UxK0N6jrVedutuPHxe1XIoqerwMw==", - "dependencies": { - "busboy": "^1.6.0" - }, - "engines": { - "node": ">=14.0" - } - }, - "node_modules/web-worker": { - "version": "1.2.0", - "license": "Apache-2.0" - }, - "node_modules/xml-utils": { - "version": "1.7.0", - "license": "CC0-1.0" - }, - "node_modules/zrender": { - "version": "5.4.3", - "license": "BSD-3-Clause", - "dependencies": { - "tslib": "2.3.0" - } - }, - "node_modules/zrender/node_modules/tslib": { - "version": "2.3.0", - "license": "0BSD" - } - } -} diff --git a/packages/rdt-search-ui/package.json b/packages/rdt-search-ui/package.json index 4b93b88c..06c9e8ba 100644 --- a/packages/rdt-search-ui/package.json +++ b/packages/rdt-search-ui/package.json @@ -4,11 +4,6 @@ "description": "", "type": "module", "main": "lib/index.tsx", - "scripts": { - "watch": "node ./scripts/watch.js", - "watch:types": "tsc --emitDeclarationOnly --declaration -w", - "build": "node ./scripts/build.js && tsc --emitDeclarationOnly --declaration" - }, "author": "", "license": "ISC", "dependencies": { @@ -16,7 +11,6 @@ "@elastic/elasticsearch": "^8.10.0", "@mui/icons-material": "^5.14.3", "@mui/material": "^5.16.7", - "clsx": "^2.0.0", "echarts": "^5.4.2", "framer-motion": "^10.15.0", "html-react-parser": "^4.2.2", @@ -28,6 +22,7 @@ "ngeohash": "^0.6.3", "notistack": "^3.0.1", "ol": "^7.3.0", + "react": "^18.2.0", "react-i18next": "^13.0.3", "react-router-dom": "^6.14.2", "styled-components": "^5.3.10" @@ -38,14 +33,7 @@ "@types/ngeohash": "^0.6.4", "@types/react": "^18.0.33", "@types/styled-components": "^5.1.26", - "esbuild": "^0.17.15", - "esbuild-css-modules-plugin": "^3.0.2", - "tslib": "^2.5.0", - "typescript": "^5.0.3", "vite": "^4.4.5" }, - "peerDependencies": { - "react": "^18.2.0" - }, "sideEffects": false } diff --git a/packages/rdt-search-ui/scripts/build.js b/packages/rdt-search-ui/scripts/build.js deleted file mode 100644 index 2bfd93e6..00000000 --- a/packages/rdt-search-ui/scripts/build.js +++ /dev/null @@ -1,37 +0,0 @@ -import esbuild from "esbuild"; -import CssModulesPlugin from "esbuild-css-modules-plugin"; - -esbuild.build({ - bundle: true, - outdir: "build", - outbase: "src", - format: "esm", - sourcemap: true, - entryPoints: [ - "src/index.tsx", - "src/facets/list/view/index.tsx", - "src/facets/map/view/index.tsx", - "src/facets/chart/view/index.tsx", - ], - external: ["react", "styled-components"], - plugins: [ - CssModulesPlugin({ - force: true, - emitDeclarationFile: true, - localsConvention: "camelCaseOnly", - namedExports: true, - inject: false, - }), - { - name: "my-plugin", - setup(build) { - let count = 0; - build.onEnd((result) => { - if (result.errors.length === 0) { - console.log("Build succes!", new Date().toLocaleTimeString()); - } - }); - }, - }, - ], -}).catch(() => process.exit(1));; \ No newline at end of file diff --git a/packages/rdt-search-ui/scripts/link-rda.sh b/packages/rdt-search-ui/scripts/link-rda.sh deleted file mode 100755 index 971fda34..00000000 --- a/packages/rdt-search-ui/scripts/link-rda.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -npm i \ - --no-save \ - ../knaw/dans/rda-client/node_modules/react \ - ../knaw/dans/rda-client/node_modules/styled-components \ No newline at end of file diff --git a/packages/rdt-search-ui/scripts/watch.js b/packages/rdt-search-ui/scripts/watch.js deleted file mode 100644 index 95ce9706..00000000 --- a/packages/rdt-search-ui/scripts/watch.js +++ /dev/null @@ -1,39 +0,0 @@ -import esbuild from 'esbuild'; -import CssModulesPlugin from 'esbuild-css-modules-plugin'; - -const context = await esbuild.context({ - bundle: true, - outdir: 'build', - outbase: 'src', - format: 'esm', - sourcemap: true, - entryPoints: [ - "src/index.tsx", - "src/facets/list/view/index.tsx", - "src/facets/map/view/index.tsx", - "src/facets/chart/view/index.tsx", - ], - external: ['react', 'styled-components'], - plugins: [ - CssModulesPlugin({ - force: true, - emitDeclarationFile: true, - localsConvention: 'camelCaseOnly', - namedExports: true, - inject: false - }), - { - name: 'my-plugin', - setup(build) { - let count = 0; - build.onEnd(result => { - if (result.errors.length === 0) { - console.log('Build succes!', new Date().toLocaleTimeString()) - } - }); - }, - } - ], -}) - -await context.watch() diff --git a/packages/rdt-search-ui/src/context/props/index.ts b/packages/rdt-search-ui/src/context/props/index.ts index eb756fcd..b9bad4a3 100644 --- a/packages/rdt-search-ui/src/context/props/index.ts +++ b/packages/rdt-search-ui/src/context/props/index.ts @@ -1,4 +1,4 @@ -import type { SearchHighlight } from "@elastic/elasticsearch/lib/api/types"; +import type { estypes } from "@elastic/elasticsearch"; import React from "react"; import { ResultBodyProps, SortOrder } from "../state/use-search/types"; @@ -62,7 +62,7 @@ interface OptionalSearchProps { // Set the ES highlight directly from the config, // gives more finegrained control over returned snippets - fullTextHighlight?: SearchHighlight; + fullTextHighlight?: estypes.SearchHighlight; SearchHomeComponent?: React.FC; } @@ -75,7 +75,7 @@ export interface EndpointBaseProps { export interface EndpointProps extends EndpointBaseProps { fullTextFields?: string[]; - fullTextHighlight?: SearchHighlight; + fullTextHighlight?: estypes.SearchHighlight; onClickResultPath?: string; dashboard: React.ReactElement[]; resultBodyComponent: React.FC; diff --git a/packages/rdt-search-ui/tsconfig.json b/packages/rdt-search-ui/tsconfig.json deleted file mode 100644 index b8ece96a..00000000 --- a/packages/rdt-search-ui/tsconfig.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "compilerOptions": { - "target": "esnext", - "allowJs": false, - "strict": true, - "noImplicitReturns": true, - "noUnusedLocals": false, - "esModuleInterop": false, - "experimentalDecorators": true, - "jsx": "react-jsx", - "module": "ESNext", - "moduleResolution": "node", - "allowSyntheticDefaultImports": true, - "isolatedModules": true, - "lib": ["DOM", "ES2019", "DOM.Iterable"], - "skipLibCheck": true, - "downlevelIteration": true, - "useDefineForClassFields": false, - "outDir": "build", - "types": ["vite/client"] - }, - "include": [ - "vite-env.d.ts", - "src/global.d.ts", - "src/index.tsx", - "src/facets/chart/view/index.tsx", - "src/facets/map/view/index.tsx", - "src/facets/list/view/index.tsx" - ] -} diff --git a/packages/rdt-search-ui/vite-env.d.ts b/packages/rdt-search-ui/vite-env.d.ts deleted file mode 100644 index 11f02fe2..00000000 --- a/packages/rdt-search-ui/vite-env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9e10e46b..6fa5040a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,20 +15,11 @@ importers: specifier: workspace:* version: link:packages/config-typescript '@types/node': - specifier: ^18.0.6 - version: 18.0.6 - eslint: - specifier: ^8.54.0 - version: 8.54.0 - prettier: - specifier: ^3.1.0 - version: 3.1.0 + specifier: ^20.11.27 + version: 20.17.9 turbo: - specifier: ^1.10.16 - version: 1.10.16 - typescript: - specifier: ^5.1.6 - version: 5.1.6 + specifier: ^1.13.4 + version: 1.13.4 apps/4tu: dependencies: @@ -55,71 +46,65 @@ importers: version: link:../../packages/utils '@fontsource/roboto': specifier: ^5.0.7 - version: 5.0.7 + version: 5.1.0 '@mui/material': specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) framer-motion: specifier: ^10.15.0 - version: 10.15.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 10.18.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) i18next: specifier: ^23.4.1 - version: 23.4.1 + version: 23.16.8 i18next-browser-languagedetector: specifier: ^7.1.0 - version: 7.1.0 + version: 7.2.1 i18next-resources-to-backend: specifier: ^1.1.4 - version: 1.1.4 + version: 1.2.1 lz-string: specifier: ^1.5.0 version: 1.5.0 notistack: specifier: ^3.0.1 - version: 3.0.1(csstype@3.1.3)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 3.0.1(csstype@3.1.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: ^18.2.0 - version: 18.2.0 + version: 18.3.1 react-dom: specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) + version: 18.3.1(react@18.3.1) react-i18next: specifier: ^13.0.3 - version: 13.0.3(i18next@23.4.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 13.5.0(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-router-dom: specifier: ^6.14.2 - version: 6.14.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 6.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) use-debounce: specifier: ^9.0.4 - version: 9.0.4(react@18.2.0) + version: 9.0.4(react@18.3.1) web-vitals: specifier: ^3.4.0 - version: 3.4.0 + version: 3.5.2 devDependencies: - '@types/node': - specifier: ^20.11.27 - version: 20.11.30 '@types/react': specifier: ^18.2.15 - version: 18.2.15 + version: 18.3.12 '@types/react-dom': specifier: ^18.2.7 - version: 18.2.7 + version: 18.3.1 '@vitejs/plugin-react': specifier: ^4.0.3 - version: 4.0.3(vite@4.4.5(@types/node@20.11.30)(lightningcss@1.22.0)) + version: 4.3.4(vite@4.5.5(@types/node@20.17.9)(lightningcss@1.28.2)) eslint-plugin-react-hooks: - specifier: ^4.6.0 - version: 4.6.0(eslint@8.54.0) - eslint-plugin-react-refresh: - specifier: ^0.4.3 - version: 0.4.3(eslint@8.54.0) + specifier: ^5.0.0 + version: 5.0.0(eslint@9.16.0) vite: specifier: ^4.4.5 - version: 4.4.5(@types/node@20.11.30)(lightningcss@1.22.0) + version: 4.5.5(@types/node@20.17.9)(lightningcss@1.28.2) vite-plugin-checker: specifier: ^0.6.2 - version: 0.6.2(eslint@8.54.0)(optionator@0.9.3)(typescript@5.1.6)(vite@4.4.5(@types/node@20.11.30)(lightningcss@1.22.0)) + version: 0.6.4(eslint@9.16.0)(optionator@0.9.4)(typescript@5.7.2)(vite@4.5.5(@types/node@20.17.9)(lightningcss@1.28.2)) apps/cat: dependencies: @@ -146,62 +131,59 @@ importers: version: link:../../packages/utils '@fontsource/roboto': specifier: ^5.0.7 - version: 5.0.7 + version: 5.1.0 '@mui/icons-material': specifier: ^5.14.3 - version: 5.14.3(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) + version: 5.16.8(@mui/material@5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) '@mui/material': specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) html-react-parser: specifier: ^4.2.2 - version: 4.2.2(react@18.2.0) + version: 4.2.10(react@18.3.1) i18next: specifier: ^23.4.1 - version: 23.4.1 + version: 23.16.8 i18next-browser-languagedetector: specifier: ^7.1.0 - version: 7.1.0 + version: 7.2.1 i18next-resources-to-backend: specifier: ^1.1.4 - version: 1.1.4 + version: 1.2.1 react: specifier: ^18.2.0 - version: 18.2.0 + version: 18.3.1 react-dom: specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) + version: 18.3.1(react@18.3.1) react-i18next: specifier: ^13.0.3 - version: 13.0.3(i18next@23.4.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 13.5.0(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-router-dom: specifier: ^6.14.2 - version: 6.14.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 6.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) web-vitals: specifier: ^3.4.0 - version: 3.4.0 + version: 3.5.2 devDependencies: '@types/react': specifier: ^18.2.15 - version: 18.2.15 + version: 18.3.12 '@types/react-dom': specifier: ^18.2.7 - version: 18.2.7 + version: 18.3.1 '@vitejs/plugin-react': specifier: ^4.0.3 - version: 4.0.3(vite@4.4.5(@types/node@20.11.30)(lightningcss@1.22.0)) + version: 4.3.4(vite@4.5.5(@types/node@20.17.9)(lightningcss@1.28.2)) eslint-plugin-react-hooks: - specifier: ^4.6.0 - version: 4.6.0(eslint@8.54.0) - eslint-plugin-react-refresh: - specifier: ^0.4.3 - version: 0.4.3(eslint@8.54.0) + specifier: ^5.0.0 + version: 5.0.0(eslint@9.16.0) vite: specifier: ^4.4.5 - version: 4.4.5(@types/node@20.11.30)(lightningcss@1.22.0) + version: 4.5.5(@types/node@20.17.9)(lightningcss@1.28.2) vite-plugin-checker: specifier: ^0.6.2 - version: 0.6.2(eslint@8.54.0)(optionator@0.9.3)(typescript@5.1.6)(vite@4.4.5(@types/node@20.11.30)(lightningcss@1.22.0)) + version: 0.6.4(eslint@9.16.0)(optionator@0.9.4)(typescript@5.7.2)(vite@4.5.5(@types/node@20.17.9)(lightningcss@1.28.2)) apps/digitaltwins: dependencies: @@ -228,62 +210,53 @@ importers: version: link:../../packages/utils '@fontsource/roboto': specifier: ^5.0.7 - version: 5.0.7 + version: 5.1.0 '@mui/material': specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) i18next: specifier: ^23.4.1 - version: 23.4.1 + version: 23.16.8 i18next-browser-languagedetector: specifier: ^7.1.0 - version: 7.1.0 + version: 7.2.1 i18next-resources-to-backend: specifier: ^1.1.4 - version: 1.1.4 + version: 1.2.1 react: specifier: ^18.2.0 - version: 18.2.0 + version: 18.3.1 react-dom: specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) + version: 18.3.1(react@18.3.1) react-i18next: specifier: ^13.0.3 - version: 13.0.3(i18next@23.4.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 13.5.0(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-router-dom: specifier: ^6.14.2 - version: 6.14.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 6.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) web-vitals: specifier: ^3.4.0 - version: 3.4.0 + version: 3.5.2 devDependencies: - '@types/node': - specifier: ^20.11.27 - version: 20.11.30 '@types/react': specifier: ^18.2.15 - version: 18.2.15 + version: 18.3.12 '@types/react-dom': specifier: ^18.2.7 - version: 18.2.7 + version: 18.3.1 '@vitejs/plugin-react': specifier: ^4.0.3 - version: 4.0.3(vite@4.4.5(@types/node@20.11.30)(lightningcss@1.22.0)) + version: 4.3.4(vite@4.5.5(@types/node@20.17.9)(lightningcss@1.28.2)) eslint-plugin-react-hooks: - specifier: ^4.6.0 - version: 4.6.0(eslint@8.54.0) - eslint-plugin-react-refresh: - specifier: ^0.4.3 - version: 0.4.3(eslint@8.54.0) - rollup-plugin-visualizer: - specifier: ^5.12.0 - version: 5.12.0(rollup@3.28.1) + specifier: ^5.0.0 + version: 5.0.0(eslint@9.16.0) vite: specifier: ^4.4.5 - version: 4.4.5(@types/node@20.11.30)(lightningcss@1.22.0) + version: 4.5.5(@types/node@20.17.9)(lightningcss@1.28.2) vite-plugin-checker: specifier: ^0.6.2 - version: 0.6.2(eslint@8.54.0)(optionator@0.9.3)(typescript@5.1.6)(vite@4.4.5(@types/node@20.11.30)(lightningcss@1.22.0)) + version: 0.6.4(eslint@9.16.0)(optionator@0.9.4)(typescript@5.7.2)(vite@4.5.5(@types/node@20.17.9)(lightningcss@1.28.2)) apps/ohsmart: dependencies: @@ -307,62 +280,56 @@ importers: version: link:../../packages/utils '@fontsource/roboto': specifier: ^5.0.7 - version: 5.0.7 + version: 5.1.0 '@mui/material': specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) i18next: specifier: ^23.4.1 - version: 23.4.1 + version: 23.16.8 i18next-browser-languagedetector: specifier: ^7.1.0 - version: 7.1.0 + version: 7.2.1 i18next-resources-to-backend: specifier: ^1.1.4 - version: 1.1.4 + version: 1.2.1 react: specifier: ^18.2.0 - version: 18.2.0 + version: 18.3.1 react-dom: specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) + version: 18.3.1(react@18.3.1) react-i18next: specifier: ^13.0.3 - version: 13.0.3(i18next@23.4.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 13.5.0(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-router-dom: specifier: ^6.14.2 - version: 6.14.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 6.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) web-vitals: specifier: ^3.4.0 - version: 3.4.0 + version: 3.5.2 devDependencies: '@playwright/test': specifier: ^1.42.1 - version: 1.42.1 - '@types/node': - specifier: ^20.11.27 - version: 20.11.30 + version: 1.49.0 '@types/react': specifier: ^18.2.15 - version: 18.2.15 + version: 18.3.12 '@types/react-dom': specifier: ^18.2.7 - version: 18.2.7 + version: 18.3.1 '@vitejs/plugin-react': specifier: ^4.0.3 - version: 4.0.3(vite@4.4.5(@types/node@20.11.30)(lightningcss@1.22.0)) + version: 4.3.4(vite@4.5.5(@types/node@20.17.9)(lightningcss@1.28.2)) eslint-plugin-react-hooks: - specifier: ^4.6.0 - version: 4.6.0(eslint@8.54.0) - eslint-plugin-react-refresh: - specifier: ^0.4.3 - version: 0.4.3(eslint@8.54.0) + specifier: ^5.0.0 + version: 5.0.0(eslint@9.16.0) vite: specifier: ^4.4.5 - version: 4.4.5(@types/node@20.11.30)(lightningcss@1.22.0) + version: 4.5.5(@types/node@20.17.9)(lightningcss@1.28.2) vite-plugin-checker: specifier: ^0.6.2 - version: 0.6.2(eslint@8.54.0)(optionator@0.9.3)(typescript@5.1.6)(vite@4.4.5(@types/node@20.11.30)(lightningcss@1.22.0)) + version: 0.6.4(eslint@9.16.0)(optionator@0.9.4)(typescript@5.7.2)(vite@4.5.5(@types/node@20.17.9)(lightningcss@1.28.2)) apps/rda: dependencies: @@ -392,62 +359,59 @@ importers: version: link:../../packages/utils '@fontsource/roboto': specifier: ^5.0.7 - version: 5.0.7 + version: 5.1.0 '@mui/icons-material': specifier: ^5.14.3 - version: 5.14.3(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) + version: 5.16.8(@mui/material@5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) '@mui/material': specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) html-react-parser: specifier: ^4.2.2 - version: 4.2.2(react@18.2.0) + version: 4.2.10(react@18.3.1) i18next: specifier: ^23.4.1 - version: 23.4.1 + version: 23.16.8 i18next-browser-languagedetector: specifier: ^7.1.0 - version: 7.1.0 + version: 7.2.1 i18next-resources-to-backend: specifier: ^1.1.4 - version: 1.1.4 + version: 1.2.1 react: specifier: ^18.2.0 - version: 18.2.0 + version: 18.3.1 react-dom: specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) + version: 18.3.1(react@18.3.1) react-i18next: specifier: ^13.0.3 - version: 13.0.3(i18next@23.4.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 13.5.0(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-router-dom: specifier: ^6.14.2 - version: 6.14.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 6.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) web-vitals: specifier: ^3.4.0 - version: 3.4.0 + version: 3.5.2 devDependencies: '@types/react': specifier: ^18.2.15 - version: 18.2.15 + version: 18.3.12 '@types/react-dom': specifier: ^18.2.7 - version: 18.2.7 + version: 18.3.1 '@vitejs/plugin-react': specifier: ^4.0.3 - version: 4.0.3(vite@4.4.5(@types/node@20.11.30)(lightningcss@1.22.0)) + version: 4.3.4(vite@4.5.5(@types/node@20.17.9)(lightningcss@1.28.2)) eslint-plugin-react-hooks: - specifier: ^4.6.0 - version: 4.6.0(eslint@8.54.0) - eslint-plugin-react-refresh: - specifier: ^0.4.3 - version: 0.4.3(eslint@8.54.0) + specifier: ^5.0.0 + version: 5.0.0(eslint@9.16.0) vite: specifier: ^4.4.5 - version: 4.4.5(@types/node@20.11.30)(lightningcss@1.22.0) + version: 4.5.5(@types/node@20.17.9)(lightningcss@1.28.2) vite-plugin-checker: specifier: ^0.6.2 - version: 0.6.2(eslint@8.54.0)(optionator@0.9.3)(typescript@5.1.6)(vite@4.4.5(@types/node@20.11.30)(lightningcss@1.22.0)) + version: 0.6.4(eslint@9.16.0)(optionator@0.9.4)(typescript@5.7.2)(vite@4.5.5(@types/node@20.17.9)(lightningcss@1.28.2)) apps/swh: dependencies: @@ -471,70 +435,77 @@ importers: version: link:../../packages/utils '@fontsource/roboto': specifier: ^5.0.7 - version: 5.0.7 + version: 5.1.0 '@mui/material': specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) i18next: specifier: ^23.4.1 - version: 23.4.1 + version: 23.16.8 i18next-browser-languagedetector: specifier: ^7.1.0 - version: 7.1.0 + version: 7.2.1 i18next-resources-to-backend: specifier: ^1.1.4 - version: 1.1.4 + version: 1.2.1 react: specifier: ^18.2.0 - version: 18.2.0 + version: 18.3.1 react-dom: specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) + version: 18.3.1(react@18.3.1) react-i18next: specifier: ^13.0.3 - version: 13.0.3(i18next@23.4.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 13.5.0(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-router-dom: specifier: ^6.14.2 - version: 6.14.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 6.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) web-vitals: specifier: ^3.4.0 - version: 3.4.0 + version: 3.5.2 devDependencies: '@types/react': specifier: ^18.2.15 - version: 18.2.15 + version: 18.3.12 '@types/react-dom': specifier: ^18.2.7 - version: 18.2.7 + version: 18.3.1 '@vitejs/plugin-react': specifier: ^4.0.3 - version: 4.0.3(vite@4.4.5(@types/node@20.11.30)(lightningcss@1.22.0)) + version: 4.3.4(vite@4.5.5(@types/node@20.17.9)(lightningcss@1.28.2)) eslint-plugin-react-hooks: - specifier: ^4.6.0 - version: 4.6.0(eslint@8.54.0) - eslint-plugin-react-refresh: - specifier: ^0.4.3 - version: 0.4.3(eslint@8.54.0) + specifier: ^5.0.0 + version: 5.0.0(eslint@9.16.0) vite: specifier: ^4.4.5 - version: 4.4.5(@types/node@20.11.30)(lightningcss@1.22.0) + version: 4.5.5(@types/node@20.17.9)(lightningcss@1.28.2) vite-plugin-checker: specifier: ^0.6.2 - version: 0.6.2(eslint@8.54.0)(optionator@0.9.3)(typescript@5.1.6)(vite@4.4.5(@types/node@20.11.30)(lightningcss@1.22.0)) + version: 0.6.4(eslint@9.16.0)(optionator@0.9.4)(typescript@5.7.2)(vite@4.5.5(@types/node@20.17.9)(lightningcss@1.28.2)) packages/config-eslint: - dependencies: + devDependencies: '@typescript-eslint/eslint-plugin': - specifier: ^6.12.0 - version: 6.12.0(@typescript-eslint/parser@6.12.0(eslint@8.54.0)(typescript@5.1.6))(eslint@8.54.0)(typescript@5.1.6) + specifier: ^8.17.0 + version: 8.17.0(@typescript-eslint/parser@8.17.0(eslint@9.16.0)(typescript@5.7.2))(eslint@9.16.0)(typescript@5.7.2) '@typescript-eslint/parser': - specifier: ^6.12.0 - version: 6.12.0(eslint@8.54.0)(typescript@5.1.6) + specifier: ^8.17.0 + version: 8.17.0(eslint@9.16.0)(typescript@5.7.2) + eslint: + specifier: ^9.16.0 + version: 9.16.0 eslint-config-prettier: - specifier: ^9.0.0 - version: 9.0.0(eslint@8.54.0) + specifier: ^9.1.0 + version: 9.1.0(eslint@9.16.0) + prettier: + specifier: ^3.4.2 + version: 3.4.2 - packages/config-typescript: {} + packages/config-typescript: + devDependencies: + typescript: + specifier: ^5.7.2 + version: 5.7.2 packages/deposit: dependencies: @@ -546,94 +517,88 @@ importers: version: link:../utils '@emotion/react': specifier: ^11.11.1 - version: 11.11.1(@types/react@18.2.15)(react@18.2.0) + version: 11.13.5(@types/react@18.3.12)(react@18.3.1) '@emotion/styled': specifier: ^11.11.0 - version: 11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) + version: 11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) '@mapbox/mapbox-gl-draw': specifier: ^1.4.3 version: 1.4.3 '@mui/icons-material': specifier: ^5.14.3 - version: 5.14.3(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) + version: 5.16.8(@mui/material@5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) '@mui/material': specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/x-date-pickers': specifier: ^6.11.0 - version: 6.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@mui/base@5.0.0-beta.11(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@mui/system@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(moment@2.29.4)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 6.20.2(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@mui/material@5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@reduxjs/toolkit': specifier: ^1.9.5 - version: 1.9.5(react-redux@8.1.2(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(redux@4.2.1))(react@18.2.0) - axios: - specifier: ^1.6.0 - version: 1.6.0 + version: 1.9.7(react-redux@8.1.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(redux@4.2.1))(react@18.3.1) fast-xml-parser: specifier: ^4.2.7 - version: 4.2.7 + version: 4.5.0 framer-motion: specifier: ^10.15.0 - version: 10.15.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 10.18.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) html-react-parser: specifier: ^4.2.2 - version: 4.2.2(react@18.2.0) + version: 4.2.10(react@18.3.1) i18next: specifier: ^23.4.1 - version: 23.4.1 + version: 23.16.8 i18next-browser-languagedetector: specifier: ^7.1.0 - version: 7.1.0 + version: 7.2.1 i18next-resources-to-backend: specifier: ^1.1.4 - version: 1.1.4 - mapbox-gl: - specifier: ^3.6.0 - version: 3.6.0 + version: 1.2.1 maplibre-gl: - specifier: ^4.5.2 - version: 4.5.2 + specifier: ^4.7.1 + version: 4.7.1 moment: specifier: ^2.29.4 - version: 2.29.4 + version: 2.30.1 notistack: specifier: ^3.0.1 - version: 3.0.1(csstype@3.1.3)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 3.0.1(csstype@3.1.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: ^18.2.0 - version: 18.2.0 + version: 18.3.1 react-dom: specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) + version: 18.3.1(react@18.3.1) react-dropzone: - specifier: ^14.2.3 - version: 14.2.3(react@18.2.0) + specifier: ^14.3.5 + version: 14.3.5(react@18.3.1) react-i18next: specifier: ^13.0.3 - version: 13.0.3(i18next@23.4.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 13.5.0(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-map-gl: specifier: ^7.1.7 - version: 7.1.7(mapbox-gl@3.6.0)(maplibre-gl@4.5.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 7.1.7(mapbox-gl@3.8.0)(maplibre-gl@4.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-oidc-context: specifier: ^2.2.2 - version: 2.2.2(oidc-client-ts@2.2.4)(react@18.2.0) + version: 2.4.0(oidc-client-ts@2.4.1)(react@18.3.1) react-redux: specifier: ^8.1.2 - version: 8.1.2(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(redux@4.2.1) + version: 8.1.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(redux@4.2.1) react-router-dom: specifier: ^6.14.2 - version: 6.14.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 6.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-transition-group: specifier: ^4.4.5 - version: 4.4.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) tus-js-client: specifier: ^4.1.0 - version: 4.1.0 + version: 4.2.3 use-debounce: specifier: ^9.0.4 - version: 9.0.4(react@18.2.0) + version: 9.0.4(react@18.3.1) uuid: specifier: ^9.0.0 - version: 9.0.0 + version: 9.0.1 devDependencies: '@dans-framework/pages': specifier: workspace:* @@ -643,28 +608,25 @@ importers: version: 7946.0.14 '@types/jest': specifier: ^29.5.3 - version: 29.5.3 - '@types/mapbox-gl': - specifier: ^3.4.0 - version: 3.4.0 + version: 29.5.14 '@types/mapbox__mapbox-gl-draw': specifier: ^1.4.7 - version: 1.4.7 + version: 1.4.8 '@types/node': specifier: ^20.4.7 - version: 20.5.3 + version: 20.17.9 '@types/react': specifier: ^18.2.15 - version: 18.2.15 + version: 18.3.12 '@types/react-dom': specifier: ^18.2.7 - version: 18.2.7 + version: 18.3.1 '@types/react-transition-group': specifier: ^4.4.6 - version: 4.4.6 + version: 4.4.11 '@types/uuid': specifier: ^9.0.2 - version: 9.0.2 + version: 9.0.8 packages/file-mapper: dependencies: @@ -676,43 +638,43 @@ importers: version: link:../utils '@mui/icons-material': specifier: ^5.14.3 - version: 5.14.3(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) + version: 5.16.8(@mui/material@5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) '@mui/material': specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@reduxjs/toolkit': specifier: ^1.9.5 - version: 1.9.5(react-redux@8.1.2(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(redux@4.2.1))(react@18.2.0) + version: 1.9.7(react-redux@8.1.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(redux@4.2.1))(react@18.3.1) i18next: specifier: ^23.4.1 - version: 23.4.1 + version: 23.16.8 i18next-browser-languagedetector: specifier: ^7.1.0 - version: 7.1.0 + version: 7.2.1 i18next-resources-to-backend: specifier: ^1.1.4 - version: 1.1.4 + version: 1.2.1 react: specifier: ^18.2.0 - version: 18.2.0 + version: 18.3.1 react-dom: specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) + version: 18.3.1(react@18.3.1) react-dropzone: specifier: ^14.2.3 - version: 14.2.3(react@18.2.0) + version: 14.3.5(react@18.3.1) react-i18next: specifier: ^13.0.3 - version: 13.0.3(i18next@23.4.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 13.5.0(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-redux: specifier: ^8.1.2 - version: 8.1.2(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(redux@4.2.1) + version: 8.1.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(redux@4.2.1) react-router-dom: specifier: ^6.14.2 - version: 6.14.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 6.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) uuid: specifier: ^9.0.0 - version: 9.0.0 + version: 9.0.1 xlsx: specifier: ^0.18.5 version: 0.18.5 @@ -722,26 +684,26 @@ importers: version: link:../pages '@types/react': specifier: ^18.2.15 - version: 18.2.15 + version: 18.3.12 '@types/react-dom': specifier: ^18.2.7 - version: 18.2.7 + version: 18.3.1 '@types/uuid': specifier: ^9.0.2 - version: 9.0.2 + version: 9.0.8 packages/freshdesk: dependencies: react: specifier: ^18.2.0 - version: 18.2.0 + version: 18.3.1 devDependencies: '@dans-framework/typescript-config': specifier: workspace:* version: link:../config-typescript '@types/react': specifier: ^18.2.15 - version: 18.2.15 + version: 18.3.12 packages/layout: dependencies: @@ -756,41 +718,41 @@ importers: version: link:../utils '@mui/icons-material': specifier: ^5.14.3 - version: 5.14.3(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) + version: 5.16.8(@mui/material@5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) '@mui/material': specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) country-flag-icons: specifier: ^1.5.7 - version: 1.5.7 + version: 1.5.13 html-react-parser: specifier: ^4.2.2 - version: 4.2.2(react@18.2.0) + version: 4.2.10(react@18.3.1) i18next: specifier: ^23.4.1 - version: 23.4.1 + version: 23.16.8 i18next-resources-to-backend: specifier: ^1.1.4 - version: 1.1.4 + version: 1.2.1 react: specifier: ^18.2.0 - version: 18.2.0 + version: 18.3.1 react-dom: specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) + version: 18.3.1(react@18.3.1) react-i18next: specifier: ^13.0.3 - version: 13.0.3(i18next@23.4.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 13.5.0(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-oidc-context: specifier: ^2.2.2 - version: 2.2.2(oidc-client-ts@2.2.4)(react@18.2.0) + version: 2.4.0(oidc-client-ts@2.4.1)(react@18.3.1) react-router-dom: specifier: ^6.14.2 - version: 6.14.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 6.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) devDependencies: '@types/react': specifier: ^18.2.15 - version: 18.2.15 + version: 18.3.12 packages/pages: dependencies: @@ -802,32 +764,32 @@ importers: version: link:../utils '@mui/material': specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) html-react-parser: specifier: ^4.2.2 - version: 4.2.2(react@18.2.0) + version: 4.2.10(react@18.3.1) react: specifier: ^18.2.0 - version: 18.2.0 + version: 18.3.1 react-dom: specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) + version: 18.3.1(react@18.3.1) react-i18next: specifier: ^13.0.3 - version: 13.0.3(i18next@23.4.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 13.5.0(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-oidc-context: specifier: ^2.2.2 - version: 2.2.2(oidc-client-ts@2.2.4)(react@18.2.0) + version: 2.4.0(oidc-client-ts@2.4.1)(react@18.3.1) react-router-dom: specifier: ^6.14.2 - version: 6.14.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 6.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) devDependencies: '@types/react': specifier: ^18.2.15 - version: 18.2.15 + version: 18.3.12 '@types/react-helmet': specifier: ^6.1.6 - version: 6.1.6 + version: 6.1.11 packages/rdt-search-ui: dependencies: @@ -836,31 +798,28 @@ importers: version: link:../utils '@elastic/elasticsearch': specifier: ^8.10.0 - version: 8.10.0 + version: 8.16.2 '@mui/icons-material': specifier: ^5.14.3 - version: 5.14.3(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) + version: 5.16.8(@mui/material@5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) '@mui/material': specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - clsx: - specifier: ^2.0.0 - version: 2.0.0 + version: 5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) echarts: specifier: ^5.4.2 - version: 5.4.3 + version: 5.5.1 framer-motion: specifier: ^10.15.0 - version: 10.15.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 10.18.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) html-react-parser: specifier: ^4.2.2 - version: 4.2.2(react@18.2.0) + version: 4.2.10(react@18.3.1) i18next: specifier: ^23.4.1 - version: 23.4.1 + version: 23.16.8 i18next-resources-to-backend: specifier: ^1.1.4 - version: 1.1.4 + version: 1.2.1 lodash.debounce: specifier: ^4.0.8 version: 4.0.8 @@ -875,53 +834,53 @@ importers: version: 0.6.3 notistack: specifier: ^3.0.1 - version: 3.0.1(csstype@3.1.3)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 3.0.1(csstype@3.1.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) ol: specifier: ^7.3.0 version: 7.5.2 react: specifier: ^18.2.0 - version: 18.2.0 + version: 18.3.1 react-i18next: specifier: ^13.0.3 - version: 13.0.3(i18next@23.4.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 13.5.0(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-router-dom: specifier: ^6.14.2 - version: 6.14.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 6.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) styled-components: specifier: ^5.3.10 - version: 5.3.10(@babel/core@7.22.10)(react-dom@18.2.0(react@18.2.0))(react-is@18.3.1)(react@18.2.0) + version: 5.3.11(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1) devDependencies: '@types/lodash.debounce': specifier: ^4.0.7 - version: 4.0.7 + version: 4.0.9 '@types/md5': specifier: ^2.3.2 - version: 2.3.3 + version: 2.3.5 '@types/ngeohash': specifier: ^0.6.4 - version: 0.6.5 + version: 0.6.8 '@types/react': specifier: ^18.0.33 - version: 18.2.15 + version: 18.3.12 '@types/styled-components': specifier: ^5.1.26 - version: 5.1.28 + version: 5.1.34 esbuild: specifier: ^0.17.15 version: 0.17.19 esbuild-css-modules-plugin: specifier: ^3.0.2 - version: 3.0.3(esbuild@0.17.19) + version: 3.1.2(esbuild@0.17.19) tslib: specifier: ^2.5.0 - version: 2.6.2 + version: 2.8.1 typescript: specifier: ^5.0.3 - version: 5.1.6 + version: 5.7.2 vite: specifier: ^4.4.5 - version: 4.4.5(@types/node@20.11.30)(lightningcss@1.22.0) + version: 4.5.5(@types/node@20.17.9)(lightningcss@1.28.2) packages/repo-advisor: dependencies: @@ -933,53 +892,53 @@ importers: version: link:../utils '@mui/material': specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@reduxjs/toolkit': specifier: ^1.9.5 - version: 1.9.5(react-redux@8.1.2(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(redux@4.2.1))(react@18.2.0) + version: 1.9.7(react-redux@8.1.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(redux@4.2.1))(react@18.3.1) framer-motion: specifier: ^10.15.0 - version: 10.15.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 10.18.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) i18next: specifier: ^23.4.1 - version: 23.4.1 + version: 23.16.8 i18next-browser-languagedetector: specifier: ^7.1.0 - version: 7.1.0 + version: 7.2.1 i18next-resources-to-backend: specifier: ^1.1.4 - version: 1.1.4 + version: 1.2.1 notistack: specifier: ^3.0.1 - version: 3.0.1(csstype@3.1.3)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 3.0.1(csstype@3.1.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: ^18.2.0 - version: 18.2.0 + version: 18.3.1 react-dom: specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) + version: 18.3.1(react@18.3.1) react-i18next: specifier: ^13.0.3 - version: 13.0.3(i18next@23.4.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 13.5.0(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-redux: specifier: ^8.1.2 - version: 8.1.2(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(redux@4.2.1) + version: 8.1.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(redux@4.2.1) react-router-dom: specifier: ^6.14.2 - version: 6.14.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 6.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) use-debounce: specifier: ^9.0.4 - version: 9.0.4(react@18.2.0) + version: 9.0.4(react@18.3.1) devDependencies: '@dans-framework/pages': specifier: workspace:* version: link:../pages '@types/react': specifier: ^18.2.15 - version: 18.2.15 + version: 18.3.12 '@types/react-dom': specifier: ^18.2.7 - version: 18.2.7 + version: 18.3.1 packages/theme: dependencies: @@ -988,20 +947,20 @@ importers: version: link:../utils '@mui/material': specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/utils': specifier: ^5.14.7 - version: 5.14.7(react@18.2.0) + version: 5.16.8(@types/react@18.3.12)(react@18.3.1) notistack: specifier: ^3.0.1 - version: 3.0.1(csstype@3.1.3)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 3.0.1(csstype@3.1.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: ^18.2.0 - version: 18.2.0 + version: 18.3.1 devDependencies: '@types/react': specifier: ^18.2.15 - version: 18.2.15 + version: 18.3.12 packages/user-auth: dependencies: @@ -1010,59 +969,59 @@ importers: version: link:../utils '@mui/icons-material': specifier: ^5.14.3 - version: 5.14.3(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) + version: 5.16.8(@mui/material@5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) '@mui/material': specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/x-data-grid': specifier: ^6.16.3 - version: 6.16.3(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@mui/system@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 6.20.4(@mui/material@5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@reduxjs/toolkit': specifier: ^1.9.5 - version: 1.9.5(react-redux@8.1.2(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(redux@4.2.1))(react@18.2.0) + version: 1.9.7(react-redux@8.1.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(redux@4.2.1))(react@18.3.1) framer-motion: specifier: ^10.15.0 - version: 10.15.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 10.18.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) i18next: specifier: ^23.4.1 - version: 23.4.1 + version: 23.16.8 i18next-resources-to-backend: specifier: ^1.1.4 - version: 1.1.4 + version: 1.2.1 moment: specifier: ^2.29.4 - version: 2.29.4 + version: 2.30.1 notistack: specifier: ^3.0.1 - version: 3.0.1(csstype@3.1.3)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 3.0.1(csstype@3.1.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) oidc-client-ts: specifier: ^2.2.4 - version: 2.2.4 + version: 2.4.1 react: specifier: ^18.2.0 - version: 18.2.0 + version: 18.3.1 react-dom: specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) + version: 18.3.1(react@18.3.1) react-i18next: specifier: ^13.0.3 - version: 13.0.3(i18next@23.4.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 13.5.0(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-oidc-context: specifier: ^2.2.2 - version: 2.2.2(oidc-client-ts@2.2.4)(react@18.2.0) + version: 2.4.0(oidc-client-ts@2.4.1)(react@18.3.1) react-redux: specifier: ^8.1.2 - version: 8.1.2(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(redux@4.2.1) + version: 8.1.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(redux@4.2.1) react-router-dom: specifier: ^6.14.2 - version: 6.14.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 6.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) use-debounce: specifier: ^9.0.4 - version: 9.0.4(react@18.2.0) + version: 9.0.4(react@18.3.1) devDependencies: '@types/react': specifier: ^18.2.15 - version: 18.2.15 + version: 18.3.12 packages/utils: {} @@ -1073,20 +1032,20 @@ importers: version: link:.. '@mui/material': specifier: ^5.16.7 - version: 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@reduxjs/toolkit': specifier: ^1.9.5 - version: 1.9.5(react-redux@8.1.2(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(redux@4.2.1))(react@18.2.0) + version: 1.9.7(react-redux@8.1.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(redux@4.2.1))(react@18.3.1) notistack: specifier: ^3.0.1 - version: 3.0.1(csstype@3.1.3)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 3.0.1(csstype@3.1.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: ^18.2.0 - version: 18.2.0 + version: 18.3.1 devDependencies: '@types/react': specifier: ^18.2.15 - version: 18.2.15 + version: 18.3.12 packages/utils/preloader: dependencies: @@ -1098,193 +1057,148 @@ importers: dependencies: react: specifier: ^18.2.0 - version: 18.2.0 + version: 18.3.1 devDependencies: '@types/react': specifier: ^18.2.15 - version: 18.2.15 + version: 18.3.12 packages/utils/user: dependencies: oidc-client-ts: specifier: ^2.2.4 - version: 2.2.4 + version: 2.4.1 packages: - '@aashutoshrathi/word-wrap@1.2.6': - resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} - engines: {node: '>=0.10.0'} - - '@ampproject/remapping@2.2.1': - resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@babel/code-frame@7.22.10': - resolution: {integrity: sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==} - engines: {node: '>=6.9.0'} - - '@babel/compat-data@7.22.9': - resolution: {integrity: sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==} + '@babel/code-frame@7.26.2': + resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} - '@babel/core@7.22.10': - resolution: {integrity: sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw==} + '@babel/compat-data@7.26.2': + resolution: {integrity: sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==} engines: {node: '>=6.9.0'} - '@babel/generator@7.22.10': - resolution: {integrity: sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==} + '@babel/core@7.26.0': + resolution: {integrity: sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==} engines: {node: '>=6.9.0'} - '@babel/helper-annotate-as-pure@7.22.5': - resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} + '@babel/generator@7.26.2': + resolution: {integrity: sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.22.10': - resolution: {integrity: sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==} + '@babel/helper-annotate-as-pure@7.25.9': + resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==} engines: {node: '>=6.9.0'} - '@babel/helper-environment-visitor@7.22.5': - resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==} + '@babel/helper-compilation-targets@7.25.9': + resolution: {integrity: sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==} engines: {node: '>=6.9.0'} - '@babel/helper-function-name@7.22.5': - resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==} + '@babel/helper-module-imports@7.25.9': + resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} engines: {node: '>=6.9.0'} - '@babel/helper-hoist-variables@7.22.5': - resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-imports@7.22.5': - resolution: {integrity: sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-transforms@7.22.9': - resolution: {integrity: sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==} + '@babel/helper-module-transforms@7.26.0': + resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-plugin-utils@7.22.5': - resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-simple-access@7.22.5': - resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} - engines: {node: '>=6.9.0'} - - '@babel/helper-split-export-declaration@7.22.6': - resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} + '@babel/helper-plugin-utils@7.25.9': + resolution: {integrity: sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.22.5': - resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.22.5': - resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.22.5': - resolution: {integrity: sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==} + '@babel/helper-validator-option@7.25.9': + resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.22.10': - resolution: {integrity: sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw==} + '@babel/helpers@7.26.0': + resolution: {integrity: sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==} engines: {node: '>=6.9.0'} - '@babel/highlight@7.22.10': - resolution: {integrity: sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.22.10': - resolution: {integrity: sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==} + '@babel/parser@7.26.2': + resolution: {integrity: sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/plugin-syntax-jsx@7.22.5': - resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==} + '@babel/plugin-syntax-jsx@7.25.9': + resolution: {integrity: sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx-self@7.22.5': - resolution: {integrity: sha512-nTh2ogNUtxbiSbxaT4Ds6aXnXEipHweN9YRgOX/oNXdf0cCrGn/+2LozFa3lnPV5D90MkjhgckCPBrsoSc1a7g==} + '@babel/plugin-transform-react-jsx-self@7.25.9': + resolution: {integrity: sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx-source@7.22.5': - resolution: {integrity: sha512-yIiRO6yobeEIaI0RTbIr8iAK9FcBHLtZq0S89ZPjDLQXBA4xvghaKqI0etp/tF3htTM0sazJKKLz9oEiGRtu7w==} + '@babel/plugin-transform-react-jsx-source@7.25.9': + resolution: {integrity: sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/runtime@7.22.10': - resolution: {integrity: sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ==} - engines: {node: '>=6.9.0'} - - '@babel/runtime@7.23.2': - resolution: {integrity: sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==} + '@babel/runtime@7.26.0': + resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} engines: {node: '>=6.9.0'} - '@babel/runtime@7.25.4': - resolution: {integrity: sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==} + '@babel/template@7.25.9': + resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} engines: {node: '>=6.9.0'} - '@babel/template@7.22.5': - resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} + '@babel/traverse@7.25.9': + resolution: {integrity: sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.22.10': - resolution: {integrity: sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig==} + '@babel/types@7.26.0': + resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} engines: {node: '>=6.9.0'} - '@babel/types@7.22.10': - resolution: {integrity: sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==} - engines: {node: '>=6.9.0'} - - '@elastic/elasticsearch@8.10.0': - resolution: {integrity: sha512-RIEyqz0D18bz/dK+wJltaak+7wKaxDELxuiwOJhuMrvbrBsYDFnEoTdP/TZ0YszHBgnRPGqBDBgH/FHNgHObiQ==} - engines: {node: '>=14'} - - '@elastic/transport@8.3.4': - resolution: {integrity: sha512-+0o8o74sbzu3BO7oOZiP9ycjzzdOt4QwmMEjFc1zfO7M0Fh7QX1xrpKqZbSd8vBwihXNlSq/EnMPfgD2uFEmFg==} - engines: {node: '>=14'} + '@elastic/elasticsearch@8.16.2': + resolution: {integrity: sha512-2ivc6uS97fbEeW4tNtg5mvh/Jy82ZLfcwQ1HhNhdYxyapNnQxIgZ83Zd8Ir+5jCPMDWKSYgwDb8t4GAINDDv2w==} + engines: {node: '>=18'} - '@emotion/babel-plugin@11.11.0': - resolution: {integrity: sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==} + '@elastic/transport@8.9.1': + resolution: {integrity: sha512-jasKNQeOb1vNf9aEYg+8zXmetaFjApDTSCC4QTl6aTixvyiRiSLcCiB8P6Q0lY9JIII/BhqNl8WbpFnsKitntw==} + engines: {node: '>=18'} - '@emotion/cache@11.11.0': - resolution: {integrity: sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==} + '@emotion/babel-plugin@11.13.5': + resolution: {integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==} - '@emotion/cache@11.13.1': - resolution: {integrity: sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==} + '@emotion/cache@11.13.5': + resolution: {integrity: sha512-Z3xbtJ+UcK76eWkagZ1onvn/wAVb1GOMuR15s30Fm2wrMgC7jzpnO2JZXr4eujTTqoQFUrZIw/rT0c6Zzjca1g==} - '@emotion/hash@0.9.1': - resolution: {integrity: sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==} + '@emotion/hash@0.9.2': + resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==} '@emotion/is-prop-valid@0.8.8': resolution: {integrity: sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==} - '@emotion/is-prop-valid@1.2.1': - resolution: {integrity: sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==} - - '@emotion/is-prop-valid@1.3.0': - resolution: {integrity: sha512-SHetuSLvJDzuNbOdtPVbq6yMMMlLoW5Q94uDqJZqy50gcmAjxFkVqmzqSGEFq9gT2iMuIeKV1PXVWmvUhuZLlQ==} + '@emotion/is-prop-valid@1.3.1': + resolution: {integrity: sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==} '@emotion/memoize@0.7.4': resolution: {integrity: sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==} - '@emotion/memoize@0.8.1': - resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} - '@emotion/memoize@0.9.0': resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==} - '@emotion/react@11.11.1': - resolution: {integrity: sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==} + '@emotion/react@11.13.5': + resolution: {integrity: sha512-6zeCUxUH+EPF1s+YF/2hPVODeV/7V07YU5x+2tfuRL8MdW6rv5vb2+CBEGTGwBdux0OIERcOS+RzxeK80k2DsQ==} peerDependencies: '@types/react': '*' react: '>=16.8.0' @@ -1292,17 +1206,14 @@ packages: '@types/react': optional: true - '@emotion/serialize@1.1.2': - resolution: {integrity: sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==} - - '@emotion/sheet@1.2.2': - resolution: {integrity: sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==} + '@emotion/serialize@1.3.3': + resolution: {integrity: sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==} '@emotion/sheet@1.4.0': resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==} - '@emotion/styled@11.11.0': - resolution: {integrity: sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==} + '@emotion/styled@11.13.5': + resolution: {integrity: sha512-gnOQ+nGLPvDXgIx119JqGalys64lhMdnNQA9TMxhDA4K0Hq5+++OE20Zs5GxiCV9r814xQ2K5WmtofSpHVW6BQ==} peerDependencies: '@emotion/react': ^11.0.0-rc.0 '@types/react': '*' @@ -1314,25 +1225,19 @@ packages: '@emotion/stylis@0.8.5': resolution: {integrity: sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==} + '@emotion/unitless@0.10.0': + resolution: {integrity: sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==} + '@emotion/unitless@0.7.5': resolution: {integrity: sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==} - '@emotion/unitless@0.8.1': - resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==} - - '@emotion/use-insertion-effect-with-fallbacks@1.0.1': - resolution: {integrity: sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==} + '@emotion/use-insertion-effect-with-fallbacks@1.1.0': + resolution: {integrity: sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==} peerDependencies: react: '>=16.8.0' - '@emotion/utils@1.2.1': - resolution: {integrity: sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==} - - '@emotion/utils@1.4.0': - resolution: {integrity: sha512-spEnrA1b6hDR/C68lC2M7m6ALPUHZC0lIY7jAS/B/9DuuO1ZP04eov8SMv/6fwRd8pzmsn2AuJEznRREWlQrlQ==} - - '@emotion/weak-memoize@0.3.1': - resolution: {integrity: sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==} + '@emotion/utils@1.4.2': + resolution: {integrity: sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==} '@emotion/weak-memoize@0.4.0': resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==} @@ -1601,44 +1506,80 @@ packages: cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.4.0': - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + '@eslint-community/eslint-utils@4.4.1': + resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.7.0': - resolution: {integrity: sha512-+HencqxU7CFJnQb7IKtuNBqS6Yx3Tz4kOL8BJXo+JyeiBm5MEX6pO8onXDkjrkCRlfYXS1Axro15ZjVFe9YgsA==} + '@eslint-community/regexpp@4.12.1': + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/eslintrc@2.1.3': - resolution: {integrity: sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/config-array@0.19.0': + resolution: {integrity: sha512-zdHg2FPIFNKPdcHWtiNT+jEFCHYVplAXRDlQDyqy0zGx/q2parwh7brGJSiTxRk/TSMkbM//zt/f5CHgyTyaSQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@8.54.0': - resolution: {integrity: sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/core@0.9.0': + resolution: {integrity: sha512-7ATR9F0e4W85D/0w7cU0SNj7qkAexMG+bAHEZOjo9akvGuhHE2m7umzWzfnpa0XAg5Kxc1BWmtPMV67jJ+9VUg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@fastify/busboy@2.0.0': - resolution: {integrity: sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==} - engines: {node: '>=14'} + '@eslint/eslintrc@3.2.0': + resolution: {integrity: sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.16.0': + resolution: {integrity: sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.4': + resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.2.3': + resolution: {integrity: sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@fontsource/roboto@5.0.7': - resolution: {integrity: sha512-Hcl5xloy9PH+hCGnKTl9Xg7SOXbvSFIg+AW2JZ5qrsAZBI9IEC4kwma6D/aTl9ywvsdEp+7TeVT2fmFImXyHTw==} + '@floating-ui/core@1.6.8': + resolution: {integrity: sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==} - '@humanwhocodes/config-array@0.11.13': - resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==} - engines: {node: '>=10.10.0'} + '@floating-ui/dom@1.6.12': + resolution: {integrity: sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==} + + '@floating-ui/react-dom@2.1.2': + resolution: {integrity: sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.8': + resolution: {integrity: sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==} + + '@fontsource/roboto@5.1.0': + resolution: {integrity: sha512-cFRRC1s6RqPygeZ8Uw/acwVHqih8Czjt6Q0MwoUoDe9U3m4dH1HmNDRBZyqlMSFwgNAUKgFImncKdmDHyKpwdg==} + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.6': + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + engines: {node: '>=18.18.0'} '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} - '@humanwhocodes/object-schema@2.0.1': - resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + + '@humanwhocodes/retry@0.4.1': + resolution: {integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==} + engines: {node: '>=18.18'} - '@jest/expect-utils@29.6.3': - resolution: {integrity: sha512-nvOEW4YoqRKD9HBJ9OJ6przvIvP9qilp5nAn1462P5ZlL/MM9SgPEZFyjTGPfs7QkocdUsJa6KjHhyRn4ueItA==} + '@jest/expect-utils@29.7.0': + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} '@jest/schemas@29.6.3': @@ -1649,26 +1590,23 @@ packages: resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@jridgewell/gen-mapping@0.3.3': - resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} - '@jridgewell/resolve-uri@3.1.1': - resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/set-array@1.1.2': - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} engines: {node: '>=6.0.0'} - '@jridgewell/sourcemap-codec@1.4.15': - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - '@jridgewell/trace-mapping@0.3.19': - resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==} - - '@jridgewell/trace-mapping@0.3.9': - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} '@mapbox/extent@0.4.0': resolution: {integrity: sha512-MSoKw3qPceGuupn04sdaJrFeLKvcSETVLZCGS8JA9x6zXQL3FWiKaIXYIZEDXd5jpXpWlRxinCZIN49yRy0C9A==} @@ -1728,13 +1666,13 @@ packages: resolution: {integrity: sha512-cOZZOVhDSulgK0meTsTkmNXb1ahVvmTmWmfx9gRBwc6hq98wS9JP35ESIoNq3xqEan+UN+gn8187Z6E4NKhLsw==} hasBin: true - '@maplibre/maplibre-gl-style-spec@20.3.1': - resolution: {integrity: sha512-5ueL4UDitzVtceQ8J4kY+Px3WK+eZTsmGwha3MBKHKqiHvKrjWWwBCIl1K8BuJSc5OFh83uI8IFNoFvQxX2uUw==} + '@maplibre/maplibre-gl-style-spec@20.4.0': + resolution: {integrity: sha512-AzBy3095fTFPjDjmWpR2w6HVRAZJ6hQZUCwk5Plz6EyfnfuQW1odeW5i2Ai47Y6TBA2hQnC+azscjBSALpaWgw==} hasBin: true - '@mui/base@5.0.0-beta.11': - resolution: {integrity: sha512-FdKZGPd8qmC3ZNke7CNhzcEgToc02M6WYZc9hcBsNQ17bgAd3s9F//1bDDYgMVBYxDM71V0sv/hBHlOY4I1ZVA==} - engines: {node: '>=12.0.0'} + '@mui/base@5.0.0-beta.63': + resolution: {integrity: sha512-W6aIqKP9X8VUX0KhSnYWo2+5C7MnKV1IhYVd517L/apvfkVq5KaTdlnxSBVwnaWt46whayVgQ/9KXwUVCXp6+w==} + engines: {node: '>=14.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 react: ^17.0.0 || ^18.0.0 @@ -1743,29 +1681,29 @@ packages: '@types/react': optional: true - '@mui/core-downloads-tracker@5.16.7': - resolution: {integrity: sha512-RtsCt4Geed2/v74sbihWzzRs+HsIQCfclHeORh5Ynu2fS4icIKozcSubwuG7vtzq2uW3fOR1zITSP84TNt2GoQ==} + '@mui/core-downloads-tracker@5.16.8': + resolution: {integrity: sha512-DARxShbBsWz6azwkTmv05rR7rJfcd9cXFsQtbcr24A+5esQBSnK2N3cbg/izlvuMGxonfWaysz/ae+6Ij9RAHQ==} - '@mui/icons-material@5.14.3': - resolution: {integrity: sha512-XkxWPhageu1OPUm2LWjo5XqeQ0t2xfGe8EiLkRW9oz2LHMMZmijvCxulhgquUVTF1DnoSh+3KoDLSsoAFtVNVw==} + '@mui/icons-material@5.16.8': + resolution: {integrity: sha512-2HKzTsCPbNgJq2z4tI6sLDwxKXqiiPh6L3IhuB8w+ypShE/qAI4FZQfI2o93vysQnkPB4Rw3FKSwAJWTThhHQA==} engines: {node: '>=12.0.0'} peerDependencies: '@mui/material': ^5.0.0 - '@types/react': ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@types/react': optional: true - '@mui/material@5.16.7': - resolution: {integrity: sha512-cwwVQxBhK60OIOqZOVLFt55t01zmarKJiJUWbk0+8s/Ix5IaUzAShqlJchxsIQ4mSrWqgcKCCXKtIlG5H+/Jmg==} + '@mui/material@5.16.8': + resolution: {integrity: sha512-amnDx385shdQasC7wAk/oQjfti8N4wm0fLEcD7n5KXDZxn9Y+0VKEC+ieVseOUGuY5B2FqzdNfeVwUPTmUBszQ==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.5.0 '@emotion/styled': ^11.3.0 - '@types/react': ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@emotion/react': optional: true @@ -1774,37 +1712,37 @@ packages: '@types/react': optional: true - '@mui/private-theming@5.16.6': - resolution: {integrity: sha512-rAk+Rh8Clg7Cd7shZhyt2HGTTE5wYKNSJ5sspf28Fqm/PZ69Er9o6KX25g03/FG2dfpg5GCwZh/xOojiTfm3hw==} + '@mui/private-theming@5.16.8': + resolution: {integrity: sha512-3Vl9yFVLU6T3CFtxRMQTcJ60Ijv7wxQi4yjH92+9YXcsqvVspeIYoocqNoIV/1bXGYfyWu5zrCmwQVHaGY7bug==} engines: {node: '>=12.0.0'} peerDependencies: - '@types/react': ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@types/react': optional: true - '@mui/styled-engine@5.16.6': - resolution: {integrity: sha512-zaThmS67ZmtHSWToTiHslbI8jwrmITcN93LQaR2lKArbvS7Z3iLkwRoiikNWutx9MBs8Q6okKvbZq1RQYB3v7g==} + '@mui/styled-engine@5.16.8': + resolution: {integrity: sha512-OFdgFf8JczSRs0kvWGdSn0ZeXxWrY0LITDPJ/nAtLEvUUTyrlFaO4il3SECX8ruzvf1VnAxHx4M/4mX9oOn9yA==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.4.1 '@emotion/styled': ^11.3.0 - react: ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@emotion/react': optional: true '@emotion/styled': optional: true - '@mui/system@5.16.7': - resolution: {integrity: sha512-Jncvs/r/d/itkxh7O7opOunTqbbSSzMTHzZkNLM+FjAOg+cYAZHrPDlYe1ZGKUYORwwb2XexlWnpZp0kZ4AHuA==} + '@mui/system@5.16.8': + resolution: {integrity: sha512-L32TaFDFpGIi1g6ysRtmhc9zDgrlxDXu3NlrGE8gAsQw/ziHrPdr0PNr20O0POUshA1q14W4dNZ/z0Nx2F9lhA==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.5.0 '@emotion/styled': ^11.3.0 - '@types/react': ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@emotion/react': optional: true @@ -1813,48 +1751,36 @@ packages: '@types/react': optional: true - '@mui/types@7.2.15': - resolution: {integrity: sha512-nbo7yPhtKJkdf9kcVOF8JZHPZTmqXjJ/tI0bdWgHg5tp9AnIN4Y7f7wm9T+0SyGYJk76+GYZ8Q5XaTYAsUHN0Q==} + '@mui/types@7.2.19': + resolution: {integrity: sha512-6XpZEM/Q3epK9RN8ENoXuygnqUQxE+siN/6rGRi2iwJPgBUR25mphYQ9ZI87plGh58YoZ5pp40bFvKYOCDJ3tA==} peerDependencies: - '@types/react': ^17.0.0 || ^18.0.0 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@types/react': optional: true - '@mui/utils@5.14.14': - resolution: {integrity: sha512-3AKp8uksje5sRfVrtgG9Q/2TBsHWVBUtA0NaXliZqGcXo8J+A+Agp0qUW2rJ+ivgPWTCCubz9FZVT2IQZ3bGsw==} + '@mui/utils@5.16.8': + resolution: {integrity: sha512-P/yb7BSWallQUeiNGxb+TM8epHteIUC8gzNTdPV2VfKhVY/EnGliHgt5np0GPkjQ7EzwDi/+gBevrAJtf+K94A==} engines: {node: '>=12.0.0'} peerDependencies: - '@types/react': ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@types/react': optional: true - '@mui/utils@5.14.5': - resolution: {integrity: sha512-6Hzw63VR9C5xYv+CbjndoRLU6Gntal8rJ5W+GUzkyHrGWIyYPWZPa6AevnyGioySNETATe1H9oXS8f/7qgIHJA==} - engines: {node: '>=12.0.0'} - peerDependencies: - react: ^17.0.0 || ^18.0.0 - - '@mui/utils@5.14.7': - resolution: {integrity: sha512-RtheP/aBoPogVdi8vj8Vo2IFnRa4mZVmnD0RGlVZ49yF60rZs+xP4/KbpIrTr83xVs34QmHQ2aQ+IX7I0a0dDw==} - engines: {node: '>=12.0.0'} - peerDependencies: - react: ^17.0.0 || ^18.0.0 - - '@mui/utils@5.16.6': - resolution: {integrity: sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==} - engines: {node: '>=12.0.0'} + '@mui/utils@6.1.9': + resolution: {integrity: sha512-N7uzBp7p2or+xanXn3aH2OTINC6F/Ru/U8h6amhRZEev8bJhKN86rIDIoxZZ902tj+09LXtH83iLxFMjMHyqNA==} + engines: {node: '>=14.0.0'} peerDependencies: - '@types/react': ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@types/react': optional: true - '@mui/x-data-grid@6.16.3': - resolution: {integrity: sha512-msohYxn11JHzeQOywaH5wGSCb/fESootqHLKG6LuET7xOxjHS8GlN/GuW/4kKcbQRunSVh/ADwqpqq+SmWrSeQ==} + '@mui/x-data-grid@6.20.4': + resolution: {integrity: sha512-I0JhinVV4e25hD2dB+R6biPBtpGeFrXf8RwlMPQbr9gUggPmPmNtWKo8Kk2PtBBMlGtdMAgHWe7PqhmucUxU1w==} engines: {node: '>=14.0.0'} peerDependencies: '@mui/material': ^5.4.1 @@ -1862,16 +1788,15 @@ packages: react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 - '@mui/x-date-pickers@6.11.0': - resolution: {integrity: sha512-yVGfpH3scUauLaHWvzckD0xswboC48YAaJ4568YTkKozXFSPPkvK7VGSQ+qo1u8K2UjYh1iZoff3k0EoDDPnww==} + '@mui/x-date-pickers@6.20.2': + resolution: {integrity: sha512-x1jLg8R+WhvkmUETRfX2wC+xJreMii78EXKLl6r3G+ggcAZlPyt0myID1Amf6hvJb9CtR7CgUo8BwR+1Vx9Ggw==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.9.0 '@emotion/styled': ^11.8.1 - '@mui/base': ^5.0.0-alpha.87 '@mui/material': ^5.8.6 '@mui/system': ^5.8.0 - date-fns: ^2.25.0 + date-fns: ^2.25.0 || ^3.2.0 date-fns-jalali: ^2.13.0-0 dayjs: ^1.10.7 luxon: ^3.0.2 @@ -1912,19 +1837,23 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@petamoriken/float16@3.8.4': - resolution: {integrity: sha512-kB+NJ5Br56ZhElKsf0pM7/PQfrDdDVMRz8f0JM6eVOGE+L89z9hwcst9QvWBBnazzuqGTGtPsJNZoQ1JdNiGSQ==} + '@opentelemetry/api@1.9.0': + resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} + engines: {node: '>=8.0.0'} - '@playwright/test@1.42.1': - resolution: {integrity: sha512-Gq9rmS54mjBL/7/MvBaNOBwbfnh7beHvS6oS4srqXFcQHpQCV1+c8JXWE8VLPyRDhgS3H8x8A7hztqI9VnwrAQ==} - engines: {node: '>=16'} + '@petamoriken/float16@3.9.0': + resolution: {integrity: sha512-rYUZ+VFjPHD0NT2JYKj64NxXxrV642IiyaUxxorTEj0S3hT7B5Ixezyc9Fn+XvSk0ETEBp5VWjGIErzh0ug0Xw==} + + '@playwright/test@1.49.0': + resolution: {integrity: sha512-DMulbwQURa8rNIQrf94+jPJQ4FmOVdpE5ZppRNvWVjvhC+6sOeo28r8MgIpQRYouXRtt/FCCXU7zn20jnHR4Qw==} + engines: {node: '>=18'} hasBin: true '@popperjs/core@2.11.8': resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} - '@reduxjs/toolkit@1.9.5': - resolution: {integrity: sha512-Rt97jHmfTeaxL4swLRNPD/zV4OxTes4la07Xc4hetpUW/vc75t5m1ANyxG6ymnEQ2FsLQsoMlYB2vV1sO3m8tQ==} + '@reduxjs/toolkit@1.9.7': + resolution: {integrity: sha512-t7v8ZPxhhKgOKtU+uyJT13lu4vL7az5aFi4IdoDs/eS548edn2M8Ik9h8fxgvMjGoAUVFSt6ZC1P5cWmQ014QQ==} peerDependencies: react: ^16.9.0 || ^17.0.0 || ^18 react-redux: ^7.2.1 || ^8.0.2 @@ -1934,48 +1863,72 @@ packages: react-redux: optional: true - '@remix-run/router@1.7.2': - resolution: {integrity: sha512-7Lcn7IqGMV+vizMPoEl5F0XDshcdDYtMI6uJLQdQz5CfZAwy3vvGKYSUk789qndt5dEC4HfSjviSYlSoHGL2+A==} - engines: {node: '>=14'} + '@remix-run/router@1.21.0': + resolution: {integrity: sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA==} + engines: {node: '>=14.0.0'} '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + '@swc/helpers@0.5.15': + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.6.8': + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.20.6': + resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + + '@types/command-line-args@5.2.3': + resolution: {integrity: sha512-uv0aG6R0Y8WHZLTamZwtfsDLVRnOa+n+n5rEvFWL5Na5gZ8V2Teab/duDPFzIIIhs9qizDpcavCusCLJZu62Kw==} + + '@types/command-line-usage@5.0.4': + resolution: {integrity: sha512-BwR5KP3Es/CSht0xqBcUXS3qCAUVXwpRKsV2+arxeb65atasuXG9LykC9Ab10Cw3s2raH92ZqOeILaQbsB2ACg==} + + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@types/geojson-vt@3.2.5': resolution: {integrity: sha512-qDO7wqtprzlpe8FfQ//ClPV9xiuoh2nkIgiouIptON9w5jvD/fA4szvP9GBlDVdJ5dldAl0kX/sy3URbWwLx0g==} '@types/geojson@7946.0.14': resolution: {integrity: sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==} - '@types/hoist-non-react-statics@3.3.1': - resolution: {integrity: sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==} + '@types/hoist-non-react-statics@3.3.5': + resolution: {integrity: sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==} - '@types/istanbul-lib-coverage@2.0.4': - resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} - '@types/istanbul-lib-report@3.0.0': - resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} - '@types/istanbul-reports@3.0.1': - resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} - '@types/jest@29.5.3': - resolution: {integrity: sha512-1Nq7YrO/vJE/FYnqYyw0FS8LdrjExSgIiHyKg7xPpn+yi8Q4huZryKnkJatN1ZRH89Kw2v33/8ZMB7DuZeSLlA==} + '@types/jest@29.5.14': + resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} - '@types/json-schema@7.0.12': - resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/lodash.debounce@4.0.7': - resolution: {integrity: sha512-X1T4wMZ+gT000M2/91SYj0d/7JfeNZ9PeeOldSNoE/lunLeQXKvkmIumI29IaKMotU/ln/McOIvgzZcQ/3TrSA==} + '@types/lodash.debounce@4.0.9': + resolution: {integrity: sha512-Ma5JcgTREwpLRwMM+XwBR7DaWe96nC38uCBDFKZWbNKD+osjVzdpnUSwBcqCptrp16sSOLBAUb50Car5I0TCsQ==} - '@types/lodash@4.14.199': - resolution: {integrity: sha512-Vrjz5N5Ia4SEzWWgIVwnHNEnb1UE1XMkvY5DGXrAeOGE9imk0hgTHh5GyDjLDJi9OTCn9oo9dXH1uToK1VRfrg==} + '@types/lodash@4.17.13': + resolution: {integrity: sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==} - '@types/mapbox-gl@3.4.0': - resolution: {integrity: sha512-tbn++Mm94H1kE7W6FF0oVC9rMXHVzDDNUbS7KfBMRF8NV/8csFi+67ytKcZJ4LsrpsJ+8MC6Os6ZinEDCsrunw==} + '@types/mapbox-gl@3.4.1': + resolution: {integrity: sha512-NsGKKtgW93B+UaLPti6B7NwlxYlES5DpV5Gzj9F75rK5ALKsqSk15CiEHbOnTr09RGbr6ZYiCdI+59NNNcAImg==} - '@types/mapbox__mapbox-gl-draw@1.4.7': - resolution: {integrity: sha512-SNiewXzHCgbJ4EIEG6B7ZMFTwYhHAoEWLdD179AujwmGBaYjn/LZBEQRJLjjq2utB4dEsy5ys2t4cXwEmShpPQ==} + '@types/mapbox__mapbox-gl-draw@1.4.8': + resolution: {integrity: sha512-700zPikQXfFMB2vtkJdXSROiqS5F19guf6QdYqvlgCdaMxGmdlLITRq6/zFpzfVQDrgpWex5M8vLtbwjZfup8g==} '@types/mapbox__point-geometry@0.1.4': resolution: {integrity: sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA==} @@ -1983,62 +1936,41 @@ packages: '@types/mapbox__vector-tile@1.3.4': resolution: {integrity: sha512-bpd8dRn9pr6xKvuEBQup8pwQfD4VUyqO/2deGjfpe6AwC8YRlyEipvefyRJUSiCJTZuCb8Pl1ciVV5ekqJ96Bg==} - '@types/md5@2.3.3': - resolution: {integrity: sha512-4K40FjTW0tiIx9NfV+/DHJ56ih3fcdkDqBYz5CffKwJVWYho1FxzjkddGcgEEIs+fP2DqmQ3lujC5c4bUOESTQ==} - - '@types/ngeohash@0.6.5': - resolution: {integrity: sha512-MBQKbbrz6OB819PUGYbEjYmdymJKvzEDYU8zAjZ45JI4f6H0nYcSwTFBWHkX9h1Vk43KPl7gIa4sGZ/D5eQRlg==} + '@types/md5@2.3.5': + resolution: {integrity: sha512-/i42wjYNgE6wf0j2bcTX6kuowmdL/6PE4IVitMpm2eYKBUuYCprdcWVK+xEF0gcV6ufMCRhtxmReGfc6hIK7Jw==} - '@types/node@18.0.6': - resolution: {integrity: sha512-/xUq6H2aQm261exT6iZTMifUySEt4GR5KX8eYyY+C4MSNPqSh9oNIP7tz2GLKTlFaiBbgZNxffoR3CVRG+cljw==} + '@types/ngeohash@0.6.8': + resolution: {integrity: sha512-A90x3HMwE1yXbWCnd0ztHzv8rAQPjwTzX2diYI/6OrWm/3oairDaehw5WPWJFgZ+8+J/OuF99IbipmMa2le6tQ==} - '@types/node@20.11.30': - resolution: {integrity: sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==} + '@types/node@20.17.9': + resolution: {integrity: sha512-0JOXkRyLanfGPE2QRCwgxhzlBAvaRdCNMcvbd7jFfpmD4eEXll7LRwy5ymJmyeZqk7Nh7eD2LeUyQ68BbndmXw==} - '@types/node@20.5.3': - resolution: {integrity: sha512-ITI7rbWczR8a/S6qjAW7DMqxqFMjjTo61qZVWJ1ubPvbIQsL5D/TvwjYEalM8Kthpe3hTzOGrF2TGbAu2uyqeA==} - - '@types/parse-json@4.0.0': - resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} + '@types/parse-json@4.0.2': + resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} '@types/pbf@3.0.5': resolution: {integrity: sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==} - '@types/prop-types@15.7.12': - resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} - - '@types/prop-types@15.7.9': - resolution: {integrity: sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g==} + '@types/prop-types@15.7.13': + resolution: {integrity: sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==} - '@types/react-dom@18.2.7': - resolution: {integrity: sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==} + '@types/react-dom@18.3.1': + resolution: {integrity: sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==} - '@types/react-helmet@6.1.6': - resolution: {integrity: sha512-ZKcoOdW/Tg+kiUbkFCBtvDw0k3nD4HJ/h/B9yWxN4uDO8OkRksWTO+EL+z/Qu3aHTeTll3Ro0Cc/8UhwBCMG5A==} - - '@types/react-is@18.2.1': - resolution: {integrity: sha512-wyUkmaaSZEzFZivD8F2ftSyAfk6L+DfFliVj/mYdOXbVjRcS87fQJLTnhk6dRZPuJjI+9g6RZJO4PNCngUrmyw==} + '@types/react-helmet@6.1.11': + resolution: {integrity: sha512-0QcdGLddTERotCXo3VFlUSWO3ztraw8nZ6e3zJSgG7apwV5xt+pJUS8ewPBqT4NYB1optGLprNQzFleIY84u/g==} '@types/react-transition-group@4.4.11': resolution: {integrity: sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==} - '@types/react-transition-group@4.4.6': - resolution: {integrity: sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==} - - '@types/react@18.2.15': - resolution: {integrity: sha512-oEjE7TQt1fFTFSbf8kkNuc798ahTUzn3Le67/PWjE8MAfYAD/qB7O8hSTcromLFqHCt9bcdOg5GXMokzTjJ5SA==} - - '@types/scheduler@0.16.3': - resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==} - - '@types/semver@7.5.0': - resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} + '@types/react@18.3.12': + resolution: {integrity: sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==} - '@types/stack-utils@2.0.1': - resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} + '@types/stack-utils@2.0.3': + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} - '@types/styled-components@5.1.28': - resolution: {integrity: sha512-nu0VKNybkjvUqJAXWtRqKd7j3iRUl8GbYSTvZNuIBJcw/HUp1Y4QUXNLlj7gcnRV/t784JnHAlvRnSnE3nPbJA==} + '@types/styled-components@5.1.34': + resolution: {integrity: sha512-mmiVvwpYklFIv9E8qfxuPyIt/OuyIrn6gMOAMOFUO3WJfSrSE+sGUoa4PiZj77Ut7bKZpaa6o1fBKS/4TOEvnA==} '@types/supercluster@7.1.3': resolution: {integrity: sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==} @@ -2046,89 +1978,90 @@ packages: '@types/use-sync-external-store@0.0.3': resolution: {integrity: sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==} - '@types/uuid@9.0.2': - resolution: {integrity: sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ==} + '@types/uuid@9.0.8': + resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} - '@types/yargs-parser@21.0.0': - resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} - '@types/yargs@17.0.24': - resolution: {integrity: sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==} + '@types/yargs@17.0.33': + resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} - '@typescript-eslint/eslint-plugin@6.12.0': - resolution: {integrity: sha512-XOpZ3IyJUIV1b15M7HVOpgQxPPF7lGXgsfcEIu3yDxFPaf/xZKt7s9QO/pbk7vpWQyVulpJbu4E5LwpZiQo4kA==} - engines: {node: ^16.0.0 || >=18.0.0} + '@typescript-eslint/eslint-plugin@8.17.0': + resolution: {integrity: sha512-HU1KAdW3Tt8zQkdvNoIijfWDMvdSweFYm4hWh+KwhPstv+sCmWb89hCIP8msFm9N1R/ooh9honpSuvqKWlYy3w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha - eslint: ^7.0.0 || ^8.0.0 + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/parser@6.12.0': - resolution: {integrity: sha512-s8/jNFPKPNRmXEnNXfuo1gemBdVmpQsK1pcu+QIvuNJuhFzGrpD7WjOcvDc/+uEdfzSYpNu7U/+MmbScjoQ6vg==} - engines: {node: ^16.0.0 || >=18.0.0} + '@typescript-eslint/parser@8.17.0': + resolution: {integrity: sha512-Drp39TXuUlD49F7ilHHCG7TTg8IkA+hxCuULdmzWYICxGXvDXmDmWEjJYZQYgf6l/TFfYNE167m7isnc3xlIEg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^7.0.0 || ^8.0.0 + eslint: ^8.57.0 || ^9.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/scope-manager@6.12.0': - resolution: {integrity: sha512-5gUvjg+XdSj8pcetdL9eXJzQNTl3RD7LgUiYTl8Aabdi8hFkaGSYnaS6BLc0BGNaDH+tVzVwmKtWvu0jLgWVbw==} - engines: {node: ^16.0.0 || >=18.0.0} + '@typescript-eslint/scope-manager@8.17.0': + resolution: {integrity: sha512-/ewp4XjvnxaREtqsZjF4Mfn078RD/9GmiEAtTeLQ7yFdKnqwTOgRMSvFz4et9U5RiJQ15WTGXPLj89zGusvxBg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/type-utils@6.12.0': - resolution: {integrity: sha512-WWmRXxhm1X8Wlquj+MhsAG4dU/Blvf1xDgGaYCzfvStP2NwPQh6KBvCDbiOEvaE0filhranjIlK/2fSTVwtBng==} - engines: {node: ^16.0.0 || >=18.0.0} + '@typescript-eslint/type-utils@8.17.0': + resolution: {integrity: sha512-q38llWJYPd63rRnJ6wY/ZQqIzPrBCkPdpIsaCfkR3Q4t3p6sb422zougfad4TFW9+ElIFLVDzWGiGAfbb/v2qw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^7.0.0 || ^8.0.0 + eslint: ^8.57.0 || ^9.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/types@6.12.0': - resolution: {integrity: sha512-MA16p/+WxM5JG/F3RTpRIcuOghWO30//VEOvzubM8zuOOBYXsP+IfjoCXXiIfy2Ta8FRh9+IO9QLlaFQUU+10Q==} - engines: {node: ^16.0.0 || >=18.0.0} + '@typescript-eslint/types@8.17.0': + resolution: {integrity: sha512-gY2TVzeve3z6crqh2Ic7Cr+CAv6pfb0Egee7J5UAVWCpVvDI/F71wNfolIim4FE6hT15EbpZFVUj9j5i38jYXA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@6.12.0': - resolution: {integrity: sha512-vw9E2P9+3UUWzhgjyyVczLWxZ3GuQNT7QpnIY3o5OMeLO/c8oHljGc8ZpryBMIyympiAAaKgw9e5Hl9dCWFOYw==} - engines: {node: ^16.0.0 || >=18.0.0} + '@typescript-eslint/typescript-estree@8.17.0': + resolution: {integrity: sha512-JqkOopc1nRKZpX+opvKqnM3XUlM7LpFMD0lYxTqOTKQfCWAmxw45e3qlOCsEqEB2yuacujivudOFpCnqkBDNMw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/utils@6.12.0': - resolution: {integrity: sha512-LywPm8h3tGEbgfyjYnu3dauZ0U7R60m+miXgKcZS8c7QALO9uWJdvNoP+duKTk2XMWc7/Q3d/QiCuLN9X6SWyQ==} - engines: {node: ^16.0.0 || >=18.0.0} + '@typescript-eslint/utils@8.17.0': + resolution: {integrity: sha512-bQC8BnEkxqG8HBGKwG9wXlZqg37RKSMY7v/X8VEWD8JG2JuTHuNK0VFvMPMUKQcbk6B+tf05k+4AShAEtCtJ/w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - - '@typescript-eslint/visitor-keys@6.12.0': - resolution: {integrity: sha512-rg3BizTZHF1k3ipn8gfrzDXXSFKyOEB5zxYXInQ6z0hUvmQlhaZQzK+YmHmNViMA9HzW5Q9+bPPt90bU6GQwyw==} - engines: {node: ^16.0.0 || >=18.0.0} + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true - '@ungap/structured-clone@1.2.0': - resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + '@typescript-eslint/visitor-keys@8.17.0': + resolution: {integrity: sha512-1Hm7THLpO6ww5QU6H/Qp+AusUUl+z/CAm3cNZZ0jQvon9yicgO7Rwd+/WWRpMKLYV6p2UvdbR27c86rzCPpreg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@vitejs/plugin-react@4.0.3': - resolution: {integrity: sha512-pwXDog5nwwvSIzwrvYYmA2Ljcd/ZNlcsSG2Q9CNDBwnsd55UGAyr2doXtB5j+2uymRCnCfExlznzzSFbBRcoCg==} + '@vitejs/plugin-react@4.3.4': + resolution: {integrity: sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: - vite: ^4.2.0 + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn@8.10.0: - resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} + acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} engines: {node: '>=0.4.0'} hasBin: true @@ -2147,10 +2080,6 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} - ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -2163,6 +2092,10 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} + apache-arrow@18.1.0: + resolution: {integrity: sha512-v/ShMp57iBnBp4lDgV8Jx3d3Q5/Hac25FWmQ98eMahUiHPXcvwIMKJD0hBIgclm/FCG+LwPkAKtkRO1O/W0YGg==} + hasBin: true + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -2170,14 +2103,18 @@ packages: resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} engines: {node: '>=0.10.0'} + array-back@3.1.0: + resolution: {integrity: sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==} + engines: {node: '>=6'} + + array-back@6.2.2: + resolution: {integrity: sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==} + engines: {node: '>=12.17'} + array-buffer-byte-length@1.0.1: resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} engines: {node: '>= 0.4'} - array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - arraybuffer.prototype.slice@1.0.3: resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} engines: {node: '>= 0.4'} @@ -2186,20 +2123,14 @@ packages: resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} engines: {node: '>=0.10.0'} - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - attr-accept@2.2.2: - resolution: {integrity: sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==} + attr-accept@2.2.5: + resolution: {integrity: sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==} engines: {node: '>=4'} available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axios@1.6.0: - resolution: {integrity: sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==} - babel-plugin-macros@3.1.0: resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} engines: {node: '>=10', npm: '>=6'} @@ -2212,19 +2143,22 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - binary-extensions@2.2.0: - resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.21.10: - resolution: {integrity: sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==} + browserslist@4.24.2: + resolution: {integrity: sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -2248,16 +2182,16 @@ packages: camelize@1.0.1: resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} - caniuse-lite@1.0.30001522: - resolution: {integrity: sha512-TKiyTVZxJGhsTszLuzb+6vUZSjVOAhClszBr2Ta2k9IwtNBT/4dzmL6aywt0HCgEZlmwJzXJd8yNiob6HgwTRg==} + caniuse-lite@1.0.30001686: + resolution: {integrity: sha512-Y7deg0Aergpa24M3qLC5xjNklnKnhsmSyR/V89dLZ1n0ucJIFNs7PgR2Yfa/Zf6W79SbBicgtGxZr2juHkEUIA==} cfb@1.2.2: resolution: {integrity: sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==} engines: {node: '>=0.8'} - chalk@2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} + chalk-template@0.4.0: + resolution: {integrity: sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==} + engines: {node: '>=12'} chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} @@ -2269,26 +2203,18 @@ packages: cheap-ruler@4.0.0: resolution: {integrity: sha512-0BJa8f4t141BYKQyn9NSQt1PguFQXMXwZiA5shfoaBYHAb2fFk2RAX+tiWMoQU+Agtzt3mdt0JtuyshAXqZ+Vw==} - chokidar@3.5.3: - resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} - ci-info@3.8.0: - resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} - cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - clsx@1.2.1: resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} engines: {node: '>=6'} - clsx@2.0.0: - resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==} - engines: {node: '>=6'} - clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} @@ -2297,25 +2223,23 @@ packages: resolution: {integrity: sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==} engines: {node: '>=0.8'} - color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} - color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} - color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} combine-errors@3.0.3: resolution: {integrity: sha512-C8ikRNRMygCwaTx+Ek3Yr+OuZzgZjduCOfSQBjbM8V3MfgcjSTeto/GXP6PAwKvJz/v15b7GHZvx5rOlczFw/Q==} - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} + command-line-args@5.2.1: + resolution: {integrity: sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==} + engines: {node: '>=4.0.0'} + + command-line-usage@7.0.3: + resolution: {integrity: sha512-PqMLy5+YGwhMh1wS04mVG44oqDsgyLRSKJBdOo1bnYhMKBW65gZF1dRp2OZRhiTjgUHljy99qkO7bsctLaw35Q==} + engines: {node: '>=12.20.0'} commander@8.3.0: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} @@ -2327,27 +2251,30 @@ packages: convert-source-map@1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cosmiconfig@7.1.0: resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} engines: {node: '>=10'} - country-flag-icons@1.5.7: - resolution: {integrity: sha512-AdvXhMcmSp7nBSkpGfW4qR/luAdRUutJqya9PuwRbsBzuoknThfultbv7Ib6fWsHXC43Es/4QJ8gzQQdBNm75A==} + country-flag-icons@1.5.13: + resolution: {integrity: sha512-4JwHNqaKZ19doQoNcBjsoYA+I7NqCH/mC/6f5cBWvdKzcK5TMmzLpq3Z/syVHMHJuDGFwJ+rPpGizvrqJybJow==} crc-32@1.2.2: resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} engines: {node: '>=0.8'} hasBin: true - cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} crypt@0.0.2: resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} - crypto-js@4.1.1: - resolution: {integrity: sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==} + crypto-js@4.2.0: + resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} css-color-keywords@1.0.0: resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==} @@ -2359,9 +2286,6 @@ packages: csscolorparser@1.0.3: resolution: {integrity: sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w==} - csstype@3.1.2: - resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} - csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} @@ -2380,8 +2304,8 @@ packages: resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} engines: {node: '>= 0.4'} - debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -2396,18 +2320,10 @@ packages: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} - define-lazy-prop@2.0.0: - resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} - engines: {node: '>=8'} - define-properties@1.2.1: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - detect-libc@1.0.3: resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} engines: {node: '>=0.10'} @@ -2417,14 +2333,6 @@ packages: resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - - doctrine@3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - dom-helpers@5.2.1: resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} @@ -2447,14 +2355,11 @@ packages: earcut@3.0.0: resolution: {integrity: sha512-41Fs7Q/PLq1SDbqjsgcY7GA42T0jvaCNGXgGtsNdvg+Yv8eIu06bxv4/PoREkZ9nMDNwnUSG9OFB9+yv8eKhDg==} - echarts@5.4.3: - resolution: {integrity: sha512-mYKxLxhzy6zyTi/FaEbJMOZU1ULGEQHaeIeuMR5L+JnJTpz+YR03mnnpBhbR4+UYJAgiXgpyTVLffPAjOTLkZA==} - - electron-to-chromium@1.4.500: - resolution: {integrity: sha512-P38NO8eOuWOKY1sQk5yE0crNtrjgjJj6r3NrbIKtG18KzCHmHE2Bt+aQA7/y0w3uYsHWxDa6icOohzjLJ4vJ4A==} + echarts@5.5.1: + resolution: {integrity: sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA==} - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + electron-to-chromium@1.5.68: + resolution: {integrity: sha512-FgMdJlma0OzUYlbrtZ4AeXjKxKPk6KT8WOP8BjcqxWtlg8qyJQjRzPJzUtUn5GBg1oQ26hFs7HOOHJMYiJRnvQ==} entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} @@ -2463,8 +2368,8 @@ packages: error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - es-abstract@1.23.3: - resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} + es-abstract@1.23.5: + resolution: {integrity: sha512-vlmniQ0WNPwXqA0BnmwV3Ng7HxiGlh6r5U6JcTMNx8OilcAGqVJBHJcPjqOMaczU9fRuRK5Px2BdVyPRnKMMVQ==} engines: {node: '>= 0.4'} es-define-property@1.0.0: @@ -2483,12 +2388,12 @@ packages: resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} engines: {node: '>= 0.4'} - es-to-primitive@1.2.1: - resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} - esbuild-css-modules-plugin@3.0.3: - resolution: {integrity: sha512-2NPTBoQMu+cs3JKl28MrrgYJFClY7RJRdHbUJu7P3wg9NOx3SAnT1Ywso0CGQUCRuzmbTMXfzR1/8E/bmwWTxg==} + esbuild-css-modules-plugin@3.1.2: + resolution: {integrity: sha512-XRpRuRT3m1Pk456djTvrq1AOEj+OB8sa8PdGN/Yha6eL8Im0TIYPq0CELgQU6DDKkHlYET++3sXZVjiF/kcgQw==} engines: {node: '>= 16.20.0'} peerDependencies: esbuild: '*' @@ -2503,14 +2408,10 @@ packages: engines: {node: '>=12'} hasBin: true - escalade@3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} - escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - escape-string-regexp@2.0.0: resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} engines: {node: '>=8'} @@ -2519,42 +2420,46 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - eslint-config-prettier@9.0.0: - resolution: {integrity: sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==} + eslint-config-prettier@9.1.0: + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} hasBin: true peerDependencies: eslint: '>=7.0.0' - eslint-plugin-react-hooks@4.6.0: - resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} + eslint-plugin-react-hooks@5.0.0: + resolution: {integrity: sha512-hIOwI+5hYGpJEc4uPRmz2ulCjAGD/N13Lukkh8cLV0i2IRk/bdZDYjgLVHj+U9Z704kLIdIO6iueGvxNur0sgw==} engines: {node: '>=10'} peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - - eslint-plugin-react-refresh@0.4.3: - resolution: {integrity: sha512-Hh0wv8bUNY877+sI0BlCUlsS0TYYQqvzEwJsJJPM2WF4RnTStSnSR3zdJYa2nPOJgg3UghXi54lVyMSmpCalzA==} - peerDependencies: - eslint: '>=7' + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 - eslint-scope@7.2.2: - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-scope@8.2.0: + resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint@8.54.0: - resolution: {integrity: sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-visitor-keys@4.2.0: + resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.16.0: + resolution: {integrity: sha512-whp8mSQI4C8VXd+fLgSM0lh3UlmcFtVwUQjyKCFfsp+2ItAIYhlq/hqGahGqHE6cv9unM41VlqKk2VtKYR2TaA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true - espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + espree@10.3.0: + resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - esquery@1.5.0: - resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} esrecurse@4.3.0: @@ -2569,8 +2474,8 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} - expect@29.6.3: - resolution: {integrity: sha512-x1vY4LlEMWUYVZQrFi4ZANXFwqYbJ/JNQspLVvzhW2BNY28aNcXMQH6imBbt+RBf5sVRTodYHXtSP/TLEU0Dxw==} + expect@29.7.0: + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} extend-shallow@2.0.1: @@ -2584,8 +2489,8 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - fast-glob@3.3.1: - resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} fast-json-stable-stringify@2.1.0: @@ -2594,28 +2499,29 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - fast-xml-parser@4.2.7: - resolution: {integrity: sha512-J8r6BriSLO1uj2miOk1NW0YVm8AGOOu3Si2HQp/cSmo6EA4m3fcwu2WKjJ4RK9wMLBtg69y1kS8baDiQBR41Ig==} + fast-xml-parser@4.5.0: + resolution: {integrity: sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==} hasBin: true - fastq@1.15.0: - resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} - - fflate@0.8.2: - resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} - file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} - file-selector@0.6.0: - resolution: {integrity: sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==} + file-selector@2.1.2: + resolution: {integrity: sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==} engines: {node: '>= 12'} - fill-range@7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + find-replace@3.0.0: + resolution: {integrity: sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==} + engines: {node: '>=4.0.0'} + find-root@1.1.0: resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} @@ -2623,35 +2529,25 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - flat-cache@3.0.4: - resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} - engines: {node: ^10.12.0 || >=12.0.0} + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} - flatted@3.2.7: - resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} + flatbuffers@24.3.25: + resolution: {integrity: sha512-3HDgPbgiwWMI9zVB7VYBHaMrbOO7Gm0v+yD2FV/sCKj+9NDeVL7BOBYUuhWAQGKWOzBo8S9WdMvV0eixO233XQ==} - follow-redirects@1.15.2: - resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true + flatted@3.3.2: + resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==} for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} - form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} - frac@1.1.2: resolution: {integrity: sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==} engines: {node: '>=0.8'} - framer-motion@10.15.0: - resolution: {integrity: sha512-HDjWrYWgbO5orKuhnXETLFzk7UUvwWur2HFs2elAZ8lVpI49ClHql31DNTVvVBcOrSHfAOS4eBDBedIvOx634w==} + framer-motion@10.18.0: + resolution: {integrity: sha512-oGlDh1Q1XqYPksuTD/usb0I70hq95OUzmL9+6Zd+Hs4XV0oaISBa/UUMSjYiq6m8EUF32132mOJ8xVZS+I0S6w==} peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 @@ -2661,13 +2557,10 @@ packages: react-dom: optional: true - fs-extra@11.1.1: - resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} + fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} engines: {node: '>=14.14'} - fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - fsevents@2.3.2: resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -2698,14 +2591,10 @@ packages: geojson-vt@4.0.2: resolution: {integrity: sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A==} - geotiff@2.0.7: - resolution: {integrity: sha512-FKvFTNowMU5K6lHYY2f83d4lS2rsCNdpUC28AX61x9ZzzqPNaWFElWv93xj0eJFaNyOYA63ic5OzJ88dHpoA5Q==} + geotiff@2.1.3: + resolution: {integrity: sha512-PT6uoF5a1+kbC3tHmZSUsLHBp2QJlHasxxxxPW47QIY1VBKpFB+FcDvX+MxER6UzgLQZ0xDzJ9s48B9JbOCTqA==} engines: {node: '>=10.19'} - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - get-intrinsic@1.2.4: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} @@ -2733,36 +2622,30 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} - glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - - global-prefix@3.0.0: - resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==} - engines: {node: '>=6'} + global-prefix@4.0.0: + resolution: {integrity: sha512-w0Uf9Y9/nyHinEk5vMJKRie+wa4kR5hmDbEhGGds/kG1PwGLLHKRoNMeJOyCQjjBkANlnScqgzcFwGHgmgLkVA==} + engines: {node: '>=16'} globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} - globals@13.21.0: - resolution: {integrity: sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==} - engines: {node: '>=8'} + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} globalthis@1.0.4: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} - globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} - - goober@2.1.13: - resolution: {integrity: sha512-jFj3BQeleOoy7t93E9rZ2de+ScC4lQICLwiAQmKMg9F6roKGaLSHoCDYKkWlSafg138jejvq/mTdvmnwDQgqoQ==} + goober@2.1.16: + resolution: {integrity: sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==} peerDependencies: csstype: ^3.0.10 - gopd@1.0.1: - resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + gopd@1.1.0: + resolution: {integrity: sha512-FQoVQnqcdk4hVM4JN1eromaun4iuS34oStkdlLENLdpULsuQcTyXj8w7ayhuUfPwEYZ1ZOooOTT6fdA9Vmx/RA==} + engines: {node: '>= 0.4'} graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -2787,22 +2670,18 @@ packages: has-property-descriptors@1.0.2: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - has-proto@1.0.3: - resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + has-proto@1.1.0: + resolution: {integrity: sha512-QLdzI9IIO1Jg7f9GT1gXpPpXArAn6cS31R1eEZqz08Gc+uQ8/XiqHWt17Fiw+2p6oTTIq5GXEpQkAlA88YRl/Q==} engines: {node: '>= 0.4'} - has-symbols@1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} engines: {node: '>= 0.4'} has-tostringtag@1.0.2: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} - has@1.0.3: - resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} - engines: {node: '>= 0.4.0'} - hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -2817,34 +2696,34 @@ packages: resolution: {integrity: sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==} engines: {node: '>=14'} - html-dom-parser@4.0.0: - resolution: {integrity: sha512-TUa3wIwi80f5NF8CVWzkopBVqVAtlawUzJoLwVLHns0XSJGynss4jiY0mTWpiDOsuyw+afP+ujjMgRh9CoZcXw==} + html-dom-parser@5.0.3: + resolution: {integrity: sha512-slsc6ipw88OUZjAayRs5NTmfOQCwcUa3hNyk6AdsbQxY09H5Lr1Y3CZ4ZlconMKql3Ga6sWg3HMoUzo7KSItaQ==} html-parse-stringify@3.0.1: resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} - html-react-parser@4.2.2: - resolution: {integrity: sha512-lh0wEGISnFZEAmvQqK4xc0duFMUh/m9YYyAhFursWxdtNv+hCZge0kj1y4wep6qPB5Zm33L+2/P6TcGWAJJbjA==} + html-react-parser@4.2.10: + resolution: {integrity: sha512-JyKZVQ+kQ8PdycISwkuLbEEvV/k4hWhU6cb6TT7yGaYwdqA7cPt4VRYXkCZcix2vlQtgDBSMJUmPI2jpNjPGvg==} peerDependencies: react: 0.14 || 15 || 16 || 17 || 18 htmlparser2@9.0.0: resolution: {integrity: sha512-uxbSI98wmFT/G4P2zXx4OVx04qWUmyFPrD2/CNepa2Zo3GPNaCaaxElDgwUrwYWkK1nr9fft0Ya8dws8coDLLQ==} - i18next-browser-languagedetector@7.1.0: - resolution: {integrity: sha512-cr2k7u1XJJ4HTOjM9GyOMtbOA47RtUoWRAtt52z43r3AoMs2StYKyjS3URPhzHaf+mn10hY9dZWamga5WPQjhA==} + i18next-browser-languagedetector@7.2.1: + resolution: {integrity: sha512-h/pM34bcH6tbz8WgGXcmWauNpQupCGr25XPp9cZwZInR9XHSjIFDYp1SIok7zSPsTOMxdvuLyu86V+g2Kycnfw==} - i18next-resources-to-backend@1.1.4: - resolution: {integrity: sha512-hMyr9AOmIea17AOaVe1srNxK/l3mbk81P7Uf3fdcjlw3ehZy3UNTd0OP3EEi6yu4J02kf9jzhCcjokz6AFlEOg==} + i18next-resources-to-backend@1.2.1: + resolution: {integrity: sha512-okHbVA+HZ7n1/76MsfhPqDou0fptl2dAlhRDu2ideXloRRduzHsqDOznJBef+R3DFZnbvWoBW+KxJ7fnFjd6Yw==} - i18next@23.4.1: - resolution: {integrity: sha512-07ekE7hbUrbxTYj97VnBzyhKcGURTJC9p4iWTwCVC8t63T+YrgqQmb/n1LBQMivZYwR61pqS+PC0G2rtENycyQ==} + i18next@23.16.8: + resolution: {integrity: sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==} ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - ignore@5.2.4: - resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} immer@9.0.21: @@ -2858,17 +2737,12 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} - inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - ini@1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + ini@4.1.3: + resolution: {integrity: sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - inline-style-parser@0.1.1: - resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} + inline-style-parser@0.2.2: + resolution: {integrity: sha512-EcKzdTHVe8wFVOGEYXiW9WmJXPjqi1T+234YpJr98RiFYKHV3cdy1+3mkTE+KHTHxFFLH51SfaGOoUdW+v7ViQ==} internal-slot@1.0.7: resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} @@ -2881,15 +2755,20 @@ packages: is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-bigint@1.0.4: - resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + is-async-function@2.0.0: + resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} - is-boolean-object@1.1.2: - resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + is-boolean-object@1.2.0: + resolution: {integrity: sha512-kR5g0+dXf/+kXnqI+lu0URKYPKgICtHGGNCDSB10AaUFj3o/HkB3u7WfpRBJGFopxxY0oH3ux7ZsDjLtK7xqvw==} engines: {node: '>= 0.4'} is-buffer@1.1.6: @@ -2899,8 +2778,9 @@ packages: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} - is-core-module@2.13.0: - resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==} + is-core-module@2.15.1: + resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} + engines: {node: '>= 0.4'} is-data-view@1.0.1: resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} @@ -2910,11 +2790,6 @@ packages: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} engines: {node: '>= 0.4'} - is-docker@2.2.1: - resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} - engines: {node: '>=8'} - hasBin: true - is-extendable@0.1.1: resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} engines: {node: '>=0.10.0'} @@ -2927,36 +2802,44 @@ packages: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} + is-finalizationregistry@1.1.0: + resolution: {integrity: sha512-qfMdqbAQEwBw78ZyReKnlA8ezmPdb9BemzIIip/JkjaZUhitfXDkkr+3QTboW0JrSXT1QWyYShpvnNHGZ4c4yA==} + engines: {node: '>= 0.4'} + + is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + is-negative-zero@2.0.3: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} - is-number-object@1.0.7: - resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + is-number-object@1.1.0: + resolution: {integrity: sha512-KVSZV0Dunv9DTPkhXwcZ3Q+tUc9TsaE1ZwX5J2WMvsSGS6Md8TFPun5uwh0yRdrNerI6vf/tbJxqSx4c1ZI1Lw==} engines: {node: '>= 0.4'} is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - is-plain-object@2.0.4: resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} engines: {node: '>=0.10.0'} - is-regex@1.1.4: - resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + is-regex@1.2.0: + resolution: {integrity: sha512-B6ohK4ZmoftlUe+uvenXSbPJFo6U37BH7oO1B3nQH8f/7h27N56s85MhUtbFJAziz5dcmuR3i8ovUl35zp8pFA==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} engines: {node: '>= 0.4'} is-shared-array-buffer@1.0.3: @@ -2967,24 +2850,28 @@ packages: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} - is-string@1.0.7: - resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + is-string@1.1.0: + resolution: {integrity: sha512-PlfzajuF9vSo5wErv3MJAKD/nqf9ngAs1NFQYm16nUYFO2IzxJ2hcm+IOCg+EEopdykNNUhVq5cz35cAUxU8+g==} engines: {node: '>= 0.4'} - is-symbol@1.0.4: - resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + is-symbol@1.1.0: + resolution: {integrity: sha512-qS8KkNNXUZ/I+nX6QT8ZS1/Yx0A444yhzdTKxCzKkNjQ9sHErBxJnJAgh+f5YhusYECEcjo4XcyH87hn6+ks0A==} engines: {node: '>= 0.4'} is-typed-array@1.1.13: resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} engines: {node: '>= 0.4'} + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} - is-wsl@2.2.0: - resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} - engines: {node: '>=8'} + is-weakset@2.0.3: + resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} + engines: {node: '>= 0.4'} isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} @@ -2992,28 +2879,32 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isexe@3.1.1: + resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} + engines: {node: '>=16'} + isobject@3.0.1: resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} engines: {node: '>=0.10.0'} - jest-diff@29.6.3: - resolution: {integrity: sha512-3sw+AdWnwH9sSNohMRKA7JiYUJSRr/WS6+sEFfBuhxU5V5GlEVKfvUn8JuMHE0wqKowemR1C2aHy8VtXbaV8dQ==} + jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} jest-get-type@29.6.3: resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - jest-matcher-utils@29.6.3: - resolution: {integrity: sha512-6ZrMYINZdwduSt5Xu18/n49O1IgXdjsfG7NEZaQws9k69eTKWKcVbJBw/MZsjOZe2sSyJFmuzh8042XWwl54Zg==} + jest-matcher-utils@29.7.0: + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - jest-message-util@29.6.3: - resolution: {integrity: sha512-FtzaEEHzjDpQp51HX4UMkPZjy46ati4T5pEMyM6Ik48ztu4T9LQplZ6OsimHx7EuM9dfEh5HJa6D3trEftu3dA==} + jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - jest-util@29.6.3: - resolution: {integrity: sha512-QUjna/xSy4B32fzcKTSz1w7YYzgiHrjjJjevdRf61HYk998R5vVMMNmrHESYZVDS5DSWs+1srPLPKxXPkeSDOA==} + jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} js-base64@3.7.7: @@ -3026,11 +2917,18 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true - jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} + jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} hasBin: true + json-bignum@0.0.3: + resolution: {integrity: sha512-2WHyXj3OfHSgNyuzDbSxI1w2jgw5gkWSWhS7Qg4bWXx1nLk3jnbwfUeS0PSba3IzpTUWdHxBieELUzXRjQB2zg==} + engines: {node: '>=0.8'} + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} @@ -3063,6 +2961,9 @@ packages: kdbush@4.0.2: resolution: {integrity: sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==} + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + kind-of@6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} @@ -3074,62 +2975,68 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - lightningcss-darwin-arm64@1.22.0: - resolution: {integrity: sha512-aH2be3nNny+It5YEVm8tBSSdRlBVWQV8m2oJ7dESiYRzyY/E/bQUe2xlw5caaMuhlM9aoTMtOH25yzMhir0qPg==} + lightningcss-darwin-arm64@1.28.2: + resolution: {integrity: sha512-/8cPSqZiusHSS+WQz0W4NuaqFjquys1x+NsdN/XOHb+idGHJSoJ7SoQTVl3DZuAgtPZwFZgRfb/vd1oi8uX6+g==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [darwin] - lightningcss-darwin-x64@1.22.0: - resolution: {integrity: sha512-9KHRFA0Y6mNxRHeoQMp0YaI0R0O2kOgUlYPRjuasU4d+pI8NRhVn9bt0yX9VPs5ibWX1RbDViSPtGJvYYrfVAQ==} + lightningcss-darwin-x64@1.28.2: + resolution: {integrity: sha512-R7sFrXlgKjvoEG8umpVt/yutjxOL0z8KWf0bfPT3cYMOW4470xu5qSHpFdIOpRWwl3FKNMUdbKtMUjYt0h2j4g==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [darwin] - lightningcss-freebsd-x64@1.22.0: - resolution: {integrity: sha512-xaYL3xperGwD85rQioDb52ozF3NAJb+9wrge3jD9lxGffplu0Mn35rXMptB8Uc2N9Mw1i3Bvl7+z1evlqVl7ww==} + lightningcss-freebsd-x64@1.28.2: + resolution: {integrity: sha512-l2qrCT+x7crAY+lMIxtgvV10R8VurzHAoUZJaVFSlHrN8kRLTvEg9ObojIDIexqWJQvJcVVV3vfzsEynpiuvgA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [freebsd] - lightningcss-linux-arm-gnueabihf@1.22.0: - resolution: {integrity: sha512-epQGvXIjOuxrZpMpMnRjK54ZqzhiHhCPLtHvw2fb6NeK2kK9YtF0wqmeTBiQ1AkbWfnnXGTstYaFNiadNK+StQ==} + lightningcss-linux-arm-gnueabihf@1.28.2: + resolution: {integrity: sha512-DKMzpICBEKnL53X14rF7hFDu8KKALUJtcKdFUCW5YOlGSiwRSgVoRjM97wUm/E0NMPkzrTi/rxfvt7ruNK8meg==} engines: {node: '>= 12.0.0'} cpu: [arm] os: [linux] - lightningcss-linux-arm64-gnu@1.22.0: - resolution: {integrity: sha512-AArGtKSY4DGTA8xP8SDyNyKtpsUl1Rzq6FW4JomeyUQ4nBrR71uPChksTpj3gmWuGhZeRKLeCUI1DBid/zhChg==} + lightningcss-linux-arm64-gnu@1.28.2: + resolution: {integrity: sha512-nhfjYkfymWZSxdtTNMWyhFk2ImUm0X7NAgJWFwnsYPOfmtWQEapzG/DXZTfEfMjSzERNUNJoQjPAbdqgB+sjiw==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - lightningcss-linux-arm64-musl@1.22.0: - resolution: {integrity: sha512-RRraNgP8hnBPhInTTUdlFm+z16C/ghbxBG51Sw00hd7HUyKmEUKRozyc5od+/N6pOrX/bIh5vIbtMXIxsos0lg==} + lightningcss-linux-arm64-musl@1.28.2: + resolution: {integrity: sha512-1SPG1ZTNnphWvAv8RVOymlZ8BDtAg69Hbo7n4QxARvkFVCJAt0cgjAw1Fox0WEhf4PwnyoOBaVH0Z5YNgzt4dA==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - lightningcss-linux-x64-gnu@1.22.0: - resolution: {integrity: sha512-grdrhYGRi2KrR+bsXJVI0myRADqyA7ekprGxiuK5QRNkv7kj3Yq1fERDNyzZvjisHwKUi29sYMClscbtl+/Zpw==} + lightningcss-linux-x64-gnu@1.28.2: + resolution: {integrity: sha512-ZhQy0FcO//INWUdo/iEdbefntTdpPVQ0XJwwtdbBuMQe+uxqZoytm9M+iqR9O5noWFaxK+nbS2iR/I80Q2Ofpg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - lightningcss-linux-x64-musl@1.22.0: - resolution: {integrity: sha512-t5f90X+iQUtIyR56oXIHMBUyQFX/zwmPt72E6Dane3P8KNGlkijTg2I75XVQS860gNoEFzV7Mm5ArRRA7u5CAQ==} + lightningcss-linux-x64-musl@1.28.2: + resolution: {integrity: sha512-alb/j1NMrgQmSFyzTbN1/pvMPM+gdDw7YBuQ5VSgcFDypN3Ah0BzC2dTZbzwzaMdUVDszX6zH5MzjfVN1oGuww==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - lightningcss-win32-x64-msvc@1.22.0: - resolution: {integrity: sha512-64HTDtOOZE9PUCZJiZZQpyqXBbdby1lnztBccnqh+NtbKxjnGzP92R2ngcgeuqMPecMNqNWxgoWgTGpC+yN5Sw==} + lightningcss-win32-arm64-msvc@1.28.2: + resolution: {integrity: sha512-WnwcjcBeAt0jGdjlgbT9ANf30pF0C/QMb1XnLnH272DQU8QXh+kmpi24R55wmWBwaTtNAETZ+m35ohyeMiNt+g==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.28.2: + resolution: {integrity: sha512-3piBifyT3avz22o6mDKywQC/OisH2yDK+caHWkiMsF82i3m5wDBadyCjlCQ5VNgzYkxrWZgiaxHDdd5uxsi0/A==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [win32] - lightningcss@1.22.0: - resolution: {integrity: sha512-+z0qvwRVzs4XGRXelnWRNwqsXUx8k3bSkbP8vD42kYKSk3z9OM2P3e/gagT7ei/gwh8DTS80LZOFZV6lm8Z8Fg==} + lightningcss@1.28.2: + resolution: {integrity: sha512-ePLRrbt3fgjXI5VFZOLbvkLD5ZRuxGKm+wJ3ujCqBtL3NanDHPo/5zicR5uEKAPiIjBYF99BM4K4okvMznjkVA==} engines: {node: '>= 12.0.0'} lines-and-columns@1.2.4: @@ -3160,6 +3067,9 @@ packages: lodash._stringtopath@4.8.0: resolution: {integrity: sha512-SXL66C731p0xPDC5LZg4wI5H+dJo/EO4KTqOMwLYCH3+FmmfAKJEZCm6ohGpI+T1xwsDsJCfL4OnhorllvlTPQ==} + lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + lodash.debounce@4.0.8: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} @@ -3169,9 +3079,6 @@ packages: lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - lodash.pick@4.4.0: - resolution: {integrity: sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==} - lodash.throttle@4.1.1: resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==} @@ -3188,22 +3095,18 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true - mapbox-gl@3.6.0: - resolution: {integrity: sha512-xjYHHIJDh6haYcKY+/9jh1eywwYfIOWCgT5Fowj4JriZexx/oOtg2S7BQDMZtpFyg9IN4VLCysmUWxY0pFNRWA==} + mapbox-gl@3.8.0: + resolution: {integrity: sha512-7iQ6wxAf8UedbNYTzNsyr2J25ozIBA4vmKY0xUDXQlHEokulzPENwjjmLxHQGRylDpOmR0c8kPEbtHCaQE2eMw==} - mapbox-to-css-font@2.4.2: - resolution: {integrity: sha512-f+NBjJJY4T3dHtlEz1wCG7YFlkODEjFIYlxDdLIDMNpkSksqTt+l/d4rjuwItxuzkuMFvPyrjzV2lxRM4ePcIA==} + mapbox-to-css-font@2.4.5: + resolution: {integrity: sha512-VJ6nB8emkO9VODI0Fk+TQ/0zKBTqmf/Pkt8Xv0kHstoc0iXRajA00DAid4Kc3K5xeFIOoiZrVxijEzj0GLVO2w==} - maplibre-gl@4.5.2: - resolution: {integrity: sha512-vlWL9EY2bSGg5FAt0mKPfYqlfX15uLW5D3kKv4Xjn54nIVn01MKdfUJMAVIr+8fXVqfSX6c095Iy5XnV+T76kQ==} + maplibre-gl@4.7.1: + resolution: {integrity: sha512-lgL7XpIwsgICiL82ITplfS7IGwrB1OJIw/pCvprDp2dhmSSEBgmPzYRvwYYYvJGJD7fxUv1Tvpih4nZ6VrLuaA==} engines: {node: '>=16.14.0', npm: '>=8.1.0'} md5@2.3.0: @@ -3213,29 +3116,22 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - moment@2.29.4: - resolution: {integrity: sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==} - - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + moment@2.30.1: + resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -3243,8 +3139,8 @@ packages: murmurhash-js@1.0.0: resolution: {integrity: sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==} - nanoid@3.3.6: - resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} + nanoid@3.3.8: + resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -3255,8 +3151,8 @@ packages: resolution: {integrity: sha512-kltF0cOxgx1AbmVzKxYZaoB0aj7mOxZeHaerEtQV0YaqnkXNq26WWqMmJ6lTqShYxVRWZ/mwvvTrNeOwdslWiw==} engines: {node: '>=v0.2.0'} - node-releases@2.0.13: - resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} + node-releases@2.0.18: + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} @@ -3277,8 +3173,8 @@ packages: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} - object-inspect@1.13.2: - resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + object-inspect@1.13.3: + resolution: {integrity: sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==} engines: {node: '>= 0.4'} object-keys@1.1.1: @@ -3289,8 +3185,8 @@ packages: resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} engines: {node: '>= 0.4'} - oidc-client-ts@2.2.4: - resolution: {integrity: sha512-nOZwIomju+AmXObl5Oq5PjrES/qTt8bLsENJCIydVgi9TEWk7SCkOU6X3RNkY7yfySRM1OJJvDKdREZdmnDT2g==} + oidc-client-ts@2.4.1: + resolution: {integrity: sha512-IxlGMsbkZPsHJGCliWT3LxjUcYzmiN21656n/Zt2jDncZlBFc//cd8WqFF0Lt681UT3AImM57E6d4N53ziTCYA==} engines: {node: '>=12.13.0'} ol-mapbox-style@10.7.0: @@ -3299,15 +3195,8 @@ packages: ol@7.5.2: resolution: {integrity: sha512-HJbb3CxXrksM6ct367LsP3N+uh+iBBMdP3DeGGipdV9YAYTP0vTJzqGnoqQ6C2IW4qf8krw9yuyQbc9fjOIaOQ==} - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - - open@8.4.2: - resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} - engines: {node: '>=12'} - - optionator@0.9.3: - resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} p-limit@3.1.0: @@ -3336,10 +3225,6 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} - path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -3359,21 +3244,21 @@ packages: resolution: {integrity: sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q==} hasBin: true - picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - playwright-core@1.42.1: - resolution: {integrity: sha512-mxz6zclokgrke9p1vtdy/COWBH+eOZgYUVVU34C73M+4j4HLlQJHtfcqiqqxpP0o8HhMkflvfbquLX5dg6wlfA==} - engines: {node: '>=16'} + playwright-core@1.49.0: + resolution: {integrity: sha512-R+3KKTQF3npy5GTiKH/T+kdhoJfJojjHESR1YEWhYuEKRVfVaxH3+4+GvXE5xyCngCxhxnykk0Vlah9v8fs3jA==} + engines: {node: '>=18'} hasBin: true - playwright@1.42.1: - resolution: {integrity: sha512-PgwB03s2DZBcNRoW+1w9E+VkLBxweib6KTXM0M3tkiT4jVxKSi6PmVJ591J+0u10LUrgxB7dLRbiJqO5s2QPMg==} - engines: {node: '>=16'} + playwright@1.49.0: + resolution: {integrity: sha512-eKpmys0UFDnfNb3vfsf8Vx2LEOtflgRebl0Im2eQQnYMA4Aqd+Zw8bEOB+7ZKvN76901mRnqdsiOGKxzVTbi7A==} + engines: {node: '>=18'} hasBin: true possible-typed-array-names@1.0.0: @@ -3383,8 +3268,8 @@ packages: postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.4.28: - resolution: {integrity: sha512-Z7V5j0cq8oEKyejIKfpD8b4eBy9cwW2JWPk0+fB1HOAMsfHbnAXLLS+PfVWlzMSLQaWttKDt607I0XHmpE67Vw==} + postcss@8.4.49: + resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} engines: {node: ^10 || ^12 || >=14} potpack@2.0.0: @@ -3394,13 +3279,13 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier@3.1.0: - resolution: {integrity: sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==} + prettier@3.4.2: + resolution: {integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==} engines: {node: '>=14'} hasBin: true - pretty-format@29.6.3: - resolution: {integrity: sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw==} + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} prop-types@15.8.1: @@ -3412,11 +3297,8 @@ packages: protocol-buffers-schema@3.6.0: resolution: {integrity: sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==} - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - - punycode@2.3.0: - resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} querystringify@2.2.0: @@ -3438,19 +3320,19 @@ packages: rbush@3.0.1: resolution: {integrity: sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w==} - react-dom@18.2.0: - resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} peerDependencies: - react: ^18.2.0 + react: ^18.3.1 - react-dropzone@14.2.3: - resolution: {integrity: sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==} + react-dropzone@14.3.5: + resolution: {integrity: sha512-9nDUaEEpqZLOz5v5SUcFA0CjM4vq8YbqO0WRls+EYT7+DvxUdzDPKNCPLqGfj3YL9MsniCLCD4RFA6M95V6KMQ==} engines: {node: '>= 10.13'} peerDependencies: react: '>= 16.8 || 18.0.0' - react-i18next@13.0.3: - resolution: {integrity: sha512-/t4kt4Y2o+21hbvx+o9zpVnmoiud7KLDncyZFGN0U6TGAWYaXdTsp/ytAHFcKKSAODg4noIMaOO3X7bMgCqLHw==} + react-i18next@13.5.0: + resolution: {integrity: sha512-CFJ5NDGJ2MUyBohEHxljOq/39NQ972rh1ajnadG9BjTk+UXbHLq4z5DKEbEQBDoIhUmmbuS/fIMJKo6VOax1HA==} peerDependencies: i18next: '>= 23.2.3' react: '>= 16.8.0' @@ -3465,9 +3347,6 @@ packages: react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - react-is@18.2.0: - resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} - react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} @@ -3484,18 +3363,18 @@ packages: maplibre-gl: optional: true - react-oidc-context@2.2.2: - resolution: {integrity: sha512-rke8goKuxxQhSAR11h8wVn56m7kEa1mcAfYDlIycsIgmbZOFzKA0Un0y0RodHZ/M/CG6u0JD1I8RKZHqRJjWnA==} + react-oidc-context@2.4.0: + resolution: {integrity: sha512-7xbEXlBBlWBQfdSibjeA7jC5w1oKTvZVAodd9A+fmqDRt4bD+gGODWgGT8dX+a0S96Vfo7lzIrEBP7eZCFkwWw==} engines: {node: '>=12.13.0'} peerDependencies: - oidc-client-ts: ^2.2.1 + oidc-client-ts: ^2.4.1 react: '>=16.8.0' - react-property@2.0.0: - resolution: {integrity: sha512-kzmNjIgU32mO4mmH5+iUyrqlpFQhF8K2k7eZ4fdLSOPFrD1XgEuSBv9LDEgxRXTMBqMd8ppT0x6TIzqE5pdGdw==} + react-property@2.0.2: + resolution: {integrity: sha512-+PbtI3VuDV0l6CleQMsx2gtK0JZbZKbpdu5ynr+lbsuvtmgbNcS3VM0tuY2QjFNOcWxvXeHjDpy42RO+4U2rug==} - react-redux@8.1.2: - resolution: {integrity: sha512-xJKYI189VwfsFc4CJvHqHlDrzyFTY/3vZACbE+rr/zQ34Xx1wQfB4OTOSeOSNrF6BDVe8OOdxIrAnMGXA3ggfw==} + react-redux@8.1.3: + resolution: {integrity: sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==} peerDependencies: '@types/react': ^16.8 || ^17.0 || ^18.0 '@types/react-dom': ^16.8 || ^17.0 || ^18.0 @@ -3515,20 +3394,20 @@ packages: redux: optional: true - react-refresh@0.14.0: - resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} + react-refresh@0.14.2: + resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} - react-router-dom@6.14.2: - resolution: {integrity: sha512-5pWX0jdKR48XFZBuJqHosX3AAHjRAzygouMTyimnBPOLdY3WjzUSKhus2FVMihUFWzeLebDgr4r8UeQFAct7Bg==} - engines: {node: '>=14'} + react-router-dom@6.28.0: + resolution: {integrity: sha512-kQ7Unsl5YdyOltsPGl31zOjLrDv+m2VcIEcIHqYYD3Lp0UppLjrzcfJqDJwXxFw3TH/yvapbnUvPlAj7Kx5nbg==} + engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' react-dom: '>=16.8' - react-router@6.14.2: - resolution: {integrity: sha512-09Zss2dE2z+T1D03IheqAFtK4UzQyX8nFPWx6jkwdYzGLXd5ie06A6ezS2fO6zJfEb/SpG6UocN2O1hfD+2urQ==} - engines: {node: '>=14'} + react-router@6.28.0: + resolution: {integrity: sha512-HrYdIFqdrnhDw0PqG/AKjAqEqM7AvxCz0DQ4h2W8k6nqmc5uRBYDag0SBxx9iYz5G8gnuNVLzUe13wl9eAsXXg==} + engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' @@ -3538,8 +3417,8 @@ packages: react: '>=16.6.0' react-dom: '>=16.6.0' - react@18.2.0: - resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} readdirp@3.6.0: @@ -3554,20 +3433,17 @@ packages: redux@4.2.1: resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==} - regenerator-runtime@0.14.0: - resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} + reflect.getprototypeof@1.0.7: + resolution: {integrity: sha512-bMvFGIUKlc/eSfXNX+aZ+EL95/EgZzuwA0OBPTbZZDEJw/0AkentjMuM1oiRfwHrshqk4RzdgiTg5CcDalXN5g==} + engines: {node: '>= 0.4'} regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - regexp.prototype.flags@1.5.2: - resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + regexp.prototype.flags@1.5.3: + resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==} engines: {node: '>= 0.4'} - require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} @@ -3581,8 +3457,8 @@ packages: resolve-protobuf-schema@2.1.0: resolution: {integrity: sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==} - resolve@1.22.4: - resolution: {integrity: sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==} + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true retry@0.12.0: @@ -3593,22 +3469,8 @@ packages: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - hasBin: true - - rollup-plugin-visualizer@5.12.0: - resolution: {integrity: sha512-8/NU9jXcHRs7Nnj07PF2o4gjxmm9lXIrZ8r175bT9dK8qoLlvKTwRMArRCMgpMGlq8CTLugRvEmyMeMXIU2pNQ==} - engines: {node: '>=14'} - hasBin: true - peerDependencies: - rollup: 2.x || 3.x || 4.x - peerDependenciesMeta: - rollup: - optional: true - - rollup@3.28.1: - resolution: {integrity: sha512-R9OMQmIHJm9znrU3m3cpE8uhN0fGdXiawME7aZIpQqvpS/85+Vt1Hq1/yVIcYfOmaQiHjvXkQAoJukvLpau6Yw==} + rollup@3.29.5: + resolution: {integrity: sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true @@ -3629,8 +3491,8 @@ packages: resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} engines: {node: '>= 0.4'} - scheduler@0.23.0: - resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} secure-json-parse@2.7.0: resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} @@ -3639,8 +3501,8 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.5.4: - resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} engines: {node: '>=10'} hasBin: true @@ -3706,18 +3568,14 @@ packages: resolution: {integrity: sha512-nK7WOY8jik6zaG9CRwZTaD5O7ETWDLZYMM12pqY8htll+7dYeqGfEUPcUBHOpSJg2vJOrvFIY2Dl5cX2ih1hAQ==} engines: {node: '>=0.10.0'} - source-map-js@1.0.2: - resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} source-map@0.5.7: resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} engines: {node: '>=0.10.0'} - source-map@0.7.4: - resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} - engines: {node: '>= 8'} - split-string@3.1.0: resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} engines: {node: '>=0.10.0'} @@ -3730,10 +3588,6 @@ packages: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - string.prototype.trim@1.2.9: resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} engines: {node: '>= 0.4'} @@ -3756,14 +3610,14 @@ packages: strnum@1.0.5: resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} - style-to-js@1.1.4: - resolution: {integrity: sha512-zEeU3vy9xL/hdLBFmzqjhm+2vJ1Y35V0ctDeB2sddsvN1856OdMZUCOOfKUn3nOjjEKr6uLhOnY4CrX6gLDRrA==} + style-to-js@1.1.8: + resolution: {integrity: sha512-bPSspCXkkhETLXnEgDbaoWRWyv3lF2bj32YIc8IElok2IIMHUlZtQUrxYmAkKUNxpluhH0qnKWrmuoXUyTY12g==} - style-to-object@0.4.2: - resolution: {integrity: sha512-1JGpfPB3lo42ZX8cuPrheZbfQ6kqPPnPHlKMyeRYtfKD+0jG+QsXgXN57O/dvJlzlB2elI6dGmrPnl5VPQFPaA==} + style-to-object@1.0.3: + resolution: {integrity: sha512-xOpx7S53E0V3DpVsvt7ySvoiumRpfXiC99PUXLqGB3wiAnN9ybEIpuzlZ8LAZg+h1sl9JkEUwtSQXxcCgFqbbg==} - styled-components@5.3.10: - resolution: {integrity: sha512-3kSzSBN0TiCnGJM04UwO1HklIQQSXW7rCARUk+VyMR7clz8XVlA3jijtf5ypqoDIdNMKx3la4VvaPFR855SFcg==} + styled-components@5.3.11: + resolution: {integrity: sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==} engines: {node: '>=10'} peerDependencies: react: '>= 16.8.0' @@ -3788,88 +3642,78 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - text-table@0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + table-layout@4.1.1: + resolution: {integrity: sha512-iK5/YhZxq5GO5z8wb0bY1317uDF3Zjpha0QFFLA8/trAoiLbQD0HUbMesEaxyzUgDxi2QlcbM8IvqOlEjgoXBA==} + engines: {node: '>=12.17'} - tiny-invariant@1.3.1: - resolution: {integrity: sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==} + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} tinyqueue@3.0.0: resolution: {integrity: sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==} - to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - traverse@0.6.9: - resolution: {integrity: sha512-7bBrcF+/LQzSgFmT0X5YclVqQxtv7TDJ1f8Wj7ibBu/U6BMLeOpUxuZjV7rMc44UtKxlnMFigdhFAIszSX1DMg==} + traverse@0.6.10: + resolution: {integrity: sha512-hN4uFRxbK+PX56DxYiGHsTn2dME3TVr9vbNqlQGcGcPhJAn+tdP126iA+TArMpI4YSgnTkMWyoLl5bf81Hi5TA==} engines: {node: '>= 0.4'} - ts-api-utils@1.0.2: - resolution: {integrity: sha512-Cbu4nIqnEdd+THNEsBdkolnOXhg0I8XteoHaEKgvsxpsbWda4IsUut2c187HxywQCvveojow0Dgw/amxtSKVkQ==} - engines: {node: '>=16.13.0'} + ts-api-utils@1.4.3: + resolution: {integrity: sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==} + engines: {node: '>=16'} peerDependencies: typescript: '>=4.2.0' tslib@2.3.0: resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==} - tslib@2.6.2: - resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - turbo-darwin-64@1.10.16: - resolution: {integrity: sha512-+Jk91FNcp9e9NCLYlvDDlp2HwEDp14F9N42IoW3dmHI5ZkGSXzalbhVcrx3DOox3QfiNUHxzWg4d7CnVNCuuMg==} + turbo-darwin-64@1.13.4: + resolution: {integrity: sha512-A0eKd73R7CGnRinTiS7txkMElg+R5rKFp9HV7baDiEL4xTG1FIg/56Vm7A5RVgg8UNgG2qNnrfatJtb+dRmNdw==} cpu: [x64] os: [darwin] - turbo-darwin-arm64@1.10.16: - resolution: {integrity: sha512-jqGpFZipIivkRp/i+jnL8npX0VssE6IAVNKtu573LXtssZdV/S+fRGYA16tI46xJGxSAivrZ/IcgZrV6Jk80bw==} + turbo-darwin-arm64@1.13.4: + resolution: {integrity: sha512-eG769Q0NF6/Vyjsr3mKCnkG/eW6dKMBZk6dxWOdrHfrg6QgfkBUk0WUUujzdtVPiUIvsh4l46vQrNVd9EOtbyA==} cpu: [arm64] os: [darwin] - turbo-linux-64@1.10.16: - resolution: {integrity: sha512-PpqEZHwLoizQ6sTUvmImcRmACyRk9EWLXGlqceogPZsJ1jTRK3sfcF9fC2W56zkSIzuLEP07k5kl+ZxJd8JMcg==} + turbo-linux-64@1.13.4: + resolution: {integrity: sha512-Bq0JphDeNw3XEi+Xb/e4xoKhs1DHN7OoLVUbTIQz+gazYjigVZvtwCvgrZI7eW9Xo1eOXM2zw2u1DGLLUfmGkQ==} cpu: [x64] os: [linux] - turbo-linux-arm64@1.10.16: - resolution: {integrity: sha512-TMjFYz8to1QE0fKVXCIvG/4giyfnmqcQIwjdNfJvKjBxn22PpbjeuFuQ5kNXshUTRaTJihFbuuCcb5OYFNx4uw==} + turbo-linux-arm64@1.13.4: + resolution: {integrity: sha512-BJcXw1DDiHO/okYbaNdcWN6szjXyHWx9d460v6fCHY65G8CyqGU3y2uUTPK89o8lq/b2C8NK0yZD+Vp0f9VoIg==} cpu: [arm64] os: [linux] - turbo-windows-64@1.10.16: - resolution: {integrity: sha512-+jsf68krs0N66FfC4/zZvioUap/Tq3sPFumnMV+EBo8jFdqs4yehd6+MxIwYTjSQLIcpH8KoNMB0gQYhJRLZzw==} + turbo-windows-64@1.13.4: + resolution: {integrity: sha512-OFFhXHOFLN7A78vD/dlVuuSSVEB3s9ZBj18Tm1hk3aW1HTWTuAw0ReN6ZNlVObZUHvGy8d57OAGGxf2bT3etQw==} cpu: [x64] os: [win32] - turbo-windows-arm64@1.10.16: - resolution: {integrity: sha512-sKm3hcMM1bl0B3PLG4ifidicOGfoJmOEacM5JtgBkYM48ncMHjkHfFY7HrJHZHUnXM4l05RQTpLFoOl/uIo2HQ==} + turbo-windows-arm64@1.13.4: + resolution: {integrity: sha512-u5A+VOKHswJJmJ8o8rcilBfU5U3Y1TTAfP9wX8bFh8teYF1ghP0EhtMRLjhtp6RPa+XCxHHVA2CiC3gbh5eg5g==} cpu: [arm64] os: [win32] - turbo@1.10.16: - resolution: {integrity: sha512-2CEaK4FIuSZiP83iFa9GqMTQhroW2QryckVqUydmg4tx78baftTOS0O+oDAhvo9r9Nit4xUEtC1RAHoqs6ZEtg==} + turbo@1.13.4: + resolution: {integrity: sha512-1q7+9UJABuBAHrcC4Sxp5lOqYS5mvxRrwa33wpIyM18hlOCpRD/fTJNxZ0vhbMcJmz15o9kkVm743mPn7p6jpQ==} hasBin: true - tus-js-client@4.1.0: - resolution: {integrity: sha512-e/nC/kJahvNYBcnwcqzuhFIvVELMMpbVXIoOOKdUn74SdQCvJd2JjqV2jZLv2EFOVbV4qLiO0lV7BxBXF21b6Q==} + tus-js-client@4.2.3: + resolution: {integrity: sha512-UkQUCeDWKh5AwArcasIJWcL5EP66XPypKQtsdPu82wNnTea8eAUHdpDx3DcfZgDERAiCII895zMYkXri4M1wzw==} engines: {node: '>=18'} - tweakpane@4.0.4: - resolution: {integrity: sha512-RkWD54zDlEbnN01wQPk0ANHGbdCvlJx/E8A1QxhTfCbX+ROWos1Ws2MnhOm39aUGMOh+36TjUwpDmLfmwTr1Fg==} - type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - type-fest@0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - type-fest@0.21.3: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} @@ -3882,20 +3726,20 @@ packages: resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} engines: {node: '>= 0.4'} - typed-array-byte-offset@1.0.2: - resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + typed-array-byte-offset@1.0.3: + resolution: {integrity: sha512-GsvTyUHTriq6o/bHcTd0vM7OQ9JEdlvluu9YISaA7+KzDzPaIzEeDFNkTfhdE3MYcNhNi0vq/LlegYgIs5yPAw==} engines: {node: '>= 0.4'} - typed-array-length@1.0.6: - resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} typedarray.prototype.slice@1.0.3: resolution: {integrity: sha512-8WbVAQAUlENo1q3c3zZYuy5k9VzBQvp8AX9WOtbvyWlLM1v5JaSRmjubLjzHF4JFtptjH/5c/i95yaElvcjC0A==} engines: {node: '>= 0.4'} - typescript@5.1.6: - resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==} + typescript@5.7.2: + resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==} engines: {node: '>=14.17'} hasBin: true @@ -3905,26 +3749,34 @@ packages: typewise@1.0.3: resolution: {integrity: sha512-aXofE06xGhaQSPzt8hlTY+/YWQhm9P0jYUp1f2XtmW/3Bk0qzXcyFWAtPoo2uTGQj1ZwbDuSyuxicq+aDo8lCQ==} + typical@4.0.0: + resolution: {integrity: sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==} + engines: {node: '>=8'} + + typical@7.3.0: + resolution: {integrity: sha512-ya4mg/30vm+DOWfBg4YK3j2WD6TWtRkCbasOJr40CseYENzCUby/7rIvXA99JGsQHeNxLbnXdyLLxKSv3tauFw==} + engines: {node: '>=12.17'} + unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} - undici@5.25.4: - resolution: {integrity: sha512-450yJxT29qKMf3aoudzFpIciqpx6Pji3hEWaXqXmanbXF58LTAGCKxcJjxMXWu3iG+Mudgo3ZUfDB6YDFd/dAw==} - engines: {node: '>=14.0'} + undici@6.21.0: + resolution: {integrity: sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw==} + engines: {node: '>=18.17'} union-value@1.0.1: resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} engines: {node: '>=0.10.0'} - universalify@2.0.0: - resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} - update-browserslist-db@1.0.11: - resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + update-browserslist-db@1.1.1: + resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -3941,17 +3793,17 @@ packages: peerDependencies: react: '>=16.8.0' - use-sync-external-store@1.2.0: - resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + use-sync-external-store@1.2.2: + resolution: {integrity: sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 - uuid@9.0.0: - resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true - vite-plugin-checker@0.6.2: - resolution: {integrity: sha512-YvvvQ+IjY09BX7Ab+1pjxkELQsBd4rPhWNw8WLBeFVxu/E7O+n6VYAqNsKdK/a2luFlX/sMpoWdGFfg4HvwdJQ==} + vite-plugin-checker@0.6.4: + resolution: {integrity: sha512-2zKHH5oxr+ye43nReRbC2fny1nyARwhxdm0uNYp/ERy4YvU9iZpNOsueoi/luXw5gnpqRSvjcEPxXbS153O2wA==} engines: {node: '>=14.16'} peerDependencies: eslint: '>=7' @@ -3981,8 +3833,8 @@ packages: vue-tsc: optional: true - vite@4.4.5: - resolution: {integrity: sha512-4m5kEtAWHYr0O1Fu7rZp64CfO1PsRGZlD3TAB32UmQlpd7qg15VF7ROqGN5CyqN7HFuwr7ICNM2+fDWRqFEKaA==} + vite@4.5.5: + resolution: {integrity: sha512-ifW3Lb2sMdX+WU91s3R0FyQlAyLxOzCSCP37ujw0+r5POeHPwe6udWVIElKQq8gk3t7b8rkmvqC6IHBpCff4GQ==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true peerDependencies: @@ -4024,8 +3876,8 @@ packages: vscode-languageserver-protocol@3.16.0: resolution: {integrity: sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==} - vscode-languageserver-textdocument@1.0.8: - resolution: {integrity: sha512-1bonkGqQs5/fxGT5UchTgjGVnfysL0O8v1AYMBjqTbWQTFn721zaPGDYFkOKtfDgFiSgXM3KwaG3FMGfW4Ed9Q==} + vscode-languageserver-textdocument@1.0.12: + resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==} vscode-languageserver-types@3.16.0: resolution: {integrity: sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==} @@ -4034,384 +3886,334 @@ packages: resolution: {integrity: sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==} hasBin: true - vscode-uri@3.0.7: - resolution: {integrity: sha512-eOpPHogvorZRobNqJGhapa0JdwaxpjVvyBp0QIUMRMSf8ZAlqOdEquKuRmw9Qwu0qXtJIWqFtMkmvJjUZmMjVA==} + vscode-uri@3.0.8: + resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} vt-pbf@3.1.3: resolution: {integrity: sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA==} - web-vitals@3.4.0: - resolution: {integrity: sha512-n9fZ5/bG1oeDkyxLWyep0eahrNcPDF6bFqoyispt7xkW0xhDzpUBTgyDKqWDi1twT0MgH4HvvqzpUyh0ZxZV4A==} + web-vitals@3.5.2: + resolution: {integrity: sha512-c0rhqNcHXRkY/ogGDJQxZ9Im9D19hDihbzSQJrsioex+KnFgmMzBiy57Z1EjkhX/+OjyBpclDCzz2ITtjokFmg==} - web-worker@1.2.0: - resolution: {integrity: sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==} + web-worker@1.3.0: + resolution: {integrity: sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==} wgs84@0.0.0: resolution: {integrity: sha512-ANHlY4Rb5kHw40D0NJ6moaVfOCMrp9Gpd1R/AIQYg2ko4/jzcJ+TVXYYF6kXJqQwITvEZP4yEthjM7U6rYlljQ==} - which-boxed-primitive@1.0.2: - resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + which-boxed-primitive@1.1.0: + resolution: {integrity: sha512-Ei7Miu/AXe2JJ4iNF5j/UphAgRoma4trE6PtisM09bPygb3egMH3YLW/befsWb1A1AxvNSFidOFTB18XtnIIng==} + engines: {node: '>= 0.4'} - which-typed-array@1.1.15: - resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + which-builtin-type@1.2.0: + resolution: {integrity: sha512-I+qLGQ/vucCby4tf5HsLmGueEla4ZhwTBSqaooS+Y0BuxN4Cp+okmGuV+8mXZ84KDI9BA+oklo+RzKg0ONdSUA==} engines: {node: '>= 0.4'} - which@1.3.1: - resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} - hasBin: true + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.16: + resolution: {integrity: sha512-g+N+GAWiRj66DngFwHvISJd+ITsyphZvD1vChfVg6cEdnzy53GzB3oy0fUNlvhz7H7+MiqhYr26qxQShCpKTTQ==} + engines: {node: '>= 0.4'} which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true + which@4.0.0: + resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==} + engines: {node: ^16.13.0 || >=18.0.0} + hasBin: true + wmf@1.0.2: resolution: {integrity: sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==} engines: {node: '>=0.8'} + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + word@0.3.0: resolution: {integrity: sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==} engines: {node: '>=0.8'} - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + wordwrapjs@5.1.0: + resolution: {integrity: sha512-JNjcULU2e4KJwUNv6CHgI46UvDGitb6dGryHajXTDiLgg1/RiGoPSDw4kZfYnwGtEXf2ZMeIewDQgFGzkCB2Sg==} + engines: {node: '>=12.17'} xlsx@0.18.5: resolution: {integrity: sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==} engines: {node: '>=0.8'} hasBin: true - xml-utils@1.7.0: - resolution: {integrity: sha512-bWB489+RQQclC7A9OW8e5BzbT8Tu//jtAOvkYwewFr+Q9T9KDGvfzC1lp0pYPEQPEoPQLDkmxkepSC/2gIAZGw==} + xml-utils@1.10.1: + resolution: {integrity: sha512-Dn6vJ1Z9v1tepSjvnCpwk5QqwIPcEFKdgnjqfYOABv1ngSofuAhtlugcUC3ehS1OHdgDWSG6C5mvj+Qm15udTQ==} xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - yaml@1.10.2: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} - yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - - yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} - yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - zrender@5.4.4: - resolution: {integrity: sha512-0VxCNJ7AGOMCWeHVyTrGzUgrK4asT4ml9PEkeGirAkKNYXYzoPJCLvmyfdoOXcjTHPs10OZVMfD1Rwg16AZyYw==} - -snapshots: + zrender@5.6.0: + resolution: {integrity: sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==} - '@aashutoshrathi/word-wrap@1.2.6': {} + zstddec@0.1.0: + resolution: {integrity: sha512-w2NTI8+3l3eeltKAdK8QpiLo/flRAr2p8AGeakfMZOXBxOg9HIu4LVDxBi81sYgVhFhdJjv1OrB5ssI8uFPoLg==} - '@ampproject/remapping@2.2.1': - dependencies: - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.9 +snapshots: - '@babel/code-frame@7.22.10': + '@ampproject/remapping@2.3.0': dependencies: - '@babel/highlight': 7.22.10 - chalk: 2.4.2 - - '@babel/compat-data@7.22.9': {} + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 - '@babel/core@7.22.10': + '@babel/code-frame@7.26.2': dependencies: - '@ampproject/remapping': 2.2.1 - '@babel/code-frame': 7.22.10 - '@babel/generator': 7.22.10 - '@babel/helper-compilation-targets': 7.22.10 - '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.10) - '@babel/helpers': 7.22.10 - '@babel/parser': 7.22.10 - '@babel/template': 7.22.5 - '@babel/traverse': 7.22.10(supports-color@5.5.0) - '@babel/types': 7.22.10 - convert-source-map: 1.9.0 - debug: 4.3.4(supports-color@5.5.0) + '@babel/helper-validator-identifier': 7.25.9 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.26.2': {} + + '@babel/core@7.26.0': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.2 + '@babel/helper-compilation-targets': 7.25.9 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) + '@babel/helpers': 7.26.0 + '@babel/parser': 7.26.2 + '@babel/template': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) + '@babel/types': 7.26.0 + convert-source-map: 2.0.0 + debug: 4.3.7(supports-color@5.5.0) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/generator@7.22.10': + '@babel/generator@7.26.2': dependencies: - '@babel/types': 7.22.10 - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.19 - jsesc: 2.5.2 + '@babel/parser': 7.26.2 + '@babel/types': 7.26.0 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.0.2 - '@babel/helper-annotate-as-pure@7.22.5': + '@babel/helper-annotate-as-pure@7.25.9': dependencies: - '@babel/types': 7.22.10 + '@babel/types': 7.26.0 - '@babel/helper-compilation-targets@7.22.10': + '@babel/helper-compilation-targets@7.25.9': dependencies: - '@babel/compat-data': 7.22.9 - '@babel/helper-validator-option': 7.22.5 - browserslist: 4.21.10 + '@babel/compat-data': 7.26.2 + '@babel/helper-validator-option': 7.25.9 + browserslist: 4.24.2 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-environment-visitor@7.22.5': {} - - '@babel/helper-function-name@7.22.5': - dependencies: - '@babel/template': 7.22.5 - '@babel/types': 7.22.10 - - '@babel/helper-hoist-variables@7.22.5': - dependencies: - '@babel/types': 7.22.10 - - '@babel/helper-module-imports@7.22.5': + '@babel/helper-module-imports@7.25.9(supports-color@5.5.0)': dependencies: - '@babel/types': 7.22.10 - - '@babel/helper-module-transforms@7.22.9(@babel/core@7.22.10)': - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-module-imports': 7.22.5 - '@babel/helper-simple-access': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/helper-validator-identifier': 7.22.5 - - '@babel/helper-plugin-utils@7.22.5': {} - - '@babel/helper-simple-access@7.22.5': - dependencies: - '@babel/types': 7.22.10 - - '@babel/helper-split-export-declaration@7.22.6': - dependencies: - '@babel/types': 7.22.10 - - '@babel/helper-string-parser@7.22.5': {} - - '@babel/helper-validator-identifier@7.22.5': {} - - '@babel/helper-validator-option@7.22.5': {} + '@babel/traverse': 7.25.9(supports-color@5.5.0) + '@babel/types': 7.26.0 + transitivePeerDependencies: + - supports-color - '@babel/helpers@7.22.10': + '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.0)': dependencies: - '@babel/template': 7.22.5 - '@babel/traverse': 7.22.10(supports-color@5.5.0) - '@babel/types': 7.22.10 + '@babel/core': 7.26.0 + '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) + '@babel/helper-validator-identifier': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) transitivePeerDependencies: - supports-color - '@babel/highlight@7.22.10': - dependencies: - '@babel/helper-validator-identifier': 7.22.5 - chalk: 2.4.2 - js-tokens: 4.0.0 + '@babel/helper-plugin-utils@7.25.9': {} - '@babel/parser@7.22.10': - dependencies: - '@babel/types': 7.22.10 + '@babel/helper-string-parser@7.25.9': {} - '@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.22.10)': + '@babel/helper-validator-identifier@7.25.9': {} + + '@babel/helper-validator-option@7.25.9': {} + + '@babel/helpers@7.26.0': dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/template': 7.25.9 + '@babel/types': 7.26.0 - '@babel/plugin-transform-react-jsx-self@7.22.5(@babel/core@7.22.10)': + '@babel/parser@7.26.2': dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/types': 7.26.0 - '@babel/plugin-transform-react-jsx-source@7.22.5(@babel/core@7.22.10)': + '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/runtime@7.22.10': + '@babel/plugin-transform-react-jsx-self@7.25.9(@babel/core@7.26.0)': dependencies: - regenerator-runtime: 0.14.1 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/runtime@7.23.2': + '@babel/plugin-transform-react-jsx-source@7.25.9(@babel/core@7.26.0)': dependencies: - regenerator-runtime: 0.14.0 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/runtime@7.25.4': + '@babel/runtime@7.26.0': dependencies: regenerator-runtime: 0.14.1 - '@babel/template@7.22.5': + '@babel/template@7.25.9': dependencies: - '@babel/code-frame': 7.22.10 - '@babel/parser': 7.22.10 - '@babel/types': 7.22.10 + '@babel/code-frame': 7.26.2 + '@babel/parser': 7.26.2 + '@babel/types': 7.26.0 - '@babel/traverse@7.22.10(supports-color@5.5.0)': + '@babel/traverse@7.25.9(supports-color@5.5.0)': dependencies: - '@babel/code-frame': 7.22.10 - '@babel/generator': 7.22.10 - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-function-name': 7.22.5 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.22.10 - '@babel/types': 7.22.10 - debug: 4.3.4(supports-color@5.5.0) + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.2 + '@babel/parser': 7.26.2 + '@babel/template': 7.25.9 + '@babel/types': 7.26.0 + debug: 4.3.7(supports-color@5.5.0) globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/types@7.22.10': + '@babel/types@7.26.0': dependencies: - '@babel/helper-string-parser': 7.22.5 - '@babel/helper-validator-identifier': 7.22.5 - to-fast-properties: 2.0.0 + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 - '@elastic/elasticsearch@8.10.0': + '@elastic/elasticsearch@8.16.2': dependencies: - '@elastic/transport': 8.3.4 - tslib: 2.6.2 + '@elastic/transport': 8.9.1 + apache-arrow: 18.1.0 + tslib: 2.8.1 transitivePeerDependencies: - supports-color - '@elastic/transport@8.3.4': + '@elastic/transport@8.9.1': dependencies: - debug: 4.3.4(supports-color@5.5.0) + '@opentelemetry/api': 1.9.0 + debug: 4.3.7(supports-color@5.5.0) hpagent: 1.2.0 ms: 2.1.3 secure-json-parse: 2.7.0 - tslib: 2.6.2 - undici: 5.25.4 + tslib: 2.8.1 + undici: 6.21.0 transitivePeerDependencies: - supports-color - '@emotion/babel-plugin@11.11.0': + '@emotion/babel-plugin@11.13.5': dependencies: - '@babel/helper-module-imports': 7.22.5 - '@babel/runtime': 7.25.4 - '@emotion/hash': 0.9.1 - '@emotion/memoize': 0.8.1 - '@emotion/serialize': 1.1.2 + '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) + '@babel/runtime': 7.26.0 + '@emotion/hash': 0.9.2 + '@emotion/memoize': 0.9.0 + '@emotion/serialize': 1.3.3 babel-plugin-macros: 3.1.0 convert-source-map: 1.9.0 escape-string-regexp: 4.0.0 find-root: 1.1.0 source-map: 0.5.7 stylis: 4.2.0 + transitivePeerDependencies: + - supports-color - '@emotion/cache@11.11.0': - dependencies: - '@emotion/memoize': 0.8.1 - '@emotion/sheet': 1.2.2 - '@emotion/utils': 1.2.1 - '@emotion/weak-memoize': 0.3.1 - stylis: 4.2.0 - - '@emotion/cache@11.13.1': + '@emotion/cache@11.13.5': dependencies: '@emotion/memoize': 0.9.0 '@emotion/sheet': 1.4.0 - '@emotion/utils': 1.4.0 + '@emotion/utils': 1.4.2 '@emotion/weak-memoize': 0.4.0 stylis: 4.2.0 - '@emotion/hash@0.9.1': {} + '@emotion/hash@0.9.2': {} '@emotion/is-prop-valid@0.8.8': dependencies: '@emotion/memoize': 0.7.4 optional: true - '@emotion/is-prop-valid@1.2.1': - dependencies: - '@emotion/memoize': 0.8.1 - - '@emotion/is-prop-valid@1.3.0': + '@emotion/is-prop-valid@1.3.1': dependencies: '@emotion/memoize': 0.9.0 '@emotion/memoize@0.7.4': optional: true - '@emotion/memoize@0.8.1': {} - '@emotion/memoize@0.9.0': {} - '@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0)': + '@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@babel/runtime': 7.22.10 - '@emotion/babel-plugin': 11.11.0 - '@emotion/cache': 11.11.0 - '@emotion/serialize': 1.1.2 - '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) - '@emotion/utils': 1.2.1 - '@emotion/weak-memoize': 0.3.1 + '@babel/runtime': 7.26.0 + '@emotion/babel-plugin': 11.13.5 + '@emotion/cache': 11.13.5 + '@emotion/serialize': 1.3.3 + '@emotion/use-insertion-effect-with-fallbacks': 1.1.0(react@18.3.1) + '@emotion/utils': 1.4.2 + '@emotion/weak-memoize': 0.4.0 hoist-non-react-statics: 3.3.2 - react: 18.2.0 + react: 18.3.1 optionalDependencies: - '@types/react': 18.2.15 + '@types/react': 18.3.12 + transitivePeerDependencies: + - supports-color - '@emotion/serialize@1.1.2': + '@emotion/serialize@1.3.3': dependencies: - '@emotion/hash': 0.9.1 - '@emotion/memoize': 0.8.1 - '@emotion/unitless': 0.8.1 - '@emotion/utils': 1.2.1 + '@emotion/hash': 0.9.2 + '@emotion/memoize': 0.9.0 + '@emotion/unitless': 0.10.0 + '@emotion/utils': 1.4.2 csstype: 3.1.3 - '@emotion/sheet@1.2.2': {} - '@emotion/sheet@1.4.0': {} - '@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0)': + '@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@babel/runtime': 7.22.10 - '@emotion/babel-plugin': 11.11.0 - '@emotion/is-prop-valid': 1.2.1 - '@emotion/react': 11.11.1(@types/react@18.2.15)(react@18.2.0) - '@emotion/serialize': 1.1.2 - '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) - '@emotion/utils': 1.2.1 - react: 18.2.0 + '@babel/runtime': 7.26.0 + '@emotion/babel-plugin': 11.13.5 + '@emotion/is-prop-valid': 1.3.1 + '@emotion/react': 11.13.5(@types/react@18.3.12)(react@18.3.1) + '@emotion/serialize': 1.3.3 + '@emotion/use-insertion-effect-with-fallbacks': 1.1.0(react@18.3.1) + '@emotion/utils': 1.4.2 + react: 18.3.1 optionalDependencies: - '@types/react': 18.2.15 + '@types/react': 18.3.12 + transitivePeerDependencies: + - supports-color '@emotion/stylis@0.8.5': {} - '@emotion/unitless@0.7.5': {} + '@emotion/unitless@0.10.0': {} - '@emotion/unitless@0.8.1': {} + '@emotion/unitless@0.7.5': {} - '@emotion/use-insertion-effect-with-fallbacks@1.0.1(react@18.2.0)': + '@emotion/use-insertion-effect-with-fallbacks@1.1.0(react@18.3.1)': dependencies: - react: 18.2.0 - - '@emotion/utils@1.2.1': {} - - '@emotion/utils@1.4.0': {} + react: 18.3.1 - '@emotion/weak-memoize@0.3.1': {} + '@emotion/utils@1.4.2': {} '@emotion/weak-memoize@0.4.0': {} @@ -4547,20 +4349,30 @@ snapshots: '@esbuild/win32-x64@0.18.20': optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@8.54.0)': + '@eslint-community/eslint-utils@4.4.1(eslint@9.16.0)': dependencies: - eslint: 8.54.0 + eslint: 9.16.0 eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.7.0': {} + '@eslint-community/regexpp@4.12.1': {} - '@eslint/eslintrc@2.1.3': + '@eslint/config-array@0.19.0': + dependencies: + '@eslint/object-schema': 2.1.4 + debug: 4.3.7(supports-color@5.5.0) + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/core@0.9.0': {} + + '@eslint/eslintrc@3.2.0': dependencies: ajv: 6.12.6 - debug: 4.3.4(supports-color@5.5.0) - espree: 9.6.1 - globals: 13.21.0 - ignore: 5.2.4 + debug: 4.3.7(supports-color@5.5.0) + espree: 10.3.0 + globals: 14.0.0 + ignore: 5.3.2 import-fresh: 3.3.0 js-yaml: 4.1.0 minimatch: 3.1.2 @@ -4568,25 +4380,47 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@8.54.0': {} + '@eslint/js@9.16.0': {} - '@fastify/busboy@2.0.0': {} + '@eslint/object-schema@2.1.4': {} - '@fontsource/roboto@5.0.7': {} + '@eslint/plugin-kit@0.2.3': + dependencies: + levn: 0.4.1 - '@humanwhocodes/config-array@0.11.13': + '@floating-ui/core@1.6.8': dependencies: - '@humanwhocodes/object-schema': 2.0.1 - debug: 4.3.4(supports-color@5.5.0) - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color + '@floating-ui/utils': 0.2.8 + + '@floating-ui/dom@1.6.12': + dependencies: + '@floating-ui/core': 1.6.8 + '@floating-ui/utils': 0.2.8 + + '@floating-ui/react-dom@2.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/dom': 1.6.12 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@floating-ui/utils@0.2.8': {} + + '@fontsource/roboto@5.1.0': {} + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.6': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.3.1 '@humanwhocodes/module-importer@1.0.1': {} - '@humanwhocodes/object-schema@2.0.1': {} + '@humanwhocodes/retry@0.3.1': {} - '@jest/expect-utils@29.6.3': + '@humanwhocodes/retry@0.4.1': {} + + '@jest/expect-utils@29.7.0': dependencies: jest-get-type: 29.6.3 @@ -4597,33 +4431,28 @@ snapshots: '@jest/types@29.6.3': dependencies: '@jest/schemas': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.4 - '@types/istanbul-reports': 3.0.1 - '@types/node': 20.11.30 - '@types/yargs': 17.0.24 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 20.17.9 + '@types/yargs': 17.0.33 chalk: 4.1.2 - '@jridgewell/gen-mapping@0.3.3': + '@jridgewell/gen-mapping@0.3.5': dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.9 - - '@jridgewell/resolve-uri@3.1.1': {} + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 - '@jridgewell/set-array@1.1.2': {} + '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/sourcemap-codec@1.4.15': {} + '@jridgewell/set-array@1.2.1': {} - '@jridgewell/trace-mapping@0.3.19': - dependencies: - '@jridgewell/resolve-uri': 3.1.1 - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/sourcemap-codec@1.5.0': {} - '@jridgewell/trace-mapping@0.3.9': + '@jridgewell/trace-mapping@0.3.25': dependencies: - '@jridgewell/resolve-uri': 3.1.1 - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 '@mapbox/extent@0.4.0': {} @@ -4641,7 +4470,7 @@ snapshots: '@mapbox/extent': 0.4.0 '@mapbox/geojson-coords': 0.0.2 rw: 0.1.4 - traverse: 0.6.9 + traverse: 0.6.10 '@mapbox/geojson-normalize@0.0.1': {} @@ -4698,7 +4527,7 @@ snapshots: rw: 1.3.3 sort-object: 3.0.3 - '@maplibre/maplibre-gl-style-spec@20.3.1': + '@maplibre/maplibre-gl-style-spec@20.4.0': dependencies: '@mapbox/jsonlint-lines-primitives': 2.0.2 '@mapbox/unitbezier': 0.0.1 @@ -4706,166 +4535,150 @@ snapshots: minimist: 1.2.8 quickselect: 2.0.0 rw: 1.3.3 - sort-object: 3.0.3 tinyqueue: 3.0.0 - '@mui/base@5.0.0-beta.11(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@mui/base@5.0.0-beta.63(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.25.4 - '@emotion/is-prop-valid': 1.3.0 - '@mui/types': 7.2.15(@types/react@18.2.15) - '@mui/utils': 5.16.6(@types/react@18.2.15)(react@18.2.0) + '@babel/runtime': 7.26.0 + '@floating-ui/react-dom': 2.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/types': 7.2.19(@types/react@18.3.12) + '@mui/utils': 6.1.9(@types/react@18.3.12)(react@18.3.1) '@popperjs/core': 2.11.8 clsx: 2.1.1 prop-types: 15.8.1 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-is: 18.3.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 18.2.15 + '@types/react': 18.3.12 - '@mui/core-downloads-tracker@5.16.7': {} + '@mui/core-downloads-tracker@5.16.8': {} - '@mui/icons-material@5.14.3(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@types/react@18.2.15)(react@18.2.0)': + '@mui/icons-material@5.16.8(@mui/material@5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.2 - '@mui/material': 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: 18.2.0 + '@babel/runtime': 7.26.0 + '@mui/material': 5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 optionalDependencies: - '@types/react': 18.2.15 + '@types/react': 18.3.12 - '@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@mui/material@5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.25.4 - '@mui/core-downloads-tracker': 5.16.7 - '@mui/system': 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) - '@mui/types': 7.2.15(@types/react@18.2.15) - '@mui/utils': 5.16.6(@types/react@18.2.15)(react@18.2.0) + '@babel/runtime': 7.26.0 + '@mui/core-downloads-tracker': 5.16.8 + '@mui/system': 5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) + '@mui/types': 7.2.19(@types/react@18.3.12) + '@mui/utils': 5.16.8(@types/react@18.3.12)(react@18.3.1) '@popperjs/core': 2.11.8 '@types/react-transition-group': 4.4.11 clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) react-is: 18.3.1 - react-transition-group: 4.4.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) optionalDependencies: - '@emotion/react': 11.11.1(@types/react@18.2.15)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) - '@types/react': 18.2.15 + '@emotion/react': 11.13.5(@types/react@18.3.12)(react@18.3.1) + '@emotion/styled': 11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) + '@types/react': 18.3.12 - '@mui/private-theming@5.16.6(@types/react@18.2.15)(react@18.2.0)': + '@mui/private-theming@5.16.8(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@babel/runtime': 7.25.4 - '@mui/utils': 5.16.6(@types/react@18.2.15)(react@18.2.0) + '@babel/runtime': 7.26.0 + '@mui/utils': 5.16.8(@types/react@18.3.12)(react@18.3.1) prop-types: 15.8.1 - react: 18.2.0 + react: 18.3.1 optionalDependencies: - '@types/react': 18.2.15 + '@types/react': 18.3.12 - '@mui/styled-engine@5.16.6(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(react@18.2.0)': + '@mui/styled-engine@5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.25.4 - '@emotion/cache': 11.13.1 + '@babel/runtime': 7.26.0 + '@emotion/cache': 11.13.5 csstype: 3.1.3 prop-types: 15.8.1 - react: 18.2.0 + react: 18.3.1 optionalDependencies: - '@emotion/react': 11.11.1(@types/react@18.2.15)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) + '@emotion/react': 11.13.5(@types/react@18.3.12)(react@18.3.1) + '@emotion/styled': 11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) - '@mui/system@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0)': + '@mui/system@5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@babel/runtime': 7.25.4 - '@mui/private-theming': 5.16.6(@types/react@18.2.15)(react@18.2.0) - '@mui/styled-engine': 5.16.6(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(react@18.2.0) - '@mui/types': 7.2.15(@types/react@18.2.15) - '@mui/utils': 5.16.6(@types/react@18.2.15)(react@18.2.0) + '@babel/runtime': 7.26.0 + '@mui/private-theming': 5.16.8(@types/react@18.3.12)(react@18.3.1) + '@mui/styled-engine': 5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(react@18.3.1) + '@mui/types': 7.2.19(@types/react@18.3.12) + '@mui/utils': 5.16.8(@types/react@18.3.12)(react@18.3.1) clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 - react: 18.2.0 + react: 18.3.1 optionalDependencies: - '@emotion/react': 11.11.1(@types/react@18.2.15)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) - '@types/react': 18.2.15 + '@emotion/react': 11.13.5(@types/react@18.3.12)(react@18.3.1) + '@emotion/styled': 11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) + '@types/react': 18.3.12 - '@mui/types@7.2.15(@types/react@18.2.15)': + '@mui/types@7.2.19(@types/react@18.3.12)': optionalDependencies: - '@types/react': 18.2.15 + '@types/react': 18.3.12 - '@mui/utils@5.14.14(@types/react@18.2.15)(react@18.2.0)': + '@mui/utils@5.16.8(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@babel/runtime': 7.25.4 - '@types/prop-types': 15.7.12 + '@babel/runtime': 7.26.0 + '@mui/types': 7.2.19(@types/react@18.3.12) + '@types/prop-types': 15.7.13 + clsx: 2.1.1 prop-types: 15.8.1 - react: 18.2.0 + react: 18.3.1 react-is: 18.3.1 optionalDependencies: - '@types/react': 18.2.15 - - '@mui/utils@5.14.5(react@18.2.0)': - dependencies: - '@babel/runtime': 7.23.2 - '@types/prop-types': 15.7.9 - '@types/react-is': 18.2.1 - prop-types: 15.8.1 - react: 18.2.0 - react-is: 18.2.0 - - '@mui/utils@5.14.7(react@18.2.0)': - dependencies: - '@babel/runtime': 7.23.2 - '@types/prop-types': 15.7.9 - '@types/react-is': 18.2.1 - prop-types: 15.8.1 - react: 18.2.0 - react-is: 18.2.0 + '@types/react': 18.3.12 - '@mui/utils@5.16.6(@types/react@18.2.15)(react@18.2.0)': + '@mui/utils@6.1.9(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@babel/runtime': 7.25.4 - '@mui/types': 7.2.15(@types/react@18.2.15) - '@types/prop-types': 15.7.12 + '@babel/runtime': 7.26.0 + '@mui/types': 7.2.19(@types/react@18.3.12) + '@types/prop-types': 15.7.13 clsx: 2.1.1 prop-types: 15.8.1 - react: 18.2.0 + react: 18.3.1 react-is: 18.3.1 optionalDependencies: - '@types/react': 18.2.15 + '@types/react': 18.3.12 - '@mui/x-data-grid@6.16.3(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@mui/system@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@mui/x-data-grid@6.20.4(@mui/material@5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.2 - '@mui/material': 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@mui/system': 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) - '@mui/utils': 5.14.14(@types/react@18.2.15)(react@18.2.0) - clsx: 2.0.0 + '@babel/runtime': 7.26.0 + '@mui/material': 5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/system': 5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) + '@mui/utils': 5.16.8(@types/react@18.3.12)(react@18.3.1) + clsx: 2.1.1 prop-types: 15.8.1 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) reselect: 4.1.8 transitivePeerDependencies: - '@types/react' - '@mui/x-date-pickers@6.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@mui/base@5.0.0-beta.11(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@mui/material@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@mui/system@5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(moment@2.29.4)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@mui/x-date-pickers@6.20.2(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@mui/material@5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(moment@2.30.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.22.10 - '@mui/base': 5.0.0-beta.11(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@mui/material': 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@mui/system': 5.16.7(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) - '@mui/utils': 5.14.5(react@18.2.0) - '@types/react-transition-group': 4.4.6 - clsx: 1.2.1 + '@babel/runtime': 7.26.0 + '@mui/base': 5.0.0-beta.63(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/material': 5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/system': 5.16.8(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) + '@mui/utils': 5.16.8(@types/react@18.3.12)(react@18.3.1) + '@types/react-transition-group': 4.4.11 + clsx: 2.1.1 prop-types: 15.8.1 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-transition-group: 4.4.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) optionalDependencies: - '@emotion/react': 11.11.1(@types/react@18.2.15)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.1(@types/react@18.2.15)(react@18.2.0))(@types/react@18.2.15)(react@18.2.0) - moment: 2.29.4 + '@emotion/react': 11.13.5(@types/react@18.3.12)(react@18.3.1) + '@emotion/styled': 11.13.5(@emotion/react@11.13.5(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) + moment: 2.30.1 + transitivePeerDependencies: + - '@types/react' '@nodelib/fs.scandir@2.1.5': dependencies: @@ -4877,72 +4690,105 @@ snapshots: '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.15.0 + fastq: 1.17.1 + + '@opentelemetry/api@1.9.0': {} - '@petamoriken/float16@3.8.4': {} + '@petamoriken/float16@3.9.0': {} - '@playwright/test@1.42.1': + '@playwright/test@1.49.0': dependencies: - playwright: 1.42.1 + playwright: 1.49.0 '@popperjs/core@2.11.8': {} - '@reduxjs/toolkit@1.9.5(react-redux@8.1.2(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(redux@4.2.1))(react@18.2.0)': + '@reduxjs/toolkit@1.9.7(react-redux@8.1.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(redux@4.2.1))(react@18.3.1)': dependencies: immer: 9.0.21 redux: 4.2.1 redux-thunk: 2.4.2(redux@4.2.1) reselect: 4.1.8 optionalDependencies: - react: 18.2.0 - react-redux: 8.1.2(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(redux@4.2.1) + react: 18.3.1 + react-redux: 8.1.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(redux@4.2.1) - '@remix-run/router@1.7.2': {} + '@remix-run/router@1.21.0': {} '@sinclair/typebox@0.27.8': {} + '@swc/helpers@0.5.15': + dependencies: + tslib: 2.8.1 + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.26.2 + '@babel/types': 7.26.0 + '@types/babel__generator': 7.6.8 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.6 + + '@types/babel__generator@7.6.8': + dependencies: + '@babel/types': 7.26.0 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.26.2 + '@babel/types': 7.26.0 + + '@types/babel__traverse@7.20.6': + dependencies: + '@babel/types': 7.26.0 + + '@types/command-line-args@5.2.3': {} + + '@types/command-line-usage@5.0.4': {} + + '@types/estree@1.0.6': {} + '@types/geojson-vt@3.2.5': dependencies: '@types/geojson': 7946.0.14 '@types/geojson@7946.0.14': {} - '@types/hoist-non-react-statics@3.3.1': + '@types/hoist-non-react-statics@3.3.5': dependencies: - '@types/react': 18.2.15 + '@types/react': 18.3.12 hoist-non-react-statics: 3.3.2 - '@types/istanbul-lib-coverage@2.0.4': {} + '@types/istanbul-lib-coverage@2.0.6': {} - '@types/istanbul-lib-report@3.0.0': + '@types/istanbul-lib-report@3.0.3': dependencies: - '@types/istanbul-lib-coverage': 2.0.4 + '@types/istanbul-lib-coverage': 2.0.6 - '@types/istanbul-reports@3.0.1': + '@types/istanbul-reports@3.0.4': dependencies: - '@types/istanbul-lib-report': 3.0.0 + '@types/istanbul-lib-report': 3.0.3 - '@types/jest@29.5.3': + '@types/jest@29.5.14': dependencies: - expect: 29.6.3 - pretty-format: 29.6.3 + expect: 29.7.0 + pretty-format: 29.7.0 - '@types/json-schema@7.0.12': {} + '@types/json-schema@7.0.15': {} - '@types/lodash.debounce@4.0.7': + '@types/lodash.debounce@4.0.9': dependencies: - '@types/lodash': 4.14.199 + '@types/lodash': 4.17.13 - '@types/lodash@4.14.199': {} + '@types/lodash@4.17.13': {} - '@types/mapbox-gl@3.4.0': + '@types/mapbox-gl@3.4.1': dependencies: '@types/geojson': 7946.0.14 - '@types/mapbox__mapbox-gl-draw@1.4.7': + '@types/mapbox__mapbox-gl-draw@1.4.8': dependencies: '@types/geojson': 7946.0.14 - mapbox-gl: 3.6.0 + mapbox-gl: 3.8.0 '@types/mapbox__point-geometry@0.1.4': {} @@ -4952,63 +4798,44 @@ snapshots: '@types/mapbox__point-geometry': 0.1.4 '@types/pbf': 3.0.5 - '@types/md5@2.3.3': {} + '@types/md5@2.3.5': {} - '@types/ngeohash@0.6.5': {} + '@types/ngeohash@0.6.8': {} - '@types/node@18.0.6': {} - - '@types/node@20.11.30': + '@types/node@20.17.9': dependencies: - undici-types: 5.26.5 - - '@types/node@20.5.3': {} + undici-types: 6.19.8 - '@types/parse-json@4.0.0': {} + '@types/parse-json@4.0.2': {} '@types/pbf@3.0.5': {} - '@types/prop-types@15.7.12': {} - - '@types/prop-types@15.7.9': {} - - '@types/react-dom@18.2.7': - dependencies: - '@types/react': 18.2.15 + '@types/prop-types@15.7.13': {} - '@types/react-helmet@6.1.6': + '@types/react-dom@18.3.1': dependencies: - '@types/react': 18.2.15 + '@types/react': 18.3.12 - '@types/react-is@18.2.1': + '@types/react-helmet@6.1.11': dependencies: - '@types/react': 18.2.15 + '@types/react': 18.3.12 '@types/react-transition-group@4.4.11': dependencies: - '@types/react': 18.2.15 + '@types/react': 18.3.12 - '@types/react-transition-group@4.4.6': + '@types/react@18.3.12': dependencies: - '@types/react': 18.2.15 - - '@types/react@18.2.15': - dependencies: - '@types/prop-types': 15.7.9 - '@types/scheduler': 0.16.3 - csstype: 3.1.2 - - '@types/scheduler@0.16.3': {} - - '@types/semver@7.5.0': {} + '@types/prop-types': 15.7.13 + csstype: 3.1.3 - '@types/stack-utils@2.0.1': {} + '@types/stack-utils@2.0.3': {} - '@types/styled-components@5.1.28': + '@types/styled-components@5.1.34': dependencies: - '@types/hoist-non-react-statics': 3.3.1 - '@types/react': 18.2.15 - csstype: 3.1.2 + '@types/hoist-non-react-statics': 3.3.5 + '@types/react': 18.3.12 + csstype: 3.1.3 '@types/supercluster@7.1.3': dependencies: @@ -5016,116 +4843,112 @@ snapshots: '@types/use-sync-external-store@0.0.3': {} - '@types/uuid@9.0.2': {} + '@types/uuid@9.0.8': {} - '@types/yargs-parser@21.0.0': {} + '@types/yargs-parser@21.0.3': {} - '@types/yargs@17.0.24': + '@types/yargs@17.0.33': dependencies: - '@types/yargs-parser': 21.0.0 + '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@6.12.0(@typescript-eslint/parser@6.12.0(eslint@8.54.0)(typescript@5.1.6))(eslint@8.54.0)(typescript@5.1.6)': + '@typescript-eslint/eslint-plugin@8.17.0(@typescript-eslint/parser@8.17.0(eslint@9.16.0)(typescript@5.7.2))(eslint@9.16.0)(typescript@5.7.2)': dependencies: - '@eslint-community/regexpp': 4.7.0 - '@typescript-eslint/parser': 6.12.0(eslint@8.54.0)(typescript@5.1.6) - '@typescript-eslint/scope-manager': 6.12.0 - '@typescript-eslint/type-utils': 6.12.0(eslint@8.54.0)(typescript@5.1.6) - '@typescript-eslint/utils': 6.12.0(eslint@8.54.0)(typescript@5.1.6) - '@typescript-eslint/visitor-keys': 6.12.0 - debug: 4.3.4(supports-color@5.5.0) - eslint: 8.54.0 + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.17.0(eslint@9.16.0)(typescript@5.7.2) + '@typescript-eslint/scope-manager': 8.17.0 + '@typescript-eslint/type-utils': 8.17.0(eslint@9.16.0)(typescript@5.7.2) + '@typescript-eslint/utils': 8.17.0(eslint@9.16.0)(typescript@5.7.2) + '@typescript-eslint/visitor-keys': 8.17.0 + eslint: 9.16.0 graphemer: 1.4.0 - ignore: 5.2.4 + ignore: 5.3.2 natural-compare: 1.4.0 - semver: 7.5.4 - ts-api-utils: 1.0.2(typescript@5.1.6) + ts-api-utils: 1.4.3(typescript@5.7.2) optionalDependencies: - typescript: 5.1.6 + typescript: 5.7.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@6.12.0(eslint@8.54.0)(typescript@5.1.6)': + '@typescript-eslint/parser@8.17.0(eslint@9.16.0)(typescript@5.7.2)': dependencies: - '@typescript-eslint/scope-manager': 6.12.0 - '@typescript-eslint/types': 6.12.0 - '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.1.6) - '@typescript-eslint/visitor-keys': 6.12.0 - debug: 4.3.4(supports-color@5.5.0) - eslint: 8.54.0 + '@typescript-eslint/scope-manager': 8.17.0 + '@typescript-eslint/types': 8.17.0 + '@typescript-eslint/typescript-estree': 8.17.0(typescript@5.7.2) + '@typescript-eslint/visitor-keys': 8.17.0 + debug: 4.3.7(supports-color@5.5.0) + eslint: 9.16.0 optionalDependencies: - typescript: 5.1.6 + typescript: 5.7.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@6.12.0': + '@typescript-eslint/scope-manager@8.17.0': dependencies: - '@typescript-eslint/types': 6.12.0 - '@typescript-eslint/visitor-keys': 6.12.0 + '@typescript-eslint/types': 8.17.0 + '@typescript-eslint/visitor-keys': 8.17.0 - '@typescript-eslint/type-utils@6.12.0(eslint@8.54.0)(typescript@5.1.6)': + '@typescript-eslint/type-utils@8.17.0(eslint@9.16.0)(typescript@5.7.2)': dependencies: - '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.1.6) - '@typescript-eslint/utils': 6.12.0(eslint@8.54.0)(typescript@5.1.6) - debug: 4.3.4(supports-color@5.5.0) - eslint: 8.54.0 - ts-api-utils: 1.0.2(typescript@5.1.6) + '@typescript-eslint/typescript-estree': 8.17.0(typescript@5.7.2) + '@typescript-eslint/utils': 8.17.0(eslint@9.16.0)(typescript@5.7.2) + debug: 4.3.7(supports-color@5.5.0) + eslint: 9.16.0 + ts-api-utils: 1.4.3(typescript@5.7.2) optionalDependencies: - typescript: 5.1.6 + typescript: 5.7.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@6.12.0': {} + '@typescript-eslint/types@8.17.0': {} - '@typescript-eslint/typescript-estree@6.12.0(typescript@5.1.6)': + '@typescript-eslint/typescript-estree@8.17.0(typescript@5.7.2)': dependencies: - '@typescript-eslint/types': 6.12.0 - '@typescript-eslint/visitor-keys': 6.12.0 - debug: 4.3.4(supports-color@5.5.0) - globby: 11.1.0 + '@typescript-eslint/types': 8.17.0 + '@typescript-eslint/visitor-keys': 8.17.0 + debug: 4.3.7(supports-color@5.5.0) + fast-glob: 3.3.2 is-glob: 4.0.3 - semver: 7.5.4 - ts-api-utils: 1.0.2(typescript@5.1.6) + minimatch: 9.0.5 + semver: 7.6.3 + ts-api-utils: 1.4.3(typescript@5.7.2) optionalDependencies: - typescript: 5.1.6 + typescript: 5.7.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@6.12.0(eslint@8.54.0)(typescript@5.1.6)': + '@typescript-eslint/utils@8.17.0(eslint@9.16.0)(typescript@5.7.2)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0) - '@types/json-schema': 7.0.12 - '@types/semver': 7.5.0 - '@typescript-eslint/scope-manager': 6.12.0 - '@typescript-eslint/types': 6.12.0 - '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.1.6) - eslint: 8.54.0 - semver: 7.5.4 + '@eslint-community/eslint-utils': 4.4.1(eslint@9.16.0) + '@typescript-eslint/scope-manager': 8.17.0 + '@typescript-eslint/types': 8.17.0 + '@typescript-eslint/typescript-estree': 8.17.0(typescript@5.7.2) + eslint: 9.16.0 + optionalDependencies: + typescript: 5.7.2 transitivePeerDependencies: - supports-color - - typescript - '@typescript-eslint/visitor-keys@6.12.0': + '@typescript-eslint/visitor-keys@8.17.0': dependencies: - '@typescript-eslint/types': 6.12.0 - eslint-visitor-keys: 3.4.3 + '@typescript-eslint/types': 8.17.0 + eslint-visitor-keys: 4.2.0 - '@ungap/structured-clone@1.2.0': {} - - '@vitejs/plugin-react@4.0.3(vite@4.4.5(@types/node@20.11.30)(lightningcss@1.22.0))': + '@vitejs/plugin-react@4.3.4(vite@4.5.5(@types/node@20.17.9)(lightningcss@1.28.2))': dependencies: - '@babel/core': 7.22.10 - '@babel/plugin-transform-react-jsx-self': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-react-jsx-source': 7.22.5(@babel/core@7.22.10) - react-refresh: 0.14.0 - vite: 4.4.5(@types/node@20.11.30)(lightningcss@1.22.0) + '@babel/core': 7.26.0 + '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.0) + '@types/babel__core': 7.20.5 + react-refresh: 0.14.2 + vite: 4.5.5(@types/node@20.17.9)(lightningcss@1.28.2) transitivePeerDependencies: - supports-color - acorn-jsx@5.3.2(acorn@8.10.0): + acorn-jsx@5.3.2(acorn@8.14.0): dependencies: - acorn: 8.10.0 + acorn: 8.14.0 - acorn@8.10.0: {} + acorn@8.14.0: {} adler-32@1.3.1: {} @@ -5142,10 +4965,6 @@ snapshots: ansi-regex@5.0.1: {} - ansi-styles@3.2.1: - dependencies: - color-convert: 1.9.3 - ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 @@ -5157,23 +4976,37 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.1 + apache-arrow@18.1.0: + dependencies: + '@swc/helpers': 0.5.15 + '@types/command-line-args': 5.2.3 + '@types/command-line-usage': 5.0.4 + '@types/node': 20.17.9 + command-line-args: 5.2.1 + command-line-usage: 7.0.3 + flatbuffers: 24.3.25 + json-bignum: 0.0.3 + tslib: 2.8.1 + argparse@2.0.1: {} arr-union@3.1.0: {} + array-back@3.1.0: {} + + array-back@6.2.2: {} + array-buffer-byte-length@1.0.1: dependencies: call-bind: 1.0.7 is-array-buffer: 3.0.4 - array-union@2.1.0: {} - arraybuffer.prototype.slice@1.0.3: dependencies: array-buffer-byte-length: 1.0.1 call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.23.3 + es-abstract: 1.23.5 es-errors: 1.3.0 get-intrinsic: 1.2.4 is-array-buffer: 3.0.4 @@ -5181,58 +5014,53 @@ snapshots: assign-symbols@1.0.0: {} - asynckit@0.4.0: {} - - attr-accept@2.2.2: {} + attr-accept@2.2.5: {} available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.0.0 - axios@1.6.0: - dependencies: - follow-redirects: 1.15.2 - form-data: 4.0.0 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - babel-plugin-macros@3.1.0: dependencies: - '@babel/runtime': 7.25.4 + '@babel/runtime': 7.26.0 cosmiconfig: 7.1.0 - resolve: 1.22.4 + resolve: 1.22.8 - babel-plugin-styled-components@2.1.4(@babel/core@7.22.10)(styled-components@5.3.10(@babel/core@7.22.10)(react-dom@18.2.0(react@18.2.0))(react-is@18.3.1)(react@18.2.0)): + babel-plugin-styled-components@2.1.4(@babel/core@7.26.0)(styled-components@5.3.11(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1))(supports-color@5.5.0): dependencies: - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-module-imports': 7.22.5 - '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.10) + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) + '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) lodash: 4.17.21 picomatch: 2.3.1 - styled-components: 5.3.10(@babel/core@7.22.10)(react-dom@18.2.0(react@18.2.0))(react-is@18.3.1)(react@18.2.0) + styled-components: 5.3.11(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1) transitivePeerDependencies: - '@babel/core' + - supports-color balanced-match@1.0.2: {} - binary-extensions@2.2.0: {} + binary-extensions@2.3.0: {} brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - braces@3.0.2: + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: dependencies: - fill-range: 7.0.1 + fill-range: 7.1.1 - browserslist@4.21.10: + browserslist@4.24.2: dependencies: - caniuse-lite: 1.0.30001522 - electron-to-chromium: 1.4.500 - node-releases: 2.0.13 - update-browserslist-db: 1.0.11(browserslist@4.21.10) + caniuse-lite: 1.0.30001686 + electron-to-chromium: 1.5.68 + node-releases: 2.0.18 + update-browserslist-db: 1.1.1(browserslist@4.24.2) buffer-from@1.1.2: {} @@ -5257,18 +5085,16 @@ snapshots: camelize@1.0.1: {} - caniuse-lite@1.0.30001522: {} + caniuse-lite@1.0.30001686: {} cfb@1.2.2: dependencies: adler-32: 1.3.1 crc-32: 1.2.2 - chalk@2.4.2: + chalk-template@0.4.0: dependencies: - ansi-styles: 3.2.1 - escape-string-regexp: 1.0.5 - supports-color: 5.5.0 + chalk: 4.1.2 chalk@4.1.2: dependencies: @@ -5279,10 +5105,10 @@ snapshots: cheap-ruler@4.0.0: {} - chokidar@3.5.3: + chokidar@3.6.0: dependencies: anymatch: 3.1.3 - braces: 3.0.2 + braces: 3.0.3 glob-parent: 5.1.2 is-binary-path: 2.1.0 is-glob: 4.0.3 @@ -5291,32 +5117,18 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - ci-info@3.8.0: {} - - cliui@8.0.1: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 + ci-info@3.9.0: {} clsx@1.2.1: {} - clsx@2.0.0: {} - clsx@2.1.1: {} codepage@1.15.0: {} - color-convert@1.9.3: - dependencies: - color-name: 1.1.3 - color-convert@2.0.1: dependencies: color-name: 1.1.4 - color-name@1.1.3: {} - color-name@1.1.4: {} combine-errors@3.0.3: @@ -5324,9 +5136,19 @@ snapshots: custom-error-instance: 2.1.1 lodash.uniqby: 4.5.0 - combined-stream@1.0.8: + command-line-args@5.2.1: + dependencies: + array-back: 3.1.0 + find-replace: 3.0.0 + lodash.camelcase: 4.3.0 + typical: 4.0.0 + + command-line-usage@7.0.3: dependencies: - delayed-stream: 1.0.0 + array-back: 6.2.2 + chalk-template: 0.4.0 + table-layout: 4.1.1 + typical: 7.3.0 commander@8.3.0: {} @@ -5334,19 +5156,21 @@ snapshots: convert-source-map@1.9.0: {} + convert-source-map@2.0.0: {} + cosmiconfig@7.1.0: dependencies: - '@types/parse-json': 4.0.0 + '@types/parse-json': 4.0.2 import-fresh: 3.3.0 parse-json: 5.2.0 path-type: 4.0.0 yaml: 1.10.2 - country-flag-icons@1.5.7: {} + country-flag-icons@1.5.13: {} crc-32@1.2.2: {} - cross-spawn@7.0.3: + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 @@ -5354,7 +5178,7 @@ snapshots: crypt@0.0.2: {} - crypto-js@4.1.1: {} + crypto-js@4.2.0: {} css-color-keywords@1.0.0: {} @@ -5366,8 +5190,6 @@ snapshots: csscolorparser@1.0.3: {} - csstype@3.1.2: {} - csstype@3.1.3: {} custom-error-instance@2.1.1: {} @@ -5390,9 +5212,9 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.1 - debug@4.3.4(supports-color@5.5.0): + debug@4.3.7(supports-color@5.5.0): dependencies: - ms: 2.1.2 + ms: 2.1.3 optionalDependencies: supports-color: 5.5.0 @@ -5402,9 +5224,7 @@ snapshots: dependencies: es-define-property: 1.0.0 es-errors: 1.3.0 - gopd: 1.0.1 - - define-lazy-prop@2.0.0: {} + gopd: 1.1.0 define-properties@1.2.1: dependencies: @@ -5412,24 +5232,14 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 - delayed-stream@1.0.0: {} - detect-libc@1.0.3: {} diff-sequences@29.6.3: {} - dir-glob@3.0.1: - dependencies: - path-type: 4.0.0 - - doctrine@3.0.0: - dependencies: - esutils: 2.0.3 - dom-helpers@5.2.1: dependencies: - '@babel/runtime': 7.23.2 - csstype: 3.1.2 + '@babel/runtime': 7.26.0 + csstype: 3.1.3 dom-serializer@2.0.0: dependencies: @@ -5453,14 +5263,12 @@ snapshots: earcut@3.0.0: {} - echarts@5.4.3: + echarts@5.5.1: dependencies: tslib: 2.3.0 - zrender: 5.4.4 + zrender: 5.6.0 - electron-to-chromium@1.4.500: {} - - emoji-regex@8.0.0: {} + electron-to-chromium@1.5.68: {} entities@4.5.0: {} @@ -5468,7 +5276,7 @@ snapshots: dependencies: is-arrayish: 0.2.1 - es-abstract@1.23.3: + es-abstract@1.23.5: dependencies: array-buffer-byte-length: 1.0.1 arraybuffer.prototype.slice: 1.0.3 @@ -5481,30 +5289,30 @@ snapshots: es-errors: 1.3.0 es-object-atoms: 1.0.0 es-set-tostringtag: 2.0.3 - es-to-primitive: 1.2.1 + es-to-primitive: 1.3.0 function.prototype.name: 1.1.6 get-intrinsic: 1.2.4 get-symbol-description: 1.0.2 globalthis: 1.0.4 - gopd: 1.0.1 + gopd: 1.1.0 has-property-descriptors: 1.0.2 - has-proto: 1.0.3 - has-symbols: 1.0.3 + has-proto: 1.1.0 + has-symbols: 1.1.0 hasown: 2.0.2 internal-slot: 1.0.7 is-array-buffer: 3.0.4 is-callable: 1.2.7 is-data-view: 1.0.1 is-negative-zero: 2.0.3 - is-regex: 1.1.4 + is-regex: 1.2.0 is-shared-array-buffer: 1.0.3 - is-string: 1.0.7 + is-string: 1.1.0 is-typed-array: 1.1.13 is-weakref: 1.0.2 - object-inspect: 1.13.2 + object-inspect: 1.13.3 object-keys: 1.1.1 object.assign: 4.1.5 - regexp.prototype.flags: 1.5.2 + regexp.prototype.flags: 1.5.3 safe-array-concat: 1.1.2 safe-regex-test: 1.0.3 string.prototype.trim: 1.2.9 @@ -5512,10 +5320,10 @@ snapshots: string.prototype.trimstart: 1.0.8 typed-array-buffer: 1.0.2 typed-array-byte-length: 1.0.1 - typed-array-byte-offset: 1.0.2 - typed-array-length: 1.0.6 + typed-array-byte-offset: 1.0.3 + typed-array-length: 1.0.7 unbox-primitive: 1.0.2 - which-typed-array: 1.1.15 + which-typed-array: 1.1.16 es-define-property@1.0.0: dependencies: @@ -5533,16 +5341,16 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.2 - es-to-primitive@1.2.1: + es-to-primitive@1.3.0: dependencies: is-callable: 1.2.7 is-date-object: 1.0.5 - is-symbol: 1.0.4 + is-symbol: 1.1.0 - esbuild-css-modules-plugin@3.0.3(esbuild@0.17.19): + esbuild-css-modules-plugin@3.1.2(esbuild@0.17.19): dependencies: esbuild: 0.17.19 - lightningcss: 1.22.0 + lightningcss: 1.28.2 lodash-es: 4.17.21 esbuild@0.17.19: @@ -5595,83 +5403,75 @@ snapshots: '@esbuild/win32-ia32': 0.18.20 '@esbuild/win32-x64': 0.18.20 - escalade@3.1.1: {} - - escape-string-regexp@1.0.5: {} + escalade@3.2.0: {} escape-string-regexp@2.0.0: {} escape-string-regexp@4.0.0: {} - eslint-config-prettier@9.0.0(eslint@8.54.0): + eslint-config-prettier@9.1.0(eslint@9.16.0): dependencies: - eslint: 8.54.0 + eslint: 9.16.0 - eslint-plugin-react-hooks@4.6.0(eslint@8.54.0): + eslint-plugin-react-hooks@5.0.0(eslint@9.16.0): dependencies: - eslint: 8.54.0 + eslint: 9.16.0 - eslint-plugin-react-refresh@0.4.3(eslint@8.54.0): - dependencies: - eslint: 8.54.0 - - eslint-scope@7.2.2: + eslint-scope@8.2.0: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 eslint-visitor-keys@3.4.3: {} - eslint@8.54.0: + eslint-visitor-keys@4.2.0: {} + + eslint@9.16.0: dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0) - '@eslint-community/regexpp': 4.7.0 - '@eslint/eslintrc': 2.1.3 - '@eslint/js': 8.54.0 - '@humanwhocodes/config-array': 0.11.13 + '@eslint-community/eslint-utils': 4.4.1(eslint@9.16.0) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.19.0 + '@eslint/core': 0.9.0 + '@eslint/eslintrc': 3.2.0 + '@eslint/js': 9.16.0 + '@eslint/plugin-kit': 0.2.3 + '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 - '@nodelib/fs.walk': 1.2.8 - '@ungap/structured-clone': 1.2.0 + '@humanwhocodes/retry': 0.4.1 + '@types/estree': 1.0.6 + '@types/json-schema': 7.0.15 ajv: 6.12.6 chalk: 4.1.2 - cross-spawn: 7.0.3 - debug: 4.3.4(supports-color@5.5.0) - doctrine: 3.0.0 + cross-spawn: 7.0.6 + debug: 4.3.7(supports-color@5.5.0) escape-string-regexp: 4.0.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 - esquery: 1.5.0 + eslint-scope: 8.2.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 + esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 + file-entry-cache: 8.0.0 find-up: 5.0.0 glob-parent: 6.0.2 - globals: 13.21.0 - graphemer: 1.4.0 - ignore: 5.2.4 + ignore: 5.3.2 imurmurhash: 0.1.4 is-glob: 4.0.3 - is-path-inside: 3.0.3 - js-yaml: 4.1.0 json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 lodash.merge: 4.6.2 minimatch: 3.1.2 natural-compare: 1.4.0 - optionator: 0.9.3 - strip-ansi: 6.0.1 - text-table: 0.2.0 + optionator: 0.9.4 transitivePeerDependencies: - supports-color - espree@9.6.1: + espree@10.3.0: dependencies: - acorn: 8.10.0 - acorn-jsx: 5.3.2(acorn@8.10.0) - eslint-visitor-keys: 3.4.3 + acorn: 8.14.0 + acorn-jsx: 5.3.2(acorn@8.14.0) + eslint-visitor-keys: 4.2.0 - esquery@1.5.0: + esquery@1.6.0: dependencies: estraverse: 5.3.0 @@ -5683,13 +5483,13 @@ snapshots: esutils@2.0.3: {} - expect@29.6.3: + expect@29.7.0: dependencies: - '@jest/expect-utils': 29.6.3 + '@jest/expect-utils': 29.7.0 jest-get-type: 29.6.3 - jest-matcher-utils: 29.6.3 - jest-message-util: 29.6.3 - jest-util: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 extend-shallow@2.0.1: dependencies: @@ -5702,40 +5502,42 @@ snapshots: fast-deep-equal@3.1.3: {} - fast-glob@3.3.1: + fast-glob@3.3.2: dependencies: '@nodelib/fs.stat': 2.0.5 '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 - micromatch: 4.0.5 + micromatch: 4.0.8 fast-json-stable-stringify@2.1.0: {} fast-levenshtein@2.0.6: {} - fast-xml-parser@4.2.7: + fast-xml-parser@4.5.0: dependencies: strnum: 1.0.5 - fastq@1.15.0: + fastq@1.17.1: dependencies: reusify: 1.0.4 - fflate@0.8.2: {} - - file-entry-cache@6.0.1: + file-entry-cache@8.0.0: dependencies: - flat-cache: 3.0.4 + flat-cache: 4.0.1 - file-selector@0.6.0: + file-selector@2.1.2: dependencies: - tslib: 2.6.2 + tslib: 2.8.1 - fill-range@7.0.1: + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 + find-replace@3.0.0: + dependencies: + array-back: 3.1.0 + find-root@1.1.0: {} find-up@5.0.0: @@ -5743,42 +5545,34 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - flat-cache@3.0.4: + flat-cache@4.0.1: dependencies: - flatted: 3.2.7 - rimraf: 3.0.2 + flatted: 3.3.2 + keyv: 4.5.4 - flatted@3.2.7: {} + flatbuffers@24.3.25: {} - follow-redirects@1.15.2: {} + flatted@3.3.2: {} for-each@0.3.3: dependencies: is-callable: 1.2.7 - form-data@4.0.0: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - frac@1.1.2: {} - framer-motion@10.15.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + framer-motion@10.18.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - tslib: 2.6.2 + tslib: 2.8.1 optionalDependencies: '@emotion/is-prop-valid': 0.8.8 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - fs-extra@11.1.1: + fs-extra@11.2.0: dependencies: graceful-fs: 4.2.11 jsonfile: 6.1.0 - universalify: 2.0.0 - - fs.realpath@1.0.0: {} + universalify: 2.0.1 fsevents@2.3.2: optional: true @@ -5792,7 +5586,7 @@ snapshots: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.23.3 + es-abstract: 1.23.5 functions-have-names: 1.2.3 functions-have-names@1.2.3: {} @@ -5803,24 +5597,23 @@ snapshots: geojson-vt@4.0.2: {} - geotiff@2.0.7: + geotiff@2.1.3: dependencies: - '@petamoriken/float16': 3.8.4 + '@petamoriken/float16': 3.9.0 lerc: 3.0.0 pako: 2.1.0 parse-headers: 2.0.5 quick-lru: 6.1.2 - web-worker: 1.2.0 - xml-utils: 1.7.0 - - get-caller-file@2.0.5: {} + web-worker: 1.3.0 + xml-utils: 1.10.1 + zstddec: 0.1.0 get-intrinsic@1.2.4: dependencies: es-errors: 1.3.0 function-bind: 1.1.2 - has-proto: 1.0.3 - has-symbols: 1.0.3 + has-proto: 1.1.0 + has-symbols: 1.1.0 hasown: 2.0.2 get-stream@6.0.1: {} @@ -5843,46 +5636,26 @@ snapshots: dependencies: is-glob: 4.0.3 - glob@7.2.3: - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - - global-prefix@3.0.0: + global-prefix@4.0.0: dependencies: - ini: 1.3.8 + ini: 4.1.3 kind-of: 6.0.3 - which: 1.3.1 + which: 4.0.0 globals@11.12.0: {} - globals@13.21.0: - dependencies: - type-fest: 0.20.2 + globals@14.0.0: {} globalthis@1.0.4: dependencies: define-properties: 1.2.1 - gopd: 1.0.1 - - globby@11.1.0: - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.1 - ignore: 5.2.4 - merge2: 1.4.1 - slash: 3.0.0 + gopd: 1.1.0 - goober@2.1.13(csstype@3.1.3): + goober@2.1.16(csstype@3.1.3): dependencies: csstype: 3.1.3 - gopd@1.0.1: + gopd@1.1.0: dependencies: get-intrinsic: 1.2.4 @@ -5902,17 +5675,15 @@ snapshots: dependencies: es-define-property: 1.0.0 - has-proto@1.0.3: {} + has-proto@1.1.0: + dependencies: + call-bind: 1.0.7 - has-symbols@1.0.3: {} + has-symbols@1.1.0: {} has-tostringtag@1.0.2: dependencies: - has-symbols: 1.0.3 - - has@1.0.3: - dependencies: - function-bind: 1.1.2 + has-symbols: 1.1.0 hasown@2.0.2: dependencies: @@ -5926,7 +5697,7 @@ snapshots: hpagent@1.2.0: {} - html-dom-parser@4.0.0: + html-dom-parser@5.0.3: dependencies: domhandler: 5.0.3 htmlparser2: 9.0.0 @@ -5935,13 +5706,13 @@ snapshots: dependencies: void-elements: 3.1.0 - html-react-parser@4.2.2(react@18.2.0): + html-react-parser@4.2.10(react@18.3.1): dependencies: domhandler: 5.0.3 - html-dom-parser: 4.0.0 - react: 18.2.0 - react-property: 2.0.0 - style-to-js: 1.1.4 + html-dom-parser: 5.0.3 + react: 18.3.1 + react-property: 2.0.2 + style-to-js: 1.1.8 htmlparser2@9.0.0: dependencies: @@ -5950,21 +5721,21 @@ snapshots: domutils: 3.1.0 entities: 4.5.0 - i18next-browser-languagedetector@7.1.0: + i18next-browser-languagedetector@7.2.1: dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.26.0 - i18next-resources-to-backend@1.1.4: + i18next-resources-to-backend@1.2.1: dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.26.0 - i18next@23.4.1: + i18next@23.16.8: dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.26.0 ieee754@1.2.1: {} - ignore@5.2.4: {} + ignore@5.3.2: {} immer@9.0.21: {} @@ -5975,16 +5746,9 @@ snapshots: imurmurhash@0.1.4: {} - inflight@1.0.6: - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - - inherits@2.0.4: {} - - ini@1.3.8: {} + ini@4.1.3: {} - inline-style-parser@0.1.1: {} + inline-style-parser@0.2.2: {} internal-slot@1.0.7: dependencies: @@ -5999,15 +5763,19 @@ snapshots: is-arrayish@0.2.1: {} - is-bigint@1.0.4: + is-async-function@2.0.0: + dependencies: + has-tostringtag: 1.0.2 + + is-bigint@1.1.0: dependencies: has-bigints: 1.0.2 is-binary-path@2.1.0: dependencies: - binary-extensions: 2.2.0 + binary-extensions: 2.3.0 - is-boolean-object@1.1.2: + is-boolean-object@1.2.0: dependencies: call-bind: 1.0.7 has-tostringtag: 1.0.2 @@ -6016,9 +5784,9 @@ snapshots: is-callable@1.2.7: {} - is-core-module@2.13.0: + is-core-module@2.15.1: dependencies: - has: 1.0.3 + hasown: 2.0.2 is-data-view@1.0.1: dependencies: @@ -6028,8 +5796,6 @@ snapshots: dependencies: has-tostringtag: 1.0.2 - is-docker@2.2.1: {} - is-extendable@0.1.1: {} is-extendable@1.0.1: @@ -6038,30 +5804,41 @@ snapshots: is-extglob@2.1.1: {} - is-fullwidth-code-point@3.0.0: {} + is-finalizationregistry@1.1.0: + dependencies: + call-bind: 1.0.7 + + is-generator-function@1.0.10: + dependencies: + has-tostringtag: 1.0.2 is-glob@4.0.3: dependencies: is-extglob: 2.1.1 + is-map@2.0.3: {} + is-negative-zero@2.0.3: {} - is-number-object@1.0.7: + is-number-object@1.1.0: dependencies: + call-bind: 1.0.7 has-tostringtag: 1.0.2 is-number@7.0.0: {} - is-path-inside@3.0.3: {} - is-plain-object@2.0.4: dependencies: isobject: 3.0.1 - is-regex@1.1.4: + is-regex@1.2.0: dependencies: call-bind: 1.0.7 + gopd: 1.1.0 has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-set@2.0.3: {} is-shared-array-buffer@1.0.3: dependencies: @@ -6069,66 +5846,74 @@ snapshots: is-stream@2.0.1: {} - is-string@1.0.7: + is-string@1.1.0: dependencies: + call-bind: 1.0.7 has-tostringtag: 1.0.2 - is-symbol@1.0.4: + is-symbol@1.1.0: dependencies: - has-symbols: 1.0.3 + call-bind: 1.0.7 + has-symbols: 1.1.0 + safe-regex-test: 1.0.3 is-typed-array@1.1.13: dependencies: - which-typed-array: 1.1.15 + which-typed-array: 1.1.16 + + is-weakmap@2.0.2: {} is-weakref@1.0.2: dependencies: call-bind: 1.0.7 - is-wsl@2.2.0: + is-weakset@2.0.3: dependencies: - is-docker: 2.2.1 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 isarray@2.0.5: {} isexe@2.0.0: {} + isexe@3.1.1: {} + isobject@3.0.1: {} - jest-diff@29.6.3: + jest-diff@29.7.0: dependencies: chalk: 4.1.2 diff-sequences: 29.6.3 jest-get-type: 29.6.3 - pretty-format: 29.6.3 + pretty-format: 29.7.0 jest-get-type@29.6.3: {} - jest-matcher-utils@29.6.3: + jest-matcher-utils@29.7.0: dependencies: chalk: 4.1.2 - jest-diff: 29.6.3 + jest-diff: 29.7.0 jest-get-type: 29.6.3 - pretty-format: 29.6.3 + pretty-format: 29.7.0 - jest-message-util@29.6.3: + jest-message-util@29.7.0: dependencies: - '@babel/code-frame': 7.22.10 + '@babel/code-frame': 7.26.2 '@jest/types': 29.6.3 - '@types/stack-utils': 2.0.1 + '@types/stack-utils': 2.0.3 chalk: 4.1.2 graceful-fs: 4.2.11 - micromatch: 4.0.5 - pretty-format: 29.6.3 + micromatch: 4.0.8 + pretty-format: 29.7.0 slash: 3.0.0 stack-utils: 2.0.6 - jest-util@29.6.3: + jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 20.11.30 + '@types/node': 20.17.9 chalk: 4.1.2 - ci-info: 3.8.0 + ci-info: 3.9.0 graceful-fs: 4.2.11 picomatch: 2.3.1 @@ -6140,7 +5925,11 @@ snapshots: dependencies: argparse: 2.0.1 - jsesc@2.5.2: {} + jsesc@3.0.2: {} + + json-bignum@0.0.3: {} + + json-buffer@3.0.1: {} json-parse-even-better-errors@2.3.1: {} @@ -6158,7 +5947,7 @@ snapshots: jsonfile@6.1.0: dependencies: - universalify: 2.0.0 + universalify: 2.0.1 optionalDependencies: graceful-fs: 4.2.11 @@ -6166,6 +5955,10 @@ snapshots: kdbush@4.0.2: {} + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + kind-of@6.0.3: {} lerc@3.0.0: {} @@ -6175,46 +5968,50 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - lightningcss-darwin-arm64@1.22.0: + lightningcss-darwin-arm64@1.28.2: optional: true - lightningcss-darwin-x64@1.22.0: + lightningcss-darwin-x64@1.28.2: optional: true - lightningcss-freebsd-x64@1.22.0: + lightningcss-freebsd-x64@1.28.2: optional: true - lightningcss-linux-arm-gnueabihf@1.22.0: + lightningcss-linux-arm-gnueabihf@1.28.2: optional: true - lightningcss-linux-arm64-gnu@1.22.0: + lightningcss-linux-arm64-gnu@1.28.2: optional: true - lightningcss-linux-arm64-musl@1.22.0: + lightningcss-linux-arm64-musl@1.28.2: optional: true - lightningcss-linux-x64-gnu@1.22.0: + lightningcss-linux-x64-gnu@1.28.2: optional: true - lightningcss-linux-x64-musl@1.22.0: + lightningcss-linux-x64-musl@1.28.2: optional: true - lightningcss-win32-x64-msvc@1.22.0: + lightningcss-win32-arm64-msvc@1.28.2: optional: true - lightningcss@1.22.0: + lightningcss-win32-x64-msvc@1.28.2: + optional: true + + lightningcss@1.28.2: dependencies: detect-libc: 1.0.3 optionalDependencies: - lightningcss-darwin-arm64: 1.22.0 - lightningcss-darwin-x64: 1.22.0 - lightningcss-freebsd-x64: 1.22.0 - lightningcss-linux-arm-gnueabihf: 1.22.0 - lightningcss-linux-arm64-gnu: 1.22.0 - lightningcss-linux-arm64-musl: 1.22.0 - lightningcss-linux-x64-gnu: 1.22.0 - lightningcss-linux-x64-musl: 1.22.0 - lightningcss-win32-x64-msvc: 1.22.0 + lightningcss-darwin-arm64: 1.28.2 + lightningcss-darwin-x64: 1.28.2 + lightningcss-freebsd-x64: 1.28.2 + lightningcss-linux-arm-gnueabihf: 1.28.2 + lightningcss-linux-arm64-gnu: 1.28.2 + lightningcss-linux-arm64-musl: 1.28.2 + lightningcss-linux-x64-gnu: 1.28.2 + lightningcss-linux-x64-musl: 1.28.2 + lightningcss-win32-arm64-msvc: 1.28.2 + lightningcss-win32-x64-msvc: 1.28.2 lines-and-columns@1.2.4: {} @@ -6243,14 +6040,14 @@ snapshots: dependencies: lodash._basetostring: 4.12.0 + lodash.camelcase@4.3.0: {} + lodash.debounce@4.0.8: {} lodash.isequal@4.5.0: {} lodash.merge@4.6.2: {} - lodash.pick@4.4.0: {} - lodash.throttle@4.1.1: {} lodash.uniqby@4.5.0: @@ -6268,13 +6065,9 @@ snapshots: dependencies: yallist: 3.1.1 - lru-cache@6.0.0: - dependencies: - yallist: 4.0.0 - lz-string@1.5.0: {} - mapbox-gl@3.6.0: + mapbox-gl@3.8.0: dependencies: '@mapbox/jsonlint-lines-primitives': 2.0.2 '@mapbox/mapbox-gl-supported': 3.0.0 @@ -6284,11 +6077,14 @@ snapshots: '@mapbox/vector-tile': 1.3.1 '@mapbox/whoots-js': 3.1.0 '@types/geojson': 7946.0.14 + '@types/geojson-vt': 3.2.5 + '@types/mapbox__point-geometry': 0.1.4 '@types/mapbox__vector-tile': 1.3.4 + '@types/pbf': 3.0.5 + '@types/supercluster': 7.1.3 cheap-ruler: 4.0.0 csscolorparser: 1.0.3 earcut: 3.0.0 - fflate: 0.8.2 geojson-vt: 4.0.2 gl-matrix: 3.4.3 grid-index: 1.1.0 @@ -6297,16 +6093,14 @@ snapshots: pbf: 3.3.0 potpack: 2.0.0 quickselect: 3.0.0 - rw: 1.3.3 serialize-to-js: 3.1.2 supercluster: 8.0.1 tinyqueue: 3.0.0 - tweakpane: 4.0.4 vt-pbf: 3.1.3 - mapbox-to-css-font@2.4.2: {} + mapbox-to-css-font@2.4.5: {} - maplibre-gl@4.5.2: + maplibre-gl@4.7.1: dependencies: '@mapbox/geojson-rewind': 0.5.2 '@mapbox/jsonlint-lines-primitives': 2.0.2 @@ -6315,7 +6109,7 @@ snapshots: '@mapbox/unitbezier': 0.0.1 '@mapbox/vector-tile': 1.3.1 '@mapbox/whoots-js': 3.1.0 - '@maplibre/maplibre-gl-style-spec': 20.3.1 + '@maplibre/maplibre-gl-style-spec': 20.4.0 '@types/geojson': 7946.0.14 '@types/geojson-vt': 3.2.5 '@types/mapbox__point-geometry': 0.1.4 @@ -6325,7 +6119,7 @@ snapshots: earcut: 3.0.0 geojson-vt: 4.0.2 gl-matrix: 3.4.3 - global-prefix: 3.0.0 + global-prefix: 4.0.0 kdbush: 4.0.2 murmurhash-js: 1.0.0 pbf: 3.3.0 @@ -6343,47 +6137,43 @@ snapshots: merge2@1.4.1: {} - micromatch@4.0.5: + micromatch@4.0.8: dependencies: - braces: 3.0.2 + braces: 3.0.3 picomatch: 2.3.1 - mime-db@1.52.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 - minimist@1.2.8: {} + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 - moment@2.29.4: {} + minimist@1.2.8: {} - ms@2.1.2: {} + moment@2.30.1: {} ms@2.1.3: {} murmurhash-js@1.0.0: {} - nanoid@3.3.6: {} + nanoid@3.3.8: {} natural-compare@1.4.0: {} ngeohash@0.6.3: {} - node-releases@2.0.13: {} + node-releases@2.0.18: {} normalize-path@3.0.0: {} - notistack@3.0.1(csstype@3.1.3)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + notistack@3.0.1(csstype@3.1.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: clsx: 1.2.1 - goober: 2.1.13(csstype@3.1.3) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + goober: 2.1.16(csstype@3.1.3) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) transitivePeerDependencies: - csstype @@ -6393,7 +6183,7 @@ snapshots: object-assign@4.1.1: {} - object-inspect@1.13.2: {} + object-inspect@1.13.3: {} object-keys@1.1.1: {} @@ -6401,46 +6191,36 @@ snapshots: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - has-symbols: 1.0.3 + has-symbols: 1.1.0 object-keys: 1.1.1 - oidc-client-ts@2.2.4: + oidc-client-ts@2.4.1: dependencies: - crypto-js: 4.1.1 + crypto-js: 4.2.0 jwt-decode: 3.1.2 ol-mapbox-style@10.7.0: dependencies: '@mapbox/mapbox-gl-style-spec': 13.28.0 - mapbox-to-css-font: 2.4.2 + mapbox-to-css-font: 2.4.5 ol: 7.5.2 ol@7.5.2: dependencies: earcut: 2.2.4 - geotiff: 2.0.7 + geotiff: 2.1.3 ol-mapbox-style: 10.7.0 pbf: 3.2.1 rbush: 3.0.1 - once@1.4.0: - dependencies: - wrappy: 1.0.2 - - open@8.4.2: - dependencies: - define-lazy-prop: 2.0.0 - is-docker: 2.2.1 - is-wsl: 2.2.0 - - optionator@0.9.3: + optionator@0.9.4: dependencies: - '@aashutoshrathi/word-wrap': 1.2.6 deep-is: 0.1.4 fast-levenshtein: 2.0.6 levn: 0.4.1 prelude-ls: 1.2.1 type-check: 0.4.0 + word-wrap: 1.2.5 p-limit@3.1.0: dependencies: @@ -6460,15 +6240,13 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.22.10 + '@babel/code-frame': 7.26.2 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 path-exists@4.0.0: {} - path-is-absolute@1.0.1: {} - path-key@3.1.1: {} path-parse@1.0.7: {} @@ -6485,15 +6263,15 @@ snapshots: ieee754: 1.2.1 resolve-protobuf-schema: 2.1.0 - picocolors@1.0.0: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} - playwright-core@1.42.1: {} + playwright-core@1.49.0: {} - playwright@1.42.1: + playwright@1.49.0: dependencies: - playwright-core: 1.42.1 + playwright-core: 1.49.0 optionalDependencies: fsevents: 2.3.2 @@ -6501,23 +6279,23 @@ snapshots: postcss-value-parser@4.2.0: {} - postcss@8.4.28: + postcss@8.4.49: dependencies: - nanoid: 3.3.6 - picocolors: 1.0.0 - source-map-js: 1.0.2 + nanoid: 3.3.8 + picocolors: 1.1.1 + source-map-js: 1.2.1 potpack@2.0.0: {} prelude-ls@1.2.1: {} - prettier@3.1.0: {} + prettier@3.4.2: {} - pretty-format@29.6.3: + pretty-format@29.7.0: dependencies: '@jest/schemas': 29.6.3 ansi-styles: 5.2.0 - react-is: 18.2.0 + react-is: 18.3.1 prop-types@15.8.1: dependencies: @@ -6533,9 +6311,7 @@ snapshots: protocol-buffers-schema@3.6.0: {} - proxy-from-env@1.1.0: {} - - punycode@2.3.0: {} + punycode@2.3.1: {} querystringify@2.2.0: {} @@ -6551,90 +6327,88 @@ snapshots: dependencies: quickselect: 2.0.0 - react-dom@18.2.0(react@18.2.0): + react-dom@18.3.1(react@18.3.1): dependencies: loose-envify: 1.4.0 - react: 18.2.0 - scheduler: 0.23.0 + react: 18.3.1 + scheduler: 0.23.2 - react-dropzone@14.2.3(react@18.2.0): + react-dropzone@14.3.5(react@18.3.1): dependencies: - attr-accept: 2.2.2 - file-selector: 0.6.0 + attr-accept: 2.2.5 + file-selector: 2.1.2 prop-types: 15.8.1 - react: 18.2.0 + react: 18.3.1 - react-i18next@13.0.3(i18next@23.4.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + react-i18next@13.5.0(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.26.0 html-parse-stringify: 3.0.1 - i18next: 23.4.1 - react: 18.2.0 + i18next: 23.16.8 + react: 18.3.1 optionalDependencies: - react-dom: 18.2.0(react@18.2.0) + react-dom: 18.3.1(react@18.3.1) react-is@16.13.1: {} - react-is@18.2.0: {} - react-is@18.3.1: {} - react-map-gl@7.1.7(mapbox-gl@3.6.0)(maplibre-gl@4.5.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + react-map-gl@7.1.7(mapbox-gl@3.8.0)(maplibre-gl@4.7.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@maplibre/maplibre-gl-style-spec': 19.3.3 - '@types/mapbox-gl': 3.4.0 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + '@types/mapbox-gl': 3.4.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - mapbox-gl: 3.6.0 - maplibre-gl: 4.5.2 + mapbox-gl: 3.8.0 + maplibre-gl: 4.7.1 - react-oidc-context@2.2.2(oidc-client-ts@2.2.4)(react@18.2.0): + react-oidc-context@2.4.0(oidc-client-ts@2.4.1)(react@18.3.1): dependencies: - oidc-client-ts: 2.2.4 - react: 18.2.0 + oidc-client-ts: 2.4.1 + react: 18.3.1 - react-property@2.0.0: {} + react-property@2.0.2: {} - react-redux@8.1.2(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(redux@4.2.1): + react-redux@8.1.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(redux@4.2.1): dependencies: - '@babel/runtime': 7.23.2 - '@types/hoist-non-react-statics': 3.3.1 + '@babel/runtime': 7.26.0 + '@types/hoist-non-react-statics': 3.3.5 '@types/use-sync-external-store': 0.0.3 hoist-non-react-statics: 3.3.2 - react: 18.2.0 - react-is: 18.2.0 - use-sync-external-store: 1.2.0(react@18.2.0) + react: 18.3.1 + react-is: 18.3.1 + use-sync-external-store: 1.2.2(react@18.3.1) optionalDependencies: - '@types/react': 18.2.15 - '@types/react-dom': 18.2.7 - react-dom: 18.2.0(react@18.2.0) + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 + react-dom: 18.3.1(react@18.3.1) redux: 4.2.1 - react-refresh@0.14.0: {} + react-refresh@0.14.2: {} - react-router-dom@6.14.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + react-router-dom@6.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@remix-run/router': 1.7.2 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-router: 6.14.2(react@18.2.0) + '@remix-run/router': 1.21.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-router: 6.28.0(react@18.3.1) - react-router@6.14.2(react@18.2.0): + react-router@6.28.0(react@18.3.1): dependencies: - '@remix-run/router': 1.7.2 - react: 18.2.0 + '@remix-run/router': 1.21.0 + react: 18.3.1 - react-transition-group@4.4.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + react-transition-group@4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.26.0 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - react@18.2.0: + react@18.3.1: dependencies: loose-envify: 1.4.0 @@ -6648,21 +6422,27 @@ snapshots: redux@4.2.1: dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.26.0 - regenerator-runtime@0.14.0: {} + reflect.getprototypeof@1.0.7: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.5 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + gopd: 1.1.0 + which-builtin-type: 1.2.0 regenerator-runtime@0.14.1: {} - regexp.prototype.flags@1.5.2: + regexp.prototype.flags@1.5.3: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-errors: 1.3.0 set-function-name: 2.0.2 - require-directory@2.1.1: {} - requires-port@1.0.0: {} reselect@4.1.8: {} @@ -6673,9 +6453,9 @@ snapshots: dependencies: protocol-buffers-schema: 3.6.0 - resolve@1.22.4: + resolve@1.22.8: dependencies: - is-core-module: 2.13.0 + is-core-module: 2.15.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 @@ -6683,20 +6463,7 @@ snapshots: reusify@1.0.4: {} - rimraf@3.0.2: - dependencies: - glob: 7.2.3 - - rollup-plugin-visualizer@5.12.0(rollup@3.28.1): - dependencies: - open: 8.4.2 - picomatch: 2.3.1 - source-map: 0.7.4 - yargs: 17.7.2 - optionalDependencies: - rollup: 3.28.1 - - rollup@3.28.1: + rollup@3.29.5: optionalDependencies: fsevents: 2.3.3 @@ -6712,16 +6479,16 @@ snapshots: dependencies: call-bind: 1.0.7 get-intrinsic: 1.2.4 - has-symbols: 1.0.3 + has-symbols: 1.1.0 isarray: 2.0.5 safe-regex-test@1.0.3: dependencies: call-bind: 1.0.7 es-errors: 1.3.0 - is-regex: 1.1.4 + is-regex: 1.2.0 - scheduler@0.23.0: + scheduler@0.23.2: dependencies: loose-envify: 1.4.0 @@ -6729,9 +6496,7 @@ snapshots: semver@6.3.1: {} - semver@7.5.4: - dependencies: - lru-cache: 6.0.0 + semver@7.6.3: {} serialize-to-js@3.1.2: {} @@ -6741,7 +6506,7 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 get-intrinsic: 1.2.4 - gopd: 1.0.1 + gopd: 1.1.0 has-property-descriptors: 1.0.2 set-function-name@2.0.2: @@ -6771,7 +6536,7 @@ snapshots: call-bind: 1.0.7 es-errors: 1.3.0 get-intrinsic: 1.2.4 - object-inspect: 1.13.2 + object-inspect: 1.13.3 signal-exit@3.0.7: {} @@ -6799,12 +6564,10 @@ snapshots: sort-desc: 0.2.0 union-value: 1.0.1 - source-map-js@1.0.2: {} + source-map-js@1.2.1: {} source-map@0.5.7: {} - source-map@0.7.4: {} - split-string@3.1.0: dependencies: extend-shallow: 3.0.2 @@ -6817,17 +6580,11 @@ snapshots: dependencies: escape-string-regexp: 2.0.0 - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - string.prototype.trim@1.2.9: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.23.3 + es-abstract: 1.23.5 es-object-atoms: 1.0.0 string.prototype.trimend@1.0.8: @@ -6850,26 +6607,26 @@ snapshots: strnum@1.0.5: {} - style-to-js@1.1.4: + style-to-js@1.1.8: dependencies: - style-to-object: 0.4.2 + style-to-object: 1.0.3 - style-to-object@0.4.2: + style-to-object@1.0.3: dependencies: - inline-style-parser: 0.1.1 + inline-style-parser: 0.2.2 - styled-components@5.3.10(@babel/core@7.22.10)(react-dom@18.2.0(react@18.2.0))(react-is@18.3.1)(react@18.2.0): + styled-components@5.3.11(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1): dependencies: - '@babel/helper-module-imports': 7.22.5 - '@babel/traverse': 7.22.10(supports-color@5.5.0) - '@emotion/is-prop-valid': 1.2.1 + '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) + '@babel/traverse': 7.25.9(supports-color@5.5.0) + '@emotion/is-prop-valid': 1.3.1 '@emotion/stylis': 0.8.5 '@emotion/unitless': 0.7.5 - babel-plugin-styled-components: 2.1.4(@babel/core@7.22.10)(styled-components@5.3.10(@babel/core@7.22.10)(react-dom@18.2.0(react@18.2.0))(react-is@18.3.1)(react@18.2.0)) + babel-plugin-styled-components: 2.1.4(@babel/core@7.26.0)(styled-components@5.3.11(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1))(supports-color@5.5.0) css-to-react-native: 3.2.0 hoist-non-react-statics: 3.3.2 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) react-is: 18.3.1 shallowequal: 1.1.0 supports-color: 5.5.0 @@ -6892,60 +6649,61 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - text-table@0.2.0: {} + table-layout@4.1.1: + dependencies: + array-back: 6.2.2 + wordwrapjs: 5.1.0 - tiny-invariant@1.3.1: {} + tiny-invariant@1.3.3: {} tinyqueue@3.0.0: {} - to-fast-properties@2.0.0: {} - to-regex-range@5.0.1: dependencies: is-number: 7.0.0 - traverse@0.6.9: + traverse@0.6.10: dependencies: - gopd: 1.0.1 + gopd: 1.1.0 typedarray.prototype.slice: 1.0.3 - which-typed-array: 1.1.15 + which-typed-array: 1.1.16 - ts-api-utils@1.0.2(typescript@5.1.6): + ts-api-utils@1.4.3(typescript@5.7.2): dependencies: - typescript: 5.1.6 + typescript: 5.7.2 tslib@2.3.0: {} - tslib@2.6.2: {} + tslib@2.8.1: {} - turbo-darwin-64@1.10.16: + turbo-darwin-64@1.13.4: optional: true - turbo-darwin-arm64@1.10.16: + turbo-darwin-arm64@1.13.4: optional: true - turbo-linux-64@1.10.16: + turbo-linux-64@1.13.4: optional: true - turbo-linux-arm64@1.10.16: + turbo-linux-arm64@1.13.4: optional: true - turbo-windows-64@1.10.16: + turbo-windows-64@1.13.4: optional: true - turbo-windows-arm64@1.10.16: + turbo-windows-arm64@1.13.4: optional: true - turbo@1.10.16: + turbo@1.13.4: optionalDependencies: - turbo-darwin-64: 1.10.16 - turbo-darwin-arm64: 1.10.16 - turbo-linux-64: 1.10.16 - turbo-linux-arm64: 1.10.16 - turbo-windows-64: 1.10.16 - turbo-windows-arm64: 1.10.16 + turbo-darwin-64: 1.13.4 + turbo-darwin-arm64: 1.13.4 + turbo-linux-64: 1.13.4 + turbo-linux-arm64: 1.13.4 + turbo-windows-64: 1.13.4 + turbo-windows-arm64: 1.13.4 - tus-js-client@4.1.0: + tus-js-client@4.2.3: dependencies: buffer-from: 1.1.2 combine-errors: 3.0.3 @@ -6955,14 +6713,10 @@ snapshots: proper-lockfile: 4.1.2 url-parse: 1.5.10 - tweakpane@4.0.4: {} - type-check@0.4.0: dependencies: prelude-ls: 1.2.1 - type-fest@0.20.2: {} - type-fest@0.21.3: {} typed-array-buffer@1.0.2: @@ -6975,38 +6729,39 @@ snapshots: dependencies: call-bind: 1.0.7 for-each: 0.3.3 - gopd: 1.0.1 - has-proto: 1.0.3 + gopd: 1.1.0 + has-proto: 1.1.0 is-typed-array: 1.1.13 - typed-array-byte-offset@1.0.2: + typed-array-byte-offset@1.0.3: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.7 for-each: 0.3.3 - gopd: 1.0.1 - has-proto: 1.0.3 + gopd: 1.1.0 + has-proto: 1.1.0 is-typed-array: 1.1.13 + reflect.getprototypeof: 1.0.7 - typed-array-length@1.0.6: + typed-array-length@1.0.7: dependencies: call-bind: 1.0.7 for-each: 0.3.3 - gopd: 1.0.1 - has-proto: 1.0.3 + gopd: 1.1.0 is-typed-array: 1.1.13 possible-typed-array-names: 1.0.0 + reflect.getprototypeof: 1.0.7 typedarray.prototype.slice@1.0.3: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.23.3 + es-abstract: 1.23.5 es-errors: 1.3.0 typed-array-buffer: 1.0.2 - typed-array-byte-offset: 1.0.2 + typed-array-byte-offset: 1.0.3 - typescript@5.1.6: {} + typescript@5.7.2: {} typewise-core@1.2.0: {} @@ -7014,18 +6769,20 @@ snapshots: dependencies: typewise-core: 1.2.0 + typical@4.0.0: {} + + typical@7.3.0: {} + unbox-primitive@1.0.2: dependencies: call-bind: 1.0.7 has-bigints: 1.0.2 - has-symbols: 1.0.3 - which-boxed-primitive: 1.0.2 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.0 - undici-types@5.26.5: {} + undici-types@6.19.8: {} - undici@5.25.4: - dependencies: - '@fastify/busboy': 2.0.0 + undici@6.21.0: {} union-value@1.0.1: dependencies: @@ -7034,67 +6791,65 @@ snapshots: is-extendable: 0.1.1 set-value: 2.0.1 - universalify@2.0.0: {} + universalify@2.0.1: {} - update-browserslist-db@1.0.11(browserslist@4.21.10): + update-browserslist-db@1.1.1(browserslist@4.24.2): dependencies: - browserslist: 4.21.10 - escalade: 3.1.1 - picocolors: 1.0.0 + browserslist: 4.24.2 + escalade: 3.2.0 + picocolors: 1.1.1 uri-js@4.4.1: dependencies: - punycode: 2.3.0 + punycode: 2.3.1 url-parse@1.5.10: dependencies: querystringify: 2.2.0 requires-port: 1.0.0 - use-debounce@9.0.4(react@18.2.0): + use-debounce@9.0.4(react@18.3.1): dependencies: - react: 18.2.0 + react: 18.3.1 - use-sync-external-store@1.2.0(react@18.2.0): + use-sync-external-store@1.2.2(react@18.3.1): dependencies: - react: 18.2.0 + react: 18.3.1 - uuid@9.0.0: {} + uuid@9.0.1: {} - vite-plugin-checker@0.6.2(eslint@8.54.0)(optionator@0.9.3)(typescript@5.1.6)(vite@4.4.5(@types/node@20.11.30)(lightningcss@1.22.0)): + vite-plugin-checker@0.6.4(eslint@9.16.0)(optionator@0.9.4)(typescript@5.7.2)(vite@4.5.5(@types/node@20.17.9)(lightningcss@1.28.2)): dependencies: - '@babel/code-frame': 7.22.10 + '@babel/code-frame': 7.26.2 ansi-escapes: 4.3.2 chalk: 4.1.2 - chokidar: 3.5.3 + chokidar: 3.6.0 commander: 8.3.0 - fast-glob: 3.3.1 - fs-extra: 11.1.1 - lodash.debounce: 4.0.8 - lodash.pick: 4.4.0 + fast-glob: 3.3.2 + fs-extra: 11.2.0 npm-run-path: 4.0.1 - semver: 7.5.4 + semver: 7.6.3 strip-ansi: 6.0.1 - tiny-invariant: 1.3.1 - vite: 4.4.5(@types/node@20.11.30)(lightningcss@1.22.0) + tiny-invariant: 1.3.3 + vite: 4.5.5(@types/node@20.17.9)(lightningcss@1.28.2) vscode-languageclient: 7.0.0 vscode-languageserver: 7.0.0 - vscode-languageserver-textdocument: 1.0.8 - vscode-uri: 3.0.7 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.0.8 optionalDependencies: - eslint: 8.54.0 - optionator: 0.9.3 - typescript: 5.1.6 + eslint: 9.16.0 + optionator: 0.9.4 + typescript: 5.7.2 - vite@4.4.5(@types/node@20.11.30)(lightningcss@1.22.0): + vite@4.5.5(@types/node@20.17.9)(lightningcss@1.28.2): dependencies: esbuild: 0.18.20 - postcss: 8.4.28 - rollup: 3.28.1 + postcss: 8.4.49 + rollup: 3.29.5 optionalDependencies: - '@types/node': 20.11.30 + '@types/node': 20.17.9 fsevents: 2.3.3 - lightningcss: 1.22.0 + lightningcss: 1.28.2 void-elements@3.1.0: {} @@ -7103,7 +6858,7 @@ snapshots: vscode-languageclient@7.0.0: dependencies: minimatch: 3.1.2 - semver: 7.5.4 + semver: 7.6.3 vscode-languageserver-protocol: 3.16.0 vscode-languageserver-protocol@3.16.0: @@ -7111,7 +6866,7 @@ snapshots: vscode-jsonrpc: 6.0.0 vscode-languageserver-types: 3.16.0 - vscode-languageserver-textdocument@1.0.8: {} + vscode-languageserver-textdocument@1.0.12: {} vscode-languageserver-types@3.16.0: {} @@ -7119,7 +6874,7 @@ snapshots: dependencies: vscode-languageserver-protocol: 3.16.0 - vscode-uri@3.0.7: {} + vscode-uri@3.0.8: {} vt-pbf@3.1.3: dependencies: @@ -7127,47 +6882,66 @@ snapshots: '@mapbox/vector-tile': 1.3.1 pbf: 3.3.0 - web-vitals@3.4.0: {} + web-vitals@3.5.2: {} - web-worker@1.2.0: {} + web-worker@1.3.0: {} wgs84@0.0.0: {} - which-boxed-primitive@1.0.2: + which-boxed-primitive@1.1.0: dependencies: - is-bigint: 1.0.4 - is-boolean-object: 1.1.2 - is-number-object: 1.0.7 - is-string: 1.0.7 - is-symbol: 1.0.4 + is-bigint: 1.1.0 + is-boolean-object: 1.2.0 + is-number-object: 1.1.0 + is-string: 1.1.0 + is-symbol: 1.1.0 - which-typed-array@1.1.15: + which-builtin-type@1.2.0: + dependencies: + call-bind: 1.0.7 + function.prototype.name: 1.1.6 + has-tostringtag: 1.0.2 + is-async-function: 2.0.0 + is-date-object: 1.0.5 + is-finalizationregistry: 1.1.0 + is-generator-function: 1.0.10 + is-regex: 1.2.0 + is-weakref: 1.0.2 + isarray: 2.0.5 + which-boxed-primitive: 1.1.0 + which-collection: 1.0.2 + which-typed-array: 1.1.16 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.3 + + which-typed-array@1.1.16: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.7 for-each: 0.3.3 - gopd: 1.0.1 + gopd: 1.1.0 has-tostringtag: 1.0.2 - which@1.3.1: + which@2.0.2: dependencies: isexe: 2.0.0 - which@2.0.2: + which@4.0.0: dependencies: - isexe: 2.0.0 + isexe: 3.1.1 wmf@1.0.2: {} - word@0.3.0: {} + word-wrap@1.2.5: {} - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 + word@0.3.0: {} - wrappy@1.0.2: {} + wordwrapjs@5.1.0: {} xlsx@0.18.5: dependencies: @@ -7179,32 +6953,18 @@ snapshots: wmf: 1.0.2 word: 0.3.0 - xml-utils@1.7.0: {} + xml-utils@1.10.1: {} xtend@4.0.2: {} - y18n@5.0.8: {} - yallist@3.1.1: {} - yallist@4.0.0: {} - yaml@1.10.2: {} - yargs-parser@21.1.1: {} - - yargs@17.7.2: - 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.8 - yargs-parser: 21.1.1 - yocto-queue@0.1.0: {} - zrender@5.4.4: + zrender@5.6.0: dependencies: tslib: 2.3.0 + + zstddec@0.1.0: {} From 83b641dc0a633c03891d04e293039eab069d5ad8 Mon Sep 17 00:00:00 2001 From: D-Unit Date: Wed, 4 Dec 2024 10:50:16 +0100 Subject: [PATCH 40/44] fixed deps --- apps/cat/src/config/elasticSearch.tsx | 3 ++- apps/digitaltwins/vite.config.ts | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/cat/src/config/elasticSearch.tsx b/apps/cat/src/config/elasticSearch.tsx index 6b675f71..37be8aed 100644 --- a/apps/cat/src/config/elasticSearch.tsx +++ b/apps/cat/src/config/elasticSearch.tsx @@ -1,6 +1,7 @@ import { PieChartFacet, ListFacet, + type EndpointProps, type RDTSearchUIProps, } from "@dans-framework/rdt-search-ui"; import { Cat2Result } from "../pages/search/result"; @@ -20,7 +21,7 @@ const fieldConfig: Partial = { * The config is for larger screens. For mobile, we use half width and full width cols. */ -export const elasticConfig = [ +export const elasticConfig: EndpointProps[] = [ { name: "CAT Catalogue", url: "https://es.ohsmart.dansdemo.nl/fc4e-cat", diff --git a/apps/digitaltwins/vite.config.ts b/apps/digitaltwins/vite.config.ts index a7ccd768..292a5edf 100644 --- a/apps/digitaltwins/vite.config.ts +++ b/apps/digitaltwins/vite.config.ts @@ -1,7 +1,6 @@ import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; import checker from "vite-plugin-checker"; -import { visualizer } from "rollup-plugin-visualizer"; // https://vitejs.dev/config/ export default defineConfig({ @@ -10,6 +9,5 @@ export default defineConfig({ checker({ typescript: true, }), - visualizer(), ], }); From 33ce5e040d50d52a513e5bb54400803ddb3cd668 Mon Sep 17 00:00:00 2001 From: D-Unit Date: Wed, 4 Dec 2024 14:09:13 +0100 Subject: [PATCH 41/44] changed vite config rda --- apps/rda/vite.config.ts | 18 ++- pnpm-lock.yaml | 261 +--------------------------------------- 2 files changed, 11 insertions(+), 268 deletions(-) diff --git a/apps/rda/vite.config.ts b/apps/rda/vite.config.ts index e8608ed2..292a5edf 100644 --- a/apps/rda/vite.config.ts +++ b/apps/rda/vite.config.ts @@ -3,13 +3,11 @@ import react from "@vitejs/plugin-react"; import checker from "vite-plugin-checker"; // https://vitejs.dev/config/ -export default () => { - return defineConfig({ - plugins: [ - react(), - checker({ - typescript: true, - }), - ], - }); -}; +export default defineConfig({ + plugins: [ + react(), + checker({ + typescript: true, + }), + ], +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6fa5040a..ca3bc4ce 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -866,18 +866,6 @@ importers: '@types/styled-components': specifier: ^5.1.26 version: 5.1.34 - esbuild: - specifier: ^0.17.15 - version: 0.17.19 - esbuild-css-modules-plugin: - specifier: ^3.0.2 - version: 3.1.2(esbuild@0.17.19) - tslib: - specifier: ^2.5.0 - version: 2.8.1 - typescript: - specifier: ^5.0.3 - version: 5.7.2 vite: specifier: ^4.4.5 version: 4.5.5(@types/node@20.17.9)(lightningcss@1.28.2) @@ -1242,264 +1230,132 @@ packages: '@emotion/weak-memoize@0.4.0': resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==} - '@esbuild/android-arm64@0.17.19': - resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - '@esbuild/android-arm64@0.18.20': resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} engines: {node: '>=12'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.17.19': - resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - '@esbuild/android-arm@0.18.20': resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} engines: {node: '>=12'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.17.19': - resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - '@esbuild/android-x64@0.18.20': resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} engines: {node: '>=12'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.17.19': - resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - '@esbuild/darwin-arm64@0.18.20': resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.17.19': - resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - '@esbuild/darwin-x64@0.18.20': resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} engines: {node: '>=12'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.17.19': - resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - '@esbuild/freebsd-arm64@0.18.20': resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.17.19': - resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - '@esbuild/freebsd-x64@0.18.20': resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.17.19': - resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - '@esbuild/linux-arm64@0.18.20': resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} engines: {node: '>=12'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.17.19': - resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - '@esbuild/linux-arm@0.18.20': resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} engines: {node: '>=12'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.17.19': - resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - '@esbuild/linux-ia32@0.18.20': resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} engines: {node: '>=12'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.17.19': - resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - '@esbuild/linux-loong64@0.18.20': resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} engines: {node: '>=12'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.17.19': - resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - '@esbuild/linux-mips64el@0.18.20': resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.17.19': - resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - '@esbuild/linux-ppc64@0.18.20': resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.17.19': - resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - '@esbuild/linux-riscv64@0.18.20': resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.17.19': - resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - '@esbuild/linux-s390x@0.18.20': resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} engines: {node: '>=12'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.17.19': - resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - '@esbuild/linux-x64@0.18.20': resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} engines: {node: '>=12'} cpu: [x64] os: [linux] - '@esbuild/netbsd-x64@0.17.19': - resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - '@esbuild/netbsd-x64@0.18.20': resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-x64@0.17.19': - resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - '@esbuild/openbsd-x64@0.18.20': resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] - '@esbuild/sunos-x64@0.17.19': - resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - '@esbuild/sunos-x64@0.18.20': resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} engines: {node: '>=12'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.17.19': - resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - '@esbuild/win32-arm64@0.18.20': resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} engines: {node: '>=12'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.17.19': - resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - '@esbuild/win32-ia32@0.18.20': resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} engines: {node: '>=12'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.17.19': - resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - '@esbuild/win32-x64@0.18.20': resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} engines: {node: '>=12'} @@ -2392,17 +2248,6 @@ packages: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} - esbuild-css-modules-plugin@3.1.2: - resolution: {integrity: sha512-XRpRuRT3m1Pk456djTvrq1AOEj+OB8sa8PdGN/Yha6eL8Im0TIYPq0CELgQU6DDKkHlYET++3sXZVjiF/kcgQw==} - engines: {node: '>= 16.20.0'} - peerDependencies: - esbuild: '*' - - esbuild@0.17.19: - resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} - engines: {node: '>=12'} - hasBin: true - esbuild@0.18.20: resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} engines: {node: '>=12'} @@ -3046,9 +2891,6 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} - lodash-es@4.17.21: - resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} - lodash._baseiteratee@4.7.0: resolution: {integrity: sha512-nqB9M+wITz0BX/Q2xg6fQ8mLkyfF7MU7eE+MNBNjTHFKeKaZAPEzEg+E8LWxKWf1DQVflNEn9N49yAuqKh2mWQ==} @@ -4217,135 +4059,69 @@ snapshots: '@emotion/weak-memoize@0.4.0': {} - '@esbuild/android-arm64@0.17.19': - optional: true - '@esbuild/android-arm64@0.18.20': optional: true - '@esbuild/android-arm@0.17.19': - optional: true - '@esbuild/android-arm@0.18.20': optional: true - '@esbuild/android-x64@0.17.19': - optional: true - '@esbuild/android-x64@0.18.20': optional: true - '@esbuild/darwin-arm64@0.17.19': - optional: true - '@esbuild/darwin-arm64@0.18.20': optional: true - '@esbuild/darwin-x64@0.17.19': - optional: true - '@esbuild/darwin-x64@0.18.20': optional: true - '@esbuild/freebsd-arm64@0.17.19': - optional: true - '@esbuild/freebsd-arm64@0.18.20': optional: true - '@esbuild/freebsd-x64@0.17.19': - optional: true - '@esbuild/freebsd-x64@0.18.20': optional: true - '@esbuild/linux-arm64@0.17.19': - optional: true - '@esbuild/linux-arm64@0.18.20': optional: true - '@esbuild/linux-arm@0.17.19': - optional: true - '@esbuild/linux-arm@0.18.20': optional: true - '@esbuild/linux-ia32@0.17.19': - optional: true - '@esbuild/linux-ia32@0.18.20': optional: true - '@esbuild/linux-loong64@0.17.19': - optional: true - '@esbuild/linux-loong64@0.18.20': optional: true - '@esbuild/linux-mips64el@0.17.19': - optional: true - '@esbuild/linux-mips64el@0.18.20': optional: true - '@esbuild/linux-ppc64@0.17.19': - optional: true - '@esbuild/linux-ppc64@0.18.20': optional: true - '@esbuild/linux-riscv64@0.17.19': - optional: true - '@esbuild/linux-riscv64@0.18.20': optional: true - '@esbuild/linux-s390x@0.17.19': - optional: true - '@esbuild/linux-s390x@0.18.20': optional: true - '@esbuild/linux-x64@0.17.19': - optional: true - '@esbuild/linux-x64@0.18.20': optional: true - '@esbuild/netbsd-x64@0.17.19': - optional: true - '@esbuild/netbsd-x64@0.18.20': optional: true - '@esbuild/openbsd-x64@0.17.19': - optional: true - '@esbuild/openbsd-x64@0.18.20': optional: true - '@esbuild/sunos-x64@0.17.19': - optional: true - '@esbuild/sunos-x64@0.18.20': optional: true - '@esbuild/win32-arm64@0.17.19': - optional: true - '@esbuild/win32-arm64@0.18.20': optional: true - '@esbuild/win32-ia32@0.17.19': - optional: true - '@esbuild/win32-ia32@0.18.20': optional: true - '@esbuild/win32-x64@0.17.19': - optional: true - '@esbuild/win32-x64@0.18.20': optional: true @@ -5232,7 +5008,8 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 - detect-libc@1.0.3: {} + detect-libc@1.0.3: + optional: true diff-sequences@29.6.3: {} @@ -5347,37 +5124,6 @@ snapshots: is-date-object: 1.0.5 is-symbol: 1.1.0 - esbuild-css-modules-plugin@3.1.2(esbuild@0.17.19): - dependencies: - esbuild: 0.17.19 - lightningcss: 1.28.2 - lodash-es: 4.17.21 - - esbuild@0.17.19: - optionalDependencies: - '@esbuild/android-arm': 0.17.19 - '@esbuild/android-arm64': 0.17.19 - '@esbuild/android-x64': 0.17.19 - '@esbuild/darwin-arm64': 0.17.19 - '@esbuild/darwin-x64': 0.17.19 - '@esbuild/freebsd-arm64': 0.17.19 - '@esbuild/freebsd-x64': 0.17.19 - '@esbuild/linux-arm': 0.17.19 - '@esbuild/linux-arm64': 0.17.19 - '@esbuild/linux-ia32': 0.17.19 - '@esbuild/linux-loong64': 0.17.19 - '@esbuild/linux-mips64el': 0.17.19 - '@esbuild/linux-ppc64': 0.17.19 - '@esbuild/linux-riscv64': 0.17.19 - '@esbuild/linux-s390x': 0.17.19 - '@esbuild/linux-x64': 0.17.19 - '@esbuild/netbsd-x64': 0.17.19 - '@esbuild/openbsd-x64': 0.17.19 - '@esbuild/sunos-x64': 0.17.19 - '@esbuild/win32-arm64': 0.17.19 - '@esbuild/win32-ia32': 0.17.19 - '@esbuild/win32-x64': 0.17.19 - esbuild@0.18.20: optionalDependencies: '@esbuild/android-arm': 0.18.20 @@ -6012,6 +5758,7 @@ snapshots: lightningcss-linux-x64-musl: 1.28.2 lightningcss-win32-arm64-msvc: 1.28.2 lightningcss-win32-x64-msvc: 1.28.2 + optional: true lines-and-columns@1.2.4: {} @@ -6019,8 +5766,6 @@ snapshots: dependencies: p-locate: 5.0.0 - lodash-es@4.17.21: {} - lodash._baseiteratee@4.7.0: dependencies: lodash._stringtopath: 4.8.0 From dda2f9a8293c38226118aef4631f0af58c86f5dc Mon Sep 17 00:00:00 2001 From: D-Unit Date: Wed, 4 Dec 2024 14:10:38 +0100 Subject: [PATCH 42/44] changed vite config cat --- apps/cat/vite.config.ts | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/apps/cat/vite.config.ts b/apps/cat/vite.config.ts index e8608ed2..292a5edf 100644 --- a/apps/cat/vite.config.ts +++ b/apps/cat/vite.config.ts @@ -3,13 +3,11 @@ import react from "@vitejs/plugin-react"; import checker from "vite-plugin-checker"; // https://vitejs.dev/config/ -export default () => { - return defineConfig({ - plugins: [ - react(), - checker({ - typescript: true, - }), - ], - }); -}; +export default defineConfig({ + plugins: [ + react(), + checker({ + typescript: true, + }), + ], +}); From c376ddf8ae026b89ea6dbca4826578a37a328c93 Mon Sep 17 00:00:00 2001 From: D-Unit Date: Wed, 4 Dec 2024 14:16:52 +0100 Subject: [PATCH 43/44] added typescript dep back to root package.json --- package.json | 3 ++- pnpm-lock.yaml | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 797f8194..d2f1956d 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,8 @@ "@dans-framework/eslint-config": "workspace:*", "@dans-framework/typescript-config": "workspace:*", "@types/node": "^20.11.27", - "turbo": "^1.13.4" + "turbo": "^1.13.4", + "typescript": "^5.7.2" }, "packageManager": "pnpm@8.6.12" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ca3bc4ce..72920dc0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,9 @@ importers: turbo: specifier: ^1.13.4 version: 1.13.4 + typescript: + specifier: ^5.7.2 + version: 5.7.2 apps/4tu: dependencies: From d745b1fe00161cb68b4e8f523e7bab90ff5af306 Mon Sep 17 00:00:00 2001 From: D-Unit Date: Wed, 4 Dec 2024 14:37:20 +0100 Subject: [PATCH 44/44] updated usersubmssion component props for all apps --- apps/4tu/src/App.tsx | 2 +- apps/cat/src/App.tsx | 2 +- apps/digitaltwins/src/App.tsx | 2 +- apps/rda/src/App.tsx | 2 +- apps/swh/src/App.tsx | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/4tu/src/App.tsx b/apps/4tu/src/App.tsx index 4a5fbd77..9f3fae32 100644 --- a/apps/4tu/src/App.tsx +++ b/apps/4tu/src/App.tsx @@ -89,7 +89,7 @@ const App = () => { element={ {repoConfig ? - + : } } diff --git a/apps/cat/src/App.tsx b/apps/cat/src/App.tsx index fde27d9f..88677abb 100644 --- a/apps/cat/src/App.tsx +++ b/apps/cat/src/App.tsx @@ -76,7 +76,7 @@ const App = () => { path="user-submissions" element={ - + } /> diff --git a/apps/digitaltwins/src/App.tsx b/apps/digitaltwins/src/App.tsx index fc7a993e..118c305b 100644 --- a/apps/digitaltwins/src/App.tsx +++ b/apps/digitaltwins/src/App.tsx @@ -67,7 +67,7 @@ const App = () => { path="user-submissions" element={ - + } /> diff --git a/apps/rda/src/App.tsx b/apps/rda/src/App.tsx index 78044605..414768da 100644 --- a/apps/rda/src/App.tsx +++ b/apps/rda/src/App.tsx @@ -87,7 +87,7 @@ const App = () => { path="user-submissions" element={ - + } /> diff --git a/apps/swh/src/App.tsx b/apps/swh/src/App.tsx index 7ff05452..34f051c0 100644 --- a/apps/swh/src/App.tsx +++ b/apps/swh/src/App.tsx @@ -62,7 +62,7 @@ const App = () => { path="user-submissions" element={ - + } />