From d1c212df4d03e8bf08aa7a8a19e49c9e7025e890 Mon Sep 17 00:00:00 2001 From: fnbellomo Date: Sun, 18 Dec 2022 10:40:19 -0300 Subject: [PATCH 001/121] fix(typescript): Fix typescript no strict mode --- plugins/lime-plugin-locate/index.ts | 8 - plugins/lime-plugin-locate/src/locatePage.tsx | 239 ------------------ .../config/{config.js => config.tsx} | 22 +- 3 files changed, 15 insertions(+), 254 deletions(-) delete mode 100755 plugins/lime-plugin-locate/index.ts delete mode 100644 plugins/lime-plugin-locate/src/locatePage.tsx rename plugins/lime-plugin-node-admin/src/components/config/{config.js => config.tsx} (50%) diff --git a/plugins/lime-plugin-locate/index.ts b/plugins/lime-plugin-locate/index.ts deleted file mode 100755 index fc2045db2..000000000 --- a/plugins/lime-plugin-locate/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { LocateMenu } from "./src/locateMenu"; -import Locate from "./src/locatePage"; - -export default { - name: "Locate", - page: Locate, - menu: LocateMenu, -} as LimePlugin; diff --git a/plugins/lime-plugin-locate/src/locatePage.tsx b/plugins/lime-plugin-locate/src/locatePage.tsx deleted file mode 100644 index cc65c67fa..000000000 --- a/plugins/lime-plugin-locate/src/locatePage.tsx +++ /dev/null @@ -1,239 +0,0 @@ -import { Trans } from "@lingui/macro"; -import L, { LatLngExpression, icon } from "leaflet"; -import { useEffect, useRef, useState } from "preact/hooks"; -import { LayersControl, MapContainer, Marker, TileLayer } from "react-leaflet"; - -import { Loading } from "components/loading"; - -import { - useChangeLocation, - useLoadLeaflet, - useLocation, - useNodesandlinks, -} from "plugins/lime-plugin-locate/src/locateQueries"; - -import { useBoardData } from "utils/queries"; - -import { getCommunityGeoJSON } from "./communityGeoJSON"; -import { homeIcon } from "./leafletUtils"; -import style from "./style.less"; - -const openStreetMapTileString = "http://{s}.tile.osm.org/{z}/{x}/{y}.png"; -const openStreetMapAttribution = - '© OpenStreetMap contributors'; - -const gmSatellite = "https://{s}.google.com/vt/lyrs=s&x={x}&y={y}&z={z}"; -const gmHybrid = "https://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}"; -const gmSubdomains = ["mt0", "mt1", "mt2", "mt3"]; - -function getCommunityLayer(nodeHostname, stationLat, stationLon, nodesData) { - /** Create a Leaflet layer with community nodes and links to be added to the map*/ - if (nodesData[nodeHostname]) { - nodesData[nodeHostname].data.coordinates = { - lat: stationLat, - lon: stationLon, - }; - } - // Get community GeoJSON, filter out nodes in same location as station host. - const geoJSON = getCommunityGeoJSON(nodesData, [stationLon, stationLat]); - return L.geoJSON(geoJSON, { - onEachFeature: (feature, layer) => { - if (feature.properties && feature.properties.name) { - layer.bindTooltip(feature.properties.name).openTooltip(); - } - }, - }); -} - -export const LocatePage = () => { - const { data: boardData } = useBoardData(); - const { - isError: isAssetError, - isFetchedAfterMount: assetsLoaded, - isLoading: isLoadingAssets, - } = useLoadLeaflet({ - refetchOnWindowFocus: false, - }); - - const { - data: nodeLocation, - isLoading: isLoadingLocation, - isFetched: locationLoaded, - } = useLocation({ - enabled: assetsLoaded, - }); - - const { data: nodesData } = useNodesandlinks({ - enabled: locationLoaded, - }); - - const { mutate: changeLocation, isLoading: submitting } = useChangeLocation( - { - onSettled: () => { - toogleEdition(); - }, - } - ); - - const loading = isLoadingLocation || isLoadingAssets; - const isCommunityLocation = nodeLocation.default; - const stationLat = - nodeLocation.location.lat !== "FIXME" - ? nodeLocation.location.lat - : null; - const stationLon = - nodeLocation.location.lon !== "FIXME" - ? nodeLocation.location.lon - : null; - const hasLocation = stationLat && !isCommunityLocation; - - const [editting, setEditting] = useState(false); - const [nodeMarker, setNodeMarker] = useState(null); - const [communityLayer, setCommunityLayer] = useState(null); - - const mapRef = useRef(); - - // Set map position when map is available or location gets updated - useEffect(() => { - function updateNodeMarker(lat, lon) { - setNodeMarker([lat, lon]); - } - const mapInstance = mapRef.current; - - if (!loading && mapInstance && stationLat) { - mapInstance.setView([+stationLat, +stationLon], 13); - updateNodeMarker(stationLat, stationLon); - } - }, [stationLat, stationLon, loading]); - - // Center the map on the node also when editting is turned on - useEffect(() => { - const map = mapRef.current; - if (map && stationLat) { - editting && map.setView([+stationLat, +stationLon], 13); - } - }, [mapRef, editting, stationLat, stationLon]); - - function onConfirmLocation() { - const position = mapRef.current.getCenter(); - changeLocation({ lat: position.lat, lon: position.lng }); - if (communityLayer) { - // Hide the community view, to avoid outdated links - toogleCommunityLayer(); - } - } - - function toogleCommunityLayer() { - if (communityLayer) { - mapRef.current.removeLayer(communityLayer); - setCommunityLayer(null); - } else { - const layer = getCommunityLayer( - boardData.hostname, - stationLat, - stationLon, - nodesData - ); - layer.addTo(mapRef.current); - setCommunityLayer(layer); - } - } - - function isReady() { - return !loading && typeof stationLat !== "undefined"; - } - - function toogleEdition() { - setEditting(!editting); - } - - if (isAssetError) { - return ( -
- Cannot load map, check your internet connection -
- ); - } - - return ( - <> - {(!isReady() || submitting) && ( -
- -
- )} - {isReady() && ( - - - - - - - - - - - - - {nodeMarker && ( - - )} - {editting && ( -
- )} - - )} - {isReady() && ( -
- {editting && ( - - )} - {!editting && ( - - )} - - -
- )} - - ); -}; - -export default LocatePage; diff --git a/plugins/lime-plugin-node-admin/src/components/config/config.js b/plugins/lime-plugin-node-admin/src/components/config/config.tsx similarity index 50% rename from plugins/lime-plugin-node-admin/src/components/config/config.js rename to plugins/lime-plugin-node-admin/src/components/config/config.tsx index f72bbd5d8..e3cacb7f0 100644 --- a/plugins/lime-plugin-node-admin/src/components/config/config.js +++ b/plugins/lime-plugin-node-admin/src/components/config/config.tsx @@ -3,6 +3,14 @@ import Loading from "components/loading"; import style from "./config.style.less"; +type ConfigProps = { + title: React.ReactNode, + subtitle?: React.ReactNode, + value: React.ReactNode, + onClick: () => void, + isLoading: boolean, +} + export const Config = ({ title, subtitle, @@ -10,22 +18,22 @@ export const Config = ({ onClick, isLoading, ...props -}) => { +}: ConfigProps) => { return ( -
+
-
{title}
+
{title}
{isLoading && } {!isLoading && (
-
{subtitle}
-
{value}
+ {subtitle &&
{subtitle}
} +
{value}
)}
-
-
+
+
From 4f80d9f7e992674bb8102df67a27121e8c682fd3 Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 10 Feb 2023 16:38:17 +0100 Subject: [PATCH 002/121] chore(tailwindcss): Install tailwindcss --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 749e20c93..a88cd386f 100644 --- a/package.json +++ b/package.json @@ -98,6 +98,7 @@ "redux": "^4.2.0", "redux-observable": "^2.0.0", "simple-color-scale": "^1.0.1", + "tailwindcss": "^3.2.6", "timeago.js": "^4.0.2" }, "husky": { From d836580a1143507a5601cb271399f7be08cd8eef Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 31 Mar 2023 15:13:27 +0200 Subject: [PATCH 003/121] chore(locate): implement react leaflet --- package-lock.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 060c516eb..096351cf4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,6 @@ "@tanstack/react-query-devtools": "^4.6.0", "compressorjs": "^1.1.1", "history": "^5.3.0", - "leaflet": "^1.9.3", "preact": "^10.11.0", "preact-i18nline": "^2.0.0", "preact-router": "^4.1.0", @@ -23603,7 +23602,8 @@ "node_modules/leaflet": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.3.tgz", - "integrity": "sha512-iB2cR9vAkDOu5l3HAay2obcUHZ7xwUBBjph8+PGtmW/2lYhbLizWtG7nTeYht36WfOslixQF9D/uSIzhZgGMfQ==" + "integrity": "sha512-iB2cR9vAkDOu5l3HAay2obcUHZ7xwUBBjph8+PGtmW/2lYhbLizWtG7nTeYht36WfOslixQF9D/uSIzhZgGMfQ==", + "peer": true }, "node_modules/less": { "version": "4.1.3", @@ -54760,7 +54760,8 @@ "leaflet": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.3.tgz", - "integrity": "sha512-iB2cR9vAkDOu5l3HAay2obcUHZ7xwUBBjph8+PGtmW/2lYhbLizWtG7nTeYht36WfOslixQF9D/uSIzhZgGMfQ==" + "integrity": "sha512-iB2cR9vAkDOu5l3HAay2obcUHZ7xwUBBjph8+PGtmW/2lYhbLizWtG7nTeYht36WfOslixQF9D/uSIzhZgGMfQ==", + "peer": true }, "less": { "version": "4.1.3", From 98c513c8dbd0efa3e1e7730dbd28cc4ef29ad9a6 Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 12 Apr 2023 16:49:03 +0200 Subject: [PATCH 004/121] chore(meshwide): bootstrap Mesh Wide page --- plugins/lime-plugin-mesh-wide/index.ts | 8 +++++++ .../src/meshWideMenu.tsx | 21 +++++++++++++++++++ .../src/meshWidePage.tsx | 17 +++++++++++++++ src/config.ts | 2 ++ 4 files changed, 48 insertions(+) create mode 100644 plugins/lime-plugin-mesh-wide/index.ts create mode 100755 plugins/lime-plugin-mesh-wide/src/meshWideMenu.tsx create mode 100644 plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx diff --git a/plugins/lime-plugin-mesh-wide/index.ts b/plugins/lime-plugin-mesh-wide/index.ts new file mode 100644 index 000000000..1837c2c72 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/index.ts @@ -0,0 +1,8 @@ +import { MeshWideMenu } from "./src/meshWideMenu"; +import MeshWidePage from "./src/meshWidePage"; + +export default { + name: "MeshWide", + page: MeshWidePage, + menu: MeshWideMenu, +} as LimePlugin; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideMenu.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideMenu.tsx new file mode 100755 index 000000000..06ffb69f9 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/meshWideMenu.tsx @@ -0,0 +1,21 @@ +import { Trans } from "@lingui/macro"; + +export const MeshWideMenu = () => ( + + + + + + Mesh Wide + + +); diff --git a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx new file mode 100644 index 000000000..ad6c8883f --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx @@ -0,0 +1,17 @@ +import Loading from "components/loading"; + +const MeshWidePage = () => { + const loading = true; + return ( + <> + {loading && ( +
+ +
+ )} + {!loading &&
HELLO WORLD
} + + ); +}; + +export default MeshWidePage; diff --git a/src/config.ts b/src/config.ts index b4302bbdd..0042a280e 100644 --- a/src/config.ts +++ b/src/config.ts @@ -3,6 +3,7 @@ import ChangeNode from "plugins/lime-plugin-changeNode"; import Fbw from "plugins/lime-plugin-fbw"; import Firmware from "plugins/lime-plugin-firmware"; import Locate from "plugins/lime-plugin-locate"; +import MeshWide from "plugins/lime-plugin-mesh-wide"; import Metrics from "plugins/lime-plugin-metrics"; import NetworkAdmin from "plugins/lime-plugin-network-admin"; import NodeAdmin from "plugins/lime-plugin-node-admin"; @@ -17,6 +18,7 @@ export const plugins: LimePlugin[] = [ Align, Locate, Metrics, + MeshWide, Notes, NodeAdmin, NetworkAdmin, From 3a8a38dfd005fac566fe88950c25285cc138356e Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 14 Apr 2023 11:46:28 +0200 Subject: [PATCH 005/121] chore(meshwide): create bottom sheet --- src/components/bottom-sheet/BottomSheet.tsx | 278 ++++++++++++++++++++ src/components/bottom-sheet/credits.md | 3 + src/components/bottom-sheet/index.ts | 1 + src/components/bottom-sheet/style.less | 84 ++++++ src/components/bottom-sheet/utils.ts | 44 ++++ 5 files changed, 410 insertions(+) create mode 100644 src/components/bottom-sheet/BottomSheet.tsx create mode 100644 src/components/bottom-sheet/credits.md create mode 100644 src/components/bottom-sheet/index.ts create mode 100644 src/components/bottom-sheet/style.less create mode 100644 src/components/bottom-sheet/utils.ts diff --git a/src/components/bottom-sheet/BottomSheet.tsx b/src/components/bottom-sheet/BottomSheet.tsx new file mode 100644 index 000000000..131a71054 --- /dev/null +++ b/src/components/bottom-sheet/BottomSheet.tsx @@ -0,0 +1,278 @@ +import React, { useEffect, useRef } from "react"; +import { animated, useSpring } from "react-spring"; + +import style from "./style.less"; +import { + TBottomSheetEventsKey, + bottomSheetEvents, + syncHeight, + useReduceMotion, +} from "./utils"; + +// TODO - account for resizing the window +const DRAWER_HEIGHT = window.innerHeight; +const INITIAL_DRAWER_DISTANCE_FROM_TOP = 400; +const MAX_WIDTH = 560; +const DRAWER_SNAP_MARGIN = 100; +const COLLAPSED_HEIGHT = 75; +const THUMB_HEIGHT = 35; + +// resize listener +window.addEventListener("resize", syncHeight); +syncHeight(); + +type TBottomSheetProps = { + /** + * nested children + */ + children: JSX.Element; + /** + * optional specific aria label for close button + */ + closeButtonAriaLabel?: string; + /** + * Custom initial expanded height + */ + initialDrawerDistanceTop?: number; + /** + * Is the BottomSheet visible on the scren? + */ + isOpen: boolean; + /** + * Optional custom maxWidth for the BottomSheet in px + */ + maxWidth?: string; + /** + * Fires when close button is fired + */ + onClose: () => void; + /** + * Fires when the status changes + */ + onStatusChange?: (status: string) => void; + /** + * Optional Subtitle for the BottomSheet + */ + subtitle?: string; + /** + * Optional Title for the BottomSheet + */ + title?: string; +}; + +export const BottomSheet: React.FC = ({ + children, + closeButtonAriaLabel = "Close", + initialDrawerDistanceTop = INITIAL_DRAWER_DISTANCE_FROM_TOP, + isOpen, + maxWidth = MAX_WIDTH, + onClose, + onStatusChange, + subtitle, + title, +}) => { + // STATE + const scrollRef = useRef(null); + const [bottom, setBottom] = React.useState(-DRAWER_HEIGHT); + const [draggingPosition, setDraggingPosition] = React.useState< + number | null + >(null); + const [debugLog, setDebugLog] = React.useState(""); + + // ANIMATION + const prefersReducedMotion = useReduceMotion(); + const styles = useSpring({ + bottom, + immediate: prefersReducedMotion, + config: { friction: 20 }, + }); + + // HANDLERS + const handlePointerDown = ( + e: React.TouchEvent | React.MouseEvent + ) => { + // @ts-ignore + const event = (e?.touches != null ? e.touches[0] : e) as MouseEvent; + // handle safari body scroll bug + document.documentElement.classList.add("is-locked"); + const newDraggingPosition = + (e.currentTarget.parentElement?.getBoundingClientRect().bottom ?? + 0) - event.clientY; + setDraggingPosition(newDraggingPosition); + }; + + const handlePointerMove = React.useCallback( + (e: TouchEvent | MouseEvent) => { + // @ts-ignore + const event = e?.touches != null ? e?.touches[0] : e; + if (draggingPosition != null) { + const newBottom = + window.innerHeight - event.clientY - draggingPosition; + if (newBottom !== bottom) { + setBottom(newBottom); + } + } + }, + [bottom, draggingPosition] + ); + + const handleScrollRepositioning = () => { + if (scrollRef && scrollRef.current) { + scrollRef.current.scrollTop = 0; + } + }; + + const handleStatusChange = React.useCallback( + (status: TBottomSheetEventsKey) => { + const newStatus = bottomSheetEvents[status]; + const newDebugLog = + debugLog !== "" ? `${debugLog}, ${newStatus}` : newStatus; + setDebugLog(newDebugLog); + onStatusChange && onStatusChange(newStatus); + }, + [debugLog, onStatusChange] + ); + + // LISTENERS + + // toggling the bottom sheet + useEffect(() => { + if (isOpen) { + handleStatusChange("expanded"); + handleScrollRepositioning(); + setBottom(-initialDrawerDistanceTop); + } else { + handleStatusChange("dismissed"); + setBottom(-DRAWER_HEIGHT); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [isOpen]); + + // dragging + useEffect(() => { + const handlePointerUp = () => { + document.documentElement.classList.remove("is-locked"); + + if (draggingPosition == null) { + return; + } + + // snap logic + if (bottom > -DRAWER_SNAP_MARGIN) { + handleStatusChange("snapToTop"); + setBottom(0); + } else if (bottom < -DRAWER_HEIGHT + COLLAPSED_HEIGHT) { + handleStatusChange("dismissed"); + onClose(); + setBottom(-DRAWER_HEIGHT); + } else if ( + bottom < + COLLAPSED_HEIGHT - DRAWER_HEIGHT + DRAWER_SNAP_MARGIN + ) { + handleStatusChange("collapsed"); + setBottom(-DRAWER_HEIGHT + COLLAPSED_HEIGHT); + } + setDraggingPosition(null); + }; + + document.addEventListener("touchend", handlePointerUp); + document.addEventListener("touchmove", handlePointerMove); + document.addEventListener("mouseup", handlePointerUp); + document.addEventListener("mousemove", handlePointerMove); + return () => { + document.removeEventListener("touchend", handlePointerUp); + document.removeEventListener("touchmove", handlePointerMove); + document.removeEventListener("mouseup", handlePointerUp); + document.removeEventListener("mousemove", handlePointerMove); + }; + }, [ + bottom, + debugLog, + draggingPosition, + handlePointerMove, + handleStatusChange, + onClose, + ]); + + const bodyHeight = + DRAWER_HEIGHT + + bottom - + (title || subtitle ? COLLAPSED_HEIGHT : THUMB_HEIGHT); + + return ( + <> + +
+
+
{ + e.preventDefault(); + // get rid of the ghost drag image in the view + e.dataTransfer.setDragImage(new Image(), 0, 0); + }} + draggable={true} + className={style.ThumbBarWrapper} + style={ + draggingPosition != null + ? { + cursor: "grabbing", + } + : { + cursor: "grab", + } + } + > +
+
+
+
+ {title && ( +

{title}

+ )} + {subtitle &&

{subtitle}

} +
+ +
+
+
+ {children} +
+
+ + + ); +}; diff --git a/src/components/bottom-sheet/credits.md b/src/components/bottom-sheet/credits.md new file mode 100644 index 000000000..1e1ac0247 --- /dev/null +++ b/src/components/bottom-sheet/credits.md @@ -0,0 +1,3 @@ +Code borrowed from: + +https://github.com/kaitlynhova/BottomSheet/ diff --git a/src/components/bottom-sheet/index.ts b/src/components/bottom-sheet/index.ts new file mode 100644 index 000000000..4f7c1036f --- /dev/null +++ b/src/components/bottom-sheet/index.ts @@ -0,0 +1 @@ +export * from "./BottomSheet"; diff --git a/src/components/bottom-sheet/style.less b/src/components/bottom-sheet/style.less new file mode 100644 index 000000000..addaf5d53 --- /dev/null +++ b/src/components/bottom-sheet/style.less @@ -0,0 +1,84 @@ +@surface: #fff; +@onSurface: #191919; +@onSurfaceSecondary: #666; +@surfaceThumbBar: #ddd; +@surfaceHover: #eee; + +.BottomSheetStyled { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", + "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", + "Helvetica Neue", sans-serif; + background: @surface; + box-shadow: 0 1px 8px rgb(0 0 0 / 30%); + border-radius: 8px; + margin: auto; + max-width: 560px; + width: 100%; + height: 100%; +} + +.CloseButton { + height: 40px; + background: @surface; + cursor: pointer; + border: none; + padding: 8px; + border-radius: 100%; + position: absolute; + right: 16px; + &:hover { + background: @surfaceHover; + } +} + +.DebugLog { + color: @onSurface; +} + +.Header { + display: flex; + position: relative; + justify-content: center; + padding-bottom: 16px; +} + +.HeaderTitle { + display: flex; + flex-direction: column; + text-align: center; + justify-content: center; + & h1 { + color: @onSurface; + font-size: 1.125rem; + line-height: 1.5; + margin: 0; + } + & h2 { + color: @onSurfaceSecondary; + font-size: 0.875rem; + line-height: 1; + font-weight: 600; + margin: 0; + } +} + +.SheetBody { + overflow-y: auto; + width: 100%; + transition: height 200ms; +} + +.ThumbBarWrapper { + width: 100%; + display: flex; + justify-content: center; + cursor: move; /* fallback if grab cursor is unsupported */ +} + +.ThumbBar { + background: @surfaceThumbBar; + width: 64px; + margin: 8px auto; + height: 0.25rem; + border-radius: 4px; +} diff --git a/src/components/bottom-sheet/utils.ts b/src/components/bottom-sheet/utils.ts new file mode 100644 index 000000000..12e7f0e32 --- /dev/null +++ b/src/components/bottom-sheet/utils.ts @@ -0,0 +1,44 @@ +import { useEffect, useState } from "preact/hooks"; + +export const syncHeight = () => { + document.documentElement.style.setProperty( + "--window-inner-height", + `${window.innerHeight}px` + ); +}; + +export type TBottomSheetEvents = { + collapsed: string; + dismissed: string; + expanded: string; + snapToTop: string; +}; + +export type TBottomSheetEventsKey = keyof TBottomSheetEvents; + +export const bottomSheetEvents: TBottomSheetEvents = { + collapsed: "in collapse state", + dismissed: "was dismissed", + expanded: "is expanded", + snapToTop: "snapped to top", +}; + +// from react-reduce-motion +// Note: library had type issues, didn't have time to fix those +export const useReduceMotion = () => { + const [matches, setMatch] = useState( + window.matchMedia("(prefers-reduced-motion: reduce)").matches + ); + useEffect(() => { + const mq = window.matchMedia("(prefers-reduced-motion: reduce)"); + const handleChange = () => { + setMatch(mq.matches); + }; + handleChange(); + mq.addEventListener("change", handleChange); + return () => { + mq.removeEventListener("change", handleChange); + }; + }, []); + return matches; +}; From 2cdc04452691d9cc8b58ecf0a0d69cf570e9c12c Mon Sep 17 00:00:00 2001 From: selankon Date: Mon, 17 Apr 2023 09:35:10 +0200 Subject: [PATCH 006/121] chore(meshwide): add footer to BottosmSheet --- src/components/bottom-sheet/BottomSheet.tsx | 13 +++++++++++++ src/components/bottom-sheet/style.less | 9 +++++++++ 2 files changed, 22 insertions(+) diff --git a/src/components/bottom-sheet/BottomSheet.tsx b/src/components/bottom-sheet/BottomSheet.tsx index 131a71054..5dc26b367 100644 --- a/src/components/bottom-sheet/BottomSheet.tsx +++ b/src/components/bottom-sheet/BottomSheet.tsx @@ -58,6 +58,10 @@ type TBottomSheetProps = { * Optional Title for the BottomSheet */ title?: string; + /** + * Element to be shown either if the sheet is expanded at all or not + */ + footer?: JSX.Element; }; export const BottomSheet: React.FC = ({ @@ -70,6 +74,7 @@ export const BottomSheet: React.FC = ({ onStatusChange, subtitle, title, + footer, }) => { // STATE const scrollRef = useRef(null); @@ -273,6 +278,14 @@ export const BottomSheet: React.FC = ({
+ {bodyHeight > 0 && ( +
+ {footer} +
+ )} ); }; diff --git a/src/components/bottom-sheet/style.less b/src/components/bottom-sheet/style.less index addaf5d53..48e9cb8f1 100644 --- a/src/components/bottom-sheet/style.less +++ b/src/components/bottom-sheet/style.less @@ -82,3 +82,12 @@ height: 0.25rem; border-radius: 4px; } + +.FooterWrapper { + position: fixed; + bottom: 0; + padding: 10px; + left: 50%; + width: 100%; + transform: translateX(-50%); +} From 04ebe642c933e064217adff7a6dabbf607de0869 Mon Sep 17 00:00:00 2001 From: selankon Date: Mon, 17 Apr 2023 09:52:32 +0200 Subject: [PATCH 007/121] chore(meshwide): add attribute to disable close button --- src/components/bottom-sheet/BottomSheet.tsx | 29 +++++++++++++-------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/components/bottom-sheet/BottomSheet.tsx b/src/components/bottom-sheet/BottomSheet.tsx index 5dc26b367..c980793b2 100644 --- a/src/components/bottom-sheet/BottomSheet.tsx +++ b/src/components/bottom-sheet/BottomSheet.tsx @@ -30,6 +30,10 @@ type TBottomSheetProps = { * optional specific aria label for close button */ closeButtonAriaLabel?: string; + /** + * Activate close button + */ + closeButton?: boolean; /** * Custom initial expanded height */ @@ -67,6 +71,7 @@ type TBottomSheetProps = { export const BottomSheet: React.FC = ({ children, closeButtonAriaLabel = "Close", + closeButton = true, initialDrawerDistanceTop = INITIAL_DRAWER_DISTANCE_FROM_TOP, isOpen, maxWidth = MAX_WIDTH, @@ -255,17 +260,19 @@ export const BottomSheet: React.FC = ({ )} {subtitle &&

{subtitle}

}
- + {closeButton && ( + + )}
Date: Mon, 17 Apr 2023 11:04:09 +0200 Subject: [PATCH 008/121] chore(components): implement danger outline button --- src/components/elements/button.tsx | 67 ++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/components/elements/button.tsx diff --git a/src/components/elements/button.tsx b/src/components/elements/button.tsx new file mode 100644 index 000000000..d2ca3920c --- /dev/null +++ b/src/components/elements/button.tsx @@ -0,0 +1,67 @@ +import React from "react"; + +interface ButtonProps { + onClick?: () => void; + children?: any; // type error with Trans component + size?: "sm" | "md" | "lg"; + color?: "primary" | "secondary" | "danger"; + href?: string; + outline?: boolean; +} + +export const Button = ({ + size = "md", + color = "primary", + onClick, + children, + href, + outline = false, + ...props +}: ButtonProps) => { + let sizeClasses = "", + colorClasses = ""; + switch (size) { + case "sm": + sizeClasses = "py-2 px-4 text-sm"; + break; + case "md": + sizeClasses = "py-4 px-6 min-w-[theme('spacing[52]')]"; + break; + case "lg": + sizeClasses = "py-6 px-8"; + break; + } + + switch (color) { + case "primary": + colorClasses = outline + ? "border-2 border-button-primary text-button-primary" + : "bg-button-primary text-white"; + break; + case "secondary": + colorClasses = outline + ? "border-2 border-button-secondary text-button-secondary" + : "bg-button-secondary text-white"; + break; + case "danger": + colorClasses = outline + ? "border-2 border-danger text-danger" + : "bg-danger text-white"; + } + + const cls = `cursor-pointer font-semibold rounded-xl text-center place-content-center + justify-center border-0 ${sizeClasses} ${colorClasses}`; + const Btn = () => ( + // @ts-ignore +
+ {children} +
+ ); + return href ? ( + + + + ) : ( + + ); +}; From 3091e64c40a7f14e38f3b34b5b9ba9d879c6a30d Mon Sep 17 00:00:00 2001 From: selankon Date: Mon, 17 Apr 2023 12:25:43 +0200 Subject: [PATCH 009/121] chore(meshwide): create bottom sheet mock --- package.json | 1 + .../src/components/NodeDetail.tsx | 65 ++++++++++++++++ .../lime-plugin-mesh-wide/src/icons/power.tsx | 15 ++++ .../src/meshWidePage.tsx | 74 ++++++++++++++++++- src/components/bottom-sheet/style.less | 1 - src/components/buttons/floatting-button.tsx | 19 +++++ 6 files changed, 172 insertions(+), 3 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/components/NodeDetail.tsx create mode 100644 plugins/lime-plugin-mesh-wide/src/icons/power.tsx create mode 100644 src/components/buttons/floatting-button.tsx diff --git a/package.json b/package.json index a88cd386f..da10654c9 100644 --- a/package.json +++ b/package.json @@ -94,6 +94,7 @@ "react-leaflet": "^4.2.1", "react-redux": "^8.0.4", "react-router-redux": "^4.0.8", + "react-spring": "^9.7.1", "react-use": "^17.4.0", "redux": "^4.2.0", "redux-observable": "^2.0.0", diff --git a/plugins/lime-plugin-mesh-wide/src/components/NodeDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/NodeDetail.tsx new file mode 100644 index 000000000..cae1f9f1a --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/components/NodeDetail.tsx @@ -0,0 +1,65 @@ +import { Trans } from "@lingui/macro"; + +import { Button } from "components/elements/button"; + +import { PowerIcon } from "plugins/lime-plugin-mesh-wide/src/icons/power"; + +const TitleAndText = ({ + title, + children, +}: { + title: any; // todo(kon): error with trans component + children: string; +}) => { + return ( +
+
{title}
+
{children}
+
+ ); +}; + +const Row = ({ children }: { children: any }) => { + return ( +
+ {children} +
+ ); +}; + +export const NodeDetail = () => { + const nodeName = "ql-arbol"; + const uptime = "1 week"; + const firmware = "e93615c947-x86-64"; + const ipv6 = "fe80::42:cff:fecf:bfff"; + const ipv4 = "192.168.1.47"; + const device = "LibreRouter"; + + return ( + <> + +
{nodeName}
+ +
+ + Uptime}> + {uptime} + + Firmware version}> + {firmware} + + + + IPv4}>{ipv4} + IPv6}>{ipv6} + + + Device}> + {device} + + + + ); +}; diff --git a/plugins/lime-plugin-mesh-wide/src/icons/power.tsx b/plugins/lime-plugin-mesh-wide/src/icons/power.tsx new file mode 100644 index 000000000..72d70e36d --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/icons/power.tsx @@ -0,0 +1,15 @@ +export const PowerIcon = () => ( + + + +); diff --git a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx index ad6c8883f..4bc6426df 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx @@ -1,7 +1,44 @@ +import { Trans } from "@lingui/macro"; +import L, { LeafletMouseEvent, Map } from "leaflet"; +import { useState } from "preact/hooks"; +import React, { Component } from "react"; +import { LayersControl, MapContainer, TileLayer } from "react-leaflet"; +import { useMap } from "react-leaflet"; + +import { BottomSheet } from "components/bottom-sheet"; +import FloatingButton from "components/buttons/floatting-button"; import Loading from "components/loading"; +import { useLoadLeaflet } from "plugins/lime-plugin-locate/src/locateQueries"; +import style from "plugins/lime-plugin-locate/src/style.less"; +import { NodeDetail } from "plugins/lime-plugin-mesh-wide/src/components/NodeDetail"; + +const openStreetMapTileString = "http://{s}.tile.osm.org/{z}/{x}/{y}.png"; +const openStreetMapAttribution = + '© OpenStreetMap contributors'; + +const BottomSheetFooter = ({ synced }: { synced?: boolean }) => { + return ( +
+ + Same status as in the reference state +
+ ); +}; + const MeshWidePage = () => { - const loading = true; + // const { + // isError: isAssetError, + // isFetchedAfterMount: assetsLoaded, + // isLoading: isLoadingAssets, + // } = useLoadLeaflet({ + // refetchOnWindowFocus: false, + // }); + // + // const loading = isLoadingAssets; + + const [isOpen, setIsOpen] = useState(true); + const loading = false; return ( <> {loading && ( @@ -9,7 +46,40 @@ const MeshWidePage = () => {
)} - {!loading &&
HELLO WORLD
} + {!loading && ( + <> + {/**/} + {/* */} + {/*
*/} + { + setIsOpen(false); + }} + initialDrawerDistanceTop={650} + footer={} + > +
+ +
+
+ { + console.log("AAAA"); + setIsOpen(!isOpen); + }} + /> + + )} ); }; diff --git a/src/components/bottom-sheet/style.less b/src/components/bottom-sheet/style.less index 48e9cb8f1..bed4fe3a5 100644 --- a/src/components/bottom-sheet/style.less +++ b/src/components/bottom-sheet/style.less @@ -86,7 +86,6 @@ .FooterWrapper { position: fixed; bottom: 0; - padding: 10px; left: 50%; width: 100%; transform: translateX(-50%); diff --git a/src/components/buttons/floatting-button.tsx b/src/components/buttons/floatting-button.tsx new file mode 100644 index 000000000..0eb8f0643 --- /dev/null +++ b/src/components/buttons/floatting-button.tsx @@ -0,0 +1,19 @@ +import React from "react"; + +interface FloatingButtonProps { + onClick?: () => void; + children?: React.ReactNode | string; +} + +const FloatingButton = ({ onClick, children = "+" }: FloatingButtonProps) => { + return ( + + ); +}; + +export default FloatingButton; From c783bb49e8a1099b3bc44cfaa627303465af9b16 Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 18 Apr 2023 09:18:30 +0200 Subject: [PATCH 010/121] chore(meshwide): implement bad sync state --- .../src/components/NodeDetail.tsx | 15 +++++--- .../src/meshWidePage.tsx | 36 ++++++++++++++----- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/NodeDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/NodeDetail.tsx index cae1f9f1a..358a16c59 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/NodeDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/NodeDetail.tsx @@ -27,7 +27,7 @@ const Row = ({ children }: { children: any }) => { ); }; -export const NodeDetail = () => { +export const NodeDetail = ({ synced }: { synced: boolean }) => { const nodeName = "ql-arbol"; const uptime = "1 week"; const firmware = "e93615c947-x86-64"; @@ -44,9 +44,16 @@ export const NodeDetail = () => { - Uptime}> - {uptime} - + {synced ? ( + Uptime}> + {uptime} + + ) : ( + Downtime}> + {uptime} + + )} + Firmware version}> {firmware} diff --git a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx index 4bc6426df..3f87c31fe 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx @@ -2,11 +2,11 @@ import { Trans } from "@lingui/macro"; import L, { LeafletMouseEvent, Map } from "leaflet"; import { useState } from "preact/hooks"; import React, { Component } from "react"; -import { LayersControl, MapContainer, TileLayer } from "react-leaflet"; -import { useMap } from "react-leaflet"; +import { LayersControl, MapContainer, TileLayer, useMap } from "react-leaflet"; import { BottomSheet } from "components/bottom-sheet"; import FloatingButton from "components/buttons/floatting-button"; +import { Button } from "components/elements/button"; import Loading from "components/loading"; import { useLoadLeaflet } from "plugins/lime-plugin-locate/src/locateQueries"; @@ -18,11 +18,29 @@ const openStreetMapAttribution = '© OpenStreetMap contributors'; const BottomSheetFooter = ({ synced }: { synced?: boolean }) => { - return ( -
- + const containerClasses = + "flex items-center justify-center text-center bg-white py-5"; + return synced ? ( +
+ Same status as in the reference state
+ ) : ( + <> +
+
+ + ! + + In the reference state this node is on +
+ +
+ ); }; @@ -38,6 +56,7 @@ const MeshWidePage = () => { // const loading = isLoadingAssets; const [isOpen, setIsOpen] = useState(true); + const synced = false; const loading = false; return ( <> @@ -65,16 +84,15 @@ const MeshWidePage = () => { onClose={() => { setIsOpen(false); }} - initialDrawerDistanceTop={650} - footer={} + // initialDrawerDistanceTop={650} + footer={} >
- +
{ - console.log("AAAA"); setIsOpen(!isOpen); }} /> From 0386803e93438ecce6c7a5de745a89c83589bf8e Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 18 Apr 2023 10:07:02 +0200 Subject: [PATCH 011/121] chore(meshwide): apply some styles --- .../src/meshWidePage.tsx | 1 - src/components/bottom-sheet/style.less | 2 +- src/components/buttons/floatting-button.tsx | 20 +++++++++++-------- src/components/elements/button.tsx | 16 +++++++-------- 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx index 3f87c31fe..108cca241 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx @@ -84,7 +84,6 @@ const MeshWidePage = () => { onClose={() => { setIsOpen(false); }} - // initialDrawerDistanceTop={650} footer={} >
diff --git a/src/components/bottom-sheet/style.less b/src/components/bottom-sheet/style.less index bed4fe3a5..2d8842d4e 100644 --- a/src/components/bottom-sheet/style.less +++ b/src/components/bottom-sheet/style.less @@ -63,7 +63,7 @@ } .SheetBody { - overflow-y: auto; + overflow-y: hidden; width: 100%; transition: height 200ms; } diff --git a/src/components/buttons/floatting-button.tsx b/src/components/buttons/floatting-button.tsx index 0eb8f0643..706ef41bd 100644 --- a/src/components/buttons/floatting-button.tsx +++ b/src/components/buttons/floatting-button.tsx @@ -1,18 +1,22 @@ import React from "react"; +import { Button, ButtonProps } from "components/elements/button"; + interface FloatingButtonProps { - onClick?: () => void; children?: React.ReactNode | string; } -const FloatingButton = ({ onClick, children = "+" }: FloatingButtonProps) => { +const FloatingButton = ({ + size = "sm", + children = "+", + ...rest +}: FloatingButtonProps & ButtonProps) => { return ( - +
+ +
); }; diff --git a/src/components/elements/button.tsx b/src/components/elements/button.tsx index d2ca3920c..f50622207 100644 --- a/src/components/elements/button.tsx +++ b/src/components/elements/button.tsx @@ -1,6 +1,6 @@ import React from "react"; -interface ButtonProps { +export interface ButtonProps { onClick?: () => void; children?: any; // type error with Trans component size?: "sm" | "md" | "lg"; @@ -35,21 +35,21 @@ export const Button = ({ switch (color) { case "primary": colorClasses = outline - ? "border-2 border-button-primary text-button-primary" - : "bg-button-primary text-white"; + ? "border-2 border-button-primary text-button-primary hover:bg-button-primary hover:text-white" + : "bg-button-primary text-white hover:bg-button-secondary"; break; case "secondary": colorClasses = outline - ? "border-2 border-button-secondary text-button-secondary" - : "bg-button-secondary text-white"; + ? "border-2 border-button-secondary text-button-secondary hover:bg-button-secondary hover:text-white" + : "bg-button-secondary text-white hover:bg-button-primary "; break; case "danger": colorClasses = outline - ? "border-2 border-danger text-danger" - : "bg-danger text-white"; + ? "border-2 border-danger text-danger hover:bg-danger hover:text-white" + : "bg-danger text-white border-2 border-danger hover:text-danger hover:bg-white"; } - const cls = `cursor-pointer font-semibold rounded-xl text-center place-content-center + const cls = `cursor-pointer font-semibold rounded-xl text-center place-content-center transition-all duration-300 justify-center border-0 ${sizeClasses} ${colorClasses}`; const Btn = () => ( // @ts-ignore From fb1ba3c9fba206dda5a473069390b012e84ba1d0 Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 20 Apr 2023 11:16:05 +0200 Subject: [PATCH 012/121] WIP save some work --- .../src/components/NodeDetail.tsx | 1 - tailwind.config.js | 22 ++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/NodeDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/NodeDetail.tsx index 358a16c59..178e58be4 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/NodeDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/NodeDetail.tsx @@ -53,7 +53,6 @@ export const NodeDetail = ({ synced }: { synced: boolean }) => { {uptime} )} - Firmware version}> {firmware} diff --git a/tailwind.config.js b/tailwind.config.js index e1888ccf0..6c22aec49 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,3 +1,5 @@ +const colors = require("tailwindcss/colors"); + /** @type {import('tailwindcss').Config} */ module.exports = { // mode: "jit", @@ -8,7 +10,25 @@ module.exports = { ], darkMode: false, // or 'media' or 'class' theme: { - extend: {}, + extend: { + colors: { + primary: { + DEFAULT: "#38927f", + light: "#6BC3AE", + dark: "#006453", + card: "#DBE5E0", + }, + button: { + primary: "#1BC47D", + secondary: "#6BC3AE", + }, + danger: "#EB7575", + info: "#EAAB7E", + success: "#76BD7D", + internet: "#5F65FF", + disabled: colors.gray["500"], + }, + }, }, plugins: [], }; From f99287fa147a74fb998d712a1d1dffdd61395c78 Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 3 May 2023 11:13:52 +0200 Subject: [PATCH 013/121] chore(rxPage): add missing changes After rebase develop some changes where missing --- package-lock.json | 1 + plugins/lime-plugin-locate/index.ts | 8 + plugins/lime-plugin-locate/src/locatePage.tsx | 239 ++++++++++++++++++ .../src/components/config/config.tsx | 21 +- 4 files changed, 262 insertions(+), 7 deletions(-) create mode 100644 plugins/lime-plugin-locate/index.ts create mode 100644 plugins/lime-plugin-locate/src/locatePage.tsx diff --git a/package-lock.json b/package-lock.json index 096351cf4..0e84e6a09 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "redux": "^4.2.0", "redux-observable": "^2.0.0", "simple-color-scale": "^1.0.1", + "tailwindcss": "^3.2.6", "timeago.js": "^4.0.2" }, "devDependencies": { diff --git a/plugins/lime-plugin-locate/index.ts b/plugins/lime-plugin-locate/index.ts new file mode 100644 index 000000000..fc2045db2 --- /dev/null +++ b/plugins/lime-plugin-locate/index.ts @@ -0,0 +1,8 @@ +import { LocateMenu } from "./src/locateMenu"; +import Locate from "./src/locatePage"; + +export default { + name: "Locate", + page: Locate, + menu: LocateMenu, +} as LimePlugin; diff --git a/plugins/lime-plugin-locate/src/locatePage.tsx b/plugins/lime-plugin-locate/src/locatePage.tsx new file mode 100644 index 000000000..cc65c67fa --- /dev/null +++ b/plugins/lime-plugin-locate/src/locatePage.tsx @@ -0,0 +1,239 @@ +import { Trans } from "@lingui/macro"; +import L, { LatLngExpression, icon } from "leaflet"; +import { useEffect, useRef, useState } from "preact/hooks"; +import { LayersControl, MapContainer, Marker, TileLayer } from "react-leaflet"; + +import { Loading } from "components/loading"; + +import { + useChangeLocation, + useLoadLeaflet, + useLocation, + useNodesandlinks, +} from "plugins/lime-plugin-locate/src/locateQueries"; + +import { useBoardData } from "utils/queries"; + +import { getCommunityGeoJSON } from "./communityGeoJSON"; +import { homeIcon } from "./leafletUtils"; +import style from "./style.less"; + +const openStreetMapTileString = "http://{s}.tile.osm.org/{z}/{x}/{y}.png"; +const openStreetMapAttribution = + '© OpenStreetMap contributors'; + +const gmSatellite = "https://{s}.google.com/vt/lyrs=s&x={x}&y={y}&z={z}"; +const gmHybrid = "https://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}"; +const gmSubdomains = ["mt0", "mt1", "mt2", "mt3"]; + +function getCommunityLayer(nodeHostname, stationLat, stationLon, nodesData) { + /** Create a Leaflet layer with community nodes and links to be added to the map*/ + if (nodesData[nodeHostname]) { + nodesData[nodeHostname].data.coordinates = { + lat: stationLat, + lon: stationLon, + }; + } + // Get community GeoJSON, filter out nodes in same location as station host. + const geoJSON = getCommunityGeoJSON(nodesData, [stationLon, stationLat]); + return L.geoJSON(geoJSON, { + onEachFeature: (feature, layer) => { + if (feature.properties && feature.properties.name) { + layer.bindTooltip(feature.properties.name).openTooltip(); + } + }, + }); +} + +export const LocatePage = () => { + const { data: boardData } = useBoardData(); + const { + isError: isAssetError, + isFetchedAfterMount: assetsLoaded, + isLoading: isLoadingAssets, + } = useLoadLeaflet({ + refetchOnWindowFocus: false, + }); + + const { + data: nodeLocation, + isLoading: isLoadingLocation, + isFetched: locationLoaded, + } = useLocation({ + enabled: assetsLoaded, + }); + + const { data: nodesData } = useNodesandlinks({ + enabled: locationLoaded, + }); + + const { mutate: changeLocation, isLoading: submitting } = useChangeLocation( + { + onSettled: () => { + toogleEdition(); + }, + } + ); + + const loading = isLoadingLocation || isLoadingAssets; + const isCommunityLocation = nodeLocation.default; + const stationLat = + nodeLocation.location.lat !== "FIXME" + ? nodeLocation.location.lat + : null; + const stationLon = + nodeLocation.location.lon !== "FIXME" + ? nodeLocation.location.lon + : null; + const hasLocation = stationLat && !isCommunityLocation; + + const [editting, setEditting] = useState(false); + const [nodeMarker, setNodeMarker] = useState(null); + const [communityLayer, setCommunityLayer] = useState(null); + + const mapRef = useRef(); + + // Set map position when map is available or location gets updated + useEffect(() => { + function updateNodeMarker(lat, lon) { + setNodeMarker([lat, lon]); + } + const mapInstance = mapRef.current; + + if (!loading && mapInstance && stationLat) { + mapInstance.setView([+stationLat, +stationLon], 13); + updateNodeMarker(stationLat, stationLon); + } + }, [stationLat, stationLon, loading]); + + // Center the map on the node also when editting is turned on + useEffect(() => { + const map = mapRef.current; + if (map && stationLat) { + editting && map.setView([+stationLat, +stationLon], 13); + } + }, [mapRef, editting, stationLat, stationLon]); + + function onConfirmLocation() { + const position = mapRef.current.getCenter(); + changeLocation({ lat: position.lat, lon: position.lng }); + if (communityLayer) { + // Hide the community view, to avoid outdated links + toogleCommunityLayer(); + } + } + + function toogleCommunityLayer() { + if (communityLayer) { + mapRef.current.removeLayer(communityLayer); + setCommunityLayer(null); + } else { + const layer = getCommunityLayer( + boardData.hostname, + stationLat, + stationLon, + nodesData + ); + layer.addTo(mapRef.current); + setCommunityLayer(layer); + } + } + + function isReady() { + return !loading && typeof stationLat !== "undefined"; + } + + function toogleEdition() { + setEditting(!editting); + } + + if (isAssetError) { + return ( +
+ Cannot load map, check your internet connection +
+ ); + } + + return ( + <> + {(!isReady() || submitting) && ( +
+ +
+ )} + {isReady() && ( + + + + + + + + + + + + + {nodeMarker && ( + + )} + {editting && ( +
+ )} + + )} + {isReady() && ( +
+ {editting && ( + + )} + {!editting && ( + + )} + + +
+ )} + + ); +}; + +export default LocatePage; diff --git a/plugins/lime-plugin-node-admin/src/components/config/config.tsx b/plugins/lime-plugin-node-admin/src/components/config/config.tsx index e3cacb7f0..f3c4792e8 100644 --- a/plugins/lime-plugin-node-admin/src/components/config/config.tsx +++ b/plugins/lime-plugin-node-admin/src/components/config/config.tsx @@ -1,15 +1,17 @@ +import { ComponentChildren } from "preact"; + import { ListItem } from "components/list"; import Loading from "components/loading"; import style from "./config.style.less"; type ConfigProps = { - title: React.ReactNode, - subtitle?: React.ReactNode, - value: React.ReactNode, - onClick: () => void, - isLoading: boolean, -} + title: ComponentChildren; + subtitle?: ComponentChildren; + value: ComponentChildren; + onClick: () => void; + isLoading: boolean; +}; export const Config = ({ title, @@ -27,7 +29,12 @@ export const Config = ({ {isLoading && } {!isLoading && (
- {subtitle &&
{subtitle}
} + {subtitle && ( +
+ {" "} + {subtitle}{" "} +
+ )}
{value}
)} From f0b3c859aed5f13c6ab929bff2e59c113199874c Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 4 May 2023 09:52:11 +0200 Subject: [PATCH 014/121] chore(meshwide): fix ts errors --- src/components/bottom-sheet/BottomSheet.tsx | 1 + src/components/buttons/floatting-button.tsx | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/bottom-sheet/BottomSheet.tsx b/src/components/bottom-sheet/BottomSheet.tsx index c980793b2..c455a864f 100644 --- a/src/components/bottom-sheet/BottomSheet.tsx +++ b/src/components/bottom-sheet/BottomSheet.tsx @@ -99,6 +99,7 @@ export const BottomSheet: React.FC = ({ // HANDLERS const handlePointerDown = ( + // @ts-ignore e: React.TouchEvent | React.MouseEvent ) => { // @ts-ignore diff --git a/src/components/buttons/floatting-button.tsx b/src/components/buttons/floatting-button.tsx index 706ef41bd..79bd3579d 100644 --- a/src/components/buttons/floatting-button.tsx +++ b/src/components/buttons/floatting-button.tsx @@ -1,9 +1,10 @@ +import { ComponentChildren } from "preact"; import React from "react"; import { Button, ButtonProps } from "components/elements/button"; interface FloatingButtonProps { - children?: React.ReactNode | string; + children?: ComponentChildren | string; } const FloatingButton = ({ From 3d87aa30dcfff684c6f509a95873f4b58adf4312 Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 4 May 2023 10:40:40 +0200 Subject: [PATCH 015/121] chore(meshwide): split on different files --- .../src/components/Map.tsx | 21 ++++ .../src/components/MapBottomSheet.tsx | 63 ++++++++++++ .../src/meshWidePage.tsx | 95 +++---------------- 3 files changed, 98 insertions(+), 81 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/components/Map.tsx create mode 100644 plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map.tsx new file mode 100644 index 000000000..3ec793273 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/components/Map.tsx @@ -0,0 +1,21 @@ +import { MapContainer, TileLayer } from "react-leaflet"; + +const openStreetMapTileString = "http://{s}.tile.osm.org/{z}/{x}/{y}.png"; +const openStreetMapAttribution = + '© OpenStreetMap contributors'; + +export const MeshWideMap = () => { + return ( + + + + ); +}; diff --git a/plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet.tsx b/plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet.tsx new file mode 100644 index 000000000..ff4f451c0 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet.tsx @@ -0,0 +1,63 @@ +import { Trans } from "@lingui/macro"; +import { useState } from "preact/hooks"; +import React from "react"; + +import { BottomSheet } from "components/bottom-sheet"; +import FloatingButton from "components/buttons/floatting-button"; +import { Button } from "components/elements/button"; + +import { NodeDetail } from "plugins/lime-plugin-mesh-wide/src/components/NodeDetail"; + +const BottomSheetFooter = ({ synced }: { synced?: boolean }) => { + const containerClasses = + "flex items-center justify-center text-center bg-white py-5"; + return synced ? ( +
+ + Same status as in the reference state +
+ ) : ( + <> +
+
+ + ! + + In the reference state this node is on +
+ +
+ + ); +}; + +export const MapBottomSheet = () => { + const [isOpen, setIsOpen] = useState(false); + const synced = false; + + return ( + <> + { + setIsOpen(false); + }} + footer={} + > +
+ +
+
+ { + setIsOpen(!isOpen); + }} + /> + + ); +}; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx index 108cca241..9dfb80e08 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx @@ -1,63 +1,22 @@ -import { Trans } from "@lingui/macro"; -import L, { LeafletMouseEvent, Map } from "leaflet"; -import { useState } from "preact/hooks"; -import React, { Component } from "react"; -import { LayersControl, MapContainer, TileLayer, useMap } from "react-leaflet"; +import React from "react"; -import { BottomSheet } from "components/bottom-sheet"; -import FloatingButton from "components/buttons/floatting-button"; -import { Button } from "components/elements/button"; import Loading from "components/loading"; import { useLoadLeaflet } from "plugins/lime-plugin-locate/src/locateQueries"; -import style from "plugins/lime-plugin-locate/src/style.less"; -import { NodeDetail } from "plugins/lime-plugin-mesh-wide/src/components/NodeDetail"; - -const openStreetMapTileString = "http://{s}.tile.osm.org/{z}/{x}/{y}.png"; -const openStreetMapAttribution = - '© OpenStreetMap contributors'; - -const BottomSheetFooter = ({ synced }: { synced?: boolean }) => { - const containerClasses = - "flex items-center justify-center text-center bg-white py-5"; - return synced ? ( -
- - Same status as in the reference state -
- ) : ( - <> -
-
- - ! - - In the reference state this node is on -
- -
- - ); -}; +import { MeshWideMap } from "plugins/lime-plugin-mesh-wide/src/components/Map"; +import { MapBottomSheet } from "plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet"; const MeshWidePage = () => { - // const { - // isError: isAssetError, - // isFetchedAfterMount: assetsLoaded, - // isLoading: isLoadingAssets, - // } = useLoadLeaflet({ - // refetchOnWindowFocus: false, - // }); - // - // const loading = isLoadingAssets; + const { + isError: isAssetError, + isFetchedAfterMount: assetsLoaded, + isLoading: isLoadingAssets, + } = useLoadLeaflet({ + refetchOnWindowFocus: false, + }); + + const loading = isLoadingAssets; - const [isOpen, setIsOpen] = useState(true); - const synced = false; - const loading = false; return ( <> {loading && ( @@ -67,34 +26,8 @@ const MeshWidePage = () => { )} {!loading && ( <> - {/**/} - {/* */} - {/**/} - { - setIsOpen(false); - }} - footer={} - > -
- -
-
- { - setIsOpen(!isOpen); - }} - /> + + )} From 18bbf285f1f32c40eebe2f4ecfa97f00635ec9e9 Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 10 May 2023 17:10:55 +0200 Subject: [PATCH 016/121] chore(meshwide): show community layer Their components change the state on hover --- .../src/components/Map.tsx | 47 ++++++- .../src/components/Map/CommunityLayer.tsx | 123 ++++++++++++++++++ .../src/components/Map/style.less | 21 +++ .../src/mesWideQueries.tsx | 11 ++ 4 files changed, 200 insertions(+), 2 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx create mode 100644 plugins/lime-plugin-mesh-wide/src/components/Map/style.less create mode 100644 plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map.tsx index 3ec793273..f300db058 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map.tsx @@ -1,21 +1,64 @@ +import L, { Layer } from "leaflet"; +import { useEffect, useRef, useState } from "preact/hooks"; import { MapContainer, TileLayer } from "react-leaflet"; +import { getCommunityGeoJSON } from "plugins/lime-plugin-locate/src/communityGeoJSON"; +import { CommunityLayer } from "plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer"; +import { useMeshWide } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; +import { radioDataResponse } from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; + const openStreetMapTileString = "http://{s}.tile.osm.org/{z}/{x}/{y}.png"; const openStreetMapAttribution = '© OpenStreetMap contributors'; export const MeshWideMap = () => { + const [communityLayer, setCommunityLayer] = useState(null); + + const [selectedLayer, setSelectedLayer] = useState(null); + + const mapRef = useRef(); + + useEffect(() => { + if (mapRef) { + mapRef.current.on("click", () => { + console.log("map click!"); + setSelectedLayer(null); + }); + } + }, [mapRef]); + + useEffect(() => { + console.log("SELECTED LAYER", selectedLayer); + }, [selectedLayer]); + + const { data: meshWideStatus } = useMeshWide({ + onSuccess: (res) => { + const geoJson = getCommunityGeoJSON(radioDataResponse.result); // todo(kon): the locate page makes a correction with the own node if is modified + setCommunityLayer(geoJson); + }, + }); + return ( + {communityLayer && ( + + )} ); }; diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx new file mode 100644 index 000000000..f9a711036 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx @@ -0,0 +1,123 @@ +import * as geojson from "geojson"; +import L, { Layer } from "leaflet"; +import { GeoJSON, Marker } from "react-leaflet"; + +import style from "./style.less"; + +export const CommunityLayer = ({ + geoJsonData, + setSelectedLayer, +}: { + geoJsonData: geojson.GeoJsonObject; + setSelectedLayer: (layer: Layer | null) => void; +}) => { + const pointToLayer = (feature: any, latlng: any) => { + const marker = L.marker(latlng, { + icon: L.divIcon({ + // className: style.defaultMarker, + iconAnchor: [0, 24], + // labelAnchor: [-6, 0], + popupAnchor: [0, -36], + // html: ``, + html: ``, + }), + }); + + const featureGroup = L.featureGroup([marker]); + + marker.on("click", function (e) { + const markerTemp = L.marker(e.latlng, { + icon: L.divIcon({ + iconAnchor: [0, 24], + popupAnchor: [0, -36], + html: ``, + }), + }).addTo(featureGroup); + + // markerTemp.on("mouseout", function (e) { + // markerTemp.remove(); + // }); + }); + return featureGroup; + }; + + const onEachFeature = (feature, layer) => { + if (feature.properties && feature.properties.name) { + layer.bindTooltip(feature.properties.name).openTooltip(); + } + layer.on({ + click: (event) => { + // if (selectedLayer) { + // selectedLayer.setStyle(defaultStyle); + // } + // layer.setStyle(selectedStyle); + L.DomEvent.stopPropagation(event); + console.log("clicked! ", layer, feature); + // layer.setStyle(selectedStyle); + setSelectedLayer(layer); + }, + mouseover: (event: any) => { + const l = event.target; + const type: string = event.target.feature.geometry.type; + if (type === "LineString") { + l.setStyle({ + color: "#0000ff", + }); + } else if (type === "Point") { + } + }, + mouseout: (event: any) => { + const l = event.target; + const type: string = l.feature.geometry.type; + if (type === "LineString") { + l.setStyle(geoJsonStyle); + } else if (type === "Point") { + } + }, + }); + }; + + return ( + + ); +}; + +const geoJsonStyle = { + color: "#ff0000", // red + weight: 5, + opacity: 0.65, +}; + +const markerStyle = ` + background-color: #583470; + width: 3rem; + height: 3rem; + display: block; + left: -1.5rem; + top: -1.5rem; + position: relative; + border-radius: 3rem 3rem 0; + transform: rotate(45deg); + border: 1px solid #FFFFFF`; + +const markerStyle2 = ` + background-color: #fff; + width: 3rem; + height: 3rem; + display: block; + left: -1.5rem; + top: -1.5rem; + position: relative; + border-radius: 3rem 3rem 0; + transform: rotate(45deg); + border: 1px solid #FFFFFF`; + +// const markerDefault = ` +// ${marker} +// background-color: #583470; +// `; diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/style.less b/plugins/lime-plugin-mesh-wide/src/components/Map/style.less new file mode 100644 index 000000000..2b13e7a95 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/style.less @@ -0,0 +1,21 @@ +.defaultMarker { + background-color: #583470; + width: 3rem; + height: 3rem; + display: block; + left: -1.5rem; + top: -1.5rem; + position: relative; + border-radius: 3rem 3rem 0; + transform: rotate(45deg); + border: 1px solid #ffffff; +} + +.defaultMarker:hover { + background-color: #fff; +} + +.activeMarker { + //.defaultMarker:active { + background-color: green !important; +} diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx new file mode 100644 index 000000000..d8537a8a0 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx @@ -0,0 +1,11 @@ +import { useQuery } from "@tanstack/react-query"; +import { UseQueryOptions } from "@tanstack/react-query/src/types"; + +import { getRadioData } from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; + +// todo(kon): this is a mock +export function useMeshWide(params: UseQueryOptions) { + return useQuery(["lime-meshwide", "get_mesh_info"], getRadioData, { + ...params, + }); +} From 42bcbe66a91247cdd25d78b81d87325129b1d365 Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 16 May 2023 08:15:51 +0200 Subject: [PATCH 017/121] chore(meshwide): try to use a callback to select a layer --- .../src/components/Map.tsx | 24 +++++++++---- .../src/components/Map/CommunityLayer.tsx | 35 ++++++++++++++++--- 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map.tsx index f300db058..ce778c966 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map.tsx @@ -11,36 +11,47 @@ const openStreetMapTileString = "http://{s}.tile.osm.org/{z}/{x}/{y}.png"; const openStreetMapAttribution = '© OpenStreetMap contributors'; +export interface SelectedLater { + layer: any; + onRemove: () => void; +} + export const MeshWideMap = () => { const [communityLayer, setCommunityLayer] = useState(null); - const [selectedLayer, setSelectedLayer] = useState(null); + const [selectedLayer, setSelectedLayer] = useState( + null + ); const mapRef = useRef(); useEffect(() => { if (mapRef) { mapRef.current.on("click", () => { - console.log("map click!"); - setSelectedLayer(null); + console.log("map click!", selectedLayer); + if (selectedLayer !== null) { + selectedLayer.onRemove(); + setSelectedLayer(null); + } }); } - }, [mapRef]); + }, [mapRef, selectedLayer]); useEffect(() => { - console.log("SELECTED LAYER", selectedLayer); + console.log("SELECTED LAYER", selectedLayer, typeof selectedLayer); }, [selectedLayer]); const { data: meshWideStatus } = useMeshWide({ onSuccess: (res) => { const geoJson = getCommunityGeoJSON(radioDataResponse.result); // todo(kon): the locate page makes a correction with the own node if is modified + console.log("XXXXXXX", geoJson); setCommunityLayer(geoJson); }, }); return ( { )} diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx index f9a711036..9e1a3def9 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx @@ -2,14 +2,18 @@ import * as geojson from "geojson"; import L, { Layer } from "leaflet"; import { GeoJSON, Marker } from "react-leaflet"; +import { SelectedLater } from "plugins/lime-plugin-mesh-wide/src/components/Map"; + import style from "./style.less"; export const CommunityLayer = ({ geoJsonData, setSelectedLayer, + selectedLayer, }: { geoJsonData: geojson.GeoJsonObject; - setSelectedLayer: (layer: Layer | null) => void; + setSelectedLayer: (layer: SelectedLater | null) => void; + selectedLayer: SelectedLater; }) => { const pointToLayer = (feature: any, latlng: any) => { const marker = L.marker(latlng, { @@ -33,7 +37,17 @@ export const CommunityLayer = ({ html: ``, }), }).addTo(featureGroup); - + if (selectedLayer) { + selectedLayer.onRemove(); + } + console.log("marker click", markerTemp); + setSelectedLayer({ + layer: markerTemp, + onRemove: () => { + console.log("ONREMOVE MARKER"); + markerTemp.remove(); + }, + }); // markerTemp.on("mouseout", function (e) { // markerTemp.remove(); // }); @@ -52,9 +66,22 @@ export const CommunityLayer = ({ // } // layer.setStyle(selectedStyle); L.DomEvent.stopPropagation(event); - console.log("clicked! ", layer, feature); + console.log("line click! ", layer, feature); // layer.setStyle(selectedStyle); - setSelectedLayer(layer); + if (selectedLayer) { + selectedLayer.onRemove(); + } + layer.setStyle({ + color: "#0000ff", + }); + setSelectedLayer({ + layer, + onRemove: () => { + console.log("ONREMOVE LINE"); + + layer.setStyle(geoJsonStyle); + }, + }); }, mouseover: (event: any) => { const l = event.target; From d421123684b448d02fed04a5413dedaddebe5043 Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 16 May 2023 10:44:00 +0200 Subject: [PATCH 018/121] chore(meshwide): use react-leaflet components to show features --- .../src/components/Map.tsx | 44 ++-- .../src/components/Map/CommunityLayer.tsx | 217 +++++++----------- .../src/mesWideTypes.tsx | 26 +++ 3 files changed, 122 insertions(+), 165 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map.tsx index ce778c966..3efb65207 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map.tsx @@ -1,51 +1,45 @@ -import L, { Layer } from "leaflet"; +import { FeatureCollection } from "geojson"; +import L from "leaflet"; import { useEffect, useRef, useState } from "preact/hooks"; import { MapContainer, TileLayer } from "react-leaflet"; import { getCommunityGeoJSON } from "plugins/lime-plugin-locate/src/communityGeoJSON"; import { CommunityLayer } from "plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer"; import { useMeshWide } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; +import { SelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; import { radioDataResponse } from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; const openStreetMapTileString = "http://{s}.tile.osm.org/{z}/{x}/{y}.png"; const openStreetMapAttribution = '© OpenStreetMap contributors'; -export interface SelectedLater { - layer: any; - onRemove: () => void; -} - export const MeshWideMap = () => { - const [communityLayer, setCommunityLayer] = useState(null); + const [communityLayer, setCommunityLayer] = + useState(null); - const [selectedLayer, setSelectedLayer] = useState( - null - ); + const [selectedFeature, setSelectedFeature] = + useState(null); const mapRef = useRef(); useEffect(() => { if (mapRef) { mapRef.current.on("click", () => { - console.log("map click!", selectedLayer); - if (selectedLayer !== null) { - selectedLayer.onRemove(); - setSelectedLayer(null); + if (selectedFeature !== null) { + setSelectedFeature(null); } }); } - }, [mapRef, selectedLayer]); + }, [mapRef, selectedFeature]); useEffect(() => { - console.log("SELECTED LAYER", selectedLayer, typeof selectedLayer); - }, [selectedLayer]); + console.log("SelectedFeature", selectedFeature); + }, [selectedFeature]); const { data: meshWideStatus } = useMeshWide({ onSuccess: (res) => { const geoJson = getCommunityGeoJSON(radioDataResponse.result); // todo(kon): the locate page makes a correction with the own node if is modified - console.log("XXXXXXX", geoJson); - setCommunityLayer(geoJson); + setCommunityLayer(geoJson as FeatureCollection); }, }); @@ -64,13 +58,11 @@ export const MeshWideMap = () => { attribution={openStreetMapAttribution} url={openStreetMapTileString} /> - {communityLayer && ( - - )} + ); }; diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx index 9e1a3def9..eff2fce67 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx @@ -1,150 +1,89 @@ -import * as geojson from "geojson"; -import L, { Layer } from "leaflet"; -import { GeoJSON, Marker } from "react-leaflet"; +import { FeatureCollection } from "geojson"; +import L from "leaflet"; +import { Marker, Polyline, Tooltip } from "react-leaflet"; -import { SelectedLater } from "plugins/lime-plugin-mesh-wide/src/components/Map"; +import { SelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; import style from "./style.less"; export const CommunityLayer = ({ geoJsonData, - setSelectedLayer, - selectedLayer, + setSelectedFeature, + selectedFeature, }: { - geoJsonData: geojson.GeoJsonObject; - setSelectedLayer: (layer: SelectedLater | null) => void; - selectedLayer: SelectedLater; + geoJsonData: FeatureCollection; + setSelectedFeature: (layer: SelectedMapFeature | null) => void; + selectedFeature: SelectedMapFeature; }) => { - const pointToLayer = (feature: any, latlng: any) => { - const marker = L.marker(latlng, { - icon: L.divIcon({ - // className: style.defaultMarker, - iconAnchor: [0, 24], - // labelAnchor: [-6, 0], - popupAnchor: [0, -36], - // html: ``, - html: ``, - }), - }); - - const featureGroup = L.featureGroup([marker]); - - marker.on("click", function (e) { - const markerTemp = L.marker(e.latlng, { - icon: L.divIcon({ - iconAnchor: [0, 24], - popupAnchor: [0, -36], - html: ``, - }), - }).addTo(featureGroup); - if (selectedLayer) { - selectedLayer.onRemove(); - } - console.log("marker click", markerTemp); - setSelectedLayer({ - layer: markerTemp, - onRemove: () => { - console.log("ONREMOVE MARKER"); - markerTemp.remove(); - }, - }); - // markerTemp.on("mouseout", function (e) { - // markerTemp.remove(); - // }); - }); - return featureGroup; - }; - - const onEachFeature = (feature, layer) => { - if (feature.properties && feature.properties.name) { - layer.bindTooltip(feature.properties.name).openTooltip(); - } - layer.on({ - click: (event) => { - // if (selectedLayer) { - // selectedLayer.setStyle(defaultStyle); - // } - // layer.setStyle(selectedStyle); - L.DomEvent.stopPropagation(event); - console.log("line click! ", layer, feature); - // layer.setStyle(selectedStyle); - if (selectedLayer) { - selectedLayer.onRemove(); - } - layer.setStyle({ - color: "#0000ff", - }); - setSelectedLayer({ - layer, - onRemove: () => { - console.log("ONREMOVE LINE"); - - layer.setStyle(geoJsonStyle); - }, - }); - }, - mouseover: (event: any) => { - const l = event.target; - const type: string = event.target.feature.geometry.type; - if (type === "LineString") { - l.setStyle({ - color: "#0000ff", - }); - } else if (type === "Point") { - } - }, - mouseout: (event: any) => { - const l = event.target; - const type: string = l.feature.geometry.type; - if (type === "LineString") { - l.setStyle(geoJsonStyle); - } else if (type === "Point") { - } - }, - }); - }; - return ( - + <> + {geoJsonData && + geoJsonData.features.map((f, i) => { + if (f.geometry.type === "LineString") { + const lineColor = + selectedFeature?.id === i ? "#f000ff" : "#ff0000"; + return ( + + [...p].reverse() + )} + pathOptions={{ + color: lineColor, + weight: 5, + opacity: 0.65, + }} + eventHandlers={{ + click: (e) => { + L.DomEvent.stopPropagation(e); + setSelectedFeature({ + id: i, + feature: f, + }); + }, + mouseover: (e) => { + const l = e.target; + l.setStyle({ + color: "#0000ff", + }); + }, + mouseout: (event) => { + const l = event.target; + l.setStyle({ + color: lineColor, + }); + }, + }} + /> + ); + } else if (f.geometry.type === "Point") { + const selected = `${ + selectedFeature?.id === i && style.activeMarker + }`; + return ( + `, + })} + eventHandlers={{ + click: (e) => { + L.DomEvent.stopPropagation(e); + setSelectedFeature({ + id: i, + feature: f, + }); + }, + }} + > + {f.properties.name} + + ); + } + })} + ); }; - -const geoJsonStyle = { - color: "#ff0000", // red - weight: 5, - opacity: 0.65, -}; - -const markerStyle = ` - background-color: #583470; - width: 3rem; - height: 3rem; - display: block; - left: -1.5rem; - top: -1.5rem; - position: relative; - border-radius: 3rem 3rem 0; - transform: rotate(45deg); - border: 1px solid #FFFFFF`; - -const markerStyle2 = ` - background-color: #fff; - width: 3rem; - height: 3rem; - display: block; - left: -1.5rem; - top: -1.5rem; - position: relative; - border-radius: 3rem 3rem 0; - transform: rotate(45deg); - border: 1px solid #FFFFFF`; - -// const markerDefault = ` -// ${marker} -// background-color: #583470; -// `; diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx new file mode 100644 index 000000000..298266556 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -0,0 +1,26 @@ +import { Feature, GeometryObject } from "geojson"; + +export interface MeshWideStatus { + [key: string]: { + bleachTTL: number; + data: { + hostname: string; + coordinates: { + lon: string; + lat: string; + }; + macs: string[]; + links: string[]; + }; + author: string; + }; +} + +export interface IMeshWideStatusResponse { + result: MeshWideStatus; +} + +export interface SelectedMapFeature { + feature: Feature; + id: number; +} From 4f65718a3284ce93a167d1929667246e193d3e37 Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 17 May 2023 15:53:28 +0200 Subject: [PATCH 019/121] chore(meshwide): use query to store selected feature --- .../src/components/Map.tsx | 29 ++++++++++--------- .../src/components/Map/CommunityLayer.tsx | 17 ++++++----- .../src/mesWideQueries.tsx | 24 ++++++++++++++- 3 files changed, 48 insertions(+), 22 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map.tsx index 3efb65207..ae33f4679 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map.tsx @@ -5,7 +5,10 @@ import { MapContainer, TileLayer } from "react-leaflet"; import { getCommunityGeoJSON } from "plugins/lime-plugin-locate/src/communityGeoJSON"; import { CommunityLayer } from "plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer"; -import { useMeshWide } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; +import { + useMeshWide, + useSelectedMapFeature, +} from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; import { SelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; import { radioDataResponse } from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; @@ -17,24 +20,28 @@ export const MeshWideMap = () => { const [communityLayer, setCommunityLayer] = useState(null); - const [selectedFeature, setSelectedFeature] = - useState(null); + // const [selectedFeature, setSelectedFeature] = + // useState(null); + + const { selectedMapFeature, setSelectedMapFeature } = + // const { data: selectedMapFeature, mutate: setSelectedMapFeature} = + useSelectedMapFeature(); const mapRef = useRef(); useEffect(() => { if (mapRef) { mapRef.current.on("click", () => { - if (selectedFeature !== null) { - setSelectedFeature(null); + if (selectedMapFeature !== null) { + setSelectedMapFeature(null); } }); } - }, [mapRef, selectedFeature]); + }, [mapRef, selectedMapFeature]); useEffect(() => { - console.log("SelectedFeature", selectedFeature); - }, [selectedFeature]); + console.log("SelectedFeature", selectedMapFeature); + }, [selectedMapFeature]); const { data: meshWideStatus } = useMeshWide({ onSuccess: (res) => { @@ -58,11 +65,7 @@ export const MeshWideMap = () => { attribution={openStreetMapAttribution} url={openStreetMapTileString} /> - + ); }; diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx index eff2fce67..ed1f61917 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx @@ -2,26 +2,27 @@ import { FeatureCollection } from "geojson"; import L from "leaflet"; import { Marker, Polyline, Tooltip } from "react-leaflet"; +import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; import { SelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; import style from "./style.less"; export const CommunityLayer = ({ geoJsonData, - setSelectedFeature, - selectedFeature, }: { geoJsonData: FeatureCollection; - setSelectedFeature: (layer: SelectedMapFeature | null) => void; - selectedFeature: SelectedMapFeature; }) => { + const { selectedMapFeature, setSelectedMapFeature } = + useSelectedMapFeature(); return ( <> {geoJsonData && geoJsonData.features.map((f, i) => { if (f.geometry.type === "LineString") { const lineColor = - selectedFeature?.id === i ? "#f000ff" : "#ff0000"; + selectedMapFeature?.id === i + ? "#f000ff" + : "#ff0000"; return ( { L.DomEvent.stopPropagation(e); - setSelectedFeature({ + setSelectedMapFeature({ id: i, feature: f, }); @@ -58,7 +59,7 @@ export const CommunityLayer = ({ ); } else if (f.geometry.type === "Point") { const selected = `${ - selectedFeature?.id === i && style.activeMarker + selectedMapFeature?.id === i && style.activeMarker }`; return ( { L.DomEvent.stopPropagation(e); - setSelectedFeature({ + setSelectedMapFeature({ id: i, feature: f, }); diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx index d8537a8a0..2b3f1e478 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx @@ -1,11 +1,33 @@ -import { useQuery } from "@tanstack/react-query"; +import { useMutation, useQuery } from "@tanstack/react-query"; import { UseQueryOptions } from "@tanstack/react-query/src/types"; +import { upgradeConfirm } from "plugins/lime-plugin-firmware/src/firmwareApi"; +import { SelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; import { getRadioData } from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; +import queryCache from "utils/queryCache"; + // todo(kon): this is a mock export function useMeshWide(params: UseQueryOptions) { return useQuery(["lime-meshwide", "get_mesh_info"], getRadioData, { ...params, }); } + +/** + * This query is used to store the selected feature on the map. + * + * Used to store the state between components. + */ +export const useSelectedMapFeature = () => { + const { data: selectedMapFeature } = useQuery( + ["lime-meshwide", "select_map_feature"], + () => null + ); + const setSelectedMapFeature = (selected: SelectedMapFeature) => + queryCache.setQueryData( + ["lime-meshwide", "select_map_feature"], + selected + ); + return { selectedMapFeature, setSelectedMapFeature }; +}; From 10ad250d9f6e28d8078fc115b9ce8613a244b649 Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 18 May 2023 09:18:31 +0200 Subject: [PATCH 020/121] chore(meshwide): configure bottom sheet logic --- .../src/components/MapBottomSheet.tsx | 17 ++++++++++++++--- .../src/components/NodeDetail.tsx | 12 +++++++++--- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet.tsx b/plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet.tsx index ff4f451c0..099bea867 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet.tsx @@ -1,5 +1,5 @@ import { Trans } from "@lingui/macro"; -import { useState } from "preact/hooks"; +import { useEffect, useState } from "preact/hooks"; import React from "react"; import { BottomSheet } from "components/bottom-sheet"; @@ -7,6 +7,7 @@ import FloatingButton from "components/buttons/floatting-button"; import { Button } from "components/elements/button"; import { NodeDetail } from "plugins/lime-plugin-mesh-wide/src/components/NodeDetail"; +import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; const BottomSheetFooter = ({ synced }: { synced?: boolean }) => { const containerClasses = @@ -39,6 +40,16 @@ export const MapBottomSheet = () => { const [isOpen, setIsOpen] = useState(false); const synced = false; + const { selectedMapFeature } = useSelectedMapFeature(); + const name = + selectedMapFeature?.feature?.properties?.name ?? + selectedMapFeature?.id ?? + ""; + + useEffect(() => { + if (selectedMapFeature == null) setIsOpen(false); + }, [selectedMapFeature]); + return ( <> { footer={} >
- +
{ - setIsOpen(!isOpen); + if (selectedMapFeature) setIsOpen(!isOpen); }} /> diff --git a/plugins/lime-plugin-mesh-wide/src/components/NodeDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/NodeDetail.tsx index 178e58be4..c5072e10e 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/NodeDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/NodeDetail.tsx @@ -27,8 +27,14 @@ const Row = ({ children }: { children: any }) => { ); }; -export const NodeDetail = ({ synced }: { synced: boolean }) => { - const nodeName = "ql-arbol"; +export const NodeDetail = ({ + name, + synced, +}: { + name: string; + synced: boolean; +}) => { + // const nodeName = "ql-arbol"; const uptime = "1 week"; const firmware = "e93615c947-x86-64"; const ipv6 = "fe80::42:cff:fecf:bfff"; @@ -38,7 +44,7 @@ export const NodeDetail = ({ synced }: { synced: boolean }) => { return ( <> -
{nodeName}
+
{name}
From e4710671601be79c7843d4795038da6e0f040b74 Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 18 May 2023 11:01:55 +0200 Subject: [PATCH 021/121] chore(meshwide): implement bottom sheet for links behaviour --- .../src/components/FeatureDetail.tsx | 223 ++++++++++++++++++ .../src/components/MapBottomSheet.tsx | 53 ++--- .../src/components/NodeDetail.tsx | 77 ------ .../src/mesWideTypes.tsx | 15 ++ 4 files changed, 254 insertions(+), 114 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx delete mode 100644 plugins/lime-plugin-mesh-wide/src/components/NodeDetail.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx new file mode 100644 index 000000000..525e01fed --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx @@ -0,0 +1,223 @@ +import { Trans } from "@lingui/macro"; +import { VNode } from "preact"; + +import { Button } from "components/elements/button"; + +import { PowerIcon } from "plugins/lime-plugin-mesh-wide/src/icons/power"; +import { + ILinkDetailFeature, + INodeDetailFeature, + SelectedMapFeature, +} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; + +const TitleAndText = ({ + title, + children, +}: { + title: any; // todo(kon): error with trans component + children: string; +}) => { + return ( +
+
{title}
+
{children}
+
+ ); +}; + +const Row = ({ children }: { children: any }) => { + return ( +
+ {children} +
+ ); +}; + +const LinkDetails = ({ + linkDetails, + selectedFeature, +}: { + linkDetails: ILinkDetailFeature; + selectedFeature: SelectedMapFeature; +}) => { + const name = linkDetails?.name ?? selectedFeature?.id ?? ""; + const gain = "5 dB"; + const linkType = "Primary"; + + return ( + <> + +
+ Link + {name} +
+ +
+ + Gain}>{gain} + Link type}> + {linkType} + + + + ); +}; + +const NodeDetails = ({ + nodeDetail, + selectedFeature, + synced, +}: { + nodeDetail: INodeDetailFeature; + selectedFeature: SelectedMapFeature; + synced: boolean; +}) => { + const name = nodeDetail?.name ?? selectedFeature?.id ?? ""; + const uptime = "1 week"; + const firmware = "e93615c947-x86-64"; + const ipv6 = "fe80::42:cff:fecf:bfff"; + const ipv4 = "192.168.1.47"; + const device = "LibreRouter"; + + return ( + <> + +
{name}
+ +
+ + {synced ? ( + Uptime}> + {uptime} + + ) : ( + Downtime}> + {uptime} + + )} + Firmware version}> + {firmware} + + + + IPv4}>{ipv4} + IPv6}>{ipv6} + + + Device}> + {device} + + + + ); +}; + +export const FeatureDetail = ({ + selectedFeature, + synced, +}: { + selectedFeature: SelectedMapFeature; + synced: boolean; +}) => { + if (!selectedFeature) return; + switch (selectedFeature.feature.geometry.type) { + case "LineString": + return ( + + ); + case "Point": + return ( + + ); + default: + return <>; + } +}; + +export const BottomSheetFooter = ({ + synced, + selectedFeature, +}: { + synced?: boolean; + selectedFeature: SelectedMapFeature; +}) => { + if (!selectedFeature) return; + + const containerClasses = + "flex items-center justify-center text-center bg-white py-5"; + + const type = selectedFeature.feature.geometry.type; + + const Synced = () => { + let txt: VNode; + if (type === "LineString") { + txt = Same status as in the reference state; + } else if (type === "Point") { + txt = Same status as in the reference state; + } + + return ( +
+ + {txt} +
+ ); + }; + + const UpdateReference = () => { + let txt: VNode; + let btn: VNode; + if (type === "LineString") { + txt = ( + + This link has 5dB + {/*{*/} + {/* (*/} + {/* selectedFeature.feature*/} + {/* .properties as ILinkDetailFeature*/} + {/* ).gain*/} + {/*}{" "}*/} + difference with the reference state + + ); + btn = Update this link on reference state; + } else if (type === "Point") { + txt = Same status as in the reference state; + btn = Update this node on reference state; + } + return ( + <> +
+
+ + ! + + {txt} +
+ +
+ + ); + }; + + return synced ? : ; +}; diff --git a/plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet.tsx b/plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet.tsx index 099bea867..e5545245e 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet.tsx @@ -1,50 +1,20 @@ -import { Trans } from "@lingui/macro"; import { useEffect, useState } from "preact/hooks"; import React from "react"; import { BottomSheet } from "components/bottom-sheet"; import FloatingButton from "components/buttons/floatting-button"; -import { Button } from "components/elements/button"; -import { NodeDetail } from "plugins/lime-plugin-mesh-wide/src/components/NodeDetail"; +import { + BottomSheetFooter, + FeatureDetail, +} from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail"; import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; -const BottomSheetFooter = ({ synced }: { synced?: boolean }) => { - const containerClasses = - "flex items-center justify-center text-center bg-white py-5"; - return synced ? ( -
- - Same status as in the reference state -
- ) : ( - <> -
-
- - ! - - In the reference state this node is on -
- -
- - ); -}; - export const MapBottomSheet = () => { const [isOpen, setIsOpen] = useState(false); - const synced = false; + const synced: boolean = Math.random() < 0.5; const { selectedMapFeature } = useSelectedMapFeature(); - const name = - selectedMapFeature?.feature?.properties?.name ?? - selectedMapFeature?.id ?? - ""; useEffect(() => { if (selectedMapFeature == null) setIsOpen(false); @@ -58,10 +28,19 @@ export const MapBottomSheet = () => { onClose={() => { setIsOpen(false); }} - footer={} + initialDrawerDistanceTop={600} + footer={ + + } >
- +
{ - return ( -
-
{title}
-
{children}
-
- ); -}; - -const Row = ({ children }: { children: any }) => { - return ( -
- {children} -
- ); -}; - -export const NodeDetail = ({ - name, - synced, -}: { - name: string; - synced: boolean; -}) => { - // const nodeName = "ql-arbol"; - const uptime = "1 week"; - const firmware = "e93615c947-x86-64"; - const ipv6 = "fe80::42:cff:fecf:bfff"; - const ipv4 = "192.168.1.47"; - const device = "LibreRouter"; - - return ( - <> - -
{name}
- -
- - {synced ? ( - Uptime}> - {uptime} - - ) : ( - Downtime}> - {uptime} - - )} - Firmware version}> - {firmware} - - - - IPv4}>{ipv4} - IPv6}>{ipv6} - - - Device}> - {device} - - - - ); -}; diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index 298266556..510a5b97b 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -24,3 +24,18 @@ export interface SelectedMapFeature { feature: Feature; id: number; } + +export interface INodeDetailFeature { + name: string; + uptime: string; + firmware: string; + ipv6: string; + ipv4: string; + device: string; +} + +export interface ILinkDetailFeature { + name: string; + gain: string; + linkType: string; +} From 62979b9f43e19a6a8ef91b865109eabc89b43f73 Mon Sep 17 00:00:00 2001 From: selankon Date: Mon, 22 May 2023 17:55:29 +0200 Subject: [PATCH 022/121] chore(meshwide): split components to reuse them --- .../src/components/Components.tsx | 50 +++++++++++++++++++ .../src/components/FeatureDetail.tsx | 35 +++---------- 2 files changed, 58 insertions(+), 27 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/components/Components.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/components/Components.tsx b/plugins/lime-plugin-mesh-wide/src/components/Components.tsx new file mode 100644 index 000000000..3f0298c75 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/components/Components.tsx @@ -0,0 +1,50 @@ +import { VNode } from "preact"; + +import { Button } from "components/elements/button"; + +interface IStatusMessage { + isError: boolean; + children: VNode | string; +} + +export const StatusAndButton = ({ + isError, + children, + btn, + onClick, +}: { btn?: VNode | string; onClick?: () => void } & IStatusMessage) => { + const containerClasses = + "flex flex-col items-center justify-center text-center bg-white py-5 gap-3"; + + return ( +
+ {children} + {btn && } +
+ ); +}; + +export const StatusMessage = ({ + isError, + children, + classes, +}: { + classes?: string; +} & IStatusMessage) => ( +
+ {isError ? ( + + ! + + ) : ( + + )} + {children} +
+); diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx index 525e01fed..5fb46fe36 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx @@ -3,6 +3,7 @@ import { VNode } from "preact"; import { Button } from "components/elements/button"; +import { StatusAndButton } from "plugins/lime-plugin-mesh-wide/src/components/Components"; import { PowerIcon } from "plugins/lime-plugin-mesh-wide/src/icons/power"; import { ILinkDetailFeature, @@ -158,9 +159,6 @@ export const BottomSheetFooter = ({ }) => { if (!selectedFeature) return; - const containerClasses = - "flex items-center justify-center text-center bg-white py-5"; - const type = selectedFeature.feature.geometry.type; const Synced = () => { @@ -171,12 +169,7 @@ export const BottomSheetFooter = ({ txt = Same status as in the reference state; } - return ( -
- - {txt} -
- ); + return {txt}; }; const UpdateReference = () => { @@ -185,37 +178,25 @@ export const BottomSheetFooter = ({ if (type === "LineString") { txt = ( - This link has 5dB + This link has 5dB difference {/*{*/} {/* (*/} {/* selectedFeature.feature*/} {/* .properties as ILinkDetailFeature*/} {/* ).gain*/} {/*}{" "}*/} - difference with the reference state +
with the reference state
); btn = Update this link on reference state; } else if (type === "Point") { - txt = Same status as in the reference state; + txt = In the reference state this node is on; btn = Update this node on reference state; } return ( - <> -
-
- - ! - - {txt} -
- -
- + + {txt} + ); }; From ffc0241b2b709e4789647ba63ca6b44bebb8861c Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 23 May 2023 11:31:47 +0200 Subject: [PATCH 023/121] chore(meshwide): create mesh wide config page --- plugins/lime-plugin-mesh-wide/index.ts | 2 + .../src/components/MapBottomSheet.tsx | 8 +-- .../src/meshWidePage.tsx | 3 + .../src/screens/configPage.tsx | 72 +++++++++++++++++++ src/containers/Modal/FullScreenModal.tsx | 43 +++++++++++ 5 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx create mode 100644 src/containers/Modal/FullScreenModal.tsx diff --git a/plugins/lime-plugin-mesh-wide/index.ts b/plugins/lime-plugin-mesh-wide/index.ts index 1837c2c72..3ea2bc26a 100644 --- a/plugins/lime-plugin-mesh-wide/index.ts +++ b/plugins/lime-plugin-mesh-wide/index.ts @@ -1,8 +1,10 @@ import { MeshWideMenu } from "./src/meshWideMenu"; import MeshWidePage from "./src/meshWidePage"; +import MeshWideConfigPage from "./src/screens/configPage"; export default { name: "MeshWide", page: MeshWidePage, menu: MeshWideMenu, + additionalRoutes: [["/meshwide/config", MeshWideConfigPage]], } as LimePlugin; diff --git a/plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet.tsx b/plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet.tsx index e5545245e..839de3706 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet.tsx @@ -2,7 +2,6 @@ import { useEffect, useState } from "preact/hooks"; import React from "react"; import { BottomSheet } from "components/bottom-sheet"; -import FloatingButton from "components/buttons/floatting-button"; import { BottomSheetFooter, @@ -17,7 +16,7 @@ export const MapBottomSheet = () => { const { selectedMapFeature } = useSelectedMapFeature(); useEffect(() => { - if (selectedMapFeature == null) setIsOpen(false); + selectedMapFeature == null ? setIsOpen(false) : setIsOpen(true); }, [selectedMapFeature]); return ( @@ -43,11 +42,6 @@ export const MapBottomSheet = () => { />
- { - if (selectedMapFeature) setIsOpen(!isOpen); - }} - /> ); }; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx index 9dfb80e08..89c6158e4 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx @@ -1,5 +1,7 @@ +import { route } from "preact-router"; import React from "react"; +import FloatingButton from "components/buttons/floatting-button"; import Loading from "components/loading"; import { useLoadLeaflet } from "plugins/lime-plugin-locate/src/locateQueries"; @@ -28,6 +30,7 @@ const MeshWidePage = () => { <> + route("/meshwide/config")} /> )} diff --git a/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx b/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx new file mode 100644 index 000000000..1e13090ac --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx @@ -0,0 +1,72 @@ +import { Trans } from "@lingui/macro"; + +import { Collapsible } from "components/collapsible"; + +import { FullScreenModal } from "containers/Modal/FullScreenModal"; + +import { StatusAndButton } from "plugins/lime-plugin-mesh-wide/src/components/Components"; + +const MeshWideConfigPage = () => { + return ( + <> + Mesh wide config}> +
+ {dropdowns.map((dropdown, index) => ( + +
+ +
+
+ ))} +
+
+
+ +
+ 10 of 12 node are ready to update +
+ + Last update: 30 second ago + +
+
+
+ + + ); +}; + +export default MeshWideConfigPage; + +const dropdowns = [ + "Dropdown 1", + "Dropdown 2", + "Dropdown 3", + "Dropdown 1", + "Dropdown 2", + "Dropdown 3", + "Dropdown 1", + "Dropdown 2", + "Dropdown 3", + "Dropdown 1", + "Dropdown 2", + "Dropdown 3", + "Dropdown 1", + "Dropdown 2", + "Dropdown 3", + "Dropdown 1", + "Dropdown 2", + "Dropdown 3", + "Dropdown 1", + "Dropdown 2", + "Dropdown 3", + "Dropdown 1", + "Dropdown 2", + "Dropdown 3", +]; diff --git a/src/containers/Modal/FullScreenModal.tsx b/src/containers/Modal/FullScreenModal.tsx new file mode 100644 index 000000000..61488eba8 --- /dev/null +++ b/src/containers/Modal/FullScreenModal.tsx @@ -0,0 +1,43 @@ +import { ComponentChildren } from "preact"; +import { route } from "preact-router"; + +import Loading from "components/loading"; + +/** + * Used to show a new view with a close button that return to the backUrl param. Is placed over + * the navbar creating a modal like effect. + */ +export const FullScreenModal = ({ + title, + children, + isLoading, + backUrl = "/meshwide", +}: { + title: ComponentChildren; + children: ComponentChildren; + isLoading?: boolean; + backUrl?: string; +}) => { + if (isLoading) { + return ( +
+ +
+ ); + } + + return ( +
+
+
route(backUrl)} + > + X +
+
{title}
+
+
{children}
+
+ ); +}; From 9e498b5d93b5f393f1beed02870f59ec9d5d4f32 Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 24 May 2023 15:26:14 +0200 Subject: [PATCH 024/121] chore(src): refactor collapsible component style --- src/components/collapsible/index.js | 22 +++++++++-------- src/components/collapsible/style.less | 5 ---- src/components/icons/teenny/chevrons.jsx | 31 ++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 15 deletions(-) delete mode 100644 src/components/collapsible/style.less create mode 100644 src/components/icons/teenny/chevrons.jsx diff --git a/src/components/collapsible/index.js b/src/components/collapsible/index.js index 617f8ccee..ece805239 100644 --- a/src/components/collapsible/index.js +++ b/src/components/collapsible/index.js @@ -1,20 +1,22 @@ import { useToggle } from "react-use"; -import style from "./style.less"; +import { ChevronDown, ChevronUp } from "components/icons/teenny/chevrons"; export const Collapsible = ({ title, children, initCollapsed }) => { const [collapsed, toggleCollapsed] = useToggle(initCollapsed); + return ( -
-
-
{title}
-
{collapsed ? "ᐯ" : "ᐱ"}
+
+
+
{title}
+
+ {collapsed ? : } +
- {!collapsed &&
{children}
} + {!collapsed &&
{children}
}
); }; diff --git a/src/components/collapsible/style.less b/src/components/collapsible/style.less deleted file mode 100644 index cd5b92e9e..000000000 --- a/src/components/collapsible/style.less +++ /dev/null @@ -1,5 +0,0 @@ -.collapsible { - border: 1px solid #222; - padding: 1em; - border-radius: .5em; -} diff --git a/src/components/icons/teenny/chevrons.jsx b/src/components/icons/teenny/chevrons.jsx new file mode 100644 index 000000000..7a710f2a0 --- /dev/null +++ b/src/components/icons/teenny/chevrons.jsx @@ -0,0 +1,31 @@ +export const ChevronUp = () => ( + + + +); + +export const ChevronDown = () => ( + + + +); From fe94f16bf627f5121669e051b5865f7c93ad1b0d Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 24 May 2023 16:23:09 +0200 Subject: [PATCH 025/121] chore(meshwide): implement meshwide config object --- .../src/mesWideQueries.tsx | 25 ++++- .../src/mesWideTypes.tsx | 5 + .../src/screens/configPage.tsx | 99 +++++++++---------- 3 files changed, 71 insertions(+), 58 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx index 2b3f1e478..5f62a85e9 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx @@ -1,9 +1,15 @@ -import { useMutation, useQuery } from "@tanstack/react-query"; +import { useQuery } from "@tanstack/react-query"; import { UseQueryOptions } from "@tanstack/react-query/src/types"; -import { upgradeConfirm } from "plugins/lime-plugin-firmware/src/firmwareApi"; -import { SelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; -import { getRadioData } from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; +import { + IMeshWideConfig, + IMeshWideStatusResponse, + SelectedMapFeature, +} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +import { + getMeshWideConfig, + getRadioData, +} from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; import queryCache from "utils/queryCache"; @@ -14,6 +20,17 @@ export function useMeshWide(params: UseQueryOptions) { }); } +// todo(kon): this is a mock +export function useMeshWideConfig(params) { + return useQuery( + ["lime-meshwide", "get_mesh_config"], + getMeshWideConfig, + { + ...params, + } + ); +} + /** * This query is used to store the selected feature on the map. * diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index 510a5b97b..53ad35dba 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -39,3 +39,8 @@ export interface ILinkDetailFeature { gain: string; linkType: string; } + +export type IMeshWideConfig = { + name: string; + options: { [key: string]: string }; +}[]; diff --git a/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx b/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx index 1e13090ac..25d431c58 100644 --- a/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx +++ b/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx @@ -5,68 +5,59 @@ import { Collapsible } from "components/collapsible"; import { FullScreenModal } from "containers/Modal/FullScreenModal"; import { StatusAndButton } from "plugins/lime-plugin-mesh-wide/src/components/Components"; +import { useMeshWideConfig } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; const MeshWideConfigPage = () => { + const { data: meshWideConfig, isLoading } = useMeshWideConfig({}); return ( <> - Mesh wide config}> -
- {dropdowns.map((dropdown, index) => ( - -
- -
-
- ))} -
-
-
- -
- 10 of 12 node are ready to update -
- - Last update: 30 second ago - + Mesh wide config} + isLoading={isLoading} + > + {meshWideConfig && ( + <> +
+ {meshWideConfig.map((dropdown, index) => ( + +
+ {Object.entries(dropdown.options).map( + ([key, value]) => ( +
+ {key}: + {value} +
+ ) + )} +
+
+ ))}
- -
+
+
+ +
+ + 10 of 12 node are ready to update + +
+ + + Last update: 30 second ago + + +
+
+
+ + )} ); }; export default MeshWideConfigPage; - -const dropdowns = [ - "Dropdown 1", - "Dropdown 2", - "Dropdown 3", - "Dropdown 1", - "Dropdown 2", - "Dropdown 3", - "Dropdown 1", - "Dropdown 2", - "Dropdown 3", - "Dropdown 1", - "Dropdown 2", - "Dropdown 3", - "Dropdown 1", - "Dropdown 2", - "Dropdown 3", - "Dropdown 1", - "Dropdown 2", - "Dropdown 3", - "Dropdown 1", - "Dropdown 2", - "Dropdown 3", - "Dropdown 1", - "Dropdown 2", - "Dropdown 3", -]; From bd21e0aba392479be03a8535229dd630e975e7b3 Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 24 May 2023 16:23:21 +0200 Subject: [PATCH 026/121] chore(meshwide): fix isLoading --- src/containers/Modal/FullScreenModal.tsx | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/containers/Modal/FullScreenModal.tsx b/src/containers/Modal/FullScreenModal.tsx index 61488eba8..12e6b95a2 100644 --- a/src/containers/Modal/FullScreenModal.tsx +++ b/src/containers/Modal/FullScreenModal.tsx @@ -18,14 +18,6 @@ export const FullScreenModal = ({ isLoading?: boolean; backUrl?: string; }) => { - if (isLoading) { - return ( -
- -
- ); - } - return (
@@ -37,7 +29,13 @@ export const FullScreenModal = ({
{title}
-
{children}
+ {isLoading ? ( +
+ +
+ ) : ( +
{children}
+ )}
); }; From e7c763284e1d3028e384431b43905c85baac5e85 Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 25 May 2023 10:36:15 +0200 Subject: [PATCH 027/121] chore(meshwide): move to proper side --- src/components/{elements => buttons}/button.tsx | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/components/{elements => buttons}/button.tsx (100%) diff --git a/src/components/elements/button.tsx b/src/components/buttons/button.tsx similarity index 100% rename from src/components/elements/button.tsx rename to src/components/buttons/button.tsx From 2bdf49c19c2bfabbe0456f48a4e204c003360a90 Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 26 May 2023 10:29:28 +0200 Subject: [PATCH 028/121] chore(meshwide): fix buttons path --- plugins/lime-plugin-mesh-wide/src/components/Components.tsx | 2 +- plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx | 2 +- src/components/buttons/floatting-button.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/Components.tsx b/plugins/lime-plugin-mesh-wide/src/components/Components.tsx index 3f0298c75..419e95e1a 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Components.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Components.tsx @@ -1,6 +1,6 @@ import { VNode } from "preact"; -import { Button } from "components/elements/button"; +import { Button } from "components/buttons/button"; interface IStatusMessage { isError: boolean; diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx index 5fb46fe36..b02ba0417 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx @@ -1,7 +1,7 @@ import { Trans } from "@lingui/macro"; import { VNode } from "preact"; -import { Button } from "components/elements/button"; +import { Button } from "components/buttons/button"; import { StatusAndButton } from "plugins/lime-plugin-mesh-wide/src/components/Components"; import { PowerIcon } from "plugins/lime-plugin-mesh-wide/src/icons/power"; diff --git a/src/components/buttons/floatting-button.tsx b/src/components/buttons/floatting-button.tsx index 79bd3579d..aac72bae0 100644 --- a/src/components/buttons/floatting-button.tsx +++ b/src/components/buttons/floatting-button.tsx @@ -1,7 +1,7 @@ import { ComponentChildren } from "preact"; import React from "react"; -import { Button, ButtonProps } from "components/elements/button"; +import { Button, ButtonProps } from "components/buttons/button"; interface FloatingButtonProps { children?: ComponentChildren | string; From 2320dc90da0280d2a993756cb280326a71d5e915 Mon Sep 17 00:00:00 2001 From: selankon Date: Mon, 29 May 2023 10:38:31 +0200 Subject: [PATCH 029/121] chore(meshwide): implement mesh wide config form --- .../src/components/Components.tsx | 15 +++ .../src/components/configPage/OptionForm.tsx | 98 +++++++++++++++++++ .../src/screens/configPage.tsx | 46 ++++++--- src/components/buttons/button.tsx | 9 +- src/components/collapsible/index.js | 10 +- src/components/divider/index.tsx | 10 ++ src/components/icons/SvgIcon.tsx | 42 ++++++++ src/components/icons/bin.tsx | 17 ++++ src/components/icons/edit.tsx | 17 ++++ src/components/inputs/InputField.tsx | 31 ++++++ src/containers/Modal/FullScreenModal.tsx | 4 +- tailwind.config.js | 1 + 12 files changed, 283 insertions(+), 17 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm.tsx create mode 100644 src/components/divider/index.tsx create mode 100644 src/components/icons/SvgIcon.tsx create mode 100644 src/components/icons/bin.tsx create mode 100644 src/components/icons/edit.tsx create mode 100644 src/components/inputs/InputField.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/components/Components.tsx b/plugins/lime-plugin-mesh-wide/src/components/Components.tsx index 419e95e1a..fe0373c70 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Components.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Components.tsx @@ -1,6 +1,8 @@ import { VNode } from "preact"; import { Button } from "components/buttons/button"; +import { BinIcon } from "components/icons/bin"; +import { EditIcon } from "components/icons/edit"; interface IStatusMessage { isError: boolean; @@ -48,3 +50,16 @@ export const StatusMessage = ({ {children}
); + +export const EditOrDelete = ({ + onEdit, + onDelete, +}: { + onEdit: (e) => void; + onDelete: (e) => void; +}) => ( +
+ + +
+); diff --git a/plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm.tsx b/plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm.tsx new file mode 100644 index 000000000..c9855ae75 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm.tsx @@ -0,0 +1,98 @@ +import { Trans } from "@lingui/macro"; +import { useState } from "preact/hooks"; +import { SubmitHandler, useForm } from "react-hook-form"; + +import { Button } from "components/buttons/button"; +import Divider from "components/divider"; +import InputField from "components/inputs/InputField"; + +import { EditOrDelete } from "plugins/lime-plugin-mesh-wide/src/components/Components"; + +const EditOptionForm = ({ + keyString, + value, + onSubmit, +}: { + keyString: string; + value: string; + onSubmit?: (data) => void; +}) => { + const { + register, + handleSubmit, + formState: { errors }, + } = useForm({ + defaultValues: { key: keyString, value }, + }); + + const _onSubmit: SubmitHandler = (data) => { + onSubmit(data); + }; + + return ( +
+ Key} + register={register} + /> + Value} + register={register} + /> + + + ); +}; + +export const OptionContainer = ({ + keyString, + value, +}: { + keyString: string; + value: string; +}) => { + const [isEditing, setIsEditing] = useState(false); + + const toggleIsEditing = () => setIsEditing(!isEditing); + + return ( +
+
+ +
+
+ {!isEditing ? ( + <> +
+
{keyString}
+ {}} + /> +
+
{value}
+ + ) : ( + { + toggleIsEditing(); + }} + /> + )} +
+
+ ); +}; diff --git a/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx b/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx index 25d431c58..b6da7a2cb 100644 --- a/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx +++ b/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx @@ -1,10 +1,24 @@ import { Trans } from "@lingui/macro"; +import { ComponentChild } from "preact"; +import { useState } from "preact/hooks"; +import { FieldValues, Path, SubmitHandler, useForm } from "react-hook-form"; +import { UseFormRegister } from "react-hook-form/dist/types/form"; +import { RegisterOptions } from "react-hook-form/dist/types/validator"; +import { Button } from "components/buttons/button"; import { Collapsible } from "components/collapsible"; +import Divider from "components/divider"; +import { BinIcon } from "components/icons/bin"; +import { EditIcon } from "components/icons/edit"; +import InputField from "components/inputs/InputField"; import { FullScreenModal } from "containers/Modal/FullScreenModal"; -import { StatusAndButton } from "plugins/lime-plugin-mesh-wide/src/components/Components"; +import { + EditOrDelete, + StatusAndButton, +} from "plugins/lime-plugin-mesh-wide/src/components/Components"; +import { OptionContainer } from "plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm"; import { useMeshWideConfig } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; const MeshWideConfigPage = () => { @@ -23,22 +37,30 @@ const MeshWideConfigPage = () => { key={index} title={dropdown.name} initCollapsed={true} + optionsComponent={ + {}} + onDelete={() => {}} + /> + } > -
- {Object.entries(dropdown.options).map( - ([key, value]) => ( -
- {key}: - {value} -
- ) - )} -
+ {Object.entries(dropdown.options).map( + ([key, value]) => ( + + ) + )} ))} +
-
+
diff --git a/src/components/buttons/button.tsx b/src/components/buttons/button.tsx index f50622207..93f7d99f4 100644 --- a/src/components/buttons/button.tsx +++ b/src/components/buttons/button.tsx @@ -4,7 +4,7 @@ export interface ButtonProps { onClick?: () => void; children?: any; // type error with Trans component size?: "sm" | "md" | "lg"; - color?: "primary" | "secondary" | "danger"; + color?: "primary" | "secondary" | "danger" | "info"; href?: string; outline?: boolean; } @@ -47,12 +47,17 @@ export const Button = ({ colorClasses = outline ? "border-2 border-danger text-danger hover:bg-danger hover:text-white" : "bg-danger text-white border-2 border-danger hover:text-danger hover:bg-white"; + break; + case "info": + colorClasses = outline + ? "border-2 border-button-info text-button-info hover:bg-button-info hover:text-white" + : "bg-button-info text-white border-2 border-button-info hover:text-button-info hover:bg-white"; + break; } const cls = `cursor-pointer font-semibold rounded-xl text-center place-content-center transition-all duration-300 justify-center border-0 ${sizeClasses} ${colorClasses}`; const Btn = () => ( - // @ts-ignore
{children}
diff --git a/src/components/collapsible/index.js b/src/components/collapsible/index.js index ece805239..3713a9e16 100644 --- a/src/components/collapsible/index.js +++ b/src/components/collapsible/index.js @@ -2,7 +2,12 @@ import { useToggle } from "react-use"; import { ChevronDown, ChevronUp } from "components/icons/teenny/chevrons"; -export const Collapsible = ({ title, children, initCollapsed }) => { +export const Collapsible = ({ + title, + children, + initCollapsed, + optionsComponent = null, +}) => { const [collapsed, toggleCollapsed] = useToggle(initCollapsed); return ( @@ -12,7 +17,8 @@ export const Collapsible = ({ title, children, initCollapsed }) => { onClick={toggleCollapsed} >
{title}
-
+
+ {optionsComponent} {collapsed ? : }
diff --git a/src/components/divider/index.tsx b/src/components/divider/index.tsx new file mode 100644 index 000000000..f7cf81b71 --- /dev/null +++ b/src/components/divider/index.tsx @@ -0,0 +1,10 @@ +type DividerColors = "gray" | "white"; +const Divider = ({ color = "gray" }: { color?: DividerColors }) => ( +
+); + +export default Divider; diff --git a/src/components/icons/SvgIcon.tsx b/src/components/icons/SvgIcon.tsx new file mode 100644 index 000000000..b699343d7 --- /dev/null +++ b/src/components/icons/SvgIcon.tsx @@ -0,0 +1,42 @@ +import { VNode } from "preact"; + +export interface IconProps { + width?: string; + height?: string; + className?: string; + dataTestId?: string; + fill?: string; + onClick?: (e) => void; +} + +interface SvgIconProps { + children?: VNode; + viewBox?: string; +} + +export const SvgIcon = ({ + children, + viewBox = "0 0 24 24", + className = "h-8 w-8", // 32px + dataTestId = "", + fill = "", + width, + height, + onClick, +}: SvgIconProps & IconProps) => { + return ( +
+ + {children} + +
+ ); +}; diff --git a/src/components/icons/bin.tsx b/src/components/icons/bin.tsx new file mode 100644 index 000000000..b26c2a9a8 --- /dev/null +++ b/src/components/icons/bin.tsx @@ -0,0 +1,17 @@ +import { IconProps, SvgIcon } from "components/icons/SvgIcon"; + +export const BinIcon = ({ ...props }: IconProps) => ( + + + +); diff --git a/src/components/icons/edit.tsx b/src/components/icons/edit.tsx new file mode 100644 index 000000000..a5f6f90a4 --- /dev/null +++ b/src/components/icons/edit.tsx @@ -0,0 +1,17 @@ +import { IconProps, SvgIcon } from "components/icons/SvgIcon"; + +export const EditIcon = ({ ...props }: IconProps) => ( + + + +); diff --git a/src/components/inputs/InputField.tsx b/src/components/inputs/InputField.tsx new file mode 100644 index 000000000..2adc49556 --- /dev/null +++ b/src/components/inputs/InputField.tsx @@ -0,0 +1,31 @@ +import { ComponentChild } from "preact"; +import { FieldValues, Path } from "react-hook-form"; +import { UseFormRegister } from "react-hook-form/dist/types/form"; +import { RegisterOptions } from "react-hook-form/dist/types/validator"; + +const InputField = ({ + id, + label, + register, + options, +}: { + id: Path; + label: string | ComponentChild; + register?: UseFormRegister; + options?: RegisterOptions; +}) => { + return ( +
+ + +
+ ); +}; + +export default InputField; diff --git a/src/containers/Modal/FullScreenModal.tsx b/src/containers/Modal/FullScreenModal.tsx index 12e6b95a2..7dec9c634 100644 --- a/src/containers/Modal/FullScreenModal.tsx +++ b/src/containers/Modal/FullScreenModal.tsx @@ -34,7 +34,9 @@ export const FullScreenModal = ({
) : ( -
{children}
+
+ {children} +
)}
); diff --git a/tailwind.config.js b/tailwind.config.js index 6c22aec49..1789829ba 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -21,6 +21,7 @@ module.exports = { button: { primary: "#1BC47D", secondary: "#6BC3AE", + info: "#00ADEE", }, danger: "#EB7575", info: "#EAAB7E", From ebfab261f0c91a48318aaacb096da5ca08515072 Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 30 May 2023 09:59:03 +0200 Subject: [PATCH 030/121] chore(components): implement modal provider --- src/components/app.tsx | 7 +- src/components/buttons/button.tsx | 2 +- src/containers/Modal/Modal.tsx | 165 ++++++++++++++++++++++++++++++ 3 files changed, 171 insertions(+), 3 deletions(-) create mode 100644 src/containers/Modal/Modal.tsx diff --git a/src/components/app.tsx b/src/components/app.tsx index d14b9ac75..d880175ef 100644 --- a/src/components/app.tsx +++ b/src/components/app.tsx @@ -7,6 +7,7 @@ import { useEffect } from "preact/hooks"; import { Provider } from "react-redux"; import { Menu } from "containers/Menu"; +import { UseModalProvider } from "containers/Modal/Modal"; import { RebootPage } from "containers/RebootPage"; import SubHeader from "containers/SubHeader"; @@ -111,8 +112,10 @@ const AppDefault = () => { {/* @ts-ignore */} - {/* @ts-ignore */} - + + {/* @ts-ignore */} + + diff --git a/src/components/buttons/button.tsx b/src/components/buttons/button.tsx index 93f7d99f4..8240491bc 100644 --- a/src/components/buttons/button.tsx +++ b/src/components/buttons/button.tsx @@ -1,7 +1,7 @@ import React from "react"; export interface ButtonProps { - onClick?: () => void; + onClick?: (e) => void; children?: any; // type error with Trans component size?: "sm" | "md" | "lg"; color?: "primary" | "secondary" | "danger" | "info"; diff --git a/src/containers/Modal/Modal.tsx b/src/containers/Modal/Modal.tsx new file mode 100644 index 000000000..714523218 --- /dev/null +++ b/src/containers/Modal/Modal.tsx @@ -0,0 +1,165 @@ +import { Trans } from "@lingui/macro"; +import { ComponentChildren, createContext } from "preact"; +import { useContext, useState } from "preact/hooks"; +import { useCallback } from "react"; + +import { Button } from "components/buttons/button"; +import Divider from "components/divider"; + +interface ModalContextProps { + isModalOpen: boolean; + toggleModal: () => void; + setModalState: (state?: ModalState) => void; +} + +interface ModalState { + content?: ComponentChildren; + title: ComponentChildren | string; + cancelBtn?: boolean; + successCb?: (e) => void; + successBtnText?: ComponentChildren; + deleteCb?: (e) => void; + deleteBtnText?: ComponentChildren; +} + +const ModalContext = createContext({ + isModalOpen: false, + toggleModal: () => {}, + setModalState: () => {}, +}); + +export const useModal = () => useContext(ModalContext); + +export type ModalActions = "success" | "delete"; + +export const UseModalProvider = ({ children }) => { + const [isModalOpen, setModalOpen] = useState(false); + const [modalState, setModalState] = useState({ + content: <>, + title: "", + cancelBtn: false, + successCb: () => {}, + successBtnText: Success, + deleteCb: () => {}, + deleteBtnText: Cancel, + }); + + const toggleModal = useCallback(() => { + setModalOpen((prevIsModalOpen) => !prevIsModalOpen); + }, [isModalOpen]); + + return ( + + {children} + + {modalState.content} + + + ); +}; + +const Modal = ({ + isModalOpen, + toggleModal, + children, + title, + cancelBtn = true, + successCb, + successBtnText = Success, + deleteCb, + deleteBtnText = Cancel, +}: { + isModalOpen: boolean; + toggleModal: () => void; + children?: ComponentChildren; +} & ModalState) => { + const stopPropagation = (e) => { + e.stopPropagation(); + }; + return ( + <> +
+
+ + + ); +}; + +export default Modal; From d03e93765635d0aefd43bd5d55d65148a89792e2 Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 31 May 2023 15:54:43 +0200 Subject: [PATCH 031/121] chore(meshwide): implement modals --- .../src/components/configPage/OptionForm.tsx | 12 ++- .../src/components/modals.tsx | 101 ++++++++++++++++++ .../src/screens/configPage.tsx | 51 +++++++-- 3 files changed, 152 insertions(+), 12 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/components/modals.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm.tsx b/plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm.tsx index c9855ae75..9ae25201a 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm.tsx @@ -7,6 +7,7 @@ import Divider from "components/divider"; import InputField from "components/inputs/InputField"; import { EditOrDelete } from "plugins/lime-plugin-mesh-wide/src/components/Components"; +import { useDeletePropModal } from "plugins/lime-plugin-mesh-wide/src/components/modals"; const EditOptionForm = ({ keyString, @@ -62,6 +63,9 @@ export const OptionContainer = ({ const toggleIsEditing = () => setIsEditing(!isEditing); + const { toggleModal: toggleDeleteModal, actionModal: deletePropModal } = + useDeletePropModal(); + return (
@@ -78,7 +82,13 @@ export const OptionContainer = ({
{keyString}
{}} + onDelete={(e) => { + e.stopPropagation(); + deletePropModal(keyString, () => { + console.log("delete stuff"); + toggleDeleteModal(); + }); + }} />
{value}
diff --git a/plugins/lime-plugin-mesh-wide/src/components/modals.tsx b/plugins/lime-plugin-mesh-wide/src/components/modals.tsx new file mode 100644 index 000000000..02cd4d0aa --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/components/modals.tsx @@ -0,0 +1,101 @@ +import { Trans } from "@lingui/macro"; +import { ComponentChildren } from "preact"; +import { useCallback } from "preact/compat"; + +import { ModalActions, useModal } from "containers/Modal/Modal"; + +const useActionModal = ( + title: ComponentChildren, + btnText: ComponentChildren, + actionName: ModalActions +) => { + const { toggleModal, setModalState } = useModal(); + + const actionModal = useCallback( + (prop: string, actionCb: () => void) => { + setModalState({ + content: ( +
+ + Are you sure you want to {title} the{" "} + {prop} property? + +
+ ), + title, + [`${actionName}Cb`]: actionCb, + [`${actionName}BtnText`]: btnText, + }); + toggleModal(); + }, + [setModalState, toggleModal] + ); + return { actionModal, toggleModal }; +}; + +export const useDeletePropModal = () => + useActionModal( + Delete property, + Delete, + "delete" + ); + +export const useEditPropModal = () => + useActionModal( + Edit property, + Edit, + "success" + ); + +// import { Trans } from "@lingui/macro"; +// import { useCallback } from "preact/compat"; +// +// import { useModal } from "containers/Modal/Modal"; +// +// export const useDeletePropModal = () => { +// const { toggleModal, setModalState } = useModal(); +// +// const deletePropModal = useCallback( +// (prop: string, deleteCb: () => void) => { +// setModalState({ +// content: ( +//
+// +// Are you sure you want to delete the{" "} +// {prop} property? +// +//
+// ), +// title: Delete property, +// onDelete: deleteCb, +// deleteBtnText: Delete, +// }); +// toggleModal(); +// }, +// [setModalState, toggleModal] +// ); +// return { deletePropModal, toggleModal }; +// }; +// +// export const useEditPropModal = () => { +// const { toggleModal, setModalState } = useModal(); +// +// const editProperty = (prop: string, editCb: () => void) => { +// setModalState({ +// content: ( +//
+// +// Do you want to edit the {prop}{" "} +// property? +// +//
+// ), +// title: Edit property, +// onSuccess: editCb, +// successBtnText: Edit, +// // onSuccess: toggleModal, +// }); +// toggleModal(); +// }; +// return { editProperty, toggleModal }; +// }; diff --git a/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx b/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx index b6da7a2cb..5befbc74b 100644 --- a/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx +++ b/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx @@ -1,28 +1,32 @@ import { Trans } from "@lingui/macro"; -import { ComponentChild } from "preact"; -import { useState } from "preact/hooks"; -import { FieldValues, Path, SubmitHandler, useForm } from "react-hook-form"; -import { UseFormRegister } from "react-hook-form/dist/types/form"; -import { RegisterOptions } from "react-hook-form/dist/types/validator"; +import { useCallback } from "preact/compat"; +import { to } from "react-spring"; import { Button } from "components/buttons/button"; import { Collapsible } from "components/collapsible"; import Divider from "components/divider"; -import { BinIcon } from "components/icons/bin"; -import { EditIcon } from "components/icons/edit"; -import InputField from "components/inputs/InputField"; import { FullScreenModal } from "containers/Modal/FullScreenModal"; +import { useModal } from "containers/Modal/Modal"; import { EditOrDelete, StatusAndButton, } from "plugins/lime-plugin-mesh-wide/src/components/Components"; import { OptionContainer } from "plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm"; +import { + useDeletePropModal, + useEditPropModal, +} from "plugins/lime-plugin-mesh-wide/src/components/modals"; import { useMeshWideConfig } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; const MeshWideConfigPage = () => { const { data: meshWideConfig, isLoading } = useMeshWideConfig({}); + const { toggleModal: toggleDeleteModal, actionModal: deletePropModal } = + useDeletePropModal(); + const { toggleModal: toggleEditModal, actionModal: editProperty } = + useEditPropModal(); + return ( <> { initCollapsed={true} optionsComponent={ {}} - onDelete={() => {}} + onEdit={(e) => { + e.stopPropagation(); + editProperty( + dropdown.name, + () => { + console.log( + "edit stuff" + ); + toggleEditModal(); + } + ); + }} + onDelete={(e) => { + e.stopPropagation(); + deletePropModal( + dropdown.name, + () => { + console.log( + "delete stuff" + ); + toggleDeleteModal(); + } + ); + }} /> } > @@ -55,7 +81,10 @@ const MeshWideConfigPage = () => { )} ))} -
From 642b8758e545eed91470a11fea4280a694282429 Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 1 Jun 2023 15:57:55 +0200 Subject: [PATCH 032/121] chore(components): move modal folder --- plugins/lime-plugin-mesh-wide/src/components/modals.tsx | 2 +- plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx | 1 + src/{containers => components}/Modal/FullScreenModal.tsx | 0 src/{containers => components}/Modal/Modal.tsx | 8 +++++++- src/components/app.tsx | 3 ++- 5 files changed, 11 insertions(+), 3 deletions(-) rename src/{containers => components}/Modal/FullScreenModal.tsx (100%) rename src/{containers => components}/Modal/Modal.tsx (96%) diff --git a/plugins/lime-plugin-mesh-wide/src/components/modals.tsx b/plugins/lime-plugin-mesh-wide/src/components/modals.tsx index 02cd4d0aa..70315cd36 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/modals.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/modals.tsx @@ -2,7 +2,7 @@ import { Trans } from "@lingui/macro"; import { ComponentChildren } from "preact"; import { useCallback } from "preact/compat"; -import { ModalActions, useModal } from "containers/Modal/Modal"; +import { ModalActions, useModal } from "components/Modal/Modal"; const useActionModal = ( title: ComponentChildren, diff --git a/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx b/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx index 5befbc74b..9f5f0d696 100644 --- a/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx +++ b/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx @@ -2,6 +2,7 @@ import { Trans } from "@lingui/macro"; import { useCallback } from "preact/compat"; import { to } from "react-spring"; +import { FullScreenModal } from "components/Modal/FullScreenModal"; import { Button } from "components/buttons/button"; import { Collapsible } from "components/collapsible"; import Divider from "components/divider"; diff --git a/src/containers/Modal/FullScreenModal.tsx b/src/components/Modal/FullScreenModal.tsx similarity index 100% rename from src/containers/Modal/FullScreenModal.tsx rename to src/components/Modal/FullScreenModal.tsx diff --git a/src/containers/Modal/Modal.tsx b/src/components/Modal/Modal.tsx similarity index 96% rename from src/containers/Modal/Modal.tsx rename to src/components/Modal/Modal.tsx index 714523218..1d8fffc84 100644 --- a/src/containers/Modal/Modal.tsx +++ b/src/components/Modal/Modal.tsx @@ -28,7 +28,13 @@ const ModalContext = createContext({ setModalState: () => {}, }); -export const useModal = () => useContext(ModalContext); +export const useModal = () => { + const context = useContext(ModalContext); + if (context === undefined) { + throw new Error("useModal must be used within a UseModalProvider"); + } + return context; +}; export type ModalActions = "success" | "delete"; diff --git a/src/components/app.tsx b/src/components/app.tsx index d880175ef..aee575d07 100644 --- a/src/components/app.tsx +++ b/src/components/app.tsx @@ -6,8 +6,9 @@ import Router from "preact-router"; import { useEffect } from "preact/hooks"; import { Provider } from "react-redux"; +import { UseModalProvider } from "components/Modal/Modal"; + import { Menu } from "containers/Menu"; -import { UseModalProvider } from "containers/Modal/Modal"; import { RebootPage } from "containers/RebootPage"; import SubHeader from "containers/SubHeader"; From d63c82bfd1b03da2d3832407d9b0733d46f7f5f2 Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 1 Jun 2023 16:14:17 +0200 Subject: [PATCH 033/121] chore(components): improve toast Use provider Add functionalities --- src/components/app.tsx | 7 ++- src/components/toast/index.tsx | 75 +++++++++++++++++++++++--- src/components/toast/style.less | 30 ++++++----- src/components/toast/toastProvider.tsx | 38 +++++++++++++ 4 files changed, 128 insertions(+), 22 deletions(-) create mode 100644 src/components/toast/toastProvider.tsx diff --git a/src/components/app.tsx b/src/components/app.tsx index aee575d07..a35407e04 100644 --- a/src/components/app.tsx +++ b/src/components/app.tsx @@ -7,6 +7,7 @@ import { useEffect } from "preact/hooks"; import { Provider } from "react-redux"; import { UseModalProvider } from "components/Modal/Modal"; +import { ToastProvider } from "components/toast/toastProvider"; import { Menu } from "containers/Menu"; import { RebootPage } from "containers/RebootPage"; @@ -114,8 +115,10 @@ const AppDefault = () => { - {/* @ts-ignore */} - + + {/* @ts-ignore */} + + diff --git a/src/components/toast/index.tsx b/src/components/toast/index.tsx index cf72a3eaf..102a67c45 100644 --- a/src/components/toast/index.tsx +++ b/src/components/toast/index.tsx @@ -1,14 +1,19 @@ import { ComponentChildren } from "preact"; +import { useEffect, useState } from "preact/hooks"; +import { animated, useSpring } from "react-spring"; import style from "./style.less"; type ToastType = "success" | "error" | "info"; -type ToastProps = { +export interface IToastProps { text: ComponentChildren; type?: ToastType; onHide?: () => void; -}; + onAction?: () => void; + actionText?: string; + duration?: number; +} const getStyle = (type: ToastType) => { switch (type) { @@ -21,12 +26,66 @@ const getStyle = (type: ToastType) => { } }; -const Toast = ({ text, type = "info", onHide }: ToastProps) => ( -
-
- {text} +const Toast = ({ + text, + type = "info", + onHide, + onAction, + actionText = "Undo", + duration, +}: IToastProps) => { + const [showToast, setShowToast] = useState(true); + const _onAction = () => { + if (onAction) onAction(); + }; + + const _onHide = () => { + setShowToast(false); + if (onHide) onHide(); + }; + + const animationProps = useSpring({ + from: { transform: "translateY(180%)" }, + to: { transform: "translateY(0)" }, + config: { duration: 30 }, + }); + + useEffect(() => { + if (duration) { + const timer = setTimeout(() => { + _onHide(); + }, duration); + return () => clearTimeout(timer); + } + }, [duration, _onHide]); + + if (!showToast) return; + + return ( +
+ { + e.stopPropagation(); + _onHide(); + }} + > +
{text}
+ {onAction && ( +
{ + e.stopPropagation(); + _onAction(); + }} + className={"text-primary-light"} + > + {actionText} +
+ )} +
-
-); + ); +}; export default Toast; diff --git a/src/components/toast/style.less b/src/components/toast/style.less index 849af08d2..818f8f4c0 100644 --- a/src/components/toast/style.less +++ b/src/components/toast/style.less @@ -1,20 +1,26 @@ .toastWrapper { - width: 100%; - position: fixed; - z-index: 99990; - bottom: 0px; - right: 0px; + width: 100%; + position: fixed; + z-index: 99990; + bottom: 40px; + right: 0px; } .toast { - background: #000; - margin: 2em 2em; - text-align: center; + background: #313033; + margin: 2em 2em; transition: all 250ms ease-in; - color: #FFF; - cursor: pointer; - padding: 0.5em; -}; + color: #fff; + cursor: pointer; + padding: 14px 16px; + box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); + border-radius: 4px; + + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; +} .success { background: #389256; diff --git a/src/components/toast/toastProvider.tsx b/src/components/toast/toastProvider.tsx new file mode 100644 index 000000000..76eccb50d --- /dev/null +++ b/src/components/toast/toastProvider.tsx @@ -0,0 +1,38 @@ +import { ComponentChildren } from "preact"; +import React, { createContext, useContext, useState } from "react"; + +import Toast, { IToastProps } from "components/toast/index"; + +const ToastContext = createContext< + | { + showToast: (toastProps: IToastProps) => void; + hideToast: () => void; + } + | undefined +>(undefined); + +interface ToastProviderProps { + children: ComponentChildren; +} + +export const ToastProvider: React.FC = ({ children }) => { + const [toastProps, setToastProps] = useState(null); + + const showToast = (props: IToastProps) => setToastProps(props); + const hideToast = () => setToastProps(null); + + return ( + + {children} + {toastProps && } + + ); +}; + +export const useToast = () => { + const context = useContext(ToastContext); + if (context === undefined) { + throw new Error("useToast must be used within a ToastProvider"); + } + return context; +}; From f291433a612500d87f6e3bbebcbc85b0ff7785bd Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 2 Jun 2023 15:46:55 +0200 Subject: [PATCH 034/121] chore(meshwide): implement add new section modal --- .../src/components/modals.tsx | 87 +++++++---------- .../src/screens/configPage.tsx | 93 +++++++++++++++++-- 2 files changed, 119 insertions(+), 61 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/modals.tsx b/plugins/lime-plugin-mesh-wide/src/components/modals.tsx index 70315cd36..44aec6123 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/modals.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/modals.tsx @@ -1,8 +1,10 @@ import { Trans } from "@lingui/macro"; import { ComponentChildren } from "preact"; import { useCallback } from "preact/compat"; +import { useForm } from "react-hook-form"; import { ModalActions, useModal } from "components/Modal/Modal"; +import InputField from "components/inputs/InputField"; const useActionModal = ( title: ComponentChildren, @@ -47,55 +49,36 @@ export const useEditPropModal = () => "success" ); -// import { Trans } from "@lingui/macro"; -// import { useCallback } from "preact/compat"; -// -// import { useModal } from "containers/Modal/Modal"; -// -// export const useDeletePropModal = () => { -// const { toggleModal, setModalState } = useModal(); -// -// const deletePropModal = useCallback( -// (prop: string, deleteCb: () => void) => { -// setModalState({ -// content: ( -//
-// -// Are you sure you want to delete the{" "} -// {prop} property? -// -//
-// ), -// title: Delete property, -// onDelete: deleteCb, -// deleteBtnText: Delete, -// }); -// toggleModal(); -// }, -// [setModalState, toggleModal] -// ); -// return { deletePropModal, toggleModal }; -// }; -// -// export const useEditPropModal = () => { -// const { toggleModal, setModalState } = useModal(); -// -// const editProperty = (prop: string, editCb: () => void) => { -// setModalState({ -// content: ( -//
-// -// Do you want to edit the {prop}{" "} -// property? -// -//
-// ), -// title: Edit property, -// onSuccess: editCb, -// successBtnText: Edit, -// // onSuccess: toggleModal, -// }); -// toggleModal(); -// }; -// return { editProperty, toggleModal }; -// }; +export const useAddNewSectionModal = () => { + const { toggleModal, setModalState } = useModal(); + + const { + register, + handleSubmit, + formState: { errors }, + } = useForm({ + defaultValues: { name: "" }, + }); + + const actionModal = useCallback( + (actionCb: (data) => void) => { + setModalState({ + content: ( +
+ Name} + register={register} + /> +
+ ), + title: Add new section, + successCb: handleSubmit(actionCb), + successBtnText: Add, + }); + toggleModal(); + }, + [setModalState, toggleModal] + ); + return { actionModal, toggleModal }; +}; diff --git a/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx b/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx index 9f5f0d696..4ef276c16 100644 --- a/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx +++ b/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx @@ -1,14 +1,10 @@ import { Trans } from "@lingui/macro"; -import { useCallback } from "preact/compat"; -import { to } from "react-spring"; import { FullScreenModal } from "components/Modal/FullScreenModal"; import { Button } from "components/buttons/button"; import { Collapsible } from "components/collapsible"; import Divider from "components/divider"; - -import { FullScreenModal } from "containers/Modal/FullScreenModal"; -import { useModal } from "containers/Modal/Modal"; +import { useToast } from "components/toast/toastProvider"; import { EditOrDelete, @@ -16,6 +12,7 @@ import { } from "plugins/lime-plugin-mesh-wide/src/components/Components"; import { OptionContainer } from "plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm"; import { + useAddNewSectionModal, useDeletePropModal, useEditPropModal, } from "plugins/lime-plugin-mesh-wide/src/components/modals"; @@ -25,8 +22,12 @@ const MeshWideConfigPage = () => { const { data: meshWideConfig, isLoading } = useMeshWideConfig({}); const { toggleModal: toggleDeleteModal, actionModal: deletePropModal } = useDeletePropModal(); - const { toggleModal: toggleEditModal, actionModal: editProperty } = + const { toggleModal: toggleEditModal, actionModal: editPropertyModal } = useEditPropModal(); + const { toggleModal: toggleNewSectionModal, actionModal: addSectionModal } = + useAddNewSectionModal(); + + const { showToast, hideToast } = useToast(); return ( <> @@ -46,13 +47,33 @@ const MeshWideConfigPage = () => { { e.stopPropagation(); - editProperty( + editPropertyModal( dropdown.name, () => { console.log( "edit stuff" ); toggleEditModal(); + showToast({ + text: ( + <> + + Edited + + { + dropdown.name + } + {" - "} + {new Date().toDateString()} + + ), + duration: 5000, + onAction: () => { + console.log( + "Undo action" + ); + }, + }); } ); }} @@ -65,6 +86,26 @@ const MeshWideConfigPage = () => { "delete stuff" ); toggleDeleteModal(); + showToast({ + text: ( + <> + + Deleted + {" "} + { + dropdown.name + } + {" - "} + {new Date().toDateString()} + + ), + duration: 5000, + onAction: () => { + console.log( + "Undo action" + ); + }, + }); } ); }} @@ -84,14 +125,48 @@ const MeshWideConfigPage = () => { ))}
- + { + showToast({ + text: ( + <> + + Updating shared state + {" "} + {new Date().toDateString()} + + ), + duration: 5000, + }); + }} + >
10 of 12 node are ready to update From a606f004afa23c7482794a79a62654ceb9953314 Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 2 Jun 2023 16:11:36 +0200 Subject: [PATCH 035/121] chore(meshwide): split code --- .../components/configPage/ConfigSection.tsx | 113 +++++++++++++ .../src/components/configPage/MeshStatus.tsx | 35 ++++ .../src/mesWideTypes.tsx | 6 +- .../src/screens/configPage.tsx | 156 ++---------------- 4 files changed, 164 insertions(+), 146 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/components/configPage/ConfigSection.tsx create mode 100644 plugins/lime-plugin-mesh-wide/src/components/configPage/MeshStatus.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/components/configPage/ConfigSection.tsx b/plugins/lime-plugin-mesh-wide/src/components/configPage/ConfigSection.tsx new file mode 100644 index 000000000..28016483b --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/components/configPage/ConfigSection.tsx @@ -0,0 +1,113 @@ +import { Trans } from "@lingui/macro"; + +import { Button } from "components/buttons/button"; +import { Collapsible } from "components/collapsible"; +import { useToast } from "components/toast/toastProvider"; + +import { EditOrDelete } from "plugins/lime-plugin-mesh-wide/src/components/Components"; +import { OptionContainer } from "plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm"; +import { + useAddNewSectionModal, + useDeletePropModal, + useEditPropModal, +} from "plugins/lime-plugin-mesh-wide/src/components/modals"; +import { IMeshWideSection } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; + +export const ConfigSection = ({ dropdown }: { dropdown: IMeshWideSection }) => { + return ( + } + > + {Object.entries(dropdown.options).map(([key, value]) => ( + + ))} + + ); +}; + +export const SectionEditOrDelete = ({ name }) => { + const { toggleModal: toggleDeleteModal, actionModal: deletePropModal } = + useDeletePropModal(); + const { toggleModal: toggleEditModal, actionModal: editPropertyModal } = + useEditPropModal(); + + const { showToast, hideToast } = useToast(); + + return ( + { + e.stopPropagation(); + editPropertyModal(name, () => { + console.log("edit stuff"); + toggleEditModal(); + showToast({ + text: ( + <> + Edited + {name} + {" - "} + {new Date().toDateString()} + + ), + duration: 5000, + onAction: () => { + console.log("Undo action"); + }, + }); + }); + }} + onDelete={(e) => { + e.stopPropagation(); + deletePropModal(name, () => { + console.log("delete stuff"); + toggleDeleteModal(); + showToast({ + text: ( + <> + Deleted {name} + {" - "} + {new Date().toDateString()} + + ), + duration: 5000, + onAction: () => { + console.log("Undo action"); + }, + }); + }); + }} + /> + ); +}; + +export const AddNewSectionBtn = () => { + const { toggleModal: toggleNewSectionModal, actionModal: addSectionModal } = + useAddNewSectionModal(); + + const { showToast, hideToast } = useToast(); + return ( + + ); +}; diff --git a/plugins/lime-plugin-mesh-wide/src/components/configPage/MeshStatus.tsx b/plugins/lime-plugin-mesh-wide/src/components/configPage/MeshStatus.tsx new file mode 100644 index 000000000..bd0de9b15 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/components/configPage/MeshStatus.tsx @@ -0,0 +1,35 @@ +import { Trans } from "@lingui/macro"; + +import { useToast } from "components/toast/toastProvider"; + +import { StatusAndButton } from "plugins/lime-plugin-mesh-wide/src/components/Components"; + +export const MeshStatus = () => { + const { showToast, hideToast } = useToast(); + + return ( + { + showToast({ + text: ( + <> + Updating shared state{" "} + {new Date().toDateString()} + + ), + duration: 5000, + }); + }} + > +
+ 10 of 12 node are ready to update +
+ + Last update: 30 second ago + +
+
+ ); +}; diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index 53ad35dba..569fbea8a 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -40,7 +40,9 @@ export interface ILinkDetailFeature { linkType: string; } -export type IMeshWideConfig = { +export interface IMeshWideSection { name: string; options: { [key: string]: string }; -}[]; +} + +export type IMeshWideConfig = [IMeshWideSection]; diff --git a/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx b/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx index 4ef276c16..8ac751b23 100644 --- a/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx +++ b/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx @@ -10,6 +10,12 @@ import { EditOrDelete, StatusAndButton, } from "plugins/lime-plugin-mesh-wide/src/components/Components"; +import { + AddNewSectionBtn, + ConfigSection, + SectionEditOrDelete, +} from "plugins/lime-plugin-mesh-wide/src/components/configPage/ConfigSection"; +import { MeshStatus } from "plugins/lime-plugin-mesh-wide/src/components/configPage/MeshStatus"; import { OptionContainer } from "plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm"; import { useAddNewSectionModal, @@ -20,14 +26,6 @@ import { useMeshWideConfig } from "plugins/lime-plugin-mesh-wide/src/mesWideQuer const MeshWideConfigPage = () => { const { data: meshWideConfig, isLoading } = useMeshWideConfig({}); - const { toggleModal: toggleDeleteModal, actionModal: deletePropModal } = - useDeletePropModal(); - const { toggleModal: toggleEditModal, actionModal: editPropertyModal } = - useEditPropModal(); - const { toggleModal: toggleNewSectionModal, actionModal: addSectionModal } = - useAddNewSectionModal(); - - const { showToast, hideToast } = useToast(); return ( <> @@ -39,146 +37,16 @@ const MeshWideConfigPage = () => { <>
{meshWideConfig.map((dropdown, index) => ( - { - e.stopPropagation(); - editPropertyModal( - dropdown.name, - () => { - console.log( - "edit stuff" - ); - toggleEditModal(); - showToast({ - text: ( - <> - - Edited - - { - dropdown.name - } - {" - "} - {new Date().toDateString()} - - ), - duration: 5000, - onAction: () => { - console.log( - "Undo action" - ); - }, - }); - } - ); - }} - onDelete={(e) => { - e.stopPropagation(); - deletePropModal( - dropdown.name, - () => { - console.log( - "delete stuff" - ); - toggleDeleteModal(); - showToast({ - text: ( - <> - - Deleted - {" "} - { - dropdown.name - } - {" - "} - {new Date().toDateString()} - - ), - duration: 5000, - onAction: () => { - console.log( - "Undo action" - ); - }, - }); - } - ); - }} - /> - } - > - {Object.entries(dropdown.options).map( - ([key, value]) => ( - - ) - )} - + dropdown={dropdown} + /> ))} - +
-
+
- { - showToast({ - text: ( - <> - - Updating shared state - {" "} - {new Date().toDateString()} - - ), - duration: 5000, - }); - }} - > -
- - 10 of 12 node are ready to update - -
- - - Last update: 30 second ago - - -
-
+
)} From 445376e0743e7bca7cbbb2e6fc3452cb741c39f8 Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 2 Jun 2023 16:30:23 +0200 Subject: [PATCH 036/121] chore(meshwide): fix form modal and toasts --- .../src/components/configPage/OptionForm.tsx | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm.tsx b/plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm.tsx index 9ae25201a..a5fddb2db 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm.tsx @@ -5,9 +5,13 @@ import { SubmitHandler, useForm } from "react-hook-form"; import { Button } from "components/buttons/button"; import Divider from "components/divider"; import InputField from "components/inputs/InputField"; +import { useToast } from "components/toast/toastProvider"; import { EditOrDelete } from "plugins/lime-plugin-mesh-wide/src/components/Components"; -import { useDeletePropModal } from "plugins/lime-plugin-mesh-wide/src/components/modals"; +import { + useDeletePropModal, + useEditPropModal, +} from "plugins/lime-plugin-mesh-wide/src/components/modals"; const EditOptionForm = ({ keyString, @@ -65,6 +69,9 @@ export const OptionContainer = ({ const { toggleModal: toggleDeleteModal, actionModal: deletePropModal } = useDeletePropModal(); + const { toggleModal: toggleEditModal, actionModal: editPropertyModal } = + useEditPropModal(); + const { showToast, hideToast } = useToast(); return (
@@ -87,6 +94,18 @@ export const OptionContainer = ({ deletePropModal(keyString, () => { console.log("delete stuff"); toggleDeleteModal(); + showToast({ + text: ( + <> + Deleted{" "} + {keyString} + + ), + duration: 5000, + onAction: () => { + console.log("Undo action"); + }, + }); }); }} /> @@ -98,7 +117,19 @@ export const OptionContainer = ({ keyString={keyString} value={value} onSubmit={(data) => { - toggleIsEditing(); + editPropertyModal(keyString, () => { + console.log("edited stuff"); + toggleEditModal(); + toggleIsEditing(); + showToast({ + text: ( + <> + Edited {keyString} + + ), + duration: 5000, + }); + }); }} /> )} From 50283bdeeb9191508b4b6bdc02e7315ddf0a51f4 Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 6 Jun 2023 17:22:54 +0200 Subject: [PATCH 037/121] chore(meshwide): add markers sync styles --- .../src/components/Map/CommunityLayer.tsx | 13 +++-- .../src/components/Map/style.less | 51 ++++++++++++++----- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx index ed1f61917..cb8aed5db 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx @@ -18,6 +18,8 @@ export const CommunityLayer = ({ <> {geoJsonData && geoJsonData.features.map((f, i) => { + const synced: boolean = Math.random() < 0.5; + if (f.geometry.type === "LineString") { const lineColor = selectedMapFeature?.id === i @@ -58,17 +60,22 @@ export const CommunityLayer = ({ /> ); } else if (f.geometry.type === "Point") { - const selected = `${ - selectedMapFeature?.id === i && style.activeMarker + const markerClasses = `${ + selectedMapFeature?.id === i && style.selectedMarker + } ${ + synced ? style.syncedMarker : style.notSyncedMarker }`; return ( `, + // html: ``, + // html: ``, + html: ``, })} eventHandlers={{ click: (e) => { diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/style.less b/plugins/lime-plugin-mesh-wide/src/components/Map/style.less index 2b13e7a95..769c88c0d 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/style.less +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/style.less @@ -1,21 +1,46 @@ +@good: #76bd7d; +@warning: #eaab7e; +@bad: #eb7575; + +//Delete a leaflet strange div +.leaflet-div-custom-icon { + background: none !important; + border: none !important; +} + +// Default Marker shape .defaultMarker { - background-color: #583470; + position: absolute; + left: -1.4rem; + top: -1.5rem; + border-radius: 50% 50% 50% 0; width: 3rem; height: 3rem; - display: block; - left: -1.5rem; - top: -1.5rem; - position: relative; - border-radius: 3rem 3rem 0; - transform: rotate(45deg); - border: 1px solid #ffffff; + transform: rotate(-45deg); } - -.defaultMarker:hover { +.defaultMarker::after { + position: absolute; + content: ""; + width: 8px; + height: 8px; + border-radius: 50%; + top: 55%; + left: 56%; + margin-left: -6px; + margin-top: -5px; background-color: #fff; } -.activeMarker { - //.defaultMarker:active { - background-color: green !important; +// Marker status colors +.syncedMarker { + background-color: @good; +} +.notSyncedMarker { + background-color: @bad; +} + +// Selected marker feature +.selectedMarker, +.defaultMarker:hover { + border: 2px solid black; } From 3fbc9636458533ebe6255127f2e7df9d8a4c0aae Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 8 Jun 2023 16:50:28 +0200 Subject: [PATCH 038/121] chore(meshwide): use query properly --- plugins/lime-plugin-mesh-wide/src/components/Map.tsx | 2 +- plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map.tsx index ae33f4679..4f315c017 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map.tsx @@ -45,7 +45,7 @@ export const MeshWideMap = () => { const { data: meshWideStatus } = useMeshWide({ onSuccess: (res) => { - const geoJson = getCommunityGeoJSON(radioDataResponse.result); // todo(kon): the locate page makes a correction with the own node if is modified + const geoJson = getCommunityGeoJSON(res.result); // todo(kon): the locate page makes a correction with the own node if is modified setCommunityLayer(geoJson as FeatureCollection); }, }); diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx index 5f62a85e9..d8b7fcfc3 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx @@ -14,10 +14,14 @@ import { import queryCache from "utils/queryCache"; // todo(kon): this is a mock -export function useMeshWide(params: UseQueryOptions) { - return useQuery(["lime-meshwide", "get_mesh_info"], getRadioData, { - ...params, - }); +export function useMeshWide(params) { + return useQuery( + ["lime-meshwide", "get_mesh_info"], + getRadioData, + { + ...params, + } + ); } // todo(kon): this is a mock From 0aa958cba43a2df477c0752030425b057c6e1fc5 Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 8 Jun 2023 16:51:17 +0200 Subject: [PATCH 039/121] chore(meshwide): fix link lines styles --- .../src/components/Map/CommunityLayer.tsx | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx index cb8aed5db..d7e91067f 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx @@ -3,7 +3,6 @@ import L from "leaflet"; import { Marker, Polyline, Tooltip } from "react-leaflet"; import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; -import { SelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; import style from "./style.less"; @@ -21,21 +20,21 @@ export const CommunityLayer = ({ const synced: boolean = Math.random() < 0.5; if (f.geometry.type === "LineString") { - const lineColor = - selectedMapFeature?.id === i - ? "#f000ff" - : "#ff0000"; + const isSelected = selectedMapFeature?.id === i; + const getPathOpts = (isSelected) => { + return { + color: synced ? "#76bd7d" : "#eb7575", + weight: isSelected ? 7 : 5, + opacity: isSelected ? 1 : 0.8, + }; + }; return ( [...p].reverse() )} - pathOptions={{ - color: lineColor, - weight: 5, - opacity: 0.65, - }} + pathOptions={getPathOpts(isSelected)} eventHandlers={{ click: (e) => { L.DomEvent.stopPropagation(e); @@ -46,15 +45,11 @@ export const CommunityLayer = ({ }, mouseover: (e) => { const l = e.target; - l.setStyle({ - color: "#0000ff", - }); + l.setStyle(getPathOpts(true)); }, mouseout: (event) => { const l = event.target; - l.setStyle({ - color: lineColor, - }); + l.setStyle(getPathOpts(isSelected)); }, }} /> From 1037af75343206daaa4a433dd37c9c98cf25b713 Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 3 Aug 2023 16:27:50 +0200 Subject: [PATCH 040/121] chore(meshwide): create shared data hook --- .../src/components/Map.tsx | 4 +-- .../src/components/Map/CommunityLayer.tsx | 2 +- .../src/components/MapBottomSheet.tsx | 2 +- .../src/mesWideQueries.tsx | 27 ++++++++++--------- src/utils/useSharedData.ts | 17 ++++++++++++ 5 files changed, 35 insertions(+), 17 deletions(-) create mode 100644 src/utils/useSharedData.ts diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map.tsx index 4f315c017..2cbad6c3b 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map.tsx @@ -9,8 +9,6 @@ import { useMeshWide, useSelectedMapFeature, } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; -import { SelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; -import { radioDataResponse } from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; const openStreetMapTileString = "http://{s}.tile.osm.org/{z}/{x}/{y}.png"; const openStreetMapAttribution = @@ -23,7 +21,7 @@ export const MeshWideMap = () => { // const [selectedFeature, setSelectedFeature] = // useState(null); - const { selectedMapFeature, setSelectedMapFeature } = + const { data: selectedMapFeature, setData: setSelectedMapFeature } = // const { data: selectedMapFeature, mutate: setSelectedMapFeature} = useSelectedMapFeature(); diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx index d7e91067f..b894614e0 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx @@ -11,7 +11,7 @@ export const CommunityLayer = ({ }: { geoJsonData: FeatureCollection; }) => { - const { selectedMapFeature, setSelectedMapFeature } = + const { data: selectedMapFeature, setData: setSelectedMapFeature } = useSelectedMapFeature(); return ( <> diff --git a/plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet.tsx b/plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet.tsx index 839de3706..1258b288a 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet.tsx @@ -13,7 +13,7 @@ export const MapBottomSheet = () => { const [isOpen, setIsOpen] = useState(false); const synced: boolean = Math.random() < 0.5; - const { selectedMapFeature } = useSelectedMapFeature(); + const { data: selectedMapFeature } = useSelectedMapFeature(); useEffect(() => { selectedMapFeature == null ? setIsOpen(false) : setIsOpen(true); diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx index d8b7fcfc3..e58623dc0 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx @@ -1,5 +1,4 @@ import { useQuery } from "@tanstack/react-query"; -import { UseQueryOptions } from "@tanstack/react-query/src/types"; import { IMeshWideConfig, @@ -11,7 +10,7 @@ import { getRadioData, } from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; -import queryCache from "utils/queryCache"; +import { useSharedData } from "utils/useSharedData"; // todo(kon): this is a mock export function useMeshWide(params) { @@ -41,14 +40,18 @@ export function useMeshWideConfig(params) { * Used to store the state between components. */ export const useSelectedMapFeature = () => { - const { data: selectedMapFeature } = useQuery( - ["lime-meshwide", "select_map_feature"], - () => null - ); - const setSelectedMapFeature = (selected: SelectedMapFeature) => - queryCache.setQueryData( - ["lime-meshwide", "select_map_feature"], - selected - ); - return { selectedMapFeature, setSelectedMapFeature }; + // const { data: selectedMapFeature } = useQuery( + // ["lime-meshwide", "select_map_feature"], + // () => null + // ); + // const setSelectedMapFeature = (selected: SelectedMapFeature) => + // queryCache.setQueryData( + // ["lime-meshwide", "select_map_feature"], + // selected + // ); + // return { selectedMapFeature, setSelectedMapFeature }; + return useSharedData([ + "lime-meshwide", + "select_map_feature", + ]); }; diff --git a/src/utils/useSharedData.ts b/src/utils/useSharedData.ts new file mode 100644 index 000000000..577686127 --- /dev/null +++ b/src/utils/useSharedData.ts @@ -0,0 +1,17 @@ +import { useQuery } from "@tanstack/react-query"; + +import queryCache from "utils/queryCache"; + +/** + * This hook is used as generic hook to share data between components using react query. On certain way is a state + * management hook using the capabilities of the react query queryCache + * @param queryKey + */ +export const useSharedData = ( + queryKey: Array +): { data: T | null; setData: (newData: T) => void } => { + const { data } = useQuery(queryKey, () => null); + const setData = (newData: T) => queryCache.setQueryData(queryKey, newData); + + return { data, setData }; +}; From dcc199208f52f9d13cf17a38a0048c15df9b26f7 Mon Sep 17 00:00:00 2001 From: selankon Date: Mon, 7 Aug 2023 15:37:14 +0200 Subject: [PATCH 041/121] chore(meshwide): write mesh wide links mocks --- .../src/mesWideTypes.tsx | 82 +- .../src/meshWideMocks.tsx | 937 ++++++++++++++++++ 2 files changed, 994 insertions(+), 25 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index 569fbea8a..f914cb8e2 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -1,44 +1,76 @@ import { Feature, GeometryObject } from "geojson"; -export interface MeshWideStatus { +export interface IWifiLinkData { + tx_rate: number; + dst_mac: string; + chains: number[]; + signal: number; + rx_rate: number; + src_mac: string; +} + +export interface IWifiLinks { [key: string]: { bleachTTL: number; - data: { - hostname: string; - coordinates: { - lon: string; - lat: string; - }; - macs: string[]; - links: string[]; - }; + data: IWifiLinkData[]; author: string; }; } -export interface IMeshWideStatusResponse { - result: MeshWideStatus; +export interface INodeInfo { + coordinates: { + lat: string; + lon: string; + }; + macs: string[]; + ipv4: string; + ipv6: string; + firmware_version: string; + uptime: string; + device: string; } +export type INodes = { [key: string]: INodeInfo }; + export interface SelectedMapFeature { feature: Feature; id: number; } -export interface INodeDetailFeature { - name: string; - uptime: string; - firmware: string; - ipv6: string; - ipv4: string; - device: string; -} +// export interface MeshWideStatus { +// [key: string]: { +// bleachTTL: number; +// data: { +// hostname: string; +// coordinates: { +// lon: string; +// lat: string; +// }; +// macs: string[]; +// links: string[]; +// }; +// author: string; +// }; +// } +// +// export interface IMeshWideStatusResponse { +// result: MeshWideStatus; +// } -export interface ILinkDetailFeature { - name: string; - gain: string; - linkType: string; -} +// export interface INodeDetailFeature { +// name: string; +// uptime: string; +// firmware: string; +// ipv6: string; +// ipv4: string; +// device: string; +// } +// +// export interface ILinkDetailFeature { +// name: string; +// gain: string; +// linkType: string; +// } export interface IMeshWideSection { name: string; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx new file mode 100644 index 000000000..cbfd71d88 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx @@ -0,0 +1,937 @@ +import { + INodes, + IWifiLinks, +} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; + +const nodesReferenceState: INodes = { + "LiMe-462895": { + coordinates: { + lon: "-123.1216", + lat: "49.2827", + }, + macs: ["a0:f3:c1:46:28:96", "a0:f3:c1:46:28:97", "a0:f3:c1:46:28:97"], + ipv4: "192.168.1.1", + ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", + firmware_version: "1.0.0", + uptime: "86400", + device: "Router", + }, + "LiMe-da4eaa": { + coordinates: { + lon: "-74.0060", + lat: "40.7128", + }, + macs: ["14:cc:20:da:4e:ab", "14:cc:20:da:4e:ac", "14:cc:20:da:4e:ac"], + ipv4: "192.168.1.2", + ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7335", + firmware_version: "1.0.1", + uptime: "43200", + device: "Switch", + }, + primero: { + coordinates: { + lon: "42.3601", + lat: "-71.0589", + }, + macs: ["a8:40:41:1d:f9:35", "a8:40:41:1d:f9:35"], + ipv4: "192.168.1.3", + ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7336", + firmware_version: "1.0.2", + uptime: "345600", + device: "Hub", + }, +}; + +const linksReferenceState: IWifiLinks = { + primero: { + bleachTTL: 30, + data: [ + { + tx_rate: 150000, + dst_mac: "A0:F3:C1:46:28:97", + chains: [-63, -59], + signal: -58, + rx_rate: 180000, + src_mac: "a8:40:41:1d:f9:35", + }, + { + tx_rate: 162000, + dst_mac: "14:CC:20:DA:4E:AC", + chains: [-57, -51], + signal: -50, + rx_rate: 240000, + src_mac: "a8:40:41:1d:f9:35", + }, + ], + author: "primero", + }, + "LiMe-da4eaa": { + bleachTTL: 30, + data: [ + { + tx_rate: 65000, + dst_mac: "A0:F3:C1:46:28:96", + chains: [-25, -43], + src_mac: "14:cc:20:da:4e:ab", + rx_rate: 65000, + signal: -25, + }, + { + tx_rate: 270000, + dst_mac: "A0:F3:C1:46:28:97", + chains: [-50, -47], + src_mac: "14:cc:20:da:4e:ac", + rx_rate: 150000, + signal: -45, + }, + { + tx_rate: 243000, + dst_mac: "A8:40:41:1D:F9:35", + chains: [-75, -64], + src_mac: "14:cc:20:da:4e:ac", + rx_rate: 162000, + signal: -64, + }, + ], + author: "LiMe-da4eaa", + }, + "LiMe-462895": { + bleachTTL: 28, + data: [ + { + tx_rate: 78000, + dst_mac: "14:CC:20:DA:4E:AB", + chains: [2, -46], + src_mac: "a0:f3:c1:46:28:96", + rx_rate: 78000, + signal: 2, + }, + { + tx_rate: 243000, + dst_mac: "14:CC:20:DA:4E:AC", + chains: [-68, -41], + src_mac: "a0:f3:c1:46:28:97", + rx_rate: 216000, + signal: -41, + }, + { + tx_rate: 240000, + dst_mac: "A8:40:41:1D:F9:35", + chains: [-77, -65], + src_mac: "a0:f3:c1:46:28:97", + rx_rate: 135000, + signal: -65, + }, + ], + author: "LiMe-462895", + }, +}; + +// Use the same as on the reference state deleting a specific node +const nodeName = "LiMe-462895"; +const links = (): IWifiLinks => { + // Create a deep copy of the state to avoid mutating the original object + const newState = JSON.parse(JSON.stringify(linksReferenceState)); + + // Get source_macs from the node to be removed + const source_macs_to_remove = newState[nodeName].data.map( + (item: any) => item.src_mac + ); + + // Remove the specified node + delete newState[nodeName]; + + // Remove data items with matching dest_mac in other objects + Object.keys(newState).forEach((key: string) => { + newState[key].data = newState[key].data.filter((item: any) => { + return !source_macs_to_remove.includes(item.dst_mac); + }); + }); + return newState; +}; + +const nodes = (): IWifiLinks => { + const newState = JSON.parse(JSON.stringify(linksReferenceState)); + delete newState[nodeName]; + return newState; +}; + +// import { IMeshWideStatusResponse } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +// +// export const getRadioData = async () => radioDataResponse_simplified; +// export const getMeshWideConfig = async () => meshWideConfig; +// +// const options = { +// primary_interface: "eth0", +// main_ipv4_address: "10.170.128.0/16/17", +// }; +// +// const meshWideConfig = [ +// { +// name: "lime sytem", +// options, +// }, +// { +// name: "lime network", +// options, +// }, +// { +// name: "lime wifi", +// options, +// }, +// { +// name: "generic_uci_config prometheus", +// options, +// }, +// { +// name: "run_asset prometheus_enable", +// options, +// }, +// ]; +// +// export const radioDataResponse_simplified: IMeshWideStatusResponse = { +// result: { +// "ql-czuk-bbone": { +// bleachTTL: 28, +// data: { +// hostname: "ql-czuk-bbone", +// coordinates: { +// lon: "-64.41515", +// lat: "-31.80130", +// }, +// macs: [ +// "a8:40:41:1d:f8:5c", +// "a8:40:41:1d:2a:a0", +// "02:cc:4e:1d:2a:a2", +// "aa:40:41:1d:f8:5c", +// "a8:40:41:1c:86:73", +// "aa:40:41:1c:86:73", +// "02:ab:46:1d:2a:a2", +// ], +// links: ["a8:40:41:1c:83:dd", "a8:40:41:1d:fa:29"], +// }, +// author: "ql-czuk-bbone", +// }, +// "ql-graciela-bbone": { +// bleachTTL: 28, +// data: { +// hostname: "ql-graciela-bbone", +// coordinates: { +// lon: "-64.42703", +// lat: "-31.80874", +// }, +// macs: [ +// "02:cc:4e:1c:85:aa", +// "a8:40:41:1c:83:f8", +// "02:ab:46:1c:85:aa", +// "ae:40:41:1c:85:a8", +// "a8:40:41:1c:83:dd", +// "a8:40:41:1c:85:a8", +// "aa:40:41:1c:85:a8", +// "02:58:47:1c:85:aa", +// ], +// links: ["a8:40:41:1c:86:73", "a8:40:41:1d:f9:f2"], +// }, +// author: "ql-graciela-bbone", +// }, +// "ql-berta": { +// bleachTTL: 28, +// data: { +// coordinates: { +// lon: "-64.41609", +// lat: "-31.80461", +// }, +// macs: [ +// "a8:40:41:1d:fa:29", +// "aa:40:41:1f:71:60", +// "a8:40:41:1f:71:60", +// "a8:40:41:1d:f9:f2", +// "02:cc:4e:1f:71:62", +// "02:ab:46:1f:71:62", +// ], +// links: ["a8:40:41:1c:83:f8", "a8:40:41:1d:f8:5c"], +// hostname: "ql-berta", +// }, +// author: "ql-berta", +// }, +// }, +// }; +// +// export const radioDataResponse: IMeshWideStatusResponse = { +// result: { +// "si-radio": { +// bleachTTL: 23, +// data: { +// hostname: "si-radio", +// coordinates: { +// lon: "-64.39240", +// lat: "-31.82056", +// }, +// macs: [ +// "aa:40:41:1c:85:50", +// "02:cc:4e:1c:85:52", +// "a8:40:41:1c:84:1a", +// "a8:40:41:1c:85:50", +// "02:58:47:1c:85:52", +// "ae:40:41:1c:85:50", +// "02:ab:46:1c:85:52", +// "a8:40:41:1c:84:16", +// ], +// links: [ +// "64:66:b3:87:4e:d1", +// "14:cc:20:ad:b0:d9", +// "a8:40:41:1c:83:eb", +// ], +// }, +// author: "si-radio", +// }, +// "ql-berta": { +// bleachTTL: 28, +// data: { +// links: ["a8:40:41:1c:83:f8"], +// coordinates: { +// lon: "-64.41609", +// lat: "-31.80461", +// }, +// macs: [ +// "a8:40:41:1d:fa:29", +// "aa:40:41:1f:71:60", +// "a8:40:41:1f:71:60", +// "a8:40:41:1d:f9:f2", +// "02:cc:4e:1f:71:62", +// "02:ab:46:1f:71:62", +// ], +// hostname: "ql-berta", +// }, +// author: "ql-berta", +// }, +// "ql-esteban": { +// bleachTTL: 25, +// data: { +// links: ["", ""], +// coordinates: { +// lon: "-64.41600680351257", +// lat: "-31.801688993108318", +// }, +// macs: [ +// "a0:f3:c1:48:cf:ec", +// "a0:f3:c1:48:cf:ed", +// "a2:f3:c1:48:cf:ec", +// "a2:f3:c1:48:cf:ed", +// ], +// hostname: "ql-esteban", +// }, +// author: "ql-esteban", +// }, +// "rl-hogardecristo": { +// bleachTTL: 22, +// data: { +// hostname: "rl-hogardecristo", +// coordinates: { +// lon: "-64.41609", +// lat: "-31.80461", +// }, +// macs: ["02:58:47:c2:e2:1a", "28:87:ba:c2:e2:1a"], +// links: ["a8:40:41:1c:85:a4"], +// }, +// author: "rl-hogardecristo", +// }, +// "ql-czuk-bbone": { +// bleachTTL: 28, +// data: { +// hostname: "ql-czuk-bbone", +// coordinates: { +// lon: "-64.41515", +// lat: "-31.80130", +// }, +// macs: [ +// "a8:40:41:1d:f8:5c", +// "a8:40:41:1d:2a:a0", +// "02:cc:4e:1d:2a:a2", +// "aa:40:41:1d:f8:5c", +// "a8:40:41:1c:86:73", +// "aa:40:41:1c:86:73", +// "02:ab:46:1d:2a:a2", +// ], +// links: ["a8:40:41:1c:84:20", "a8:40:41:1c:83:dd"], +// }, +// author: "ql-czuk-bbone", +// }, +// "ql-czuk": { +// bleachTTL: 25, +// data: { +// links: [ +// "14:cc:20:ad:b0:83", +// "64:66:b3:87:4b:39", +// "a2:f3:c1:48:cf:ed", +// ], +// coordinates: { +// lon: "-64.41506", +// lat: "-31.80137", +// }, +// macs: [ +// "a8:40:41:1f:71:f0", +// "02:58:47:1f:71:f2", +// "a8:40:41:1c:86:7f", +// "a8:40:41:1c:86:96", +// "02:ab:46:1f:71:f2", +// "02:cc:4e:1f:71:f2", +// ], +// hostname: "ql-czuk", +// }, +// author: "ql-czuk", +// }, +// "ql-refu-bbone": { +// bleachTTL: 25, +// data: { +// links: [ +// "a8:40:41:1d:f8:5c", +// "9c:a2:f4:8c:b8:58", +// "a8:40:41:1c:85:a4", +// "9c:a2:f4:8c:b9:48", +// "a8:40:41:1d:27:b4", +// "a8:40:41:1d:f8:f9", +// ], +// coordinates: { +// lon: "-64.385177", +// lat: "-31.837354", +// }, +// macs: [ +// "02:cc:4e:1c:85:46", +// "a8:40:41:1c:85:44", +// "02:ab:46:1c:85:46", +// "a8:40:41:1c:84:20", +// "02:58:47:1c:85:46", +// "a8:40:41:1c:84:28", +// ], +// hostname: "ql-refu-bbone", +// }, +// author: "ql-refu-bbone", +// }, +// "rl-vacas": { +// bleachTTL: 25, +// data: { +// hostname: "rl-vacas", +// coordinates: { +// lon: "-64.41609", +// lat: "-31.80461", +// }, +// macs: ["9c:a2:f4:8c:b9:48", "02:58:47:8c:b9:48"], +// links: [ +// "a8:40:41:1c:85:44", +// "a8:40:41:1c:85:a4", +// "a8:40:41:1d:27:b4", +// ], +// }, +// author: "rl-vacas", +// }, +// "mc-escuela-larrea": { +// bleachTTL: 23, +// data: { +// links: [ +// "a8:40:41:1c:85:5a", +// "a8:40:41:1c:84:99", +// "a8:40:41:1c:86:6d", +// "a8:40:41:1d:f9:26", +// "a8:40:41:1c:85:5a", +// "a8:40:41:1c:84:99", +// ], +// coordinates: { +// lon: "-64.37752", +// lat: "-31.85442", +// }, +// macs: [ +// "a8:40:41:1c:86:6e", +// "aa:40:41:1c:86:6d", +// "a8:40:41:1c:86:6d", +// "aa:40:41:1d:2a:b0", +// "a8:40:41:1d:2a:b0", +// "02:cc:4e:1d:2a:b2", +// "02:ab:46:1d:2a:b2", +// ], +// hostname: "mc-escuela-larrea", +// }, +// author: "mc-escuela-larrea", +// }, +// "ql-graciela": { +// bleachTTL: 28, +// data: { +// hostname: "ql-graciela", +// coordinates: { +// lon: "-64.42705", +// lat: "-31.80873", +// }, +// macs: [ +// "02:58:47:1c:85:3e", +// "ae:40:41:1c:85:3c", +// "02:cc:4e:1c:85:3e", +// "02:ab:46:1c:85:3e", +// "a8:40:41:1c:84:18", +// "a8:40:41:1c:84:05", +// "aa:40:41:1c:85:3c", +// "a8:40:41:1c:85:3c", +// ], +// links: [ +// "a8:40:41:1c:86:1d", +// "a8:40:41:1d:2a:40", +// "a0:f3:c1:85:fb:42", +// "a8:40:41:1c:86:2d", +// ], +// }, +// author: "ql-graciela", +// }, +// "ql-quinteros": { +// bleachTTL: 27, +// data: { +// hostname: "ql-quinteros", +// coordinates: { +// lon: "-64.4300052523613", +// lat: "-31.805773853144796", +// }, +// macs: [ +// "aa:40:41:1d:2a:40", +// "02:cc:4e:1d:2a:42", +// "a8:40:41:1c:86:2d", +// "a8:40:41:1d:2a:40", +// "02:ab:46:1d:2a:42", +// "ae:40:41:1d:2a:40", +// "02:58:47:1d:2a:42", +// "a8:40:41:1c:86:1d", +// ], +// links: [ +// "a0:f3:c1:85:fb:43", +// "a8:40:41:1d:f9:2c", +// "a8:40:41:1c:84:05", +// "a8:40:41:1c:85:3c", +// "a0:f3:c1:85:fb:42", +// "a8:40:41:1d:f8:fb", +// "a8:40:41:1c:84:18", +// ], +// }, +// author: "ql-quinteros", +// }, +// "mc-lidia": { +// bleachTTL: 22, +// data: { +// links: [ +// "a8:40:41:1c:85:5a", +// "a8:40:41:1c:84:99", +// "a8:40:41:1c:86:6d", +// ], +// coordinates: { +// lon: "-64.37990", +// lat: "-31.85474", +// }, +// macs: [ +// "a8:40:41:1d:27:7c", +// "a8:40:41:1c:85:2e", +// "02:ab:46:1d:27:7e", +// "aa:40:41:1d:27:7c", +// ], +// hostname: "mc-lidia", +// }, +// author: "mc-lidia", +// }, +// "ql-ipem265": { +// bleachTTL: 13, +// data: { +// links: ["a8:40:41:1c:86:96"], +// coordinates: { +// lon: "-64.41609", +// lat: "-31.80461", +// }, +// macs: [ +// "a8:40:41:1c:85:98", +// "02:ab:46:1c:85:9a", +// "aa:40:41:1c:85:98", +// "a8:40:41:1c:84:0b", +// "02:58:47:1c:85:9a", +// "02:cc:4e:1c:85:9a", +// "a8:40:41:1c:84:2e", +// "ae:40:41:1c:85:98", +// ], +// hostname: "ql-ipem265", +// }, +// author: "ql-ipem265", +// }, +// "ql-irenecasa": { +// bleachTTL: 25, +// data: { +// hostname: "ql-irenecasa", +// coordinates: { +// lon: "-64.41609", +// lat: "-31.80461", +// }, +// macs: [ +// "66:70:02:4e:cc:e2", +// "02:ab:46:4e:cc:e1", +// "64:70:02:4e:cc:e2", +// "62:70:02:4e:cc:e2", +// "64:70:02:4e:cc:e3", +// "02:58:47:4e:cc:e1", +// ], +// links: ["64:66:b3:87:4b:38", "64:66:b3:87:4b:39"], +// }, +// author: "ql-irenecasa", +// }, +// "ql-flor": { +// bleachTTL: 25, +// data: { +// links: ["a8:40:41:1c:86:7f"], +// coordinates: { +// lon: "-64.41365", +// lat: "-31.79897", +// }, +// macs: [ +// "16:cc:20:ad:b0:82", +// "02:ab:46:ad:b0:81", +// "14:cc:20:ad:b0:83", +// "02:58:47:ad:b0:81", +// "14:cc:20:ad:b0:82", +// ], +// hostname: "ql-flor", +// }, +// author: "ql-flor", +// }, +// "si-andrea": { +// bleachTTL: 23, +// data: { +// links: ["a8:40:41:1c:85:50", "a8:40:41:1c:85:a4"], +// coordinates: { +// lon: "-64.40097", +// lat: "-31.81854", +// }, +// macs: [ +// "16:cc:20:ad:b0:d9", +// "14:cc:20:ad:b0:d9", +// "12:cc:20:ad:b0:d9", +// "02:ab:46:ad:b0:d8", +// "02:58:47:ad:b0:d8", +// "14:cc:20:ad:b0:da", +// ], +// hostname: "si-andrea", +// }, +// author: "si-andrea", +// }, +// "rl-tanque": { +// bleachTTL: 23, +// data: { +// links: [], +// coordinates: { +// lon: "-64.38414", +// lat: "-31.84013", +// }, +// macs: ["a8:40:41:1d:f9:05", "a8:40:41:1d:fa:26"], +// hostname: "rl-tanque", +// }, +// author: "rl-tanque", +// }, +// "mc-yohana": { +// bleachTTL: 23, +// data: { +// links: ["a8:40:41:1c:85:a4", "a8:40:41:1d:27:b4"], +// coordinates: { +// lon: "-64.37864", +// lat: "-31.83969", +// }, +// macs: ["9c:a2:f4:8c:b8:58", "02:58:47:8c:b8:58"], +// hostname: "mc-yohana", +// }, +// author: "mc-yohana", +// }, +// "mc-eli": { +// bleachTTL: 21, +// data: { +// links: ["a8:40:41:1d:29:68", "a8:40:41:1d:2a:1c"], +// coordinates: { +// lon: "-64.38097", +// lat: "-31.85566", +// }, +// macs: ["9c:a2:f4:8c:b6:f4", "02:58:47:8c:b6:f4"], +// hostname: "mc-eli", +// }, +// author: "mc-eli", +// }, +// "si-soniam": { +// bleachTTL: 23, +// data: { +// links: [ +// "a8:40:41:1c:85:50", +// "64:70:02:4e:cd:0b", +// "a8:40:41:1c:84:16", +// ], +// coordinates: { +// lon: "-64.39240", +// lat: "-31.82056", +// }, +// macs: [ +// "66:66:b3:87:4e:d0", +// "64:66:b3:87:4e:d0", +// "62:66:b3:87:4e:d0", +// "64:66:b3:87:4e:d1", +// "02:ab:46:87:4e:cf", +// "02:58:47:87:4e:cf", +// ], +// hostname: "si-soniam", +// }, +// author: "si-soniam", +// }, +// "mc-martinez": { +// bleachTTL: 22, +// data: { +// hostname: "mc-martinez", +// coordinates: { +// lon: "-64.37988", +// lat: "-31.85802", +// }, +// macs: [ +// "ae:40:41:1d:29:68", +// "02:ab:46:1d:29:6a", +// "02:58:47:1d:29:6a", +// "a8:40:41:1c:84:99", +// "02:cc:4e:1d:29:6a", +// "a8:40:41:1c:85:1f", +// "a8:40:41:1d:29:68", +// "aa:40:41:1d:29:68", +// ], +// links: [ +// "a8:40:41:1c:85:5a", +// "a8:40:41:1c:86:6d", +// "a8:40:41:1c:85:2e", +// "9c:a2:f4:8c:b6:f4", +// "a8:40:41:1d:2a:1c", +// "a8:40:41:1c:85:5c", +// ], +// }, +// author: "mc-martinez", +// }, +// "mc-capilla": { +// bleachTTL: 23, +// data: { +// links: [ +// "a8:40:41:1c:84:28", +// "a8:40:41:1c:86:6e", +// "a8:40:41:1c:86:6d", +// ], +// coordinates: { +// lon: "-64.37827", +// lat: "-31.85482", +// }, +// macs: [ +// "a8:40:41:1d:f9:26", +// "aa:40:41:1f:74:f4", +// "a8:40:41:1d:f8:f9", +// "02:cc:4e:1f:74:f6", +// "02:ab:46:1f:74:f6", +// "a8:40:41:1f:74:f4", +// ], +// hostname: "mc-capilla", +// }, +// author: "mc-capilla", +// }, +// "ql-refu-bbone-2": { +// bleachTTL: 22, +// data: { +// links: [ +// "a8:40:41:1c:84:1a", +// "9c:a2:f4:8c:b8:58", +// "a8:40:41:1d:27:b4", +// "28:87:ba:c2:e2:1a", +// ], +// coordinates: { +// lon: "-64.385177", +// lat: "-31.837354", +// }, +// macs: [ +// "02:cc:4e:1c:85:a6", +// "a8:40:41:1c:85:a4", +// "a8:40:41:1c:83:eb", +// "aa:40:41:1c:83:e3", +// "a8:40:41:1c:83:e3", +// "aa:40:41:1c:83:eb", +// "02:58:47:1c:85:a6", +// "02:ab:46:1c:85:a6", +// ], +// hostname: "ql-refu-bbone-2", +// }, +// author: "ql-refu-bbone-2", +// }, +// "mc-rocio": { +// bleachTTL: 22, +// data: { +// links: [ +// "a8:40:41:1c:85:1f", +// "a8:40:41:1d:29:68", +// "9c:a2:f4:8c:b6:f4", +// "a8:40:41:1c:84:99", +// "a8:40:41:1c:86:6d", +// "a8:40:41:1c:85:2e", +// ], +// coordinates: { +// lon: "-64.38025", +// lat: "-31.85570", +// }, +// macs: [ +// "a8:40:41:1c:85:5a", +// "02:cc:4e:1d:2a:1e", +// "aa:40:41:1c:85:5a", +// "a8:40:41:1c:85:5c", +// "aa:40:41:1c:85:5c", +// "02:ab:46:1d:2a:1e", +// "02:58:47:1d:2a:1e", +// "a8:40:41:1d:2a:1c", +// ], +// hostname: "mc-rocio", +// }, +// author: "mc-rocio", +// }, +// "lbl-mikigonza": { +// bleachTTL: 28, +// data: { +// hostname: "lbl-mikigonza", +// coordinates: { +// lon: "-64.425602", +// lat: "-31.734109", +// }, +// macs: [ +// "a0:f3:c1:86:1e:f2", +// "a0:f3:c1:86:1e:f3", +// "a2:f3:c1:86:1e:f2", +// ], +// links: [""], +// }, +// author: "lbl-mikigonza", +// }, +// "ql-graciela-bbone": { +// bleachTTL: 28, +// data: { +// hostname: "ql-graciela-bbone", +// coordinates: { +// lon: "-64.42703", +// lat: "-31.80874", +// }, +// macs: [ +// "02:cc:4e:1c:85:aa", +// "a8:40:41:1c:83:f8", +// "02:ab:46:1c:85:aa", +// "ae:40:41:1c:85:a8", +// "a8:40:41:1c:83:dd", +// "a8:40:41:1c:85:a8", +// "aa:40:41:1c:85:a8", +// "02:58:47:1c:85:aa", +// ], +// links: ["a8:40:41:1c:86:73", "a8:40:41:1d:f9:f2"], +// }, +// author: "ql-graciela-bbone", +// }, +// "rl-tanque-2": { +// bleachTTL: 23, +// data: { +// links: ["a8:40:41:1c:85:a4", "9c:a2:f4:8c:b8:58"], +// coordinates: { +// lon: "-64.41609", +// lat: "-31.80461", +// }, +// macs: [ +// "02:58:47:1d:27:b6", +// "a8:40:41:1c:85:50", +// "a8:40:41:1d:27:b4", +// "aa:40:41:1d:27:b4", +// "a8:40:41:1c:85:4f", +// ], +// hostname: "rl-tanque-2", +// }, +// author: "rl-tanque-2", +// }, +// "ql-cutieddo": { +// bleachTTL: 28, +// data: { +// links: ["a8:40:41:1c:86:2d", "a0:f3:c1:85:fb:43"], +// coordinates: { +// lon: "-64.43312", +// lat: "-31.80787", +// }, +// macs: [ +// "a8:40:41:1d:f9:2c", +// "a8:40:41:1f:75:c4", +// "aa:40:41:1f:75:c4", +// "a8:40:41:1d:f8:fb", +// "02:ab:46:1f:74:7a", +// "02:cc:4e:1f:74:7a", +// ], +// hostname: "ql-cutieddo", +// }, +// author: "ql-cutieddo", +// }, +// "si-claudio": { +// bleachTTL: 21, +// data: { +// hostname: "si-claudio", +// coordinates: { +// lon: "-64.39444", +// lat: "-31.82071", +// }, +// macs: [ +// "66:70:02:4e:cd:0a", +// "64:70:02:4e:cd:0b", +// "64:70:02:4e:cd:0a", +// "02:ab:46:4e:cd:09", +// ], +// links: ["64:66:b3:87:4e:d1", "a8:40:41:1c:84:16"], +// }, +// author: "si-claudio", +// }, +// "ql-irene": { +// bleachTTL: 25, +// data: { +// links: [ +// "a2:f3:c1:48:cf:ec", +// "64:70:02:4e:cc:e2", +// "64:70:02:4e:cc:e3", +// "a2:f3:c1:48:cf:ed", +// "a8:40:41:1c:86:96", +// ], +// coordinates: { +// lon: "-64.41682", +// lat: "-31.80584", +// }, +// macs: [ +// "02:ab:46:87:4b:37", +// "66:66:b3:87:4b:38", +// "02:58:47:87:4b:37", +// "64:66:b3:87:4b:38", +// "64:66:b3:87:4b:39", +// "62:66:b3:87:4b:38", +// ], +// hostname: "ql-irene", +// }, +// author: "ql-irene", +// }, +// "ql-guillermina": { +// bleachTTL: 27, +// data: { +// links: [ +// "a8:40:41:1c:85:3c", +// "a8:40:41:1d:2a:40", +// "a8:40:41:1f:71:f0", +// "a8:40:41:1c:86:2d", +// "a8:40:41:1d:f9:2c", +// ], +// coordinates: { +// lon: "-64.43312", +// lat: "-31.80740", +// }, +// macs: [ +// "a0:f3:c1:85:fb:43", +// "02:ab:46:85:fb:41", +// "02:58:47:85:fb:41", +// "a0:f3:c1:85:fb:42", +// "a6:f3:c1:85:fb:42", +// "a2:f3:c1:85:fb:42", +// ], +// hostname: "ql-guillermina", +// }, +// author: "ql-guillermina", +// }, +// }, +// }; From 842ae6164fda8efa8a2d29c0ef57760ba97b799f Mon Sep 17 00:00:00 2001 From: selankon Date: Mon, 7 Aug 2023 16:35:25 +0200 Subject: [PATCH 042/121] chore(meshwide): refactor with state reference queries --- .../src/components/Map.tsx | 37 ++++----- .../src/components/Map/NodesAndLinks.tsx | 14 ++++ .../lime-plugin-mesh-wide/src/mesWideApi.ts | 22 +++++ .../src/mesWideQueries.tsx | 55 ++++++++----- .../src/mesWideTypes.tsx | 2 +- .../src/meshWideMocks.tsx | 80 +++++++++---------- 6 files changed, 128 insertions(+), 82 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx create mode 100644 plugins/lime-plugin-mesh-wide/src/mesWideApi.ts diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map.tsx index 2cbad6c3b..652f8c32d 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map.tsx @@ -1,28 +1,22 @@ -import { FeatureCollection } from "geojson"; import L from "leaflet"; -import { useEffect, useRef, useState } from "preact/hooks"; +import { useEffect, useRef } from "preact/hooks"; import { MapContainer, TileLayer } from "react-leaflet"; -import { getCommunityGeoJSON } from "plugins/lime-plugin-locate/src/communityGeoJSON"; -import { CommunityLayer } from "plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer"; -import { - useMeshWide, - useSelectedMapFeature, -} from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; +import { NodesAndLinks } from "plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks"; +import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; const openStreetMapTileString = "http://{s}.tile.osm.org/{z}/{x}/{y}.png"; const openStreetMapAttribution = '© OpenStreetMap contributors'; export const MeshWideMap = () => { - const [communityLayer, setCommunityLayer] = - useState(null); + // const [communityLayer, setCommunityLayer] = + // useState(null); // const [selectedFeature, setSelectedFeature] = // useState(null); const { data: selectedMapFeature, setData: setSelectedMapFeature } = - // const { data: selectedMapFeature, mutate: setSelectedMapFeature} = useSelectedMapFeature(); const mapRef = useRef(); @@ -37,16 +31,16 @@ export const MeshWideMap = () => { } }, [mapRef, selectedMapFeature]); - useEffect(() => { - console.log("SelectedFeature", selectedMapFeature); - }, [selectedMapFeature]); + // useEffect(() => { + // console.log("SelectedFeature", selectedMapFeature); + // }, [selectedMapFeature]); - const { data: meshWideStatus } = useMeshWide({ - onSuccess: (res) => { - const geoJson = getCommunityGeoJSON(res.result); // todo(kon): the locate page makes a correction with the own node if is modified - setCommunityLayer(geoJson as FeatureCollection); - }, - }); + // const { data: meshWideStatus } = useMeshWide({ + // onSuccess: (res) => { + // const geoJson = getCommunityGeoJSON(res.result); // todo(kon): the locate page makes a correction with the own node if is modified + // setCommunityLayer(geoJson as FeatureCollection); + // }, + // }); return ( { attribution={openStreetMapAttribution} url={openStreetMapTileString} /> - + + {/**/} ); }; diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx new file mode 100644 index 000000000..ecaf24141 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx @@ -0,0 +1,14 @@ +import { + useMeshWideNodes, + useSelectedMapFeature, +} from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; + +export const NodesAndLinks = () => { + const { data: selectedMapFeature, setData: setSelectedMapFeature } = + useSelectedMapFeature(); + + // const { data: meshWideLinks } = useMeshWideLinks({}); + const { data: meshWideNodes } = useMeshWideNodes({}); + + return <>; +}; diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts b/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts new file mode 100644 index 000000000..52a2e92b9 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts @@ -0,0 +1,22 @@ +import { + links, + linksReferenceState, + nodes, + nodesReferenceState, +} from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; + +export const getMeshWideLinksReference = () => { + return linksReferenceState; +}; + +export const getMeshWideLinks = () => { + return links(); +}; + +export const getMeshWideNodesReference = () => { + return nodesReferenceState; +}; + +export const getMeshWideNodes = () => { + return nodes(); +}; diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx index e58623dc0..ab67fb665 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx @@ -1,29 +1,54 @@ import { useQuery } from "@tanstack/react-query"; +import { + getMeshWideLinks, + getMeshWideLinksReference, + getMeshWideNodes, + getMeshWideNodesReference, +} from "plugins/lime-plugin-mesh-wide/src/mesWideApi"; import { IMeshWideConfig, - IMeshWideStatusResponse, + INodes, + IWifiLinks, SelectedMapFeature, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; -import { - getMeshWideConfig, - getRadioData, -} from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; +import { getMeshWideConfig } from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; import { useSharedData } from "utils/useSharedData"; // todo(kon): this is a mock -export function useMeshWide(params) { - return useQuery( - ["lime-meshwide", "get_mesh_info"], - getRadioData, +export function useMeshWideLinksReference(params) { + return useQuery( + ["lime-meshwide", "links_reference"], + getMeshWideLinksReference, { ...params, } ); } -// todo(kon): this is a mock +export function useMeshWideLinks(params) { + return useQuery(["lime-meshwide", "links"], getMeshWideLinks, { + ...params, + }); +} + +export function useMeshWideNodesReference(params) { + return useQuery( + ["lime-meshwide", "nodes_reference"], + getMeshWideNodesReference, + { + ...params, + } + ); +} + +export function useMeshWideNodes(params) { + return useQuery(["lime-meshwide", "nodes"], getMeshWideNodes, { + ...params, + }); +} + export function useMeshWideConfig(params) { return useQuery( ["lime-meshwide", "get_mesh_config"], @@ -40,16 +65,6 @@ export function useMeshWideConfig(params) { * Used to store the state between components. */ export const useSelectedMapFeature = () => { - // const { data: selectedMapFeature } = useQuery( - // ["lime-meshwide", "select_map_feature"], - // () => null - // ); - // const setSelectedMapFeature = (selected: SelectedMapFeature) => - // queryCache.setQueryData( - // ["lime-meshwide", "select_map_feature"], - // selected - // ); - // return { selectedMapFeature, setSelectedMapFeature }; return useSharedData([ "lime-meshwide", "select_map_feature", diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index f914cb8e2..7574b0a1a 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -77,4 +77,4 @@ export interface IMeshWideSection { options: { [key: string]: string }; } -export type IMeshWideConfig = [IMeshWideSection]; +export type IMeshWideConfig = IMeshWideSection[]; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx index cbfd71d88..3b6484e74 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx @@ -1,13 +1,14 @@ import { + IMeshWideConfig, INodes, IWifiLinks, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; -const nodesReferenceState: INodes = { +export const nodesReferenceState: INodes = { "LiMe-462895": { coordinates: { - lon: "-123.1216", - lat: "49.2827", + lon: "-64.42703", + lat: "-31.80874", }, macs: ["a0:f3:c1:46:28:96", "a0:f3:c1:46:28:97", "a0:f3:c1:46:28:97"], ipv4: "192.168.1.1", @@ -18,8 +19,8 @@ const nodesReferenceState: INodes = { }, "LiMe-da4eaa": { coordinates: { - lon: "-74.0060", - lat: "40.7128", + lon: "-64.42703", + lat: "-31.80874", }, macs: ["14:cc:20:da:4e:ab", "14:cc:20:da:4e:ac", "14:cc:20:da:4e:ac"], ipv4: "192.168.1.2", @@ -30,8 +31,8 @@ const nodesReferenceState: INodes = { }, primero: { coordinates: { - lon: "42.3601", - lat: "-71.0589", + lon: "-64.41609", + lat: "-31.80461", }, macs: ["a8:40:41:1d:f9:35", "a8:40:41:1d:f9:35"], ipv4: "192.168.1.3", @@ -42,7 +43,7 @@ const nodesReferenceState: INodes = { }, }; -const linksReferenceState: IWifiLinks = { +export const linksReferenceState: IWifiLinks = { primero: { bleachTTL: 30, data: [ @@ -129,7 +130,7 @@ const linksReferenceState: IWifiLinks = { // Use the same as on the reference state deleting a specific node const nodeName = "LiMe-462895"; -const links = (): IWifiLinks => { +export const links = (): IWifiLinks => { // Create a deep copy of the state to avoid mutating the original object const newState = JSON.parse(JSON.stringify(linksReferenceState)); @@ -150,44 +151,43 @@ const links = (): IWifiLinks => { return newState; }; -const nodes = (): IWifiLinks => { +export const nodes = (): INodes => { const newState = JSON.parse(JSON.stringify(linksReferenceState)); delete newState[nodeName]; return newState; }; -// import { IMeshWideStatusResponse } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +export const getMeshWideConfig = async () => meshWideConfig; // +const options = { + primary_interface: "eth0", + main_ipv4_address: "10.170.128.0/16/17", +}; + +const meshWideConfig: IMeshWideConfig = [ + { + name: "lime system", + options, + }, + { + name: "lime network", + options, + }, + { + name: "lime wifi", + options, + }, + { + name: "generic_uci_config prometheus", + options, + }, + { + name: "run_asset prometheus_enable", + options, + }, +]; // export const getRadioData = async () => radioDataResponse_simplified; -// export const getMeshWideConfig = async () => meshWideConfig; -// -// const options = { -// primary_interface: "eth0", -// main_ipv4_address: "10.170.128.0/16/17", -// }; -// -// const meshWideConfig = [ -// { -// name: "lime sytem", -// options, -// }, -// { -// name: "lime network", -// options, -// }, -// { -// name: "lime wifi", -// options, -// }, -// { -// name: "generic_uci_config prometheus", -// options, -// }, -// { -// name: "run_asset prometheus_enable", -// options, -// }, -// ]; + // // export const radioDataResponse_simplified: IMeshWideStatusResponse = { // result: { From e26186687b799342383a1f3a516612bbc05db27c Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 8 Aug 2023 17:20:21 +0200 Subject: [PATCH 043/121] chore(meshwide): show links on map --- .../src/components/Map/NodesAndLinks.tsx | 116 +++++++++++++++++- .../src/mesWideTypes.tsx | 23 ++-- .../src/meshWideMocks.tsx | 6 +- .../src/utils/getLinksCoordinates.ts | 40 ++++++ 4 files changed, 170 insertions(+), 15 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx index ecaf24141..8d5e79df3 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx @@ -1,14 +1,120 @@ +import L from "leaflet"; +import { Marker, Polyline, Tooltip } from "react-leaflet"; + +import style from "plugins/lime-plugin-mesh-wide/src/components/Map/style.less"; import { - useMeshWideNodes, + useMeshWideLinksReference, + useMeshWideNodesReference, useSelectedMapFeature, } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; +import { + INodeInfo, + LocatedWifiLinkData, +} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +import { mergeLinksAndCoordinates } from "plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates"; -export const NodesAndLinks = () => { +const NodeMarker = ({ name, info }: { name: string; info: INodeInfo }) => { + const { data: selectedMapFeature, setData: setSelectedMapFeature } = + useSelectedMapFeature(); + const synced: boolean = Math.random() < 0.5; + + const markerClasses = `${ + selectedMapFeature?.id === name && style.selectedMarker + } ${synced ? style.syncedMarker : style.notSyncedMarker}`; + + return ( + `, + })} + eventHandlers={{ + click: (e) => { + L.DomEvent.stopPropagation(e); + setSelectedMapFeature({ + id: name, + feature: info, + }); + }, + }} + > + {name} + + ); +}; + +const LinkLine = ({ link }: { link: LocatedWifiLinkData }) => { + // const isSelected = selectedMapFeature?.id === i; const { data: selectedMapFeature, setData: setSelectedMapFeature } = useSelectedMapFeature(); + const synced: boolean = Math.random() < 0.5; + + const getPathOpts = (isSelected) => { + return { + color: synced ? "#76bd7d" : "#eb7575", + weight: isSelected ? 7 : 5, + opacity: isSelected ? 1 : 0.8, + }; + }; + + const coordinates = Object.values(link).map((entry) => entry.coordinates); + + return ( + [...p].reverse())} + positions={coordinates} + // pathOptions={getPathOpts(isSelected)} + eventHandlers={{ + click: (e) => { + L.DomEvent.stopPropagation(e); + // todo(kon): redefine selected map feature stuff + // setSelectedMapFeature({ + // id: i, + // feature: f, + // }); + }, + mouseover: (e) => { + const l = e.target; + l.setStyle(getPathOpts(true)); + }, + mouseout: (event) => { + const l = event.target; + // l.setStyle(getPathOpts(isSelected)); + // todo + l.setStyle(getPathOpts(false)); + }, + }} + /> + ); +}; + +export const NodesAndLinks = () => { + // const { data: selectedMapFeature, setData: setSelectedMapFeature } = + // useSelectedMapFeature(); + + const { data: meshWideLinks } = useMeshWideLinksReference({}); + const { data: meshWideNodes } = useMeshWideNodesReference({}); + + let locatedLinks: LocatedWifiLinkData[] = []; + if (meshWideNodes && meshWideLinks) { + locatedLinks = mergeLinksAndCoordinates(meshWideNodes, meshWideLinks); + } - // const { data: meshWideLinks } = useMeshWideLinks({}); - const { data: meshWideNodes } = useMeshWideNodes({}); + // console.log("AAAAAA ", locatedLinks[0][0]); - return <>; + return ( + <> + {meshWideNodes && + Object.entries(meshWideNodes).map(([k, v], i) => { + return ; + })} + {locatedLinks?.length && + locatedLinks.map((link, i) => { + return ; + })} + + ); }; diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index 7574b0a1a..b3dd2bace 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -1,4 +1,10 @@ -import { Feature, GeometryObject } from "geojson"; +// todo(kon): Two nodes could have more than one active link, we should merge this into somehow to show it on +// the ui +export type LocatedWifiLinkData = { + [key: string]: IWifiLinkData & { + coordinates: Coordinates; + }; +}; export interface IWifiLinkData { tx_rate: number; @@ -17,11 +23,13 @@ export interface IWifiLinks { }; } +export type Coordinates = { + lat: string; + lon: string; +}; + export interface INodeInfo { - coordinates: { - lat: string; - lon: string; - }; + coordinates: Coordinates; macs: string[]; ipv4: string; ipv6: string; @@ -33,8 +41,9 @@ export interface INodeInfo { export type INodes = { [key: string]: INodeInfo }; export interface SelectedMapFeature { - feature: Feature; - id: number; + // feature: Feature; + feature: INodeInfo | IWifiLinkData; + id: number | string; } // export interface MeshWideStatus { diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx index 3b6484e74..f6a2de1f8 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx @@ -19,8 +19,8 @@ export const nodesReferenceState: INodes = { }, "LiMe-da4eaa": { coordinates: { - lon: "-64.42703", - lat: "-31.80874", + lon: "-64.42315", + lat: "-31.80461", }, macs: ["14:cc:20:da:4e:ab", "14:cc:20:da:4e:ac", "14:cc:20:da:4e:ac"], ipv4: "192.168.1.2", @@ -152,7 +152,7 @@ export const links = (): IWifiLinks => { }; export const nodes = (): INodes => { - const newState = JSON.parse(JSON.stringify(linksReferenceState)); + const newState = JSON.parse(JSON.stringify(nodesReferenceState)); delete newState[nodeName]; return newState; }; diff --git a/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts new file mode 100644 index 000000000..2fa035136 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts @@ -0,0 +1,40 @@ +import { + INodes, + IWifiLinks, + LocatedWifiLinkData, +} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; + +export const mergeLinksAndCoordinates = (nodes: INodes, links: IWifiLinks) => { + if (!nodes || !links) return []; + const result: LocatedWifiLinkData[] = []; + + for (const pointId in links) { + for (const data of links[pointId].data) { + const dstPointId = Object.keys(nodes).find((pid) => { + return nodes[pid].macs.filter((str) => + str.toLowerCase().includes(data.dst_mac.toLowerCase()) + ); + }); + if (dstPointId) { + const entry: LocatedWifiLinkData = { + [pointId]: { + ...data, + coordinates: nodes[pointId].coordinates, + }, + [dstPointId!]: { + tx_rate: data.tx_rate, + dst_mac: data.src_mac, + chains: data.chains, + src_mac: data.dst_mac, + rx_rate: data.rx_rate, + signal: data.signal, + coordinates: nodes[dstPointId!].coordinates, + }, + }; + result.push(entry); + } + } + } + + return result; +}; From fb8f15fffb466a25335892bb24afe228c166f746 Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 9 Aug 2023 16:43:54 +0200 Subject: [PATCH 044/121] chore(meshwide): refactor to have a point to point with multiple links --- .../src/components/Map/NodesAndLinks.tsx | 22 +++--- .../src/mesWideTypes.tsx | 24 ++++++- .../src/meshWideMocks.tsx | 4 +- .../src/utils/getLinksCoordinates.ts | 70 ++++++++++++++++--- 4 files changed, 97 insertions(+), 23 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx index 8d5e79df3..cc0396355 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx @@ -11,7 +11,10 @@ import { INodeInfo, LocatedWifiLinkData, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; -import { mergeLinksAndCoordinates } from "plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates"; +import { + PontToPointLink, + mergeLinksAndCoordinates, +} from "plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates"; const NodeMarker = ({ name, info }: { name: string; info: INodeInfo }) => { const { data: selectedMapFeature, setData: setSelectedMapFeature } = @@ -46,7 +49,7 @@ const NodeMarker = ({ name, info }: { name: string; info: INodeInfo }) => { ); }; -const LinkLine = ({ link }: { link: LocatedWifiLinkData }) => { +const LinkLine = ({ link }: { link: PontToPointLink }) => { // const isSelected = selectedMapFeature?.id === i; const { data: selectedMapFeature, setData: setSelectedMapFeature } = useSelectedMapFeature(); @@ -60,13 +63,14 @@ const LinkLine = ({ link }: { link: LocatedWifiLinkData }) => { }; }; - const coordinates = Object.values(link).map((entry) => entry.coordinates); + const coordinates = link.coordinates.map((c) => [c.lat, c.lon]); return ( [...p].reverse())} positions={coordinates} + // todo(kon): redefine selected map feature stuff // pathOptions={getPathOpts(isSelected)} + pathOptions={getPathOpts(false)} eventHandlers={{ click: (e) => { L.DomEvent.stopPropagation(e); @@ -98,22 +102,20 @@ export const NodesAndLinks = () => { const { data: meshWideLinks } = useMeshWideLinksReference({}); const { data: meshWideNodes } = useMeshWideNodesReference({}); - let locatedLinks: LocatedWifiLinkData[] = []; + let locatedLinks: LocatedWifiLinkData; if (meshWideNodes && meshWideLinks) { locatedLinks = mergeLinksAndCoordinates(meshWideNodes, meshWideLinks); } - // console.log("AAAAAA ", locatedLinks[0][0]); - return ( <> {meshWideNodes && Object.entries(meshWideNodes).map(([k, v], i) => { return ; })} - {locatedLinks?.length && - locatedLinks.map((link, i) => { - return ; + {locatedLinks && + Object.entries(locatedLinks).map((link, i) => { + return ; })} ); diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index b3dd2bace..1fb1a0ff9 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -1,11 +1,26 @@ -// todo(kon): Two nodes could have more than one active link, we should merge this into somehow to show it on -// the ui -export type LocatedWifiLinkData = { +import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates"; + +/** + * Describe a link with a coordinates + */ +export type ILocatedLink = { [key: string]: IWifiLinkData & { coordinates: Coordinates; }; }; +/** + * List of located links. Are grouped by id based on their coordinates + * + * The array of classes contain an indeterminated number of links that are from certain point to another. + */ +export type LocatedWifiLinkData = { + [key: string]: PontToPointLink; +}; + +/** + * Link info retrieved from the API + */ export interface IWifiLinkData { tx_rate: number; dst_mac: string; @@ -15,6 +30,9 @@ export interface IWifiLinkData { src_mac: string; } +/** + * List of Link info retrieved from the API + */ export interface IWifiLinks { [key: string]: { bleachTTL: number; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx index f6a2de1f8..f1b3724ff 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx @@ -10,7 +10,7 @@ export const nodesReferenceState: INodes = { lon: "-64.42703", lat: "-31.80874", }, - macs: ["a0:f3:c1:46:28:96", "a0:f3:c1:46:28:97", "a0:f3:c1:46:28:97"], + macs: ["a0:f3:c1:46:28:96", "a0:f3:c1:46:28:97"], ipv4: "192.168.1.1", ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", firmware_version: "1.0.0", @@ -22,7 +22,7 @@ export const nodesReferenceState: INodes = { lon: "-64.42315", lat: "-31.80461", }, - macs: ["14:cc:20:da:4e:ab", "14:cc:20:da:4e:ac", "14:cc:20:da:4e:ac"], + macs: ["14:cc:20:da:4e:ab", "14:cc:20:da:4e:ac"], ipv4: "192.168.1.2", ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7335", firmware_version: "1.0.1", diff --git a/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts index 2fa035136..a423efa3f 100644 --- a/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts +++ b/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts @@ -1,22 +1,40 @@ import { + Coordinates, + ILocatedLink, INodes, IWifiLinks, LocatedWifiLinkData, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; -export const mergeLinksAndCoordinates = (nodes: INodes, links: IWifiLinks) => { - if (!nodes || !links) return []; - const result: LocatedWifiLinkData[] = []; +export const mergeLinksAndCoordinates = ( + nodes: INodes, + links: IWifiLinks +): LocatedWifiLinkData => { + if (!nodes || !links) return {}; + const result: LocatedWifiLinkData = {}; for (const pointId in links) { for (const data of links[pointId].data) { const dstPointId = Object.keys(nodes).find((pid) => { - return nodes[pid].macs.filter((str) => - str.toLowerCase().includes(data.dst_mac.toLowerCase()) + return nodes[pid].macs.filter((nodeMac) => + nodeMac.toLowerCase().includes(data.dst_mac.toLowerCase()) ); }); - if (dstPointId) { - const entry: LocatedWifiLinkData = { + + if (dstPointId && dstPointId !== pointId) { + const linkKey = PontToPointLink.generateId( + nodes[pointId].coordinates, + nodes[dstPointId!].coordinates + ); + + if (!result[linkKey]) { + result[linkKey] = new PontToPointLink( + nodes[pointId].coordinates, + nodes[dstPointId!].coordinates + ); + } + + const entry: ILocatedLink = { [pointId]: { ...data, coordinates: nodes[pointId].coordinates, @@ -31,10 +49,46 @@ export const mergeLinksAndCoordinates = (nodes: INodes, links: IWifiLinks) => { coordinates: nodes[dstPointId!].coordinates, }, }; - result.push(entry); + result[linkKey].addLink(entry); } } } return result; }; + +/** + * This class should store a group of links between the same geo coordinates. + */ +export class PontToPointLink { + private _links: ILocatedLink[] = []; + public readonly id: string; + public readonly coordinates: Coordinates[] = []; + + constructor(coord1: Coordinates, coord2: Coordinates) { + this.id = PontToPointLink.generateId(coord1, coord2); + this.coordinates.push(coord1, coord2); + } + + addLink(link: ILocatedLink) { + this.links.push(link); + } + + get links() { + return this._links; + } + + static generateId(coord1: Coordinates, coord2: Coordinates): string { + const _prepareCoord = (coord: string) => + parseFloat(coord.replace("-", "").replace(".", "")); + + const allCoordinates = [ + _prepareCoord(coord1.lon), + _prepareCoord(coord1.lat), + _prepareCoord(coord2.lon), + _prepareCoord(coord2.lat), + ]; + + return allCoordinates.sort((a, b) => a - b).toString(); + } +} From 756d2ea8f9d74f530421089fb2c4345570a5be5d Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 9 Aug 2023 17:25:24 +0200 Subject: [PATCH 045/121] chore(meshwide): fix selected feature --- .../src/components/FeatureDetail.tsx | 34 +++---- .../src/components/Map/CommunityLayer.tsx | 92 ------------------- .../src/components/Map/NodesAndLinks.tsx | 27 +++--- .../src/mesWideTypes.tsx | 45 ++------- .../src/utils/getLinksCoordinates.ts | 9 ++ tsconfig.json | 2 +- 6 files changed, 44 insertions(+), 165 deletions(-) delete mode 100644 plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx index b02ba0417..4afcd8cc3 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx @@ -6,10 +6,10 @@ import { Button } from "components/buttons/button"; import { StatusAndButton } from "plugins/lime-plugin-mesh-wide/src/components/Components"; import { PowerIcon } from "plugins/lime-plugin-mesh-wide/src/icons/power"; import { - ILinkDetailFeature, - INodeDetailFeature, + INamedNodeInfo, SelectedMapFeature, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates"; const TitleAndText = ({ title, @@ -38,10 +38,10 @@ const LinkDetails = ({ linkDetails, selectedFeature, }: { - linkDetails: ILinkDetailFeature; + linkDetails: PontToPointLink; selectedFeature: SelectedMapFeature; }) => { - const name = linkDetails?.name ?? selectedFeature?.id ?? ""; + const name = linkDetails?.names ?? selectedFeature?.id ?? ""; const gain = "5 dB"; const linkType = "Primary"; @@ -71,7 +71,7 @@ const NodeDetails = ({ selectedFeature, synced, }: { - nodeDetail: INodeDetailFeature; + nodeDetail: INamedNodeInfo; selectedFeature: SelectedMapFeature; synced: boolean; }) => { @@ -125,22 +125,18 @@ export const FeatureDetail = ({ synced: boolean; }) => { if (!selectedFeature) return; - switch (selectedFeature.feature.geometry.type) { - case "LineString": + switch (selectedFeature.type) { + case "link": return ( ); - case "Point": + case "node": return ( @@ -159,13 +155,13 @@ export const BottomSheetFooter = ({ }) => { if (!selectedFeature) return; - const type = selectedFeature.feature.geometry.type; + const type = selectedFeature.type; const Synced = () => { let txt: VNode; - if (type === "LineString") { + if (type === "link") { txt = Same status as in the reference state; - } else if (type === "Point") { + } else if (type === "node") { txt = Same status as in the reference state; } @@ -175,7 +171,7 @@ export const BottomSheetFooter = ({ const UpdateReference = () => { let txt: VNode; let btn: VNode; - if (type === "LineString") { + if (type === "link") { txt = ( This link has 5dB difference @@ -189,7 +185,7 @@ export const BottomSheetFooter = ({ ); btn = Update this link on reference state; - } else if (type === "Point") { + } else if (type === "node") { txt = In the reference state this node is on; btn = Update this node on reference state; } diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx deleted file mode 100644 index b894614e0..000000000 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/CommunityLayer.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import { FeatureCollection } from "geojson"; -import L from "leaflet"; -import { Marker, Polyline, Tooltip } from "react-leaflet"; - -import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; - -import style from "./style.less"; - -export const CommunityLayer = ({ - geoJsonData, -}: { - geoJsonData: FeatureCollection; -}) => { - const { data: selectedMapFeature, setData: setSelectedMapFeature } = - useSelectedMapFeature(); - return ( - <> - {geoJsonData && - geoJsonData.features.map((f, i) => { - const synced: boolean = Math.random() < 0.5; - - if (f.geometry.type === "LineString") { - const isSelected = selectedMapFeature?.id === i; - const getPathOpts = (isSelected) => { - return { - color: synced ? "#76bd7d" : "#eb7575", - weight: isSelected ? 7 : 5, - opacity: isSelected ? 1 : 0.8, - }; - }; - return ( - - [...p].reverse() - )} - pathOptions={getPathOpts(isSelected)} - eventHandlers={{ - click: (e) => { - L.DomEvent.stopPropagation(e); - setSelectedMapFeature({ - id: i, - feature: f, - }); - }, - mouseover: (e) => { - const l = e.target; - l.setStyle(getPathOpts(true)); - }, - mouseout: (event) => { - const l = event.target; - l.setStyle(getPathOpts(isSelected)); - }, - }} - /> - ); - } else if (f.geometry.type === "Point") { - const markerClasses = `${ - selectedMapFeature?.id === i && style.selectedMarker - } ${ - synced ? style.syncedMarker : style.notSyncedMarker - }`; - return ( - `, - // html: ``, - html: ``, - })} - eventHandlers={{ - click: (e) => { - L.DomEvent.stopPropagation(e); - setSelectedMapFeature({ - id: i, - feature: f, - }); - }, - }} - > - {f.properties.name} - - ); - } - })} - - ); -}; diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx index cc0396355..cc21a1873 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx @@ -39,7 +39,8 @@ const NodeMarker = ({ name, info }: { name: string; info: INodeInfo }) => { L.DomEvent.stopPropagation(e); setSelectedMapFeature({ id: name, - feature: info, + feature: { ...info, name }, + type: "node", }); }, }} @@ -50,9 +51,10 @@ const NodeMarker = ({ name, info }: { name: string; info: INodeInfo }) => { }; const LinkLine = ({ link }: { link: PontToPointLink }) => { - // const isSelected = selectedMapFeature?.id === i; const { data: selectedMapFeature, setData: setSelectedMapFeature } = useSelectedMapFeature(); + const isSelected = selectedMapFeature?.id === link.id; + const synced: boolean = Math.random() < 0.5; const getPathOpts = (isSelected) => { @@ -68,17 +70,15 @@ const LinkLine = ({ link }: { link: PontToPointLink }) => { return ( { L.DomEvent.stopPropagation(e); - // todo(kon): redefine selected map feature stuff - // setSelectedMapFeature({ - // id: i, - // feature: f, - // }); + setSelectedMapFeature({ + id: link.id, + feature: link, + type: "link", + }); }, mouseover: (e) => { const l = e.target; @@ -86,9 +86,7 @@ const LinkLine = ({ link }: { link: PontToPointLink }) => { }, mouseout: (event) => { const l = event.target; - // l.setStyle(getPathOpts(isSelected)); - // todo - l.setStyle(getPathOpts(false)); + l.setStyle(getPathOpts(isSelected)); }, }} /> @@ -96,9 +94,6 @@ const LinkLine = ({ link }: { link: PontToPointLink }) => { }; export const NodesAndLinks = () => { - // const { data: selectedMapFeature, setData: setSelectedMapFeature } = - // useSelectedMapFeature(); - const { data: meshWideLinks } = useMeshWideLinksReference({}); const { data: meshWideNodes } = useMeshWideNodesReference({}); diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index 1fb1a0ff9..0dd200b74 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -56,49 +56,20 @@ export interface INodeInfo { device: string; } +export type INamedNodeInfo = { + name: string; +} & INodeInfo; + export type INodes = { [key: string]: INodeInfo }; +type FeatureType = "node" | "link"; + export interface SelectedMapFeature { - // feature: Feature; - feature: INodeInfo | IWifiLinkData; + feature: INamedNodeInfo | PontToPointLink; + type: FeatureType; id: number | string; } -// export interface MeshWideStatus { -// [key: string]: { -// bleachTTL: number; -// data: { -// hostname: string; -// coordinates: { -// lon: string; -// lat: string; -// }; -// macs: string[]; -// links: string[]; -// }; -// author: string; -// }; -// } -// -// export interface IMeshWideStatusResponse { -// result: MeshWideStatus; -// } - -// export interface INodeDetailFeature { -// name: string; -// uptime: string; -// firmware: string; -// ipv6: string; -// ipv4: string; -// device: string; -// } -// -// export interface ILinkDetailFeature { -// name: string; -// gain: string; -// linkType: string; -// } - export interface IMeshWideSection { name: string; options: { [key: string]: string }; diff --git a/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts index a423efa3f..94c044b68 100644 --- a/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts +++ b/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts @@ -74,6 +74,15 @@ export class PontToPointLink { this.links.push(link); } + get names() { + return [ + ...this._links.reduce((acc, link) => { + Object.keys(link).forEach((key) => acc.add(key)); + return acc; + }, new Set()), + ]; + } + get links() { return this._links; } diff --git a/tsconfig.json b/tsconfig.json index 32e04bb05..33de5df08 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { /* Basic Options */ - "target": "ES5", + "target": "es2015", "allowJs": true, "checkJs": true, "jsx": "preserve", From b97516fa9c6f4bc03efdbe346be9259c4f1df0ea Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 10 Aug 2023 09:31:12 +0200 Subject: [PATCH 046/121] chore(meshwide): pass reference state links --- .../src/components/Map/NodesAndLinks.tsx | 65 ++++++++++++++----- 1 file changed, 50 insertions(+), 15 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx index cc21a1873..34b3daab7 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx @@ -3,6 +3,7 @@ import { Marker, Polyline, Tooltip } from "react-leaflet"; import style from "plugins/lime-plugin-mesh-wide/src/components/Map/style.less"; import { + useMeshWideLinks, useMeshWideLinksReference, useMeshWideNodesReference, useSelectedMapFeature, @@ -50,10 +51,16 @@ const NodeMarker = ({ name, info }: { name: string; info: INodeInfo }) => { ); }; -const LinkLine = ({ link }: { link: PontToPointLink }) => { +const LinkLine = ({ + referenceLink, + actualLink, +}: { + referenceLink: PontToPointLink; + actualLink: PontToPointLink | undefined; +}) => { const { data: selectedMapFeature, setData: setSelectedMapFeature } = useSelectedMapFeature(); - const isSelected = selectedMapFeature?.id === link.id; + const isSelected = selectedMapFeature?.id === referenceLink.id; const synced: boolean = Math.random() < 0.5; @@ -62,10 +69,11 @@ const LinkLine = ({ link }: { link: PontToPointLink }) => { color: synced ? "#76bd7d" : "#eb7575", weight: isSelected ? 7 : 5, opacity: isSelected ? 1 : 0.8, + dashArray: actualLink ? null : "7 10", }; }; - const coordinates = link.coordinates.map((c) => [c.lat, c.lon]); + const coordinates = referenceLink.coordinates.map((c) => [c.lat, c.lon]); return ( { click: (e) => { L.DomEvent.stopPropagation(e); setSelectedMapFeature({ - id: link.id, - feature: link, + id: referenceLink.id, + feature: referenceLink, type: "link", }); }, @@ -94,24 +102,51 @@ const LinkLine = ({ link }: { link: PontToPointLink }) => { }; export const NodesAndLinks = () => { - const { data: meshWideLinks } = useMeshWideLinksReference({}); - const { data: meshWideNodes } = useMeshWideNodesReference({}); + const { data: meshWideLinksReference } = useMeshWideLinksReference({}); + const { data: meshWideLinks } = useMeshWideLinks({}); + const { data: meshWideNodesReference } = useMeshWideNodesReference({}); + + let locatedLinksReference: LocatedWifiLinkData; + if (meshWideNodesReference && meshWideLinksReference) { + locatedLinksReference = mergeLinksAndCoordinates( + meshWideNodesReference, + meshWideLinksReference + ); + } let locatedLinks: LocatedWifiLinkData; - if (meshWideNodes && meshWideLinks) { - locatedLinks = mergeLinksAndCoordinates(meshWideNodes, meshWideLinks); + if (meshWideNodesReference && meshWideLinks) { + locatedLinks = mergeLinksAndCoordinates( + meshWideNodesReference, + meshWideLinks + ); } return ( <> - {meshWideNodes && - Object.entries(meshWideNodes).map(([k, v], i) => { + {meshWideNodesReference && + Object.entries(meshWideNodesReference).map(([k, v], i) => { return ; })} - {locatedLinks && - Object.entries(locatedLinks).map((link, i) => { - return ; - })} + {locatedLinksReference && + locatedLinks && + Object.entries(locatedLinksReference).map( + (referenceLink, i) => { + const actualLink: PontToPointLink = Object.values( + locatedLinks + ).find((value) => value.id === referenceLink[0]); + + console.log("Reference", referenceLink[0]); + console.log("actual", actualLink.id); + return ( + + ); + } + )} ); }; From 03d784a035f530bc6c866b40d3c9113474f1f570 Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 10 Aug 2023 16:32:45 +0200 Subject: [PATCH 047/121] chore(meshwide): fix merge geo and links algorithm --- .../src/components/Map/NodesAndLinks.tsx | 13 ++- .../src/meshWideMocks.tsx | 13 ++- .../src/utils/getLinksCoordinates.ts | 93 ++++++++++++++----- 3 files changed, 84 insertions(+), 35 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx index 34b3daab7..c1a20548e 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx @@ -129,15 +129,14 @@ export const NodesAndLinks = () => { return ; })} {locatedLinksReference && - locatedLinks && Object.entries(locatedLinksReference).map( (referenceLink, i) => { - const actualLink: PontToPointLink = Object.values( - locatedLinks - ).find((value) => value.id === referenceLink[0]); - - console.log("Reference", referenceLink[0]); - console.log("actual", actualLink.id); + let actualLink: PontToPointLink; + if (locatedLinks) { + actualLink = Object.values(locatedLinks).find( + (value) => value.id === referenceLink[0] + ); + } return ( { // Create a deep copy of the state to avoid mutating the original object - const newState = JSON.parse(JSON.stringify(linksReferenceState)); + const newState: IWifiLinks = JSON.parse( + JSON.stringify(linksReferenceState) + ); // Get source_macs from the node to be removed - const source_macs_to_remove = newState[nodeName].data.map( - (item: any) => item.src_mac + const source_macs_to_remove = newState[nodeName].data.map((item: any) => + item.src_mac.toLowerCase() ); // Remove the specified node @@ -144,10 +146,11 @@ export const links = (): IWifiLinks => { // Remove data items with matching dest_mac in other objects Object.keys(newState).forEach((key: string) => { - newState[key].data = newState[key].data.filter((item: any) => { - return !source_macs_to_remove.includes(item.dst_mac); + newState[key].data = newState[key].data.filter((item) => { + return !source_macs_to_remove.includes(item.dst_mac.toLowerCase()); }); }); + return newState; }; diff --git a/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts index 94c044b68..d805eaef3 100644 --- a/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts +++ b/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts @@ -8,45 +8,69 @@ import { export const mergeLinksAndCoordinates = ( nodes: INodes, - links: IWifiLinks + wifiLinks: IWifiLinks ): LocatedWifiLinkData => { - if (!nodes || !links) return {}; + if (!nodes || !wifiLinks) return {}; const result: LocatedWifiLinkData = {}; - for (const pointId in links) { - for (const data of links[pointId].data) { - const dstPointId = Object.keys(nodes).find((pid) => { - return nodes[pid].macs.filter((nodeMac) => - nodeMac.toLowerCase().includes(data.dst_mac.toLowerCase()) + // for every node check all links + for (const wifiNodeName in wifiLinks) { + for (const wifiLinkData of wifiLinks[wifiNodeName].data) { + // Get the nodeName of the destination node + const dstNodeName = Object.keys(nodes).find((pid) => { + return nodes[pid].macs.find( + (mac) => + mac.toLowerCase() === wifiLinkData.dst_mac.toLowerCase() ); }); - if (dstPointId && dstPointId !== pointId) { + if (dstNodeName && dstNodeName !== wifiNodeName) { + // Generate a unique id of the point to point link based on the coordinates const linkKey = PontToPointLink.generateId( - nodes[pointId].coordinates, - nodes[dstPointId!].coordinates + nodes[wifiNodeName].coordinates, + nodes[dstNodeName!].coordinates ); + // If this point to point link no exists, instantiate it if (!result[linkKey]) { result[linkKey] = new PontToPointLink( - nodes[pointId].coordinates, - nodes[dstPointId!].coordinates + nodes[wifiNodeName].coordinates, + nodes[dstNodeName!].coordinates ); } + // Else if the link is not already added don't do it. + else if ( + result[linkKey].linkExists( + wifiLinkData.src_mac, + wifiLinkData.dst_mac + ) || + !wifiLinks[dstNodeName] + ) { + continue; + } + + // Get the destination link info + const destPointData = wifiLinks[dstNodeName].data.find( + (data) => + data.dst_mac.toLowerCase() === + wifiLinkData.src_mac.toLowerCase() && + data.src_mac.toLowerCase() === + wifiLinkData.dst_mac.toLowerCase() + ); const entry: ILocatedLink = { - [pointId]: { - ...data, - coordinates: nodes[pointId].coordinates, + [wifiNodeName]: { + ...wifiLinkData, + coordinates: nodes[wifiNodeName].coordinates, }, - [dstPointId!]: { - tx_rate: data.tx_rate, - dst_mac: data.src_mac, - chains: data.chains, - src_mac: data.dst_mac, - rx_rate: data.rx_rate, - signal: data.signal, - coordinates: nodes[dstPointId!].coordinates, + [dstNodeName]: { + tx_rate: destPointData.tx_rate, + dst_mac: destPointData.src_mac, + chains: destPointData.chains, + src_mac: destPointData.dst_mac, + rx_rate: destPointData.rx_rate, + signal: destPointData.signal, + coordinates: nodes[dstNodeName].coordinates, }, }; result[linkKey].addLink(entry); @@ -74,6 +98,29 @@ export class PontToPointLink { this.links.push(link); } + /** + * For a given two macs check if any of the links on the _links array contain a node with this macs. (which should + * mean that the link is already added on the array). + * @param mac1 + * @param mac2 + */ + linkExists(mac1: string, mac2: string) { + for (const link of this._links) { + // Just needed to check the first node of the link object becouse the other till have the same macs but reversed + const node = link[Object.keys(link)[0]]; + if ( + node && + (node.dst_mac.toLowerCase() === mac1.toLowerCase() || + node.src_mac.toLowerCase() === mac1.toLowerCase()) && + (node.dst_mac.toLowerCase() === mac2.toLowerCase() || + node.src_mac.toLowerCase() === mac2.toLowerCase()) + ) { + return true; + } + } + return false; + } + get names() { return [ ...this._links.reduce((acc, link) => { From ad9823f15a48f40e510f23f9be93c6726743be46 Mon Sep 17 00:00:00 2001 From: selankon Date: Mon, 28 Aug 2023 17:23:06 +0200 Subject: [PATCH 048/121] chore(meshwide): test mergeLinksAndCoordinates --- .../src/utils/getLinksCoordinates.spec.ts | 33 +++++++++++++++++++ .../src/utils/getLinksCoordinates.ts | 9 +++-- 2 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.spec.ts diff --git a/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.spec.ts b/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.spec.ts new file mode 100644 index 000000000..7f24eeaea --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.spec.ts @@ -0,0 +1,33 @@ +import "@testing-library/jest-dom/extend-expect"; + +import { + linksReferenceState, + nodesReferenceState, +} from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; +import { mergeLinksAndCoordinates } from "plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates"; + +describe("tests for the algorithm that merge point and links data types", () => { + beforeEach(() => {}); + + it("assert that merged nodes have the correct coordinates", async () => { + const locatedLinksReference = mergeLinksAndCoordinates( + nodesReferenceState, + linksReferenceState + ); + // Iterate between merged link objects + Object.entries(locatedLinksReference).map(([k, merged], i) => { + expect(merged.coordinates.length).toBe(2); // Merged objects haw to be exactly two geo points + for (const link of merged.links) { + Object.entries(link).map(([name, linkData], i) => { + // const link = linksReferenceState[name]; + const node = nodesReferenceState[name]; + expect(link[name].coordinates).toBe(node.coordinates); + }); + } + }); + }); + + // Implement this tests + it.skip("no duplicated links", async () => {}); + it.skip("check that a link between two points can have different links with different macs", async () => {}); +}); diff --git a/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts index d805eaef3..f6e896b92 100644 --- a/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts +++ b/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts @@ -121,19 +121,24 @@ export class PontToPointLink { return false; } - get names() { + get names(): string[] { return [ ...this._links.reduce((acc, link) => { Object.keys(link).forEach((key) => acc.add(key)); return acc; }, new Set()), - ]; + ] as string[]; } get links() { return this._links; } + /** + * Generate a deterministic unique id based on the coordinates of a node. + * @param coord1 + * @param coord2 + */ static generateId(coord1: Coordinates, coord2: Coordinates): string { const _prepareCoord = (coord: string) => parseFloat(coord.replace("-", "").replace(".", "")); From baba8b3597b260b49f56593a7a6376c6a682878d Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 29 Aug 2023 18:14:33 +0200 Subject: [PATCH 049/121] chore(meshwide): create LinkDetail object --- .../src/components/Map/NodesAndLinks.tsx | 31 ++++++----- .../src/utils/getLinksCoordinates.ts | 51 ++++++++++++++++--- 2 files changed, 61 insertions(+), 21 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx index c1a20548e..594522042 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx @@ -1,4 +1,5 @@ import L from "leaflet"; +import { useMemo } from "preact/compat"; import { Marker, Polyline, Tooltip } from "react-leaflet"; import style from "plugins/lime-plugin-mesh-wide/src/components/Map/style.less"; @@ -106,21 +107,23 @@ export const NodesAndLinks = () => { const { data: meshWideLinks } = useMeshWideLinks({}); const { data: meshWideNodesReference } = useMeshWideNodesReference({}); - let locatedLinksReference: LocatedWifiLinkData; - if (meshWideNodesReference && meshWideLinksReference) { - locatedLinksReference = mergeLinksAndCoordinates( - meshWideNodesReference, - meshWideLinksReference - ); - } + const locatedLinksReference: LocatedWifiLinkData = useMemo(() => { + if (meshWideNodesReference && meshWideLinksReference) { + return mergeLinksAndCoordinates( + meshWideNodesReference, + meshWideLinksReference + ); + } + }, [meshWideNodesReference, meshWideLinksReference]); - let locatedLinks: LocatedWifiLinkData; - if (meshWideNodesReference && meshWideLinks) { - locatedLinks = mergeLinksAndCoordinates( - meshWideNodesReference, - meshWideLinks - ); - } + const locatedLinks: LocatedWifiLinkData = useMemo(() => { + if (meshWideNodesReference && meshWideLinks) { + return mergeLinksAndCoordinates( + meshWideNodesReference, + meshWideLinks + ); + } + }, [meshWideNodesReference, meshWideLinks]); return ( <> diff --git a/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts index f6e896b92..4ddc99216 100644 --- a/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts +++ b/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts @@ -65,15 +65,15 @@ export const mergeLinksAndCoordinates = ( }, [dstNodeName]: { tx_rate: destPointData.tx_rate, - dst_mac: destPointData.src_mac, + dst_mac: destPointData.dst_mac, chains: destPointData.chains, - src_mac: destPointData.dst_mac, + src_mac: destPointData.src_mac, rx_rate: destPointData.rx_rate, signal: destPointData.signal, coordinates: nodes[dstNodeName].coordinates, }, }; - result[linkKey].addLink(entry); + result[linkKey].addLink(new LinkDetail(entry)); } } } @@ -85,7 +85,7 @@ export const mergeLinksAndCoordinates = ( * This class should store a group of links between the same geo coordinates. */ export class PontToPointLink { - private _links: ILocatedLink[] = []; + private _links: LinkDetail[] = []; public readonly id: string; public readonly coordinates: Coordinates[] = []; @@ -94,7 +94,7 @@ export class PontToPointLink { this.coordinates.push(coord1, coord2); } - addLink(link: ILocatedLink) { + addLink(link: LinkDetail) { this.links.push(link); } @@ -106,8 +106,8 @@ export class PontToPointLink { */ linkExists(mac1: string, mac2: string) { for (const link of this._links) { - // Just needed to check the first node of the link object becouse the other till have the same macs but reversed - const node = link[Object.keys(link)[0]]; + // Just needed to check the first node of the link object becouse the other will have the same macs but reversed + const node = link.data[Object.keys(link.data)[0]]; if ( node && (node.dst_mac.toLowerCase() === mac1.toLowerCase() || @@ -153,3 +153,40 @@ export class PontToPointLink { return allCoordinates.sort((a, b) => a - b).toString(); } } + +export class LinkDetail { + private _data: ILocatedLink; + private _id: string; + + constructor(data: ILocatedLink) { + this._data = data; + // this._id = LinkDetail.generateId(data); + this._id = LinkDetail.generateId(data); + } + + /** + * Deterministically generation of a unique id using the macs of this link + * @param data + */ + static generateId(data: ILocatedLink): string { + return [ + ...Object.entries(data).map(([k, v]) => { + return v.src_mac.toLowerCase().replace(/:/g, ""); + }), + ] + .sort() + .join(""); + } + + get id() { + return this._id; + } + + get data() { + return this._data; + } + + get names(): string[] { + return [...Object.keys(this._data)]; + } +} From cbb01fea6f9dd50e6520c13ebbb5ca44c9a2da55 Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 30 Aug 2023 15:28:40 +0200 Subject: [PATCH 050/121] chore(meshwide): implement multiple links between points --- .../src/components/FeatureDetail.tsx | 59 ++++++++++++++----- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx index 4afcd8cc3..5fa2a3aa9 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx @@ -1,7 +1,9 @@ import { Trans } from "@lingui/macro"; import { VNode } from "preact"; +import { useState } from "preact/hooks"; import { Button } from "components/buttons/button"; +import Tabs from "components/tabs"; import { StatusAndButton } from "plugins/lime-plugin-mesh-wide/src/components/Components"; import { PowerIcon } from "plugins/lime-plugin-mesh-wide/src/icons/power"; @@ -9,7 +11,10 @@ import { INamedNodeInfo, SelectedMapFeature, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; -import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates"; +import { + LinkDetail, + PontToPointLink, +} from "plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates"; const TitleAndText = ({ title, @@ -34,24 +39,21 @@ const Row = ({ children }: { children: any }) => { ); }; -const LinkDetails = ({ - linkDetails, - selectedFeature, -}: { - linkDetails: PontToPointLink; - selectedFeature: SelectedMapFeature; -}) => { - const name = linkDetails?.names ?? selectedFeature?.id ?? ""; +const SelectedLink = ({ linkDetail }: { linkDetail: LinkDetail }) => { + const names = linkDetail?.names; const gain = "5 dB"; const linkType = "Primary"; return ( <> -
- Link - {name} -
+ {names && ( +
+ + Link from {names[0]} to {names[1]} + +
+ )} @@ -66,6 +68,36 @@ const LinkDetails = ({ ); }; +const LinkDetails = ({ linkDetails }: { linkDetails: PontToPointLink }) => { + const [selectedLink, setSelectedLink] = useState(0); + + const tabs = linkDetails.links.map((link: LinkDetail, i) => { + return { + key: i, + repr: Link {i + 1}, + }; + }); + + return ( + <> +
+ {tabs.length > 1 && ( + + )} + {selectedLink !== null && ( + + )} +
+ + ); +}; + const NodeDetails = ({ nodeDetail, selectedFeature, @@ -130,7 +162,6 @@ export const FeatureDetail = ({ return ( ); case "node": From b3e2f687464d29171fcf8502194b51290f5e54cc Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 30 Aug 2023 16:25:25 +0200 Subject: [PATCH 051/121] chore(meshwide): refactor component folders --- .../src/components/FeatureDetail.tsx | 231 ------------------ .../components/FeatureDetail/LinkDetail.tsx | 101 ++++++++ .../components/FeatureDetail/NodeDetail.tsx | 66 +++++ .../src/components/FeatureDetail/index.tsx | 90 +++++++ .../src/components/Map/LinkLine.tsx | 57 +++++ .../src/components/Map/NodeMarker.tsx | 71 ++++++ .../src/components/Map/NodesAndLinks.tsx | 154 ------------ .../components/configPage/ConfigSection.tsx | 2 +- .../src/components/configPage/OptionForm.tsx | 2 +- .../components/{ => configPage}/modals.tsx | 0 .../{components => containers/Map}/Map.tsx | 7 +- .../src/containers/Map/NodesAndLinksLayer.tsx | 63 +++++ .../SelectedFeatureBottomSheet.tsx} | 12 +- .../src/lib/links/PointToPointLink.ts | 114 +++++++++ .../links}/getLinksCoordinates.spec.ts | 2 +- .../src/lib/links/getLinksCoordinates.ts | 85 +++++++ .../src/mesWideTypes.tsx | 2 +- .../src/meshWidePage.tsx | 6 +- .../src/screens/configPage.tsx | 14 -- .../src/utils/getLinksCoordinates.ts | 192 --------------- tailwind.config.js | 1 + 21 files changed, 664 insertions(+), 608 deletions(-) delete mode 100644 plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx create mode 100644 plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx create mode 100644 plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx create mode 100644 plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx create mode 100644 plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx create mode 100644 plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx delete mode 100644 plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx rename plugins/lime-plugin-mesh-wide/src/components/{ => configPage}/modals.tsx (100%) rename plugins/lime-plugin-mesh-wide/src/{components => containers/Map}/Map.tsx (89%) create mode 100644 plugins/lime-plugin-mesh-wide/src/containers/Map/NodesAndLinksLayer.tsx rename plugins/lime-plugin-mesh-wide/src/{components/MapBottomSheet.tsx => containers/SelectedFeatureBottomSheet.tsx} (82%) create mode 100644 plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts rename plugins/lime-plugin-mesh-wide/src/{utils => lib/links}/getLinksCoordinates.spec.ts (96%) create mode 100644 plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts delete mode 100644 plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx deleted file mode 100644 index 5fa2a3aa9..000000000 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail.tsx +++ /dev/null @@ -1,231 +0,0 @@ -import { Trans } from "@lingui/macro"; -import { VNode } from "preact"; -import { useState } from "preact/hooks"; - -import { Button } from "components/buttons/button"; -import Tabs from "components/tabs"; - -import { StatusAndButton } from "plugins/lime-plugin-mesh-wide/src/components/Components"; -import { PowerIcon } from "plugins/lime-plugin-mesh-wide/src/icons/power"; -import { - INamedNodeInfo, - SelectedMapFeature, -} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; -import { - LinkDetail, - PontToPointLink, -} from "plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates"; - -const TitleAndText = ({ - title, - children, -}: { - title: any; // todo(kon): error with trans component - children: string; -}) => { - return ( -
-
{title}
-
{children}
-
- ); -}; - -const Row = ({ children }: { children: any }) => { - return ( -
- {children} -
- ); -}; - -const SelectedLink = ({ linkDetail }: { linkDetail: LinkDetail }) => { - const names = linkDetail?.names; - const gain = "5 dB"; - const linkType = "Primary"; - - return ( - <> - - {names && ( -
- - Link from {names[0]} to {names[1]} - -
- )} - -
- - Gain}>{gain} - Link type}> - {linkType} - - - - ); -}; - -const LinkDetails = ({ linkDetails }: { linkDetails: PontToPointLink }) => { - const [selectedLink, setSelectedLink] = useState(0); - - const tabs = linkDetails.links.map((link: LinkDetail, i) => { - return { - key: i, - repr: Link {i + 1}, - }; - }); - - return ( - <> -
- {tabs.length > 1 && ( - - )} - {selectedLink !== null && ( - - )} -
- - ); -}; - -const NodeDetails = ({ - nodeDetail, - selectedFeature, - synced, -}: { - nodeDetail: INamedNodeInfo; - selectedFeature: SelectedMapFeature; - synced: boolean; -}) => { - const name = nodeDetail?.name ?? selectedFeature?.id ?? ""; - const uptime = "1 week"; - const firmware = "e93615c947-x86-64"; - const ipv6 = "fe80::42:cff:fecf:bfff"; - const ipv4 = "192.168.1.47"; - const device = "LibreRouter"; - - return ( - <> - -
{name}
- -
- - {synced ? ( - Uptime}> - {uptime} - - ) : ( - Downtime}> - {uptime} - - )} - Firmware version}> - {firmware} - - - - IPv4}>{ipv4} - IPv6}>{ipv6} - - - Device}> - {device} - - - - ); -}; - -export const FeatureDetail = ({ - selectedFeature, - synced, -}: { - selectedFeature: SelectedMapFeature; - synced: boolean; -}) => { - if (!selectedFeature) return; - switch (selectedFeature.type) { - case "link": - return ( - - ); - case "node": - return ( - - ); - default: - return <>; - } -}; - -export const BottomSheetFooter = ({ - synced, - selectedFeature, -}: { - synced?: boolean; - selectedFeature: SelectedMapFeature; -}) => { - if (!selectedFeature) return; - - const type = selectedFeature.type; - - const Synced = () => { - let txt: VNode; - if (type === "link") { - txt = Same status as in the reference state; - } else if (type === "node") { - txt = Same status as in the reference state; - } - - return {txt}; - }; - - const UpdateReference = () => { - let txt: VNode; - let btn: VNode; - if (type === "link") { - txt = ( - - This link has 5dB difference - {/*{*/} - {/* (*/} - {/* selectedFeature.feature*/} - {/* .properties as ILinkDetailFeature*/} - {/* ).gain*/} - {/*}{" "}*/} -
with the reference state -
- ); - btn = Update this link on reference state; - } else if (type === "node") { - txt = In the reference state this node is on; - btn = Update this node on reference state; - } - return ( - - {txt} - - ); - }; - - return synced ? : ; -}; diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx new file mode 100644 index 000000000..4648cb71c --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx @@ -0,0 +1,101 @@ +import { Trans } from "@lingui/macro"; +import { VNode } from "preact"; +import { useState } from "preact/hooks"; + +import { Button } from "components/buttons/button"; +import Tabs from "components/tabs"; + +import { StatusAndButton } from "plugins/lime-plugin-mesh-wide/src/components/Components"; +import { PowerIcon } from "plugins/lime-plugin-mesh-wide/src/icons/power"; +import { + LinkDetailData, + PontToPointLink, +} from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; + +import { Row, TitleAndText } from "./index"; + +const SelectedLink = ({ linkDetail }: { linkDetail: LinkDetailData }) => { + const names = linkDetail?.names; + const gain = "5 dB"; + const linkType = "Primary"; + + return ( + <> + + {names && ( +
+ + Link from {names[0]} to {names[1]} + +
+ )} + +
+ + Gain}>{gain} + Link type}> + {linkType} + + + + ); +}; + +const Links = ({ linkDetails }: { linkDetails: PontToPointLink }) => { + const [selectedLink, setSelectedLink] = useState(0); + + const tabs = linkDetails.links.map((link: LinkDetailData, i) => { + return { + key: i, + repr: Link {i + 1}, + }; + }); + + return ( + <> +
+ {tabs.length > 1 && ( + + )} + {selectedLink !== null && ( + + )} +
+ + ); +}; + +export const LinkReferenceStatus = ({ + hasError, + selectedFeature, +}: { + hasError?: boolean; + selectedFeature: PontToPointLink; +}) => { + const txt: VNode = hasError ? ( + + This link has 5dB difference +
with the reference state +
+ ) : ( + Same status as in the reference state + ); + return ( + Update this link on reference state} + > + {txt} + + ); +}; + +export default Links; diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx new file mode 100644 index 000000000..73b02b7f1 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx @@ -0,0 +1,66 @@ +import { Trans } from "@lingui/macro"; + +import { Button } from "components/buttons/button"; + +import { + Row, + TitleAndText, +} from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index"; +import { PowerIcon } from "plugins/lime-plugin-mesh-wide/src/icons/power"; +import { + INamedNodeInfo, + SelectedMapFeature, +} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; + +const NodeDetails = ({ + nodeDetail, + selectedFeature, + hasError, +}: { + nodeDetail: INamedNodeInfo; + selectedFeature: SelectedMapFeature; + hasError: boolean; +}) => { + const name = nodeDetail?.name ?? selectedFeature?.id ?? ""; + const uptime = "1 week"; + const firmware = "e93615c947-x86-64"; + const ipv6 = "fe80::42:cff:fecf:bfff"; + const ipv4 = "192.168.1.47"; + const device = "LibreRouter"; + + return ( + <> + +
{name}
+ +
+ + {!hasError ? ( + Uptime}> + {uptime} + + ) : ( + Downtime}> + {uptime} + + )} + Firmware version}> + {firmware} + + + + IPv4}>{ipv4} + IPv6}>{ipv6} + + + Device}> + {device} + + + + ); +}; + +export default NodeDetails; diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx new file mode 100644 index 000000000..a10798a00 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx @@ -0,0 +1,90 @@ +import Links, { + LinkReferenceStatus, +} from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail"; +import NodeDetails from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail"; +import { NodeReferenceStatus } from "plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker"; +import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; +import { + INamedNodeInfo, + SelectedMapFeature, +} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; + +export const TitleAndText = ({ + title, + children, +}: { + title: any; // todo(kon): error with trans component + children: string; +}) => { + return ( +
+
{title}
+
{children}
+
+ ); +}; + +export const Row = ({ children }: { children: any }) => { + return ( +
+ {children} +
+ ); +}; + +export const FeatureDetail = ({ + selectedFeature, + hasError, +}: { + selectedFeature: SelectedMapFeature; + hasError: boolean; +}) => { + if (!selectedFeature) return; + switch (selectedFeature.type) { + case "link": + return ( + + ); + case "node": + return ( + + ); + default: + return <>; + } +}; + +export const FeatureReferenceStatus = ({ + hasError, + selectedFeature, +}: { + hasError?: boolean; + selectedFeature: SelectedMapFeature; +}) => { + if (!selectedFeature) return; + const type = selectedFeature.type; + + if (type === "link") { + return ( + + ); + } else if (type === "node") { + return ( + + ); + } +}; + +export default FeatureDetail; diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx new file mode 100644 index 000000000..cf51e3746 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx @@ -0,0 +1,57 @@ +import L from "leaflet"; +import { Polyline } from "react-leaflet"; + +import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; +import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; + +const LinkLine = ({ + referenceLink, + actualLink, +}: { + referenceLink: PontToPointLink; + actualLink: PontToPointLink | undefined; +}) => { + const { data: selectedMapFeature, setData: setSelectedMapFeature } = + useSelectedMapFeature(); + const isSelected = selectedMapFeature?.id === referenceLink.id; + + const synced: boolean = Math.random() < 0.5; + + const getPathOpts = (isSelected) => { + return { + color: synced ? "#76bd7d" : "#eb7575", + weight: isSelected ? 7 : 5, + opacity: isSelected ? 1 : 0.8, + dashArray: actualLink ? null : "7 10", + }; + }; + + const coordinates = referenceLink.coordinates.map((c) => [c.lat, c.lon]); + + return ( + { + L.DomEvent.stopPropagation(e); + setSelectedMapFeature({ + id: referenceLink.id, + feature: referenceLink, + type: "link", + }); + }, + mouseover: (e) => { + const l = e.target; + l.setStyle(getPathOpts(true)); + }, + mouseout: (event) => { + const l = event.target; + l.setStyle(getPathOpts(isSelected)); + }, + }} + /> + ); +}; + +export default LinkLine; diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx new file mode 100644 index 000000000..bdfda77d6 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx @@ -0,0 +1,71 @@ +import { Trans } from "@lingui/macro"; +import L from "leaflet"; +import { VNode } from "preact"; +import { Marker, Tooltip } from "react-leaflet"; + +import { StatusAndButton } from "plugins/lime-plugin-mesh-wide/src/components/Components"; +import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; +import { + INamedNodeInfo, + INodeInfo, +} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; + +import style from "./style.less"; + +const NodeMarker = ({ name, info }: { name: string; info: INodeInfo }) => { + const { data: selectedMapFeature, setData: setSelectedMapFeature } = + useSelectedMapFeature(); + const synced: boolean = Math.random() < 0.5; + + const markerClasses = `${ + selectedMapFeature?.id === name && style.selectedMarker + } ${synced ? style.syncedMarker : style.notSyncedMarker}`; + + return ( + `, + })} + eventHandlers={{ + click: (e) => { + L.DomEvent.stopPropagation(e); + setSelectedMapFeature({ + id: name, + feature: { ...info, name }, + type: "node", + }); + }, + }} + > + {name} + + ); +}; + +export const NodeReferenceStatus = ({ + hasError, + selectedFeature, +}: { + hasError?: boolean; + selectedFeature: INamedNodeInfo; +}) => { + const txt: VNode = hasError ? ( + In the reference state this node is on + ) : ( + Same status as in the reference state + ); + return ( + Update this node on reference state} + > + {txt} + + ); +}; + +export default NodeMarker; diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx deleted file mode 100644 index 594522042..000000000 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks.tsx +++ /dev/null @@ -1,154 +0,0 @@ -import L from "leaflet"; -import { useMemo } from "preact/compat"; -import { Marker, Polyline, Tooltip } from "react-leaflet"; - -import style from "plugins/lime-plugin-mesh-wide/src/components/Map/style.less"; -import { - useMeshWideLinks, - useMeshWideLinksReference, - useMeshWideNodesReference, - useSelectedMapFeature, -} from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; -import { - INodeInfo, - LocatedWifiLinkData, -} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; -import { - PontToPointLink, - mergeLinksAndCoordinates, -} from "plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates"; - -const NodeMarker = ({ name, info }: { name: string; info: INodeInfo }) => { - const { data: selectedMapFeature, setData: setSelectedMapFeature } = - useSelectedMapFeature(); - const synced: boolean = Math.random() < 0.5; - - const markerClasses = `${ - selectedMapFeature?.id === name && style.selectedMarker - } ${synced ? style.syncedMarker : style.notSyncedMarker}`; - - return ( - `, - })} - eventHandlers={{ - click: (e) => { - L.DomEvent.stopPropagation(e); - setSelectedMapFeature({ - id: name, - feature: { ...info, name }, - type: "node", - }); - }, - }} - > - {name} - - ); -}; - -const LinkLine = ({ - referenceLink, - actualLink, -}: { - referenceLink: PontToPointLink; - actualLink: PontToPointLink | undefined; -}) => { - const { data: selectedMapFeature, setData: setSelectedMapFeature } = - useSelectedMapFeature(); - const isSelected = selectedMapFeature?.id === referenceLink.id; - - const synced: boolean = Math.random() < 0.5; - - const getPathOpts = (isSelected) => { - return { - color: synced ? "#76bd7d" : "#eb7575", - weight: isSelected ? 7 : 5, - opacity: isSelected ? 1 : 0.8, - dashArray: actualLink ? null : "7 10", - }; - }; - - const coordinates = referenceLink.coordinates.map((c) => [c.lat, c.lon]); - - return ( - { - L.DomEvent.stopPropagation(e); - setSelectedMapFeature({ - id: referenceLink.id, - feature: referenceLink, - type: "link", - }); - }, - mouseover: (e) => { - const l = e.target; - l.setStyle(getPathOpts(true)); - }, - mouseout: (event) => { - const l = event.target; - l.setStyle(getPathOpts(isSelected)); - }, - }} - /> - ); -}; - -export const NodesAndLinks = () => { - const { data: meshWideLinksReference } = useMeshWideLinksReference({}); - const { data: meshWideLinks } = useMeshWideLinks({}); - const { data: meshWideNodesReference } = useMeshWideNodesReference({}); - - const locatedLinksReference: LocatedWifiLinkData = useMemo(() => { - if (meshWideNodesReference && meshWideLinksReference) { - return mergeLinksAndCoordinates( - meshWideNodesReference, - meshWideLinksReference - ); - } - }, [meshWideNodesReference, meshWideLinksReference]); - - const locatedLinks: LocatedWifiLinkData = useMemo(() => { - if (meshWideNodesReference && meshWideLinks) { - return mergeLinksAndCoordinates( - meshWideNodesReference, - meshWideLinks - ); - } - }, [meshWideNodesReference, meshWideLinks]); - - return ( - <> - {meshWideNodesReference && - Object.entries(meshWideNodesReference).map(([k, v], i) => { - return ; - })} - {locatedLinksReference && - Object.entries(locatedLinksReference).map( - (referenceLink, i) => { - let actualLink: PontToPointLink; - if (locatedLinks) { - actualLink = Object.values(locatedLinks).find( - (value) => value.id === referenceLink[0] - ); - } - return ( - - ); - } - )} - - ); -}; diff --git a/plugins/lime-plugin-mesh-wide/src/components/configPage/ConfigSection.tsx b/plugins/lime-plugin-mesh-wide/src/components/configPage/ConfigSection.tsx index 28016483b..70b5c0726 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/configPage/ConfigSection.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/configPage/ConfigSection.tsx @@ -10,7 +10,7 @@ import { useAddNewSectionModal, useDeletePropModal, useEditPropModal, -} from "plugins/lime-plugin-mesh-wide/src/components/modals"; +} from "plugins/lime-plugin-mesh-wide/src/components/configPage/modals"; import { IMeshWideSection } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; export const ConfigSection = ({ dropdown }: { dropdown: IMeshWideSection }) => { diff --git a/plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm.tsx b/plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm.tsx index a5fddb2db..3610454ca 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm.tsx @@ -11,7 +11,7 @@ import { EditOrDelete } from "plugins/lime-plugin-mesh-wide/src/components/Compo import { useDeletePropModal, useEditPropModal, -} from "plugins/lime-plugin-mesh-wide/src/components/modals"; +} from "plugins/lime-plugin-mesh-wide/src/components/configPage/modals"; const EditOptionForm = ({ keyString, diff --git a/plugins/lime-plugin-mesh-wide/src/components/modals.tsx b/plugins/lime-plugin-mesh-wide/src/components/configPage/modals.tsx similarity index 100% rename from plugins/lime-plugin-mesh-wide/src/components/modals.tsx rename to plugins/lime-plugin-mesh-wide/src/components/configPage/modals.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map/Map.tsx similarity index 89% rename from plugins/lime-plugin-mesh-wide/src/components/Map.tsx rename to plugins/lime-plugin-mesh-wide/src/containers/Map/Map.tsx index 652f8c32d..0ea6e9d56 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map/Map.tsx @@ -2,7 +2,7 @@ import L from "leaflet"; import { useEffect, useRef } from "preact/hooks"; import { MapContainer, TileLayer } from "react-leaflet"; -import { NodesAndLinks } from "plugins/lime-plugin-mesh-wide/src/components/Map/NodesAndLinks"; +import { NodesAndLinksLayer } from "plugins/lime-plugin-mesh-wide/src/containers/Map/NodesAndLinksLayer"; import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; const openStreetMapTileString = "http://{s}.tile.osm.org/{z}/{x}/{y}.png"; @@ -44,7 +44,7 @@ export const MeshWideMap = () => { return ( { attribution={openStreetMapAttribution} url={openStreetMapTileString} /> - - {/**/} + ); }; diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map/NodesAndLinksLayer.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map/NodesAndLinksLayer.tsx new file mode 100644 index 000000000..ae6099a60 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map/NodesAndLinksLayer.tsx @@ -0,0 +1,63 @@ +import { useMemo } from "preact/compat"; + +import LinkLine from "plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine"; +import NodeMarker from "plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker"; +import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; +import { mergeLinksAndCoordinates } from "plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates"; +import { + useMeshWideLinks, + useMeshWideLinksReference, + useMeshWideNodesReference, +} from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; +import { LocatedWifiLinkData } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; + +export const NodesAndLinksLayer = () => { + const { data: meshWideLinksReference } = useMeshWideLinksReference({}); + const { data: meshWideLinks } = useMeshWideLinks({}); + const { data: meshWideNodesReference } = useMeshWideNodesReference({}); + + const locatedLinksReference: LocatedWifiLinkData = useMemo(() => { + if (meshWideNodesReference && meshWideLinksReference) { + return mergeLinksAndCoordinates( + meshWideNodesReference, + meshWideLinksReference + ); + } + }, [meshWideNodesReference, meshWideLinksReference]); + + const locatedLinks: LocatedWifiLinkData = useMemo(() => { + if (meshWideNodesReference && meshWideLinks) { + return mergeLinksAndCoordinates( + meshWideNodesReference, + meshWideLinks + ); + } + }, [meshWideNodesReference, meshWideLinks]); + + return ( + <> + {meshWideNodesReference && + Object.entries(meshWideNodesReference).map(([k, v], i) => { + return ; + })} + {locatedLinksReference && + Object.entries(locatedLinksReference).map( + (referenceLink, i) => { + let actualLink: PontToPointLink; + if (locatedLinks) { + actualLink = Object.values(locatedLinks).find( + (value) => value.id === referenceLink[0] + ); + } + return ( + + ); + } + )} + + ); +}; diff --git a/plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet.tsx b/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.tsx similarity index 82% rename from plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet.tsx rename to plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.tsx index 1258b288a..dbf03fbca 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.tsx @@ -4,14 +4,14 @@ import React from "react"; import { BottomSheet } from "components/bottom-sheet"; import { - BottomSheetFooter, FeatureDetail, + FeatureReferenceStatus, } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail"; import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; -export const MapBottomSheet = () => { +export const SelectedFeatureBottomSheet = () => { const [isOpen, setIsOpen] = useState(false); - const synced: boolean = Math.random() < 0.5; + const hasError: boolean = Math.random() < 0.5; const { data: selectedMapFeature } = useSelectedMapFeature(); @@ -29,15 +29,15 @@ export const MapBottomSheet = () => { }} initialDrawerDistanceTop={600} footer={ - } >
diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts new file mode 100644 index 000000000..7380d5cb4 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts @@ -0,0 +1,114 @@ +import { + Coordinates, + ILocatedLink, +} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; + +/** + * This class should store a group of links between the same geo coordinates. + */ +export class PontToPointLink { + private _links: LinkDetailData[] = []; + public readonly id: string; + public readonly coordinates: Coordinates[] = []; + + constructor(coord1: Coordinates, coord2: Coordinates) { + this.id = PontToPointLink.generateId(coord1, coord2); + this.coordinates.push(coord1, coord2); + } + + addLink(link: LinkDetailData) { + this.links.push(link); + } + + /** + * For a given two macs check if any of the links on the _links array contain a node with this macs. (which should + * mean that the link is already added on the array). + * @param mac1 + * @param mac2 + */ + linkExists(mac1: string, mac2: string) { + for (const link of this._links) { + // Just needed to check the first node of the link object becouse the other will have the same macs but reversed + const node = link.data[Object.keys(link.data)[0]]; + if ( + node && + (node.dst_mac.toLowerCase() === mac1.toLowerCase() || + node.src_mac.toLowerCase() === mac1.toLowerCase()) && + (node.dst_mac.toLowerCase() === mac2.toLowerCase() || + node.src_mac.toLowerCase() === mac2.toLowerCase()) + ) { + return true; + } + } + return false; + } + + get names(): string[] { + return [ + ...this._links.reduce((acc, link) => { + Object.keys(link).forEach((key) => acc.add(key)); + return acc; + }, new Set()), + ] as string[]; + } + + get links() { + return this._links; + } + + /** + * Generate a deterministic unique id based on the coordinates of a node. + * @param coord1 + * @param coord2 + */ + static generateId(coord1: Coordinates, coord2: Coordinates): string { + const _prepareCoord = (coord: string) => + parseFloat(coord.replace("-", "").replace(".", "")); + + const allCoordinates = [ + _prepareCoord(coord1.lon), + _prepareCoord(coord1.lat), + _prepareCoord(coord2.lon), + _prepareCoord(coord2.lat), + ]; + + return allCoordinates.sort((a, b) => a - b).toString(); + } +} + +export class LinkDetailData { + private _data: ILocatedLink; + private _id: string; + + constructor(data: ILocatedLink) { + this._data = data; + // this._id = LinkDetail.generateId(data); + this._id = LinkDetailData.generateId(data); + } + + /** + * Deterministically generation of a unique id using the macs of this link + * @param data + */ + static generateId(data: ILocatedLink): string { + return [ + ...Object.entries(data).map(([k, v]) => { + return v.src_mac.toLowerCase().replace(/:/g, ""); + }), + ] + .sort() + .join(""); + } + + get id() { + return this._id; + } + + get data() { + return this._data; + } + + get names(): string[] { + return [...Object.keys(this._data)]; + } +} diff --git a/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.spec.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.spec.ts similarity index 96% rename from plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.spec.ts rename to plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.spec.ts index 7f24eeaea..d9b4217cc 100644 --- a/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.spec.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.spec.ts @@ -1,10 +1,10 @@ import "@testing-library/jest-dom/extend-expect"; +import { mergeLinksAndCoordinates } from "plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates"; import { linksReferenceState, nodesReferenceState, } from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; -import { mergeLinksAndCoordinates } from "plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates"; describe("tests for the algorithm that merge point and links data types", () => { beforeEach(() => {}); diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts new file mode 100644 index 000000000..a787b2af2 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts @@ -0,0 +1,85 @@ +import { + LinkDetailData, + PontToPointLink, +} from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; +import { + ILocatedLink, + INodes, + IWifiLinks, + LocatedWifiLinkData, +} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; + +export const mergeLinksAndCoordinates = ( + nodes: INodes, + wifiLinks: IWifiLinks +): LocatedWifiLinkData => { + if (!nodes || !wifiLinks) return {}; + const result: LocatedWifiLinkData = {}; + + // for every node check all links + for (const wifiNodeName in wifiLinks) { + for (const wifiLinkData of wifiLinks[wifiNodeName].data) { + // Get the nodeName of the destination node + const dstNodeName = Object.keys(nodes).find((pid) => { + return nodes[pid].macs.find( + (mac) => + mac.toLowerCase() === wifiLinkData.dst_mac.toLowerCase() + ); + }); + + if (dstNodeName && dstNodeName !== wifiNodeName) { + // Generate a unique id of the point to point link based on the coordinates + const linkKey = PontToPointLink.generateId( + nodes[wifiNodeName].coordinates, + nodes[dstNodeName!].coordinates + ); + + // If this point to point link no exists, instantiate it + if (!result[linkKey]) { + result[linkKey] = new PontToPointLink( + nodes[wifiNodeName].coordinates, + nodes[dstNodeName!].coordinates + ); + } + // Else if the link is not already added don't do it. + else if ( + result[linkKey].linkExists( + wifiLinkData.src_mac, + wifiLinkData.dst_mac + ) || + !wifiLinks[dstNodeName] + ) { + continue; + } + + // Get the destination link info + const destPointData = wifiLinks[dstNodeName].data.find( + (data) => + data.dst_mac.toLowerCase() === + wifiLinkData.src_mac.toLowerCase() && + data.src_mac.toLowerCase() === + wifiLinkData.dst_mac.toLowerCase() + ); + + const entry: ILocatedLink = { + [wifiNodeName]: { + ...wifiLinkData, + coordinates: nodes[wifiNodeName].coordinates, + }, + [dstNodeName]: { + tx_rate: destPointData.tx_rate, + dst_mac: destPointData.dst_mac, + chains: destPointData.chains, + src_mac: destPointData.src_mac, + rx_rate: destPointData.rx_rate, + signal: destPointData.signal, + coordinates: nodes[dstNodeName].coordinates, + }, + }; + result[linkKey].addLink(new LinkDetailData(entry)); + } + } + } + + return result; +}; diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index 0dd200b74..20165af85 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -1,4 +1,4 @@ -import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates"; +import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; /** * Describe a link with a coordinates diff --git a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx index 89c6158e4..8823abe80 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx @@ -5,8 +5,8 @@ import FloatingButton from "components/buttons/floatting-button"; import Loading from "components/loading"; import { useLoadLeaflet } from "plugins/lime-plugin-locate/src/locateQueries"; -import { MeshWideMap } from "plugins/lime-plugin-mesh-wide/src/components/Map"; -import { MapBottomSheet } from "plugins/lime-plugin-mesh-wide/src/components/MapBottomSheet"; +import { MeshWideMap } from "plugins/lime-plugin-mesh-wide/src/containers/Map/Map"; +import { SelectedFeatureBottomSheet } from "plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet"; const MeshWidePage = () => { const { @@ -29,7 +29,7 @@ const MeshWidePage = () => { {!loading && ( <> - + route("/meshwide/config")} /> )} diff --git a/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx b/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx index 8ac751b23..e7be52b1c 100644 --- a/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx +++ b/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx @@ -1,27 +1,13 @@ import { Trans } from "@lingui/macro"; import { FullScreenModal } from "components/Modal/FullScreenModal"; -import { Button } from "components/buttons/button"; -import { Collapsible } from "components/collapsible"; import Divider from "components/divider"; -import { useToast } from "components/toast/toastProvider"; -import { - EditOrDelete, - StatusAndButton, -} from "plugins/lime-plugin-mesh-wide/src/components/Components"; import { AddNewSectionBtn, ConfigSection, - SectionEditOrDelete, } from "plugins/lime-plugin-mesh-wide/src/components/configPage/ConfigSection"; import { MeshStatus } from "plugins/lime-plugin-mesh-wide/src/components/configPage/MeshStatus"; -import { OptionContainer } from "plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm"; -import { - useAddNewSectionModal, - useDeletePropModal, - useEditPropModal, -} from "plugins/lime-plugin-mesh-wide/src/components/modals"; import { useMeshWideConfig } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; const MeshWideConfigPage = () => { diff --git a/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts deleted file mode 100644 index 4ddc99216..000000000 --- a/plugins/lime-plugin-mesh-wide/src/utils/getLinksCoordinates.ts +++ /dev/null @@ -1,192 +0,0 @@ -import { - Coordinates, - ILocatedLink, - INodes, - IWifiLinks, - LocatedWifiLinkData, -} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; - -export const mergeLinksAndCoordinates = ( - nodes: INodes, - wifiLinks: IWifiLinks -): LocatedWifiLinkData => { - if (!nodes || !wifiLinks) return {}; - const result: LocatedWifiLinkData = {}; - - // for every node check all links - for (const wifiNodeName in wifiLinks) { - for (const wifiLinkData of wifiLinks[wifiNodeName].data) { - // Get the nodeName of the destination node - const dstNodeName = Object.keys(nodes).find((pid) => { - return nodes[pid].macs.find( - (mac) => - mac.toLowerCase() === wifiLinkData.dst_mac.toLowerCase() - ); - }); - - if (dstNodeName && dstNodeName !== wifiNodeName) { - // Generate a unique id of the point to point link based on the coordinates - const linkKey = PontToPointLink.generateId( - nodes[wifiNodeName].coordinates, - nodes[dstNodeName!].coordinates - ); - - // If this point to point link no exists, instantiate it - if (!result[linkKey]) { - result[linkKey] = new PontToPointLink( - nodes[wifiNodeName].coordinates, - nodes[dstNodeName!].coordinates - ); - } - // Else if the link is not already added don't do it. - else if ( - result[linkKey].linkExists( - wifiLinkData.src_mac, - wifiLinkData.dst_mac - ) || - !wifiLinks[dstNodeName] - ) { - continue; - } - - // Get the destination link info - const destPointData = wifiLinks[dstNodeName].data.find( - (data) => - data.dst_mac.toLowerCase() === - wifiLinkData.src_mac.toLowerCase() && - data.src_mac.toLowerCase() === - wifiLinkData.dst_mac.toLowerCase() - ); - - const entry: ILocatedLink = { - [wifiNodeName]: { - ...wifiLinkData, - coordinates: nodes[wifiNodeName].coordinates, - }, - [dstNodeName]: { - tx_rate: destPointData.tx_rate, - dst_mac: destPointData.dst_mac, - chains: destPointData.chains, - src_mac: destPointData.src_mac, - rx_rate: destPointData.rx_rate, - signal: destPointData.signal, - coordinates: nodes[dstNodeName].coordinates, - }, - }; - result[linkKey].addLink(new LinkDetail(entry)); - } - } - } - - return result; -}; - -/** - * This class should store a group of links between the same geo coordinates. - */ -export class PontToPointLink { - private _links: LinkDetail[] = []; - public readonly id: string; - public readonly coordinates: Coordinates[] = []; - - constructor(coord1: Coordinates, coord2: Coordinates) { - this.id = PontToPointLink.generateId(coord1, coord2); - this.coordinates.push(coord1, coord2); - } - - addLink(link: LinkDetail) { - this.links.push(link); - } - - /** - * For a given two macs check if any of the links on the _links array contain a node with this macs. (which should - * mean that the link is already added on the array). - * @param mac1 - * @param mac2 - */ - linkExists(mac1: string, mac2: string) { - for (const link of this._links) { - // Just needed to check the first node of the link object becouse the other will have the same macs but reversed - const node = link.data[Object.keys(link.data)[0]]; - if ( - node && - (node.dst_mac.toLowerCase() === mac1.toLowerCase() || - node.src_mac.toLowerCase() === mac1.toLowerCase()) && - (node.dst_mac.toLowerCase() === mac2.toLowerCase() || - node.src_mac.toLowerCase() === mac2.toLowerCase()) - ) { - return true; - } - } - return false; - } - - get names(): string[] { - return [ - ...this._links.reduce((acc, link) => { - Object.keys(link).forEach((key) => acc.add(key)); - return acc; - }, new Set()), - ] as string[]; - } - - get links() { - return this._links; - } - - /** - * Generate a deterministic unique id based on the coordinates of a node. - * @param coord1 - * @param coord2 - */ - static generateId(coord1: Coordinates, coord2: Coordinates): string { - const _prepareCoord = (coord: string) => - parseFloat(coord.replace("-", "").replace(".", "")); - - const allCoordinates = [ - _prepareCoord(coord1.lon), - _prepareCoord(coord1.lat), - _prepareCoord(coord2.lon), - _prepareCoord(coord2.lat), - ]; - - return allCoordinates.sort((a, b) => a - b).toString(); - } -} - -export class LinkDetail { - private _data: ILocatedLink; - private _id: string; - - constructor(data: ILocatedLink) { - this._data = data; - // this._id = LinkDetail.generateId(data); - this._id = LinkDetail.generateId(data); - } - - /** - * Deterministically generation of a unique id using the macs of this link - * @param data - */ - static generateId(data: ILocatedLink): string { - return [ - ...Object.entries(data).map(([k, v]) => { - return v.src_mac.toLowerCase().replace(/:/g, ""); - }), - ] - .sort() - .join(""); - } - - get id() { - return this._id; - } - - get data() { - return this._data; - } - - get names(): string[] { - return [...Object.keys(this._data)]; - } -} diff --git a/tailwind.config.js b/tailwind.config.js index 1789829ba..4b4076d8d 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,3 +1,4 @@ +// eslint-disable-next-line @typescript-eslint/no-var-requires const colors = require("tailwindcss/colors"); /** @type {import('tailwindcss').Config} */ From 52f2a92dcf67f4639f5e03ac7b5ad4a9094ba6bd Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 30 Aug 2023 17:35:12 +0200 Subject: [PATCH 052/121] chore(meshwide): show specific link point data --- .../components/FeatureDetail/LinkDetail.tsx | 38 ++++++++++++++----- .../src/lib/links/PointToPointLink.ts | 5 +++ .../lime-plugin-mesh-wide/src/lib/utils.ts | 1 + 3 files changed, 35 insertions(+), 9 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/lib/utils.ts diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx index 4648cb71c..d702a5805 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx @@ -11,13 +11,12 @@ import { LinkDetailData, PontToPointLink, } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; +import { bytesToMB } from "plugins/lime-plugin-mesh-wide/src/lib/utils"; import { Row, TitleAndText } from "./index"; const SelectedLink = ({ linkDetail }: { linkDetail: LinkDetailData }) => { const names = linkDetail?.names; - const gain = "5 dB"; - const linkType = "Primary"; return ( <> @@ -25,7 +24,8 @@ const SelectedLink = ({ linkDetail }: { linkDetail: LinkDetailData }) => { {names && (
- Link from {names[0]} to {names[1]} + Link from {names[0]} to{" "} + {names[1]}
)} @@ -33,12 +33,32 @@ const SelectedLink = ({ linkDetail }: { linkDetail: LinkDetailData }) => {
- - Gain}>{gain} - Link type}> - {linkType} - - + {names.map((name, i) => { + const node = linkDetail.linkByName(name); + return ( +
+ + {name} + + + Signal}> + {node.signal.toString()} + + Chains}> + {node.chains.toString()} + + + + TxRate}> + {`${bytesToMB(node.tx_rate).toString()}MB`} + + RxRate}> + {`${bytesToMB(node.rx_rate).toString()}MB`} + + +
+ ); + })} ); }; diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts index 7380d5cb4..897e95784 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts @@ -1,6 +1,7 @@ import { Coordinates, ILocatedLink, + IWifiLinkData, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; /** @@ -111,4 +112,8 @@ export class LinkDetailData { get names(): string[] { return [...Object.keys(this._data)]; } + + linkByName(name: string): IWifiLinkData { + return this._data[name]; + } } diff --git a/plugins/lime-plugin-mesh-wide/src/lib/utils.ts b/plugins/lime-plugin-mesh-wide/src/lib/utils.ts new file mode 100644 index 000000000..73fb62cff --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/lib/utils.ts @@ -0,0 +1 @@ +export const bytesToMB = (bytes: number) => Math.round(bytes / 1024 / 1024); From b2a53f14d95dfe57ffa260cb3e53027312a3baab Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 31 Aug 2023 15:36:33 +0200 Subject: [PATCH 053/121] chore(meshwide): split NodesLayer on sepparated folder --- .../{NodesAndLinksLayer.tsx => LinksLayer.tsx} | 7 +------ .../src/containers/Map/Map.tsx | 6 ++++-- .../src/containers/Map/NodesLayer.tsx | 17 +++++++++++++++++ 3 files changed, 22 insertions(+), 8 deletions(-) rename plugins/lime-plugin-mesh-wide/src/containers/Map/{NodesAndLinksLayer.tsx => LinksLayer.tsx} (87%) create mode 100644 plugins/lime-plugin-mesh-wide/src/containers/Map/NodesLayer.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map/NodesAndLinksLayer.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map/LinksLayer.tsx similarity index 87% rename from plugins/lime-plugin-mesh-wide/src/containers/Map/NodesAndLinksLayer.tsx rename to plugins/lime-plugin-mesh-wide/src/containers/Map/LinksLayer.tsx index ae6099a60..362562752 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/Map/NodesAndLinksLayer.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map/LinksLayer.tsx @@ -1,7 +1,6 @@ import { useMemo } from "preact/compat"; import LinkLine from "plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine"; -import NodeMarker from "plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker"; import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; import { mergeLinksAndCoordinates } from "plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates"; import { @@ -11,7 +10,7 @@ import { } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; import { LocatedWifiLinkData } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; -export const NodesAndLinksLayer = () => { +export const LinksLayer = () => { const { data: meshWideLinksReference } = useMeshWideLinksReference({}); const { data: meshWideLinks } = useMeshWideLinks({}); const { data: meshWideNodesReference } = useMeshWideNodesReference({}); @@ -36,10 +35,6 @@ export const NodesAndLinksLayer = () => { return ( <> - {meshWideNodesReference && - Object.entries(meshWideNodesReference).map(([k, v], i) => { - return ; - })} {locatedLinksReference && Object.entries(locatedLinksReference).map( (referenceLink, i) => { diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map/Map.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map/Map.tsx index 0ea6e9d56..8496c8ee2 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/Map/Map.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map/Map.tsx @@ -2,7 +2,8 @@ import L from "leaflet"; import { useEffect, useRef } from "preact/hooks"; import { MapContainer, TileLayer } from "react-leaflet"; -import { NodesAndLinksLayer } from "plugins/lime-plugin-mesh-wide/src/containers/Map/NodesAndLinksLayer"; +import { LinksLayer } from "plugins/lime-plugin-mesh-wide/src/containers/Map/LinksLayer"; +import NodesLayer from "plugins/lime-plugin-mesh-wide/src/containers/Map/NodesLayer"; import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; const openStreetMapTileString = "http://{s}.tile.osm.org/{z}/{x}/{y}.png"; @@ -57,7 +58,8 @@ export const MeshWideMap = () => { attribution={openStreetMapAttribution} url={openStreetMapTileString} /> - + + ); }; diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map/NodesLayer.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map/NodesLayer.tsx new file mode 100644 index 000000000..6c30b9f26 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map/NodesLayer.tsx @@ -0,0 +1,17 @@ +import NodeMarker from "plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker"; +import { useMeshWideNodesReference } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; + +const NodesLayer = () => { + const { data: meshWideNodesReference } = useMeshWideNodesReference({}); + + return ( + <> + {meshWideNodesReference && + Object.entries(meshWideNodesReference).map(([k, v], i) => { + return ; + })} + + ); +}; + +export default NodesLayer; From 830b13d507d3ffb762e1632adb0fb92f9dead70f Mon Sep 17 00:00:00 2001 From: selankon Date: Mon, 4 Sep 2023 16:48:02 +0200 Subject: [PATCH 054/121] chore(meshwide): share actual and reference state on selected feature --- .../components/FeatureDetail/LinkDetail.tsx | 27 +++++--- .../src/components/FeatureDetail/index.tsx | 11 ++- .../src/containers/Map/LinksLayer.tsx | 4 +- .../src/lib/links/PointToPointLink.ts | 25 ++++--- .../src/lib/links/getLinksCoordinates.ts | 4 +- .../src/lib/links/processErrors.ts | 68 +++++++++++++++++++ .../src/mesWideTypes.tsx | 9 ++- 7 files changed, 124 insertions(+), 24 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/lib/links/processErrors.ts diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx index d702a5805..e593b3b89 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx @@ -8,14 +8,21 @@ import Tabs from "components/tabs"; import { StatusAndButton } from "plugins/lime-plugin-mesh-wide/src/components/Components"; import { PowerIcon } from "plugins/lime-plugin-mesh-wide/src/icons/power"; import { - LinkDetailData, + MacToMacLink, PontToPointLink, } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; import { bytesToMB } from "plugins/lime-plugin-mesh-wide/src/lib/utils"; import { Row, TitleAndText } from "./index"; -const SelectedLink = ({ linkDetail }: { linkDetail: LinkDetailData }) => { +const SelectedLink = ({ linkDetail }: { linkDetail: MacToMacLink }) => { + if (linkDetail === undefined) + return ( +
+ This link seems down +
+ ); + const names = linkDetail?.names; return ( @@ -63,10 +70,16 @@ const SelectedLink = ({ linkDetail }: { linkDetail: LinkDetailData }) => { ); }; -const Links = ({ linkDetails }: { linkDetails: PontToPointLink }) => { +const Links = ({ + actual, + reference, +}: { + actual: PontToPointLink; + reference: PontToPointLink; +}) => { const [selectedLink, setSelectedLink] = useState(0); - const tabs = linkDetails.links.map((link: LinkDetailData, i) => { + const tabs = reference.links.map((link: MacToMacLink, i) => { return { key: i, repr: Link {i + 1}, @@ -76,7 +89,7 @@ const Links = ({ linkDetails }: { linkDetails: PontToPointLink }) => { return ( <>
- {tabs.length > 1 && ( + {tabs?.length > 1 && ( { /> )} {selectedLink !== null && ( - + )}
diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx index a10798a00..afbb5dc75 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx @@ -3,9 +3,9 @@ import Links, { } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail"; import NodeDetails from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail"; import { NodeReferenceStatus } from "plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker"; -import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; import { INamedNodeInfo, + LinkMapFeature, SelectedMapFeature, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; @@ -44,7 +44,10 @@ export const FeatureDetail = ({ case "link": return ( ); case "node": @@ -74,7 +77,9 @@ export const FeatureReferenceStatus = ({ return ( ); } else if (type === "node") { diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map/LinksLayer.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map/LinksLayer.tsx index 362562752..4086ad035 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/Map/LinksLayer.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map/LinksLayer.tsx @@ -33,9 +33,11 @@ export const LinksLayer = () => { } }, [meshWideNodesReference, meshWideLinks]); + const linksLoaded = !!locatedLinksReference && !!locatedLinks; + return ( <> - {locatedLinksReference && + {linksLoaded && Object.entries(locatedLinksReference).map( (referenceLink, i) => { let actualLink: PontToPointLink; diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts index 897e95784..9e990917c 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts @@ -2,14 +2,18 @@ import { Coordinates, ILocatedLink, IWifiLinkData, + MacToMacLinkId, + PointToPointLinkId, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; /** * This class should store a group of links between the same geo coordinates. + * + * Could store two links between same geo but with different macs */ export class PontToPointLink { - private _links: LinkDetailData[] = []; - public readonly id: string; + private _links: MacToMacLink[] = []; + public readonly id: PointToPointLinkId; public readonly coordinates: Coordinates[] = []; constructor(coord1: Coordinates, coord2: Coordinates) { @@ -17,7 +21,7 @@ export class PontToPointLink { this.coordinates.push(coord1, coord2); } - addLink(link: LinkDetailData) { + addLink(link: MacToMacLink) { this.links.push(link); } @@ -77,21 +81,24 @@ export class PontToPointLink { } } -export class LinkDetailData { +/** + * Store link info between two macs + */ +export class MacToMacLink { private _data: ILocatedLink; - private _id: string; + private _id: MacToMacLinkId; constructor(data: ILocatedLink) { this._data = data; - // this._id = LinkDetail.generateId(data); - this._id = LinkDetailData.generateId(data); + this._id = MacToMacLink.generateId(data); } /** - * Deterministically generation of a unique id using the macs of this link + * Deterministically generation of a unique id using the macs of this link. Concatenate the sorted macs that + * are involved on this link * @param data */ - static generateId(data: ILocatedLink): string { + static generateId(data: ILocatedLink): MacToMacLinkId { return [ ...Object.entries(data).map(([k, v]) => { return v.src_mac.toLowerCase().replace(/:/g, ""); diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts index a787b2af2..98b8e1f97 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts @@ -1,5 +1,5 @@ import { - LinkDetailData, + MacToMacLink, PontToPointLink, } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; import { @@ -76,7 +76,7 @@ export const mergeLinksAndCoordinates = ( coordinates: nodes[dstNodeName].coordinates, }, }; - result[linkKey].addLink(new LinkDetailData(entry)); + result[linkKey].addLink(new MacToMacLink(entry)); } } } diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/processErrors.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/processErrors.ts new file mode 100644 index 000000000..ea3becbaa --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/processErrors.ts @@ -0,0 +1,68 @@ +import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; +import { + ILinkErrors, + IWifiLinkData, + WifiLinkErrorCodes, +} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; + +import { DEFAULT_COMMUNITY_SETTINGS } from "utils/constants"; + +/** + * It compares two links and return an array of error codes. + * @param reference + * @param actual + */ +const compareWifiData = (reference: IWifiLinkData, actual: IWifiLinkData) => { + // todo(kon): use community settings and not limeapp defaults + // const { data: communitySettings } = useCommunitySettings(); + + const errors: WifiLinkErrorCodes[] = []; + if ( + actual === undefined || + actual.signal === undefined || + actual.signal === 0 + ) { + return [WifiLinkErrorCodes.LINK_DOWN]; + } + + if ( + actual.signal - DEFAULT_COMMUNITY_SETTINGS.mw_link_signal_threshold < + reference.signal + ) { + errors.push(WifiLinkErrorCodes.SIGNAL_LOSS); + } + + if ( + Math.abs(actual.chains[0] - actual.chains[1]) > + DEFAULT_COMMUNITY_SETTINGS.mw_link_chain_threshold + ) { + errors.push(WifiLinkErrorCodes.CHAIN_LOSS); + } + return errors; +}; + +export const compareLinks = ({ + referenceLink, + actualLink, +}: { + referenceLink: PontToPointLink; + actualLink: PontToPointLink | undefined; +}) => { + const errors: ILinkErrors = {}; + + referenceLink.links.forEach((macToMacReference) => { + const macToMacActual = actualLink?.links.find( + (actual) => actual.id === macToMacReference.id + ); + + errors[macToMacReference.id] = {}; + Object.entries(macToMacReference.data).forEach( + ([nodeNameReference, wifiDataReference]) => { + const wifiDataActual = macToMacActual?.data[nodeNameReference]; + errors[macToMacReference.id][nodeNameReference] = + compareWifiData(wifiDataReference, wifiDataActual); + } + ); + }); + return errors; +}; diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index 20165af85..1da1c7865 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -64,8 +64,15 @@ export type INodes = { [key: string]: INodeInfo }; type FeatureType = "node" | "link"; +export type LinkMapFeature = { + actual: PontToPointLink; + reference: PontToPointLink; +}; + +type MapFeature = INamedNodeInfo | LinkMapFeature; + export interface SelectedMapFeature { - feature: INamedNodeInfo | PontToPointLink; + feature: MapFeature; type: FeatureType; id: number | string; } From ec4a185e3f96cf7b6e71a4237ec3c51bc8e3a129 Mon Sep 17 00:00:00 2001 From: selankon Date: Mon, 4 Sep 2023 16:48:27 +0200 Subject: [PATCH 055/121] chore(meshwide): implement wifi links errors --- .../src/components/Map/LinkLine.tsx | 60 +++++++++++++++---- .../src/mesWideQueries.tsx | 9 +++ .../src/mesWideTypes.tsx | 31 +++++++++- src/utils/constants.js | 2 + 4 files changed, 88 insertions(+), 14 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx index cf51e3746..b559fad83 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx @@ -1,31 +1,54 @@ import L from "leaflet"; +import { useEffect } from "preact/hooks"; import { Polyline } from "react-leaflet"; import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; -import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; +import { compareLinks } from "plugins/lime-plugin-mesh-wide/src/lib/links/processErrors"; +import { + useLinkErrors, + useSelectedMapFeature, +} from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; -const LinkLine = ({ - referenceLink, - actualLink, -}: { +interface ILinkLineProps { referenceLink: PontToPointLink; actualLink: PontToPointLink | undefined; -}) => { +} + +const LinkPolyLine = ({ referenceLink, actualLink }: ILinkLineProps) => { const { data: selectedMapFeature, setData: setSelectedMapFeature } = useSelectedMapFeature(); const isSelected = selectedMapFeature?.id === referenceLink.id; + const { data: linksErrors, setData: setLinkError } = useLinkErrors( + referenceLink.id + ); + + const hasError: boolean = Math.random() < 0.5; - const synced: boolean = Math.random() < 0.5; + const _setSelectedFeature = () => { + setSelectedMapFeature({ + id: referenceLink.id, + feature: { reference: referenceLink, actual: actualLink }, + type: "link", + }); + }; const getPathOpts = (isSelected) => { return { - color: synced ? "#76bd7d" : "#eb7575", + color: hasError ? "#eb7575" : "#76bd7d", weight: isSelected ? 7 : 5, opacity: isSelected ? 1 : 0.8, dashArray: actualLink ? null : "7 10", }; }; + useEffect(() => { + if (referenceLink) { + for (const l of Object.values(referenceLink.links)) { + l.id; + } + } + }, [actualLink, referenceLink]); + const coordinates = referenceLink.coordinates.map((c) => [c.lat, c.lon]); return ( @@ -35,11 +58,7 @@ const LinkLine = ({ eventHandlers={{ click: (e) => { L.DomEvent.stopPropagation(e); - setSelectedMapFeature({ - id: referenceLink.id, - feature: referenceLink, - type: "link", - }); + _setSelectedFeature(); }, mouseover: (e) => { const l = e.target; @@ -54,4 +73,19 @@ const LinkLine = ({ ); }; +const LinkLine = ({ referenceLink, actualLink }: ILinkLineProps) => { + const { data, setData: setLinkError } = useLinkErrors(referenceLink.id); + + useEffect(() => { + if (referenceLink) { + const errors = compareLinks({ referenceLink, actualLink }); + setLinkError(errors); + } + }, [referenceLink, actualLink, setLinkError]); + + return ( + + ); +}; + export default LinkLine; diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx index ab67fb665..d6a9da14c 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx @@ -7,9 +7,11 @@ import { getMeshWideNodesReference, } from "plugins/lime-plugin-mesh-wide/src/mesWideApi"; import { + ILinkErrors, IMeshWideConfig, INodes, IWifiLinks, + PointToPointLinkId, SelectedMapFeature, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; import { getMeshWideConfig } from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; @@ -70,3 +72,10 @@ export const useSelectedMapFeature = () => { "select_map_feature", ]); }; + +/** + * Store list of link error codes for every source node. + */ +export const useLinkErrors = (linkId: PointToPointLinkId) => { + return useSharedData(["lime-meshwide", "wifi_link", linkId]); +}; diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index 1da1c7865..cc63c08b8 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -10,7 +10,9 @@ export type ILocatedLink = { }; /** - * List of located links. Are grouped by id based on their coordinates + * List of located links. + * + * Are grouped by id based on their coordinates * * The array of classes contain an indeterminated number of links that are from certain point to another. */ @@ -83,3 +85,30 @@ export interface IMeshWideSection { } export type IMeshWideConfig = IMeshWideSection[]; + +export enum WifiLinkErrorCodes { + LINK_DOWN = "LINK_DOWN", + SIGNAL_LOSS = "SIGNAL_LOSS", + CHAIN_LOSS = "CHAIN_LOSS", +} + +/** + * Store the error for every wifi node data. Use the ids for the point to point and mac to mac as dictionary + */ +export type ILinkErrors = { + [macToMacKey: MacToMacLinkId]: { + [nodeName: string]: WifiLinkErrorCodes[]; + }; +}; + +/** + * Type to store the link detail id, created deterministically by the + * two macs of this link + */ +export type MacToMacLinkId = string; + +/** + * Type to store a point to point link detail id, created deterministically by the + * two geo points of this link + */ +export type PointToPointLinkId = string; diff --git a/src/utils/constants.js b/src/utils/constants.js index 8db62bcc6..d633a93ab 100644 --- a/src/utils/constants.js +++ b/src/utils/constants.js @@ -4,4 +4,6 @@ export const DEFAULT_COMMUNITY_SETTINGS = { bad_bandwidth: "1", good_signal: "-65", good_bandwidth: "5", + mw_link_signal_threshold: 10, + mw_link_chain_threshold: 3, }; From d9ce6a8be83c32529cd72263f9c2d2c3f6bab3a1 Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 5 Sep 2023 15:06:15 +0200 Subject: [PATCH 056/121] chore(meshwide): improve mocks --- .../src/lib/links/PointToPointLink.ts | 2 +- .../src/lib/links/getLinksCoordinates.ts | 12 ++--- .../src/meshWideMocks.tsx | 54 ++++++++++++++++++- 3 files changed, 60 insertions(+), 8 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts index 9e990917c..4ce9ccf6c 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts @@ -101,7 +101,7 @@ export class MacToMacLink { static generateId(data: ILocatedLink): MacToMacLinkId { return [ ...Object.entries(data).map(([k, v]) => { - return v.src_mac.toLowerCase().replace(/:/g, ""); + return v.src_mac?.toLowerCase().replace(/:/g, ""); }), ] .sort() diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts index 98b8e1f97..4ed37d445 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts @@ -67,12 +67,12 @@ export const mergeLinksAndCoordinates = ( coordinates: nodes[wifiNodeName].coordinates, }, [dstNodeName]: { - tx_rate: destPointData.tx_rate, - dst_mac: destPointData.dst_mac, - chains: destPointData.chains, - src_mac: destPointData.src_mac, - rx_rate: destPointData.rx_rate, - signal: destPointData.signal, + tx_rate: destPointData?.tx_rate, + dst_mac: destPointData?.dst_mac, + chains: destPointData?.chains, + src_mac: destPointData?.src_mac, + rx_rate: destPointData?.rx_rate, + signal: destPointData?.signal, coordinates: nodes[dstNodeName].coordinates, }, }; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx index cd920afda..8d85c84f2 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx @@ -41,6 +41,18 @@ export const nodesReferenceState: INodes = { uptime: "345600", device: "Hub", }, + segundo: { + coordinates: { + lon: "-64.42609", + lat: "-31.80461", + }, + macs: ["a8:40:41:1d:f9:ff", "a8:40:41:1d:f9:aa"], + ipv4: "192.168.1.3", + ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7336", + firmware_version: "1.0.2", + uptime: "345600", + device: "Hub", + }, }; export const linksReferenceState: IWifiLinks = { @@ -66,6 +78,28 @@ export const linksReferenceState: IWifiLinks = { ], author: "primero", }, + segundo: { + bleachTTL: 30, + data: [ + { + tx_rate: 150000, + dst_mac: "A0:F3:C1:46:28:97", + chains: [-63, -59], + signal: -58, + rx_rate: 180000, + src_mac: "a8:40:41:1d:f9:ff", + }, + { + tx_rate: 162000, + dst_mac: "14:CC:20:DA:4E:AC", + chains: [-57, -51], + signal: -50, + rx_rate: 240000, + src_mac: "a8:40:41:1d:f9:aa", + }, + ], + author: "segundo", + }, "LiMe-da4eaa": { bleachTTL: 30, data: [ @@ -93,6 +127,14 @@ export const linksReferenceState: IWifiLinks = { rx_rate: 162000, signal: -64, }, + { + tx_rate: 243000, + dst_mac: "A8:40:41:1D:F9:aa", + chains: [-75, -64], + src_mac: "14:cc:20:da:4e:ac", + rx_rate: 162000, + signal: -64, + }, ], author: "LiMe-da4eaa", }, @@ -123,13 +165,23 @@ export const linksReferenceState: IWifiLinks = { rx_rate: 135000, signal: -65, }, + { + tx_rate: 240000, + dst_mac: "A8:40:41:1D:F9:ff", + chains: [-77, -65], + src_mac: "a0:f3:c1:46:28:97", + rx_rate: 135000, + signal: -65, + }, ], author: "LiMe-462895", }, }; // Use the same as on the reference state deleting a specific node -const nodeName = "LiMe-462895"; +// const nodeName = "LiMe-462895"; +const nodeName = "primero"; + export const links = (): IWifiLinks => { // Create a deep copy of the state to avoid mutating the original object const newState: IWifiLinks = JSON.parse( From bf4059f608248703c9829d0695e437265c571a7e Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 5 Sep 2023 15:13:54 +0200 Subject: [PATCH 057/121] chore(meshwide): show link errors on map --- .../src/components/Map/LinkLine.tsx | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx index b559fad83..18b20b615 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx @@ -1,4 +1,5 @@ import L from "leaflet"; +import { useMemo } from "preact/compat"; import { useEffect } from "preact/hooks"; import { Polyline } from "react-leaflet"; @@ -18,11 +19,21 @@ const LinkPolyLine = ({ referenceLink, actualLink }: ILinkLineProps) => { const { data: selectedMapFeature, setData: setSelectedMapFeature } = useSelectedMapFeature(); const isSelected = selectedMapFeature?.id === referenceLink.id; - const { data: linksErrors, setData: setLinkError } = useLinkErrors( - referenceLink.id - ); + const { data: linkErrors } = useLinkErrors(referenceLink.id); - const hasError: boolean = Math.random() < 0.5; + const linkDown: boolean = actualLink != null; + + const hasError: boolean = useMemo(() => { + if (linkDown) return true; + for (const macToMacKey in linkErrors) { + for (const nodeName in linkErrors[macToMacKey]) { + if (linkErrors[macToMacKey][nodeName].length > 0) { + return true; + } + } + } + return false; + }, [linkErrors]); const _setSelectedFeature = () => { setSelectedMapFeature({ @@ -37,18 +48,10 @@ const LinkPolyLine = ({ referenceLink, actualLink }: ILinkLineProps) => { color: hasError ? "#eb7575" : "#76bd7d", weight: isSelected ? 7 : 5, opacity: isSelected ? 1 : 0.8, - dashArray: actualLink ? null : "7 10", + dashArray: linkDown ? null : "7 10", }; }; - useEffect(() => { - if (referenceLink) { - for (const l of Object.values(referenceLink.links)) { - l.id; - } - } - }, [actualLink, referenceLink]); - const coordinates = referenceLink.coordinates.map((c) => [c.lat, c.lon]); return ( From 7cc09411b07d5a07c7934928cf101a0b6ca1e942 Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 5 Sep 2023 16:13:21 +0200 Subject: [PATCH 058/121] chore(meshwide): move located links into a hook --- .../src/containers/Map/LinksLayer.tsx | 35 ++---------------- .../src/hooks/useLocatedLinks.tsx | 37 +++++++++++++++++++ 2 files changed, 40 insertions(+), 32 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map/LinksLayer.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map/LinksLayer.tsx index 4086ad035..fee9a0c7a 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/Map/LinksLayer.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map/LinksLayer.tsx @@ -1,39 +1,10 @@ -import { useMemo } from "preact/compat"; - import LinkLine from "plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine"; +import { useLocatedLinks } from "plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks"; import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; -import { mergeLinksAndCoordinates } from "plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates"; -import { - useMeshWideLinks, - useMeshWideLinksReference, - useMeshWideNodesReference, -} from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; -import { LocatedWifiLinkData } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; export const LinksLayer = () => { - const { data: meshWideLinksReference } = useMeshWideLinksReference({}); - const { data: meshWideLinks } = useMeshWideLinks({}); - const { data: meshWideNodesReference } = useMeshWideNodesReference({}); - - const locatedLinksReference: LocatedWifiLinkData = useMemo(() => { - if (meshWideNodesReference && meshWideLinksReference) { - return mergeLinksAndCoordinates( - meshWideNodesReference, - meshWideLinksReference - ); - } - }, [meshWideNodesReference, meshWideLinksReference]); - - const locatedLinks: LocatedWifiLinkData = useMemo(() => { - if (meshWideNodesReference && meshWideLinks) { - return mergeLinksAndCoordinates( - meshWideNodesReference, - meshWideLinks - ); - } - }, [meshWideNodesReference, meshWideLinks]); - - const linksLoaded = !!locatedLinksReference && !!locatedLinks; + const { locatedLinks, locatedLinksReference, linksLoaded } = + useLocatedLinks(); return ( <> diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx new file mode 100644 index 000000000..1a1a8ac5b --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx @@ -0,0 +1,37 @@ +import { useMemo } from "preact/compat"; + +import { mergeLinksAndCoordinates } from "plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates"; +import { + useMeshWideLinks, + useMeshWideLinksReference, + useMeshWideNodesReference, +} from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; +import { LocatedWifiLinkData } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; + +export const useLocatedLinks = () => { + const { data: meshWideLinksReference } = useMeshWideLinksReference({}); + const { data: meshWideLinks } = useMeshWideLinks({}); + const { data: meshWideNodesReference } = useMeshWideNodesReference({}); + + const locatedLinksReference: LocatedWifiLinkData = useMemo(() => { + if (meshWideNodesReference && meshWideLinksReference) { + return mergeLinksAndCoordinates( + meshWideNodesReference, + meshWideLinksReference + ); + } + }, [meshWideNodesReference, meshWideLinksReference]); + + const locatedLinks: LocatedWifiLinkData = useMemo(() => { + if (meshWideNodesReference && meshWideLinks) { + return mergeLinksAndCoordinates( + meshWideNodesReference, + meshWideLinks + ); + } + }, [meshWideNodesReference, meshWideLinks]); + + const linksLoaded = !!locatedLinksReference && !!locatedLinks; + + return { locatedLinks, locatedLinksReference, linksLoaded }; +}; From f90df704ee05393ea7209f4bacbf45cfe7e9f87a Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 5 Sep 2023 17:29:03 +0200 Subject: [PATCH 059/121] chore(meshwide): store errors on a hook --- .../src/components/Map/LinkLine.tsx | 45 +++---------------- .../src/hooks/useLocatedLinks.tsx | 30 ++++++++++++- ...{processErrors.ts => processLinkErrors.ts} | 35 ++++++++++++--- .../src/mesWideQueries.tsx | 9 ---- .../src/mesWideTypes.tsx | 18 ++++++-- 5 files changed, 79 insertions(+), 58 deletions(-) rename plugins/lime-plugin-mesh-wide/src/lib/links/{processErrors.ts => processLinkErrors.ts} (65%) diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx index 18b20b615..728462fb3 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx @@ -1,39 +1,23 @@ import L from "leaflet"; -import { useMemo } from "preact/compat"; -import { useEffect } from "preact/hooks"; import { Polyline } from "react-leaflet"; +import { useLocatedLinks } from "plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks"; import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; -import { compareLinks } from "plugins/lime-plugin-mesh-wide/src/lib/links/processErrors"; -import { - useLinkErrors, - useSelectedMapFeature, -} from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; +import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; interface ILinkLineProps { referenceLink: PontToPointLink; actualLink: PontToPointLink | undefined; } -const LinkPolyLine = ({ referenceLink, actualLink }: ILinkLineProps) => { +export const LinkLine = ({ referenceLink, actualLink }: ILinkLineProps) => { const { data: selectedMapFeature, setData: setSelectedMapFeature } = useSelectedMapFeature(); const isSelected = selectedMapFeature?.id === referenceLink.id; - const { data: linkErrors } = useLinkErrors(referenceLink.id); + const { linksErrors } = useLocatedLinks(); - const linkDown: boolean = actualLink != null; - - const hasError: boolean = useMemo(() => { - if (linkDown) return true; - for (const macToMacKey in linkErrors) { - for (const nodeName in linkErrors[macToMacKey]) { - if (linkErrors[macToMacKey][nodeName].length > 0) { - return true; - } - } - } - return false; - }, [linkErrors]); + const hasError = linksErrors[referenceLink.id].hasErrors; + const linkUp = linksErrors[referenceLink.id].linkUp; const _setSelectedFeature = () => { setSelectedMapFeature({ @@ -48,7 +32,7 @@ const LinkPolyLine = ({ referenceLink, actualLink }: ILinkLineProps) => { color: hasError ? "#eb7575" : "#76bd7d", weight: isSelected ? 7 : 5, opacity: isSelected ? 1 : 0.8, - dashArray: linkDown ? null : "7 10", + dashArray: linkUp ? null : "7 10", }; }; @@ -76,19 +60,4 @@ const LinkPolyLine = ({ referenceLink, actualLink }: ILinkLineProps) => { ); }; -const LinkLine = ({ referenceLink, actualLink }: ILinkLineProps) => { - const { data, setData: setLinkError } = useLinkErrors(referenceLink.id); - - useEffect(() => { - if (referenceLink) { - const errors = compareLinks({ referenceLink, actualLink }); - setLinkError(errors); - } - }, [referenceLink, actualLink, setLinkError]); - - return ( - - ); -}; - export default LinkLine; diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx index 1a1a8ac5b..1467e2f16 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx @@ -1,12 +1,17 @@ import { useMemo } from "preact/compat"; +import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; import { mergeLinksAndCoordinates } from "plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates"; +import { compareLinks } from "plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors"; import { useMeshWideLinks, useMeshWideLinksReference, useMeshWideNodesReference, } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; -import { LocatedWifiLinkData } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +import { + ILinkErrors, + LocatedWifiLinkData, +} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; export const useLocatedLinks = () => { const { data: meshWideLinksReference } = useMeshWideLinksReference({}); @@ -33,5 +38,26 @@ export const useLocatedLinks = () => { const linksLoaded = !!locatedLinksReference && !!locatedLinks; - return { locatedLinks, locatedLinksReference, linksLoaded }; + const linksErrors: ILinkErrors = useMemo(() => { + if (locatedLinksReference) { + const errors: ILinkErrors = {}; + Object.entries(locatedLinksReference).forEach( + ([k, referenceLink]) => { + let actualLink: PontToPointLink; + if (locatedLinks) { + actualLink = Object.values(locatedLinks).find( + (value) => value.id === referenceLink.id + ); + } + errors[referenceLink.id] = compareLinks({ + referenceLink, + actualLink, + }); + } + ); + return errors; + } + }, [locatedLinksReference, locatedLinks]); + + return { locatedLinks, locatedLinksReference, linksLoaded, linksErrors }; }; diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/processErrors.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts similarity index 65% rename from plugins/lime-plugin-mesh-wide/src/lib/links/processErrors.ts rename to plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts index ea3becbaa..f313a891f 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/processErrors.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts @@ -1,6 +1,6 @@ import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; import { - ILinkErrors, + ILinkPtoPErrors, IWifiLinkData, WifiLinkErrorCodes, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; @@ -48,21 +48,44 @@ export const compareLinks = ({ referenceLink: PontToPointLink; actualLink: PontToPointLink | undefined; }) => { - const errors: ILinkErrors = {}; + if (!referenceLink) return; + + const ptoPErrors: ILinkPtoPErrors = { + macToMacErrors: {}, + hasErrors: false, + linkUp: true, + }; referenceLink.links.forEach((macToMacReference) => { const macToMacActual = actualLink?.links.find( (actual) => actual.id === macToMacReference.id ); - errors[macToMacReference.id] = {}; + const isUp = !!actualLink; + if (!isUp) ptoPErrors.linkUp = isUp; + + ptoPErrors.macToMacErrors[macToMacReference.id] = { + hasErrors: false, + linkErrors: {}, + linkUp: isUp, + }; Object.entries(macToMacReference.data).forEach( ([nodeNameReference, wifiDataReference]) => { const wifiDataActual = macToMacActual?.data[nodeNameReference]; - errors[macToMacReference.id][nodeNameReference] = - compareWifiData(wifiDataReference, wifiDataActual); + const wifiErrors = compareWifiData( + wifiDataReference, + wifiDataActual + ); + ptoPErrors.macToMacErrors[macToMacReference.id].linkErrors[ + nodeNameReference + ] = wifiErrors; + if (wifiErrors.length) { + ptoPErrors.macToMacErrors[macToMacReference.id].hasErrors = + true; + ptoPErrors.hasErrors = true; + } } ); }); - return errors; + return ptoPErrors; }; diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx index d6a9da14c..ab67fb665 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx @@ -7,11 +7,9 @@ import { getMeshWideNodesReference, } from "plugins/lime-plugin-mesh-wide/src/mesWideApi"; import { - ILinkErrors, IMeshWideConfig, INodes, IWifiLinks, - PointToPointLinkId, SelectedMapFeature, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; import { getMeshWideConfig } from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; @@ -72,10 +70,3 @@ export const useSelectedMapFeature = () => { "select_map_feature", ]); }; - -/** - * Store list of link error codes for every source node. - */ -export const useLinkErrors = (linkId: PointToPointLinkId) => { - return useSharedData(["lime-meshwide", "wifi_link", linkId]); -}; diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index cc63c08b8..6fa5a35ff 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -95,10 +95,22 @@ export enum WifiLinkErrorCodes { /** * Store the error for every wifi node data. Use the ids for the point to point and mac to mac as dictionary */ -export type ILinkErrors = { - [macToMacKey: MacToMacLinkId]: { - [nodeName: string]: WifiLinkErrorCodes[]; +export type ILinkPtoPErrors = { + macToMacErrors: { + [macToMacKey: MacToMacLinkId]: { + linkErrors: { + [nodeName: string]: WifiLinkErrorCodes[]; + }; + hasErrors: boolean; + linkUp: boolean; + }; }; + hasErrors: boolean; + linkUp: boolean; +}; + +export type ILinkErrors = { + [pointToPointKey: MacToMacLinkId]: ILinkPtoPErrors; }; /** From ea2265c5ae8e4887ad40d495f15c4a006ff18d5e Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 6 Sep 2023 16:19:07 +0200 Subject: [PATCH 060/121] chore(meshwide): split icons --- .../src/components/Components.tsx | 15 ++++----------- .../src/icons/SuccessIcon.tsx | 3 +++ .../lime-plugin-mesh-wide/src/icons/errorIcon.tsx | 11 +++++++++++ 3 files changed, 18 insertions(+), 11 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/icons/SuccessIcon.tsx create mode 100644 plugins/lime-plugin-mesh-wide/src/icons/errorIcon.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/components/Components.tsx b/plugins/lime-plugin-mesh-wide/src/components/Components.tsx index fe0373c70..7305e4563 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Components.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Components.tsx @@ -4,6 +4,9 @@ import { Button } from "components/buttons/button"; import { BinIcon } from "components/icons/bin"; import { EditIcon } from "components/icons/edit"; +import SuccessIcon from "plugins/lime-plugin-mesh-wide/src/icons/SuccessIcon"; +import ErrorIcon from "plugins/lime-plugin-mesh-wide/src/icons/errorIcon"; + interface IStatusMessage { isError: boolean; children: VNode | string; @@ -36,17 +39,7 @@ export const StatusMessage = ({
- {isError ? ( - - ! - - ) : ( - - )} + {isError ? : } {children}
); diff --git a/plugins/lime-plugin-mesh-wide/src/icons/SuccessIcon.tsx b/plugins/lime-plugin-mesh-wide/src/icons/SuccessIcon.tsx new file mode 100644 index 000000000..0c606d9a2 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/icons/SuccessIcon.tsx @@ -0,0 +1,3 @@ +const SuccessIcon = () => ; + +export default SuccessIcon; diff --git a/plugins/lime-plugin-mesh-wide/src/icons/errorIcon.tsx b/plugins/lime-plugin-mesh-wide/src/icons/errorIcon.tsx new file mode 100644 index 000000000..1417d3775 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/icons/errorIcon.tsx @@ -0,0 +1,11 @@ +const ErrorIcon = () => ( + + ! + +); + +export default ErrorIcon; From 0015dd1275a448e5533b5d9c31d94fcaa25f4695 Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 6 Sep 2023 17:07:28 +0200 Subject: [PATCH 061/121] chore(meshwide): show errors on feature detail --- .../components/FeatureDetail/LinkDetail.tsx | 108 ++++++++++++------ .../components/FeatureDetail/NodeDetail.tsx | 3 +- .../src/components/FeatureDetail/index.tsx | 27 ++--- .../src/components/Map/NodeMarker.tsx | 3 +- .../containers/SelectedFeatureBottomSheet.tsx | 7 +- .../src/hooks/useLocatedLinks.tsx | 6 + .../src/lib/links/processLinkErrors.ts | 5 +- .../lime-plugin-mesh-wide/src/lib/utils.ts | 13 ++- .../src/mesWideTypes.tsx | 16 +-- .../src/meshWideMocks.tsx | 20 ++-- 10 files changed, 128 insertions(+), 80 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx index e593b3b89..f31f3f673 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx @@ -6,17 +6,27 @@ import { Button } from "components/buttons/button"; import Tabs from "components/tabs"; import { StatusAndButton } from "plugins/lime-plugin-mesh-wide/src/components/Components"; +import { usePointToPointErrors } from "plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks"; +import ErrorIcon from "plugins/lime-plugin-mesh-wide/src/icons/errorIcon"; import { PowerIcon } from "plugins/lime-plugin-mesh-wide/src/icons/power"; +import { MacToMacLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; +import { readableBytes } from "plugins/lime-plugin-mesh-wide/src/lib/utils"; import { - MacToMacLink, - PontToPointLink, -} from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; -import { bytesToMB } from "plugins/lime-plugin-mesh-wide/src/lib/utils"; + ILinkMtoMErrors, + LinkMapFeature, + WifiLinkErrorCodes, +} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; import { Row, TitleAndText } from "./index"; -const SelectedLink = ({ linkDetail }: { linkDetail: MacToMacLink }) => { - if (linkDetail === undefined) +const SelectedLink = ({ + linkDetail, + errors, +}: { + linkDetail: MacToMacLink; + errors: ILinkMtoMErrors; +}) => { + if (linkDetail === undefined || !errors.linkUp) return (
This link seems down @@ -42,25 +52,53 @@ const SelectedLink = ({ linkDetail }: { linkDetail: MacToMacLink }) => { {names.map((name, i) => { const node = linkDetail.linkByName(name); + const errorsArray = errors.linkErrors[name]; return (
- {name} +
+ {name}{" "} + {errorsArray.length > 0 && } +
- Signal}> + Signal} + error={ + errorsArray.includes( + WifiLinkErrorCodes.SIGNAL_LOSS + ) ? ( + + The signal is X below the reference + state + + ) : null + } + > {node.signal.toString()} - Chains}> + Chains} + error={ + errorsArray.includes( + WifiLinkErrorCodes.CHAIN_LOSS + ) ? ( + + The difference between chains is too + big + + ) : null + } + > {node.chains.toString()} TxRate}> - {`${bytesToMB(node.tx_rate).toString()}MB`} + {`${readableBytes(node.tx_rate)}`} RxRate}> - {`${bytesToMB(node.rx_rate).toString()}MB`} + {`${readableBytes(node.rx_rate)}`}
@@ -70,19 +108,23 @@ const SelectedLink = ({ linkDetail }: { linkDetail: MacToMacLink }) => { ); }; -const Links = ({ - actual, - reference, -}: { - actual: PontToPointLink; - reference: PontToPointLink; -}) => { +const LinkFeatureDetail = ({ actual, reference }: LinkMapFeature) => { const [selectedLink, setSelectedLink] = useState(0); + const { errors } = usePointToPointErrors({ id: reference.id }); const tabs = reference.links.map((link: MacToMacLink, i) => { return { key: i, - repr: Link {i + 1}, + repr: ( +
+ + Link {i + 1}{" "} + {errors.macToMacErrors[link.id].hasErrors ? ( + + ) : null} + +
+ ), }; }); @@ -97,25 +139,27 @@ const Links = ({ /> )} {selectedLink !== null && ( - + )}
); }; -export const LinkReferenceStatus = ({ - hasError, - selectedFeature, -}: { - hasError?: boolean; - selectedFeature: PontToPointLink; -}) => { +export const LinkReferenceStatus = ({ actual, reference }: LinkMapFeature) => { + const { errors } = usePointToPointErrors({ id: reference.id }); + + const hasError = errors.hasErrors; + const txt: VNode = hasError ? ( - - This link has 5dB difference -
with the reference state -
+ This link has errors ) : ( Same status as in the reference state ); @@ -129,4 +173,4 @@ export const LinkReferenceStatus = ({ ); }; -export default Links; +export default LinkFeatureDetail; diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx index 73b02b7f1..72ec828e2 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx @@ -15,12 +15,11 @@ import { const NodeDetails = ({ nodeDetail, selectedFeature, - hasError, }: { nodeDetail: INamedNodeInfo; selectedFeature: SelectedMapFeature; - hasError: boolean; }) => { + const hasError: boolean = Math.random() < 0.5; const name = nodeDetail?.name ?? selectedFeature?.id ?? ""; const uptime = "1 week"; const firmware = "e93615c947-x86-64"; diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx index afbb5dc75..b748846c4 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx @@ -1,4 +1,6 @@ -import Links, { +import { VNode } from "preact"; + +import LinkFeatureDetail, { LinkReferenceStatus, } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail"; import NodeDetails from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail"; @@ -12,14 +14,17 @@ import { export const TitleAndText = ({ title, children, + error, }: { - title: any; // todo(kon): error with trans component + title: VNode | string; children: string; + error?: VNode | string; }) => { return (
{title}
{children}
+ {error &&
{error}
}
); }; @@ -34,20 +39,15 @@ export const Row = ({ children }: { children: any }) => { export const FeatureDetail = ({ selectedFeature, - hasError, }: { selectedFeature: SelectedMapFeature; - hasError: boolean; }) => { if (!selectedFeature) return; switch (selectedFeature.type) { case "link": return ( - ); case "node": @@ -55,7 +55,6 @@ export const FeatureDetail = ({ ); default: @@ -64,10 +63,8 @@ export const FeatureDetail = ({ }; export const FeatureReferenceStatus = ({ - hasError, selectedFeature, }: { - hasError?: boolean; selectedFeature: SelectedMapFeature; }) => { if (!selectedFeature) return; @@ -76,16 +73,12 @@ export const FeatureReferenceStatus = ({ if (type === "link") { return ( ); } else if (type === "node") { return ( ); diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx index bdfda77d6..32934ed43 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx @@ -47,12 +47,11 @@ const NodeMarker = ({ name, info }: { name: string; info: INodeInfo }) => { }; export const NodeReferenceStatus = ({ - hasError, selectedFeature, }: { - hasError?: boolean; selectedFeature: INamedNodeInfo; }) => { + const hasError: boolean = Math.random() < 0.5; const txt: VNode = hasError ? ( In the reference state this node is on ) : ( diff --git a/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.tsx b/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.tsx index dbf03fbca..addc83e43 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.tsx @@ -11,7 +11,6 @@ import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWide export const SelectedFeatureBottomSheet = () => { const [isOpen, setIsOpen] = useState(false); - const hasError: boolean = Math.random() < 0.5; const { data: selectedMapFeature } = useSelectedMapFeature(); @@ -30,16 +29,12 @@ export const SelectedFeatureBottomSheet = () => { initialDrawerDistanceTop={600} footer={ } >
- +
diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx index 1467e2f16..d689d2536 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx @@ -11,6 +11,7 @@ import { import { ILinkErrors, LocatedWifiLinkData, + PointToPointLinkId, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; export const useLocatedLinks = () => { @@ -61,3 +62,8 @@ export const useLocatedLinks = () => { return { locatedLinks, locatedLinksReference, linksLoaded, linksErrors }; }; + +export const usePointToPointErrors = ({ id }: { id: PointToPointLinkId }) => { + const { linksErrors } = useLocatedLinks(); + return { errors: linksErrors[id] }; +}; diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts index f313a891f..2ebc57a65 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts @@ -26,12 +26,11 @@ const compareWifiData = (reference: IWifiLinkData, actual: IWifiLinkData) => { } if ( - actual.signal - DEFAULT_COMMUNITY_SETTINGS.mw_link_signal_threshold < - reference.signal + reference.signal - actual.signal > + DEFAULT_COMMUNITY_SETTINGS.mw_link_signal_threshold ) { errors.push(WifiLinkErrorCodes.SIGNAL_LOSS); } - if ( Math.abs(actual.chains[0] - actual.chains[1]) > DEFAULT_COMMUNITY_SETTINGS.mw_link_chain_threshold diff --git a/plugins/lime-plugin-mesh-wide/src/lib/utils.ts b/plugins/lime-plugin-mesh-wide/src/lib/utils.ts index 73fb62cff..db910df15 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/utils.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/utils.ts @@ -1 +1,12 @@ -export const bytesToMB = (bytes: number) => Math.round(bytes / 1024 / 1024); +export const readableBytes = (bytes: number) => { + const sizes = ["B", "KB", "MB", "GB", "TB"]; + + if (bytes === 0) return "0 Byte"; + const i = parseInt( + Math.floor(Math.log(bytes) / Math.log(1024)).toString(), + 10 + ); + if (i === 0) return `${bytes} ${sizes[i]}`; + + return `${(bytes / Math.pow(1024, i)).toFixed(1)} ${sizes[i]}`; +}; diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index 6fa5a35ff..9098803f7 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -95,15 +95,17 @@ export enum WifiLinkErrorCodes { /** * Store the error for every wifi node data. Use the ids for the point to point and mac to mac as dictionary */ +export type ILinkMtoMErrors = { + linkErrors: { + [nodeName: string]: WifiLinkErrorCodes[]; + }; + hasErrors: boolean; + linkUp: boolean; +}; + export type ILinkPtoPErrors = { macToMacErrors: { - [macToMacKey: MacToMacLinkId]: { - linkErrors: { - [nodeName: string]: WifiLinkErrorCodes[]; - }; - hasErrors: boolean; - linkUp: boolean; - }; + [macToMacKey: MacToMacLinkId]: ILinkMtoMErrors; }; hasErrors: boolean; linkUp: boolean; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx index 8d85c84f2..890840202 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx @@ -10,7 +10,7 @@ export const nodesReferenceState: INodes = { lon: "-64.42703", lat: "-31.80874", }, - macs: ["a0:f3:c1:46:28:96", "a0:f3:c1:46:28:97"], + macs: ["a0:f3:c1:46:28:96", "a0:f3:c1:46:28:97", "a0:f3:c1:46:11:97"], ipv4: "192.168.1.1", ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", firmware_version: "1.0.0", @@ -43,8 +43,8 @@ export const nodesReferenceState: INodes = { }, segundo: { coordinates: { - lon: "-64.42609", - lat: "-31.80461", + lon: "-64.43209", + lat: "-31.79461", }, macs: ["a8:40:41:1d:f9:ff", "a8:40:41:1d:f9:aa"], ipv4: "192.168.1.3", @@ -83,8 +83,8 @@ export const linksReferenceState: IWifiLinks = { data: [ { tx_rate: 150000, - dst_mac: "A0:F3:C1:46:28:97", - chains: [-63, -59], + dst_mac: "A0:F3:C1:46:11:97", + chains: [-58, -59], signal: -58, rx_rate: 180000, src_mac: "a8:40:41:1d:f9:ff", @@ -92,7 +92,7 @@ export const linksReferenceState: IWifiLinks = { { tx_rate: 162000, dst_mac: "14:CC:20:DA:4E:AC", - chains: [-57, -51], + chains: [-52, -51], signal: -50, rx_rate: 240000, src_mac: "a8:40:41:1d:f9:aa", @@ -106,7 +106,7 @@ export const linksReferenceState: IWifiLinks = { { tx_rate: 65000, dst_mac: "A0:F3:C1:46:28:96", - chains: [-25, -43], + chains: [-25, -25], src_mac: "14:cc:20:da:4e:ab", rx_rate: 65000, signal: -25, @@ -144,7 +144,7 @@ export const linksReferenceState: IWifiLinks = { { tx_rate: 78000, dst_mac: "14:CC:20:DA:4E:AB", - chains: [2, -46], + chains: [-43, -46], src_mac: "a0:f3:c1:46:28:96", rx_rate: 78000, signal: 2, @@ -168,8 +168,8 @@ export const linksReferenceState: IWifiLinks = { { tx_rate: 240000, dst_mac: "A8:40:41:1D:F9:ff", - chains: [-77, -65], - src_mac: "a0:f3:c1:46:28:97", + chains: [-64, -65], + src_mac: "a0:f3:c1:46:11:97", rx_rate: 135000, signal: -65, }, From 98bfc33ee6e9597acfb14228f33be7302ab4d259 Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 8 Sep 2023 16:01:32 +0200 Subject: [PATCH 062/121] chore(meshwide): fix node interface --- .../src/components/Map/NodeMarker.tsx | 2 +- .../src/lib/links/getLinksCoordinates.ts | 14 +-- .../src/mesWideTypes.tsx | 20 ++-- .../src/meshWideMocks.tsx | 100 +++++++++++------- 4 files changed, 85 insertions(+), 51 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx index 32934ed43..058ef7fb1 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx @@ -23,7 +23,7 @@ const NodeMarker = ({ name, info }: { name: string; info: INodeInfo }) => { return ( { - return nodes[pid].macs.find( + return nodes[pid].data.macs.find( (mac) => mac.toLowerCase() === wifiLinkData.dst_mac.toLowerCase() ); @@ -30,15 +30,15 @@ export const mergeLinksAndCoordinates = ( if (dstNodeName && dstNodeName !== wifiNodeName) { // Generate a unique id of the point to point link based on the coordinates const linkKey = PontToPointLink.generateId( - nodes[wifiNodeName].coordinates, - nodes[dstNodeName!].coordinates + nodes[wifiNodeName].data.coordinates, + nodes[dstNodeName!].data.coordinates ); // If this point to point link no exists, instantiate it if (!result[linkKey]) { result[linkKey] = new PontToPointLink( - nodes[wifiNodeName].coordinates, - nodes[dstNodeName!].coordinates + nodes[wifiNodeName].data.coordinates, + nodes[dstNodeName!].data.coordinates ); } // Else if the link is not already added don't do it. @@ -64,7 +64,7 @@ export const mergeLinksAndCoordinates = ( const entry: ILocatedLink = { [wifiNodeName]: { ...wifiLinkData, - coordinates: nodes[wifiNodeName].coordinates, + coordinates: nodes[wifiNodeName].data.coordinates, }, [dstNodeName]: { tx_rate: destPointData?.tx_rate, @@ -73,7 +73,7 @@ export const mergeLinksAndCoordinates = ( src_mac: destPointData?.src_mac, rx_rate: destPointData?.rx_rate, signal: destPointData?.signal, - coordinates: nodes[dstNodeName].coordinates, + coordinates: nodes[dstNodeName].data.coordinates, }, }; result[linkKey].addLink(new MacToMacLink(entry)); diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index 9098803f7..a9f20ab6e 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -49,13 +49,19 @@ export type Coordinates = { }; export interface INodeInfo { - coordinates: Coordinates; - macs: string[]; - ipv4: string; - ipv6: string; - firmware_version: string; - uptime: string; - device: string; + bleachTTL: number; + author: string; + data: { + coordinates: Coordinates; + board: string; + device: string; + macs: string[]; + hostname: string; + ipv4: string; + ipv6: string; + firmware_version: string; + uptime: number; + }; } export type INamedNodeInfo = { diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx index 890840202..67421bb57 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx @@ -6,52 +6,80 @@ import { export const nodesReferenceState: INodes = { "LiMe-462895": { - coordinates: { - lon: "-64.42703", - lat: "-31.80874", + bleachTTL: 12, + author: "LiMe-462895", + data: { + coordinates: { + lon: "-64.42703", + lat: "-31.80874", + }, + macs: [ + "a0:f3:c1:46:28:96", + "a0:f3:c1:46:28:97", + "a0:f3:c1:46:11:97", + ], + ipv4: "192.168.1.1", + ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", + firmware_version: "1.0.0", + uptime: 1010.03, + device: "Router", + board: "", + hostname: "", }, - macs: ["a0:f3:c1:46:28:96", "a0:f3:c1:46:28:97", "a0:f3:c1:46:11:97"], - ipv4: "192.168.1.1", - ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", - firmware_version: "1.0.0", - uptime: "86400", - device: "Router", }, "LiMe-da4eaa": { - coordinates: { - lon: "-64.42315", - lat: "-31.80461", + bleachTTL: 12, + author: "LiMe-da4eaa", + data: { + coordinates: { + lon: "-64.42315", + lat: "-31.79461", + }, + macs: ["14:cc:20:da:4e:ab", "14:cc:20:da:4e:ac"], + ipv4: "192.168.1.2", + ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7335", + firmware_version: "1.0.1", + uptime: 37.89, + device: "Switch", + board: "", + hostname: "", }, - macs: ["14:cc:20:da:4e:ab", "14:cc:20:da:4e:ac"], - ipv4: "192.168.1.2", - ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7335", - firmware_version: "1.0.1", - uptime: "43200", - device: "Switch", }, primero: { - coordinates: { - lon: "-64.41609", - lat: "-31.80461", + bleachTTL: 12, + author: "primero", + data: { + coordinates: { + lon: "-64.41609", + lat: "-31.80461", + }, + macs: ["a8:40:41:1d:f9:35", "a8:40:41:1d:f9:35"], + ipv4: "192.168.1.3", + ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7336", + firmware_version: "1.0.2", + uptime: 37.89, + device: "Hub", + board: "", + hostname: "", }, - macs: ["a8:40:41:1d:f9:35", "a8:40:41:1d:f9:35"], - ipv4: "192.168.1.3", - ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7336", - firmware_version: "1.0.2", - uptime: "345600", - device: "Hub", }, segundo: { - coordinates: { - lon: "-64.43209", - lat: "-31.79461", + bleachTTL: 12, + author: "segundo", + data: { + coordinates: { + lon: "-64.43209", + lat: "-31.79461", + }, + macs: ["a8:40:41:1d:f9:ff", "a8:40:41:1d:f9:aa"], + ipv4: "192.168.1.3", + ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7336", + firmware_version: "1.0.2", + uptime: 37.89, + device: "Hub", + board: "", + hostname: "", }, - macs: ["a8:40:41:1d:f9:ff", "a8:40:41:1d:f9:aa"], - ipv4: "192.168.1.3", - ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7336", - firmware_version: "1.0.2", - uptime: "345600", - device: "Hub", }, }; From 9bcdb062b5211a1d0f50e0b05a63f0ef319cb38d Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 8 Sep 2023 17:02:45 +0200 Subject: [PATCH 063/121] chore(meshwide): implement node erros --- .../src/components/Map/NodeMarker.tsx | 28 +++++++++++++--- .../src/components/Map/style.less | 13 +++++++- .../src/containers/{Map => }/Map.tsx | 4 +-- .../src/containers/Map/NodesLayer.tsx | 17 ---------- .../{Map => MapLayers}/LinksLayer.tsx | 0 .../src/containers/MapLayers/NodesLayer.tsx | 33 +++++++++++++++++++ .../src/lib/links/processLinkErrors.ts | 6 ++++ .../src/lib/nodes/processErrors.ts | 23 +++++++++++++ .../src/mesWideTypes.tsx | 5 +++ .../src/meshWidePage.tsx | 2 +- src/utils/constants.js | 1 + 11 files changed, 106 insertions(+), 26 deletions(-) rename plugins/lime-plugin-mesh-wide/src/containers/{Map => }/Map.tsx (97%) delete mode 100644 plugins/lime-plugin-mesh-wide/src/containers/Map/NodesLayer.tsx rename plugins/lime-plugin-mesh-wide/src/containers/{Map => MapLayers}/LinksLayer.tsx (100%) create mode 100644 plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx create mode 100644 plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx index 058ef7fb1..c0edb02c8 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx @@ -4,26 +4,44 @@ import { VNode } from "preact"; import { Marker, Tooltip } from "react-leaflet"; import { StatusAndButton } from "plugins/lime-plugin-mesh-wide/src/components/Components"; +import { processNodeErrors } from "plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors"; import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; import { INamedNodeInfo, INodeInfo, + NodeErrorCodes, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; import style from "./style.less"; -const NodeMarker = ({ name, info }: { name: string; info: INodeInfo }) => { +const NodeMarker = ({ + name, + actual, + reference, +}: { + name: string; + reference: INodeInfo; + actual: INodeInfo; +}) => { const { data: selectedMapFeature, setData: setSelectedMapFeature } = useSelectedMapFeature(); - const synced: boolean = Math.random() < 0.5; + + const errors = processNodeErrors(reference, actual); + const hasErrors = errors.length > 0; + const isDown = errors.includes(NodeErrorCodes.NODE_DOWN); const markerClasses = `${ selectedMapFeature?.id === name && style.selectedMarker - } ${synced ? style.syncedMarker : style.notSyncedMarker}`; + } ${hasErrors ? style.errorMarker : style.syncedMarker} ${ + isDown && style.notUpMarker + }`; return ( { L.DomEvent.stopPropagation(e); setSelectedMapFeature({ id: name, - feature: { ...info, name }, + feature: { ...reference, name }, type: "node", }); }, diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/style.less b/plugins/lime-plugin-mesh-wide/src/components/Map/style.less index 769c88c0d..3e3f02783 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/style.less +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/style.less @@ -35,9 +35,20 @@ .syncedMarker { background-color: @good; } -.notSyncedMarker { +.errorMarker { background-color: @bad; } +.notUpMarker { + opacity: 0.8; + background-size: 10px 10px; + background-image: repeating-linear-gradient( + 45deg, + #fff 0, + #fff 1px, + @bad 0, + @bad 50% + ); +} // Selected marker feature .selectedMarker, diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map/Map.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx similarity index 97% rename from plugins/lime-plugin-mesh-wide/src/containers/Map/Map.tsx rename to plugins/lime-plugin-mesh-wide/src/containers/Map.tsx index 8496c8ee2..3b44f1625 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/Map/Map.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx @@ -2,8 +2,8 @@ import L from "leaflet"; import { useEffect, useRef } from "preact/hooks"; import { MapContainer, TileLayer } from "react-leaflet"; -import { LinksLayer } from "plugins/lime-plugin-mesh-wide/src/containers/Map/LinksLayer"; -import NodesLayer from "plugins/lime-plugin-mesh-wide/src/containers/Map/NodesLayer"; +import { LinksLayer } from "plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayer"; +import NodesLayer from "plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer"; import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; const openStreetMapTileString = "http://{s}.tile.osm.org/{z}/{x}/{y}.png"; diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map/NodesLayer.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map/NodesLayer.tsx deleted file mode 100644 index 6c30b9f26..000000000 --- a/plugins/lime-plugin-mesh-wide/src/containers/Map/NodesLayer.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import NodeMarker from "plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker"; -import { useMeshWideNodesReference } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; - -const NodesLayer = () => { - const { data: meshWideNodesReference } = useMeshWideNodesReference({}); - - return ( - <> - {meshWideNodesReference && - Object.entries(meshWideNodesReference).map(([k, v], i) => { - return ; - })} - - ); -}; - -export default NodesLayer; diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map/LinksLayer.tsx b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayer.tsx similarity index 100% rename from plugins/lime-plugin-mesh-wide/src/containers/Map/LinksLayer.tsx rename to plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayer.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx new file mode 100644 index 000000000..e4f5bbb48 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx @@ -0,0 +1,33 @@ +import NodeMarker from "plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker"; +import { + useMeshWideNodes, + useMeshWideNodesReference, +} from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; +import { INodeInfo } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; + +const NodesLayer = () => { + const { data: meshWideNodesReference } = useMeshWideNodesReference({}); + const { data: meshWideNodesActual } = useMeshWideNodes({}); + + return ( + <> + {meshWideNodesReference && + Object.entries(meshWideNodesReference).map(([k, v], i) => { + let actualNode: INodeInfo; + if (meshWideNodesActual) { + actualNode = meshWideNodesActual[k]; + } + return ( + + ); + })} + + ); +}; + +export default NodesLayer; diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts index 2ebc57a65..686400ce3 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts @@ -40,6 +40,12 @@ const compareWifiData = (reference: IWifiLinkData, actual: IWifiLinkData) => { return errors; }; +/** + * Function that receive 2 PontToPointLink and iterate over every mac to mac link and its data executing a function + * to compare the wifi data. + * @param referenceLink + * @param actualLink + */ export const compareLinks = ({ referenceLink, actualLink, diff --git a/plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts b/plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts new file mode 100644 index 000000000..08ad4e8f6 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts @@ -0,0 +1,23 @@ +import { + INodeInfo, + NodeErrorCodes, +} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; + +import { DEFAULT_COMMUNITY_SETTINGS } from "utils/constants"; + +export const processNodeErrors = ( + reference: INodeInfo, + actual: INodeInfo | undefined +) => { + const errors: NodeErrorCodes[] = []; + // todo(kon): use community settings and not limeapp defaults + // const { data: communitySettings } = useCommunitySettings(); + + if (!actual) return [NodeErrorCodes.NODE_DOWN]; + + if (actual.data.uptime < DEFAULT_COMMUNITY_SETTINGS.mw_node_low_uptime) { + errors.push(NodeErrorCodes.LOW_UPTIME); + } + + return errors; +}; diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index a9f20ab6e..e530a9dc8 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -98,6 +98,11 @@ export enum WifiLinkErrorCodes { CHAIN_LOSS = "CHAIN_LOSS", } +export enum NodeErrorCodes { + NODE_DOWN = "NODE_DOWN", + LOW_UPTIME = "LOW_UPTIME", +} + /** * Store the error for every wifi node data. Use the ids for the point to point and mac to mac as dictionary */ diff --git a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx index 8823abe80..4414bc811 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx @@ -5,7 +5,7 @@ import FloatingButton from "components/buttons/floatting-button"; import Loading from "components/loading"; import { useLoadLeaflet } from "plugins/lime-plugin-locate/src/locateQueries"; -import { MeshWideMap } from "plugins/lime-plugin-mesh-wide/src/containers/Map/Map"; +import { MeshWideMap } from "plugins/lime-plugin-mesh-wide/src/containers/Map"; import { SelectedFeatureBottomSheet } from "plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet"; const MeshWidePage = () => { diff --git a/src/utils/constants.js b/src/utils/constants.js index d633a93ab..8c6a88392 100644 --- a/src/utils/constants.js +++ b/src/utils/constants.js @@ -6,4 +6,5 @@ export const DEFAULT_COMMUNITY_SETTINGS = { good_bandwidth: "5", mw_link_signal_threshold: 10, mw_link_chain_threshold: 3, + mw_node_low_uptime: 40, }; From 0f60b9fef4865b58a55925d79e8e431c4a2e62cd Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 13 Sep 2023 16:21:12 +0200 Subject: [PATCH 064/121] chore(meshwide): show node detail errors --- .../components/FeatureDetail/NodeDetail.tsx | 55 ++++++++++++------- .../src/components/FeatureDetail/index.tsx | 14 ++--- .../src/components/Map/NodeMarker.tsx | 35 ++---------- .../src/hooks/useNodeErrors.tsx | 19 +++++++ .../src/mesWideTypes.tsx | 8 ++- 5 files changed, 70 insertions(+), 61 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/hooks/useNodeErrors.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx index 72ec828e2..0b66579f3 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx @@ -1,31 +1,24 @@ import { Trans } from "@lingui/macro"; +import { VNode } from "preact"; import { Button } from "components/buttons/button"; +import { StatusAndButton } from "plugins/lime-plugin-mesh-wide/src/components/Components"; import { Row, TitleAndText, } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index"; +import { useNodeErrors } from "plugins/lime-plugin-mesh-wide/src/hooks/useNodeErrors"; import { PowerIcon } from "plugins/lime-plugin-mesh-wide/src/icons/power"; -import { - INamedNodeInfo, - SelectedMapFeature, -} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +import { NodeMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; -const NodeDetails = ({ - nodeDetail, - selectedFeature, -}: { - nodeDetail: INamedNodeInfo; - selectedFeature: SelectedMapFeature; -}) => { - const hasError: boolean = Math.random() < 0.5; - const name = nodeDetail?.name ?? selectedFeature?.id ?? ""; - const uptime = "1 week"; - const firmware = "e93615c947-x86-64"; - const ipv6 = "fe80::42:cff:fecf:bfff"; - const ipv4 = "192.168.1.47"; - const device = "LibreRouter"; +const NodeDetails = ({ actual, reference, name }: NodeMapFeature) => { + const uptime = reference.data.uptime; + const firmware = reference.data.firmware_version; + const ipv6 = reference.data.ipv6; + const ipv4 = reference.data.ipv4; + const device = reference.data.device; + const { errors, hasErrors, isDown } = useNodeErrors({ actual, reference }); return ( <> @@ -36,13 +29,13 @@ const NodeDetails = ({ - {!hasError ? ( + {!isDown ? ( Uptime}> - {uptime} + {uptime.toString()} ) : ( Downtime}> - {uptime} + todo )} Firmware version}> @@ -62,4 +55,24 @@ const NodeDetails = ({ ); }; +export const NodeReferenceStatus = ({ actual, reference }: NodeMapFeature) => { + const { errors, hasErrors, isDown } = useNodeErrors({ actual, reference }); + + const txt: VNode = isDown ? ( + In the reference state this node is on + ) : ( + Same status as in the reference state + ); + return ( + Update this node on reference state + } + > + {txt} + + ); +}; + export default NodeDetails; diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx index b748846c4..4b5600b80 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx @@ -3,11 +3,12 @@ import { VNode } from "preact"; import LinkFeatureDetail, { LinkReferenceStatus, } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail"; -import NodeDetails from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail"; -import { NodeReferenceStatus } from "plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker"; +import NodeDetails, { + NodeReferenceStatus, +} from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail"; import { - INamedNodeInfo, LinkMapFeature, + NodeMapFeature, SelectedMapFeature, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; @@ -52,10 +53,7 @@ export const FeatureDetail = ({ ); case "node": return ( - + ); default: return <>; @@ -79,7 +77,7 @@ export const FeatureReferenceStatus = ({ } else if (type === "node") { return ( ); } diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx index c0edb02c8..9216c703c 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx @@ -1,15 +1,11 @@ -import { Trans } from "@lingui/macro"; import L from "leaflet"; -import { VNode } from "preact"; import { Marker, Tooltip } from "react-leaflet"; -import { StatusAndButton } from "plugins/lime-plugin-mesh-wide/src/components/Components"; -import { processNodeErrors } from "plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors"; +import { useNodeErrors } from "plugins/lime-plugin-mesh-wide/src/hooks/useNodeErrors"; import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; import { - INamedNodeInfo, INodeInfo, - NodeErrorCodes, + NodeMapFeature, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; import style from "./style.less"; @@ -26,9 +22,7 @@ const NodeMarker = ({ const { data: selectedMapFeature, setData: setSelectedMapFeature } = useSelectedMapFeature(); - const errors = processNodeErrors(reference, actual); - const hasErrors = errors.length > 0; - const isDown = errors.includes(NodeErrorCodes.NODE_DOWN); + const { hasErrors, isDown } = useNodeErrors({ actual, reference }); const markerClasses = `${ selectedMapFeature?.id === name && style.selectedMarker @@ -53,7 +47,7 @@ const NodeMarker = ({ L.DomEvent.stopPropagation(e); setSelectedMapFeature({ id: name, - feature: { ...reference, name }, + feature: { actual, reference, name } as NodeMapFeature, type: "node", }); }, @@ -64,25 +58,4 @@ const NodeMarker = ({ ); }; -export const NodeReferenceStatus = ({ - selectedFeature, -}: { - selectedFeature: INamedNodeInfo; -}) => { - const hasError: boolean = Math.random() < 0.5; - const txt: VNode = hasError ? ( - In the reference state this node is on - ) : ( - Same status as in the reference state - ); - return ( - Update this node on reference state} - > - {txt} - - ); -}; - export default NodeMarker; diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useNodeErrors.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useNodeErrors.tsx new file mode 100644 index 000000000..36c9f6026 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useNodeErrors.tsx @@ -0,0 +1,19 @@ +import { processNodeErrors } from "plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors"; +import { + INodeInfo, + NodeErrorCodes, +} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; + +export const useNodeErrors = ({ + actual, + reference, +}: { + actual: INodeInfo; + reference: INodeInfo; +}) => { + const errors = processNodeErrors(reference, actual); + const hasErrors = errors.length > 0; + const isDown = errors.includes(NodeErrorCodes.NODE_DOWN); + + return { errors, hasErrors, isDown }; +}; diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index e530a9dc8..a2c72f545 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -77,7 +77,13 @@ export type LinkMapFeature = { reference: PontToPointLink; }; -type MapFeature = INamedNodeInfo | LinkMapFeature; +export type NodeMapFeature = { + actual: INodeInfo; + reference: INodeInfo; + name: string; +}; + +type MapFeature = NodeMapFeature | LinkMapFeature; export interface SelectedMapFeature { feature: MapFeature; From 2cef8a0b53aab914965927fc1de75ba7a603b2cf Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 13 Sep 2023 17:22:09 +0200 Subject: [PATCH 065/121] chore(meshwide): im[plement missing macs without missing nodes --- .../src/meshWideMocks.tsx | 43 ++++++++++++++----- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx index 67421bb57..6030a3078 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx @@ -4,6 +4,8 @@ import { IWifiLinks, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +// todo(kon): if a mac disappear from mac list and a link with this mac as src mac disappear also, is not shown on the map. + export const nodesReferenceState: INodes = { "LiMe-462895": { bleachTTL: 12, @@ -193,14 +195,15 @@ export const linksReferenceState: IWifiLinks = { rx_rate: 135000, signal: -65, }, - { - tx_rate: 240000, - dst_mac: "A8:40:41:1D:F9:ff", - chains: [-64, -65], - src_mac: "a0:f3:c1:46:11:97", - rx_rate: 135000, - signal: -65, - }, + // todo(kon): if a link disappear from one of the nodes and not from the other, is not drawed on the map. And should be. + // { + // tx_rate: 240000, + // dst_mac: "A8:40:41:1D:F9:ff", + // chains: [-64, -65], + // src_mac: "a0:f3:c1:46:11:97", + // rx_rate: 135000, + // signal: -65, + // }, ], author: "LiMe-462895", }, @@ -210,6 +213,13 @@ export const linksReferenceState: IWifiLinks = { // const nodeName = "LiMe-462895"; const nodeName = "primero"; +// Used to delete a mac from a node. To see what happend if the returning list is different +const macToDelete = ""; +// const macToDelete = "a0:f3:c1:46:11:97"; +// delete a link where the src_mac is +// const linkToDelete = macToDelete; +const linkToDelete = "a0:f3:c1:46:11:97"; + export const links = (): IWifiLinks => { // Create a deep copy of the state to avoid mutating the original object const newState: IWifiLinks = JSON.parse( @@ -227,7 +237,12 @@ export const links = (): IWifiLinks => { // Remove data items with matching dest_mac in other objects Object.keys(newState).forEach((key: string) => { newState[key].data = newState[key].data.filter((item) => { - return !source_macs_to_remove.includes(item.dst_mac.toLowerCase()); + return ( + !source_macs_to_remove.includes(item.dst_mac.toLowerCase()) || + // Added to delete a specific link of a node and not an entire node + item.src_mac.toLowerCase() === linkToDelete.toLowerCase() || + item.dst_mac.toLowerCase() === linkToDelete.toLowerCase() + ); }); }); @@ -235,8 +250,16 @@ export const links = (): IWifiLinks => { }; export const nodes = (): INodes => { - const newState = JSON.parse(JSON.stringify(nodesReferenceState)); + const newState = JSON.parse(JSON.stringify(nodesReferenceState)) as INodes; + + // This only delete a particular mac from the list of macs + for (const [k, v] of Object.entries(newState)) { + v.data.macs = v.data.macs.filter((mac) => mac !== macToDelete); + } + + // This delete an entire node delete newState[nodeName]; + return newState; }; From fe11c89ea078cbed302af4a602635025fe746e1d Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 14 Sep 2023 11:19:42 +0200 Subject: [PATCH 066/121] chore(meshwide): implement show missing macs --- .../components/FeatureDetail/NodeDetail.tsx | 32 ++++++++++++++++++- .../src/components/FeatureDetail/index.tsx | 2 +- .../src/lib/nodes/processErrors.ts | 16 +++++++--- .../lime-plugin-mesh-wide/src/lib/utils.ts | 9 ++++++ .../src/mesWideTypes.tsx | 2 +- .../src/meshWideMocks.tsx | 8 +++-- src/utils/constants.js | 1 - 7 files changed, 59 insertions(+), 11 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx index 0b66579f3..3ffeb7894 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx @@ -10,7 +10,11 @@ import { } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index"; import { useNodeErrors } from "plugins/lime-plugin-mesh-wide/src/hooks/useNodeErrors"; import { PowerIcon } from "plugins/lime-plugin-mesh-wide/src/icons/power"; -import { NodeMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +import { getArrayDifference } from "plugins/lime-plugin-mesh-wide/src/lib/utils"; +import { + NodeErrorCodes, + NodeMapFeature, +} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; const NodeDetails = ({ actual, reference, name }: NodeMapFeature) => { const uptime = reference.data.uptime; @@ -18,6 +22,7 @@ const NodeDetails = ({ actual, reference, name }: NodeMapFeature) => { const ipv6 = reference.data.ipv6; const ipv4 = reference.data.ipv4; const device = reference.data.device; + const macs = actual.data.macs; const { errors, hasErrors, isDown } = useNodeErrors({ actual, reference }); return ( @@ -51,6 +56,31 @@ const NodeDetails = ({ actual, reference, name }: NodeMapFeature) => { {device} + + Macs}> + <> + {macs.map((mac, k) => ( +
{mac}
+ ))} + +
+ {errors.includes(NodeErrorCodes.MACS_MISSMATCH) && ( + Macs not found} + error={ + This macs are not on the actual state + } + > + <> + {getArrayDifference(reference.data.macs, macs).map( + (mac, k) => ( +
{mac}
+ ) + )} + +
+ )} +
); }; diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx index 4b5600b80..ddba1a6c0 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx @@ -18,7 +18,7 @@ export const TitleAndText = ({ error, }: { title: VNode | string; - children: string; + children: VNode | string; error?: VNode | string; }) => { return ( diff --git a/plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts b/plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts index 08ad4e8f6..a9e46ef30 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts @@ -3,8 +3,6 @@ import { NodeErrorCodes, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; -import { DEFAULT_COMMUNITY_SETTINGS } from "utils/constants"; - export const processNodeErrors = ( reference: INodeInfo, actual: INodeInfo | undefined @@ -15,8 +13,18 @@ export const processNodeErrors = ( if (!actual) return [NodeErrorCodes.NODE_DOWN]; - if (actual.data.uptime < DEFAULT_COMMUNITY_SETTINGS.mw_node_low_uptime) { - errors.push(NodeErrorCodes.LOW_UPTIME); + // Check mac list are equal + if (reference.data.macs.length !== actual.data.macs.length) { + errors.push(NodeErrorCodes.MACS_MISSMATCH); + } + const sortedRefMacs = reference.data.macs.slice().sort(); + const sortedActualMacs = actual.data.macs.slice().sort(); + + for (let i = 0; i < sortedRefMacs.length; i++) { + if (sortedRefMacs[i] !== sortedActualMacs[i]) { + errors.push(NodeErrorCodes.MACS_MISSMATCH); + break; + } } return errors; diff --git a/plugins/lime-plugin-mesh-wide/src/lib/utils.ts b/plugins/lime-plugin-mesh-wide/src/lib/utils.ts index db910df15..9e8032be2 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/utils.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/utils.ts @@ -10,3 +10,12 @@ export const readableBytes = (bytes: number) => { return `${(bytes / Math.pow(1024, i)).toFixed(1)} ${sizes[i]}`; }; + +/** + * Get the strings that appear on the first array but not on the second one + * @param array1 + * @param array2 + */ +export const getArrayDifference = (array1: string[], array2: string[]) => { + return array1.filter((item) => !array2.includes(item)); +}; diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index a2c72f545..19c953433 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -106,7 +106,7 @@ export enum WifiLinkErrorCodes { export enum NodeErrorCodes { NODE_DOWN = "NODE_DOWN", - LOW_UPTIME = "LOW_UPTIME", + MACS_MISSMATCH = "MACS_MISSMATCH", } /** diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx index 6030a3078..05f8f1c6a 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx @@ -214,11 +214,13 @@ export const linksReferenceState: IWifiLinks = { const nodeName = "primero"; // Used to delete a mac from a node. To see what happend if the returning list is different -const macToDelete = ""; -// const macToDelete = "a0:f3:c1:46:11:97"; +// This will delete a mac from the node macs list +// const macToDelete = ""; +const macToDelete = "a0:f3:c1:46:11:97"; // delete a link where the src_mac is // const linkToDelete = macToDelete; -const linkToDelete = "a0:f3:c1:46:11:97"; +// const linkToDelete = "a0:f3:c1:46:11:97"; +const linkToDelete = ""; export const links = (): IWifiLinks => { // Create a deep copy of the state to avoid mutating the original object diff --git a/src/utils/constants.js b/src/utils/constants.js index 8c6a88392..d633a93ab 100644 --- a/src/utils/constants.js +++ b/src/utils/constants.js @@ -6,5 +6,4 @@ export const DEFAULT_COMMUNITY_SETTINGS = { good_bandwidth: "5", mw_link_signal_threshold: 10, mw_link_chain_threshold: 3, - mw_node_low_uptime: 40, }; From 3260d225c62a7fc40be16e16da77386111389f1d Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 14 Sep 2023 11:51:48 +0200 Subject: [PATCH 067/121] chore(meshwide): fix errors visualization --- .../src/components/FeatureDetail/LinkDetail.tsx | 4 ++-- .../src/components/FeatureDetail/NodeDetail.tsx | 6 +++++- .../src/lib/links/processLinkErrors.ts | 8 +++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx index f31f3f673..b7c8d83de 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx @@ -75,7 +75,7 @@ const SelectedLink = ({ ) : null } > - {node.signal.toString()} + {node?.signal?.toString() ?? "0"} Chains} @@ -90,7 +90,7 @@ const SelectedLink = ({ ) : null } > - {node.chains.toString()} + {node?.chains?.toString() ?? "0/0"} diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx index 3ffeb7894..b6779eb85 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx @@ -22,9 +22,13 @@ const NodeDetails = ({ actual, reference, name }: NodeMapFeature) => { const ipv6 = reference.data.ipv6; const ipv4 = reference.data.ipv4; const device = reference.data.device; - const macs = actual.data.macs; const { errors, hasErrors, isDown } = useNodeErrors({ actual, reference }); + if (isDown) { + return This node seems down; + } + const macs = actual.data.macs; + return ( <> diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts index 686400ce3..ddd402fd9 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts @@ -62,12 +62,16 @@ export const compareLinks = ({ }; referenceLink.links.forEach((macToMacReference) => { + const setLinkIsDown = () => { + ptoPErrors.linkUp = false; + }; + const macToMacActual = actualLink?.links.find( (actual) => actual.id === macToMacReference.id ); const isUp = !!actualLink; - if (!isUp) ptoPErrors.linkUp = isUp; + if (!isUp) setLinkIsDown(); ptoPErrors.macToMacErrors[macToMacReference.id] = { hasErrors: false, @@ -89,6 +93,8 @@ export const compareLinks = ({ true; ptoPErrors.hasErrors = true; } + if (wifiErrors.includes(WifiLinkErrorCodes.LINK_DOWN)) + setLinkIsDown(); } ); }); From 47f89380dc399f55e1791de15f5eff2a9145da3a Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 14 Sep 2023 18:49:53 +0200 Subject: [PATCH 068/121] chore(meshwide): clean nodes that are not geolocated On this way are not shown on the map and neither break things --- .../src/containers/MapLayers/NodesLayer.tsx | 11 ++--- .../src/hooks/useLocatedLinks.tsx | 5 +- .../src/hooks/useNodes.tsx | 48 +++++++++++++++++++ .../src/lib/links/getLinksCoordinates.ts | 6 ++- .../lime-plugin-mesh-wide/src/lib/utils.ts | 13 +++++ .../src/mesWideTypes.tsx | 2 +- .../src/meshWideMocks.tsx | 33 +++++++------ 7 files changed, 93 insertions(+), 25 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx index e4f5bbb48..edb9b7bd9 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx @@ -1,13 +1,12 @@ import NodeMarker from "plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker"; -import { - useMeshWideNodes, - useMeshWideNodesReference, -} from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; +import { useNodes } from "plugins/lime-plugin-mesh-wide/src/hooks/useNodes"; import { INodeInfo } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; const NodesLayer = () => { - const { data: meshWideNodesReference } = useMeshWideNodesReference({}); - const { data: meshWideNodesActual } = useMeshWideNodes({}); + const { + geolocatedNodesReference: meshWideNodesReference, + geolocatedNodesActual: meshWideNodesActual, + } = useNodes(); return ( <> diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx index d689d2536..d5bd1d00e 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx @@ -1,12 +1,12 @@ import { useMemo } from "preact/compat"; +import { useNodes } from "plugins/lime-plugin-mesh-wide/src/hooks/useNodes"; import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; import { mergeLinksAndCoordinates } from "plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates"; import { compareLinks } from "plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors"; import { useMeshWideLinks, useMeshWideLinksReference, - useMeshWideNodesReference, } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; import { ILinkErrors, @@ -17,7 +17,8 @@ import { export const useLocatedLinks = () => { const { data: meshWideLinksReference } = useMeshWideLinksReference({}); const { data: meshWideLinks } = useMeshWideLinks({}); - const { data: meshWideNodesReference } = useMeshWideNodesReference({}); + + const { geolocatedNodesReference: meshWideNodesReference } = useNodes(); const locatedLinksReference: LocatedWifiLinkData = useMemo(() => { if (meshWideNodesReference && meshWideLinksReference) { diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx new file mode 100644 index 000000000..5fe561fce --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx @@ -0,0 +1,48 @@ +import { useMemo } from "preact/compat"; + +import { isValidCoordinate } from "plugins/lime-plugin-mesh-wide/src/lib/utils"; +import { + useMeshWideNodes, + useMeshWideNodesReference, +} from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; +import { INodes } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; + +export const useNodes = () => { + const { data: meshWideNodesReference } = useMeshWideNodesReference({}); + const { data: meshWideNodesActual } = useMeshWideNodes({}); + + // Delete nodes that are not properly geolocated + const filterNodeList = (nodeList: INodes): INodes => { + return Object.entries(nodeList) + .filter(([, v]) => { + try { + return isValidCoordinate( + v.data.coordinates.lat, + v.data.coordinates.lon + ); + } catch (e) { + return false; + } + }) + .reduce((acc: INodes, [key, nodeInfo]) => { + acc[key] = nodeInfo; + return acc; + }, {}); + }; + + const geolocatedNodesReference: INodes = useMemo(() => { + if (meshWideNodesReference) + return filterNodeList(meshWideNodesReference); + }, [meshWideNodesReference]); + + const geolocatedNodesActual: INodes = useMemo(() => { + if (meshWideNodesActual) return filterNodeList(meshWideNodesActual); + }, [meshWideNodesActual]); + + return { + meshWideNodesReference, + meshWideNodesActual, + geolocatedNodesReference, + geolocatedNodesActual, + }; +}; diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts index 54c389e66..50408c8ce 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts @@ -27,7 +27,11 @@ export const mergeLinksAndCoordinates = ( ); }); - if (dstNodeName && dstNodeName !== wifiNodeName) { + if ( + dstNodeName && + dstNodeName !== wifiNodeName && + nodes[wifiNodeName] // If is the link for a non geolocated node + ) { // Generate a unique id of the point to point link based on the coordinates const linkKey = PontToPointLink.generateId( nodes[wifiNodeName].data.coordinates, diff --git a/plugins/lime-plugin-mesh-wide/src/lib/utils.ts b/plugins/lime-plugin-mesh-wide/src/lib/utils.ts index 9e8032be2..3d01384ab 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/utils.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/utils.ts @@ -19,3 +19,16 @@ export const readableBytes = (bytes: number) => { export const getArrayDifference = (array1: string[], array2: string[]) => { return array1.filter((item) => !array2.includes(item)); }; + +export const isValidCoordinate = ( + lat: number | string, + lng: number | string +) => { + return ( + (!isNaN(Number(lat)) || !isNaN(Number(lng))) && + lat >= -90 && + lat <= 90 && + lng >= -180 && + lng <= 180 + ); +}; diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index 19c953433..3a30825b2 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -52,7 +52,7 @@ export interface INodeInfo { bleachTTL: number; author: string; data: { - coordinates: Coordinates; + coordinates?: Coordinates; // Coordinates may not be set board: string; device: string; macs: string[]; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx index 05f8f1c6a..7b67183be 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx @@ -69,9 +69,13 @@ export const nodesReferenceState: INodes = { bleachTTL: 12, author: "segundo", data: { + // coordinates: { + // lon: "-64.43209", + // lat: "-31.79461", + // }, coordinates: { - lon: "-64.43209", - lat: "-31.79461", + lon: "FIXME", + lat: "FIXME", }, macs: ["a8:40:41:1d:f9:ff", "a8:40:41:1d:f9:aa"], ipv4: "192.168.1.3", @@ -195,15 +199,14 @@ export const linksReferenceState: IWifiLinks = { rx_rate: 135000, signal: -65, }, - // todo(kon): if a link disappear from one of the nodes and not from the other, is not drawed on the map. And should be. - // { - // tx_rate: 240000, - // dst_mac: "A8:40:41:1D:F9:ff", - // chains: [-64, -65], - // src_mac: "a0:f3:c1:46:11:97", - // rx_rate: 135000, - // signal: -65, - // }, + { + tx_rate: 240000, + dst_mac: "A8:40:41:1D:F9:ff", + chains: [-64, -65], + src_mac: "a0:f3:c1:46:11:97", + rx_rate: 135000, + signal: -65, + }, ], author: "LiMe-462895", }, @@ -215,12 +218,12 @@ const nodeName = "primero"; // Used to delete a mac from a node. To see what happend if the returning list is different // This will delete a mac from the node macs list -// const macToDelete = ""; -const macToDelete = "a0:f3:c1:46:11:97"; +const macToDelete = ""; +// const macToDelete = "a0:f3:c1:46:11:97"; // delete a link where the src_mac is // const linkToDelete = macToDelete; -// const linkToDelete = "a0:f3:c1:46:11:97"; -const linkToDelete = ""; +const linkToDelete = "a0:f3:c1:46:11:97"; +// const linkToDelete = ""; export const links = (): IWifiLinks => { // Create a deep copy of the state to avoid mutating the original object From 97ea07f4bcf9e9f3a852859c30c0a99118c77f96 Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 15 Sep 2023 11:31:44 +0200 Subject: [PATCH 069/121] chore(meshwide): implement invalid nodes list --- .../src/containers/MapLayers/NodesLayer.tsx | 6 +- .../src/hooks/useLocatedLinks.tsx | 4 +- .../src/hooks/useNodes.tsx | 86 +++++++++++++------ 3 files changed, 66 insertions(+), 30 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx index edb9b7bd9..0b08b5561 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx @@ -4,8 +4,10 @@ import { INodeInfo } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; const NodesLayer = () => { const { - geolocatedNodesReference: meshWideNodesReference, - geolocatedNodesActual: meshWideNodesActual, + locatedNodes: { + locatedNodesReference: meshWideNodesReference, + locatedNodesActual: meshWideNodesActual, + }, } = useNodes(); return ( diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx index d5bd1d00e..da1debdb4 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx @@ -18,7 +18,9 @@ export const useLocatedLinks = () => { const { data: meshWideLinksReference } = useMeshWideLinksReference({}); const { data: meshWideLinks } = useMeshWideLinks({}); - const { geolocatedNodesReference: meshWideNodesReference } = useNodes(); + const { + locatedNodes: { locatedNodesReference: meshWideNodesReference }, + } = useNodes(); const locatedLinksReference: LocatedWifiLinkData = useMemo(() => { if (meshWideNodesReference && meshWideLinksReference) { diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx index 5fe561fce..b5d593ee6 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx @@ -11,38 +11,70 @@ export const useNodes = () => { const { data: meshWideNodesReference } = useMeshWideNodesReference({}); const { data: meshWideNodesActual } = useMeshWideNodes({}); - // Delete nodes that are not properly geolocated - const filterNodeList = (nodeList: INodes): INodes => { - return Object.entries(nodeList) - .filter(([, v]) => { - try { - return isValidCoordinate( - v.data.coordinates.lat, - v.data.coordinates.lon - ); - } catch (e) { - return false; + const splitNodesByValidity = ( + nodeList: INodes + ): { validNodes: INodes; invalidNodes: INodes } => { + const validNodes: INodes = {}; + const invalidNodes: INodes = {}; + + Object.entries(nodeList).forEach(([key, nodeInfo]) => { + try { + if ( + isValidCoordinate( + nodeInfo.data.coordinates.lat, + nodeInfo.data.coordinates.lon + ) + ) { + validNodes[key] = nodeInfo; + } else { + invalidNodes[key] = nodeInfo; } - }) - .reduce((acc: INodes, [key, nodeInfo]) => { - acc[key] = nodeInfo; - return acc; - }, {}); + } catch (e) { + invalidNodes[key] = nodeInfo; + } + }); + + return { validNodes, invalidNodes }; }; - const geolocatedNodesReference: INodes = useMemo(() => { - if (meshWideNodesReference) - return filterNodeList(meshWideNodesReference); - }, [meshWideNodesReference]); + const { + validNodes: locatedNodesReference, + invalidNodes: invalidNodesReference, + }: { validNodes: INodes; invalidNodes: INodes } | undefined = + useMemo(() => { + if (meshWideNodesReference) + return splitNodesByValidity(meshWideNodesReference); + return { validNodes: undefined, invalidNodes: undefined }; + }, [meshWideNodesReference]); + + const { + validNodes: locatedNodesActual, + invalidNodes: invalidNodesActual, + }: { validNodes: INodes; invalidNodes: INodes } | undefined = + useMemo(() => { + if (meshWideNodesActual) + return splitNodesByValidity(meshWideNodesActual); + return { validNodes: undefined, invalidNodes: undefined }; + }, [meshWideNodesActual]); - const geolocatedNodesActual: INodes = useMemo(() => { - if (meshWideNodesActual) return filterNodeList(meshWideNodesActual); - }, [meshWideNodesActual]); + const hasInvalidNodes = + (invalidNodesReference && + Object.keys(invalidNodesReference).length > 0) || + (invalidNodesActual && Object.keys(invalidNodesActual).length > 0); return { - meshWideNodesReference, - meshWideNodesActual, - geolocatedNodesReference, - geolocatedNodesActual, + hasInvalidNodes, + allNodes: { + meshWideNodesReference, + meshWideNodesActual, + }, + invalidNodes: { + invalidNodesReference, + invalidNodesActual, + }, + locatedNodes: { + locatedNodesReference, + locatedNodesActual, + }, }; }; From 7017e1c7c2e1c0de4a16cba310e0d2f8e5936b67 Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 15 Sep 2023 17:36:51 +0200 Subject: [PATCH 070/121] chore(meshwide): implement invalid nodes alert --- .../FeatureDetail/InvalidNodesDetail.tsx | 25 +++++++++++ .../src/components/FeatureDetail/index.tsx | 8 ++++ .../src/components/Map/FloatingAlert.tsx | 42 +++++++++++++++++++ .../src/containers/Map.tsx | 38 +++++++++-------- .../src/icons/warningIcon.tsx | 16 +++++++ .../src/mesWideTypes.tsx | 6 ++- 6 files changed, 116 insertions(+), 19 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/InvalidNodesDetail.tsx create mode 100644 plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx create mode 100644 plugins/lime-plugin-mesh-wide/src/icons/warningIcon.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/InvalidNodesDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/InvalidNodesDetail.tsx new file mode 100644 index 000000000..171f39c33 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/InvalidNodesDetail.tsx @@ -0,0 +1,25 @@ +import { Trans } from "@lingui/macro"; + +import { Row } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index"; +import { InvalidNodes } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; + +export const InvalidNodesDetail = ({ nodes }: { nodes: InvalidNodes }) => { + return ( + <> + +
+ Invalid Nodes +
+
+ + + The following nodes are not located. Please, set their + location to see them on the map: + + + {[...nodes].map((name, k) => ( +
{name}
+ ))} + + ); +}; diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx index ddba1a6c0..e50c2b89c 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx @@ -1,5 +1,6 @@ import { VNode } from "preact"; +import { InvalidNodesDetail } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/InvalidNodesDetail"; import LinkFeatureDetail, { LinkReferenceStatus, } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail"; @@ -7,6 +8,7 @@ import NodeDetails, { NodeReferenceStatus, } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail"; import { + InvalidNodes, LinkMapFeature, NodeMapFeature, SelectedMapFeature, @@ -55,6 +57,12 @@ export const FeatureDetail = ({ return ( ); + case "invalidNodes": + return ( + + ); default: return <>; } diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx new file mode 100644 index 000000000..9fdde9133 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx @@ -0,0 +1,42 @@ +import { useCallback } from "react"; + +import { useNodes } from "plugins/lime-plugin-mesh-wide/src/hooks/useNodes"; +import { WarningIcon } from "plugins/lime-plugin-mesh-wide/src/icons/warningIcon"; +import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; +import { InvalidNodes } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; + +export const FloatingAlert = () => { + const { + hasInvalidNodes, + invalidNodes: { invalidNodesReference, invalidNodesActual }, + } = useNodes(); + + const { setData: setSelectedFeature } = useSelectedMapFeature(); + + const callback = useCallback(() => { + const list: InvalidNodes = new Set([ + ...Object.keys(invalidNodesReference), + ...Object.keys(invalidNodesActual), + ]); + setSelectedFeature({ + id: "invalidNodes", + type: "invalidNodes", + feature: list, + }); + }, [invalidNodesActual, invalidNodesReference]); + + return ( + <> + {hasInvalidNodes ? ( +
+
+ +
+
+ ) : null} + + ); +}; diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx index 3b44f1625..1e92a3de1 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx @@ -2,6 +2,7 @@ import L from "leaflet"; import { useEffect, useRef } from "preact/hooks"; import { MapContainer, TileLayer } from "react-leaflet"; +import { FloatingAlert } from "plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert"; import { LinksLayer } from "plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayer"; import NodesLayer from "plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer"; import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; @@ -44,22 +45,25 @@ export const MeshWideMap = () => { // }); return ( - - - - - + <> + + + + + + + ); }; diff --git a/plugins/lime-plugin-mesh-wide/src/icons/warningIcon.tsx b/plugins/lime-plugin-mesh-wide/src/icons/warningIcon.tsx new file mode 100644 index 000000000..db17d5232 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/icons/warningIcon.tsx @@ -0,0 +1,16 @@ +export const WarningIcon = () => { + return ( + + + + ); +}; diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index 3a30825b2..88af948cd 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -70,7 +70,7 @@ export type INamedNodeInfo = { export type INodes = { [key: string]: INodeInfo }; -type FeatureType = "node" | "link"; +type FeatureType = "node" | "link" | "invalidNodes"; export type LinkMapFeature = { actual: PontToPointLink; @@ -83,7 +83,9 @@ export type NodeMapFeature = { name: string; }; -type MapFeature = NodeMapFeature | LinkMapFeature; +export type InvalidNodes = Set; + +type MapFeature = NodeMapFeature | LinkMapFeature | InvalidNodes; export interface SelectedMapFeature { feature: MapFeature; From e673a482c3dbf89ff3b6b85a7358212608c4ee70 Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 27 Sep 2023 16:43:21 +0200 Subject: [PATCH 071/121] chore(meshwide): implement feature bottom sheet tests --- .../FeatureDetail/InvalidNodesDetail.tsx | 4 +- .../components/FeatureDetail/NodeDetail.tsx | 8 +- .../src/containers/Map.tsx | 10 -- .../SelectedFeatureBottomSheet.spec.tsx | 116 ++++++++++++++++++ .../containers/SelectedFeatureBottomSheet.tsx | 5 +- .../src/meshWideMocks.tsx | 8 +- src/components/bottom-sheet/BottomSheet.tsx | 21 ++-- 7 files changed, 137 insertions(+), 35 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.spec.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/InvalidNodesDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/InvalidNodesDetail.tsx index 171f39c33..7fc9edd29 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/InvalidNodesDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/InvalidNodesDetail.tsx @@ -5,7 +5,7 @@ import { InvalidNodes } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; export const InvalidNodesDetail = ({ nodes }: { nodes: InvalidNodes }) => { return ( - <> +
Invalid Nodes @@ -20,6 +20,6 @@ export const InvalidNodesDetail = ({ nodes }: { nodes: InvalidNodes }) => { {[...nodes].map((name, k) => (
{name}
))} - +
); }; diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx index b6779eb85..95b344bce 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx @@ -30,7 +30,7 @@ const NodeDetails = ({ actual, reference, name }: NodeMapFeature) => { const macs = actual.data.macs; return ( - <> +
{name}
); }; diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx index 1e92a3de1..086126b8d 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx @@ -12,12 +12,6 @@ const openStreetMapAttribution = '© OpenStreetMap contributors'; export const MeshWideMap = () => { - // const [communityLayer, setCommunityLayer] = - // useState(null); - - // const [selectedFeature, setSelectedFeature] = - // useState(null); - const { data: selectedMapFeature, setData: setSelectedMapFeature } = useSelectedMapFeature(); @@ -33,10 +27,6 @@ export const MeshWideMap = () => { } }, [mapRef, selectedMapFeature]); - // useEffect(() => { - // console.log("SelectedFeature", selectedMapFeature); - // }, [selectedMapFeature]); - // const { data: meshWideStatus } = useMeshWide({ // onSuccess: (res) => { // const geoJson = getCommunityGeoJSON(res.result); // todo(kon): the locate page makes a correction with the own node if is modified diff --git a/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.spec.tsx b/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.spec.tsx new file mode 100644 index 000000000..2ab835fdd --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.spec.tsx @@ -0,0 +1,116 @@ +import "@testing-library/jest-dom"; +// import "@testing-library/jest-dom/extend-expect"; +import { screen } from "@testing-library/preact"; + +import { SelectedFeatureBottomSheet } from "plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet"; +import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; +import { + INodeInfo, + NodeMapFeature, +} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +import { + links, + linksReferenceState, + nodes, + nodesReferenceState, +} from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; + +import { render } from "utils/test_utils"; + +jest.mock("plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx"); +const mockedSelectedMapFeature = jest.mocked(useSelectedMapFeature); + +function pxToNumber(pxString: string): number { + const numericString = pxString.replace("px", ""); + return parseInt(numericString, 10); +} + +describe("Feature bottom sheet", () => { + // beforeEach(() => {}); + beforeAll(() => { + Object.defineProperty(window, "matchMedia", { + writable: true, + value: jest.fn().mockImplementation((query) => ({ + matches: false, // or true if you want it to match + media: query, + onchange: null, + addListener: jest.fn(), // deprecated in favor of `addEventListener` + removeListener: jest.fn(), // deprecated in favor of `removeEventListener` + addEventListener: jest.fn(), + removeEventListener: jest.fn(), + dispatchEvent: jest.fn(), + })), + }); + }); + + it("should not open BottomSheet when selectedMapFeature is null", () => { + // Mock the return value for the hook + mockedSelectedMapFeature.mockReturnValue({ + data: null, + setData: () => {}, + }); + + render(); + + expect( + pxToNumber(screen.queryByTestId("bottom-sheet-body").style.height) + ).toBeLessThan(0); + }); + + it("should open BottomSheet with invalid nodes feature", () => { + const invalid = "invalid_node"; + mockedSelectedMapFeature.mockReturnValue({ + data: { + type: "invalidNodes", + feature: new Set([invalid]), + id: "invalidNodes", + }, + setData: () => {}, + }); + + render(); + expect( + pxToNumber(screen.queryByTestId("bottom-sheet-body").style.height) + ).toBeGreaterThan(0); + expect(screen.getByText(invalid)).toBeInTheDocument(); + expect(screen.getByText("Invalid Nodes")).toBeInTheDocument(); + }); + + it("should open BottomSheet with node feature", () => { + const name = "LiMe-da4eaa"; + const actual: INodeInfo = nodes()[name]; + const reference: INodeInfo = nodesReferenceState[name]; + // Mock the return value for the hook + mockedSelectedMapFeature.mockReturnValue({ + data: { + type: "node", + feature: { actual, reference, name } as NodeMapFeature, + id: "node", + }, + setData: () => {}, + }); + + render(); + + expect(screen.getByText(name)).toBeInTheDocument(); + }); + + it.skip("should open BottomSheet with link feature", () => { + const name = "LiMe-da4eaa"; + const actual = links()[name]; + const reference = linksReferenceState[name]; + // todo: fix this test + // mockedSelectedMapFeature.mockReturnValue({ + // data: { + // type: "link", + // feature: { PontToPointLink(actual), reference } as LinkMapFeature, + // id: "node", + // }, + // setData: () => {}, + // }); + // + // render(); + // + // expect(screen.getByText(name)).toBeInTheDocument(); + }); +}); diff --git a/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.tsx b/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.tsx index addc83e43..f00392ebe 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.tsx @@ -1,5 +1,4 @@ import { useEffect, useState } from "preact/hooks"; -import React from "react"; import { BottomSheet } from "components/bottom-sheet"; @@ -19,7 +18,7 @@ export const SelectedFeatureBottomSheet = () => { }, [selectedMapFeature]); return ( - <> +
{
- +
); }; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx index 7b67183be..fd57911eb 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx @@ -69,13 +69,9 @@ export const nodesReferenceState: INodes = { bleachTTL: 12, author: "segundo", data: { - // coordinates: { - // lon: "-64.43209", - // lat: "-31.79461", - // }, coordinates: { - lon: "FIXME", - lat: "FIXME", + lon: "-64.43209", + lat: "-31.79461", }, macs: ["a8:40:41:1d:f9:ff", "a8:40:41:1d:f9:aa"], ipv4: "192.168.1.3", diff --git a/src/components/bottom-sheet/BottomSheet.tsx b/src/components/bottom-sheet/BottomSheet.tsx index c455a864f..cc1bc086e 100644 --- a/src/components/bottom-sheet/BottomSheet.tsx +++ b/src/components/bottom-sheet/BottomSheet.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useRef } from "react"; +import { useCallback, useEffect, useRef, useState } from "preact/hooks"; import { animated, useSpring } from "react-spring"; import style from "./style.less"; @@ -83,11 +83,11 @@ export const BottomSheet: React.FC = ({ }) => { // STATE const scrollRef = useRef(null); - const [bottom, setBottom] = React.useState(-DRAWER_HEIGHT); - const [draggingPosition, setDraggingPosition] = React.useState< - number | null - >(null); - const [debugLog, setDebugLog] = React.useState(""); + const [bottom, setBottom] = useState(-DRAWER_HEIGHT); + const [draggingPosition, setDraggingPosition] = useState( + null + ); + const [debugLog, setDebugLog] = useState(""); // ANIMATION const prefersReducedMotion = useReduceMotion(); @@ -112,7 +112,7 @@ export const BottomSheet: React.FC = ({ setDraggingPosition(newDraggingPosition); }; - const handlePointerMove = React.useCallback( + const handlePointerMove = useCallback( (e: TouchEvent | MouseEvent) => { // @ts-ignore const event = e?.touches != null ? e?.touches[0] : e; @@ -133,7 +133,7 @@ export const BottomSheet: React.FC = ({ } }; - const handleStatusChange = React.useCallback( + const handleStatusChange = useCallback( (status: TBottomSheetEventsKey) => { const newStatus = bottomSheetEvents[status]; const newDebugLog = @@ -211,7 +211,7 @@ export const BottomSheet: React.FC = ({ (title || subtitle ? COLLAPSED_HEIGHT : THUMB_HEIGHT); return ( - <> +
= ({ ref={scrollRef} tabIndex={0} style={{ height: bodyHeight }} + data-testid="bottom-sheet-body" > {children}
@@ -294,6 +295,6 @@ export const BottomSheet: React.FC = ({ {footer}
)} - +
); }; From 663aa66f26ee646f251f2ff2b9527111411642d7 Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 27 Sep 2023 17:09:32 +0200 Subject: [PATCH 072/121] chore(meshwide): link selected feature with type string --- .../src/components/FeatureDetail/index.tsx | 17 +++----------- .../src/mesWideTypes.tsx | 22 ++++++++++++------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx index e50c2b89c..f3718cd6d 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx @@ -8,7 +8,6 @@ import NodeDetails, { NodeReferenceStatus, } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail"; import { - InvalidNodes, LinkMapFeature, NodeMapFeature, SelectedMapFeature, @@ -48,21 +47,11 @@ export const FeatureDetail = ({ if (!selectedFeature) return; switch (selectedFeature.type) { case "link": - return ( - - ); + return ; case "node": - return ( - - ); + return ; case "invalidNodes": - return ( - - ); + return ; default: return <>; } diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index 88af948cd..1191ee6da 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -70,8 +70,6 @@ export type INamedNodeInfo = { export type INodes = { [key: string]: INodeInfo }; -type FeatureType = "node" | "link" | "invalidNodes"; - export type LinkMapFeature = { actual: PontToPointLink; reference: PontToPointLink; @@ -85,13 +83,21 @@ export type NodeMapFeature = { export type InvalidNodes = Set; -type MapFeature = NodeMapFeature | LinkMapFeature | InvalidNodes; +type FeatureMap = { + node: NodeMapFeature; + link: LinkMapFeature; + invalidNodes: InvalidNodes; +}; -export interface SelectedMapFeature { - feature: MapFeature; - type: FeatureType; - id: number | string; -} +type FeatureType = keyof FeatureMap; + +export type SelectedMapFeature = { + [T in FeatureType]: { + feature: FeatureMap[T]; + type: T; + id: number | string; + }; +}[FeatureType]; export interface IMeshWideSection { name: string; From 3a8d0c53deef7c9f078a3c6663bdea9fbf65a5ce Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 28 Sep 2023 15:54:49 +0200 Subject: [PATCH 073/121] chore(meshwide): implement layers control --- .../src/containers/Map.tsx | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx index 086126b8d..e7172d3df 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx @@ -1,6 +1,12 @@ +import { t } from "@lingui/macro"; import L from "leaflet"; import { useEffect, useRef } from "preact/hooks"; -import { MapContainer, TileLayer } from "react-leaflet"; +import { + LayerGroup, + LayersControl, + MapContainer, + TileLayer, +} from "react-leaflet"; import { FloatingAlert } from "plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert"; import { LinksLayer } from "plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayer"; @@ -51,8 +57,18 @@ export const MeshWideMap = () => { attribution={openStreetMapAttribution} url={openStreetMapTileString} /> - - + + + + + + + + + + + + ); From b201e90bd61911ed4de58eefe4bc5952876d2eb1 Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 28 Sep 2023 18:53:32 +0200 Subject: [PATCH 074/121] chore(meshwide): implement generic link functions --- .../components/FeatureDetail/LinkDetail.tsx | 8 +- .../Map/{LinkLine.tsx => WifiLinkLine.tsx} | 10 +- .../src/containers/Map.tsx | 23 +-- .../src/containers/MapLayers/LinksLayer.tsx | 31 ---- .../src/containers/MapLayers/LinksLayers.tsx | 78 +++++++++ .../SelectedFeatureBottomSheet.spec.tsx | 2 +- .../src/hooks/useLocatedLinks.tsx | 37 ++-- .../src/lib/links/PointToPointLink.ts | 20 ++- .../src/lib/links/getLinksCoordinates.spec.ts | 8 +- .../src/lib/links/getLinksCoordinates.ts | 67 +++---- .../src/lib/links/processLinkErrors.ts | 4 +- .../lime-plugin-mesh-wide/src/mesWideApi.ts | 11 +- .../src/mesWideQueries.tsx | 23 +++ .../src/mesWideTypes.tsx | 44 +++-- .../src/meshWideMocks.tsx | 164 ++++++++++++++++-- 15 files changed, 397 insertions(+), 133 deletions(-) rename plugins/lime-plugin-mesh-wide/src/components/Map/{LinkLine.tsx => WifiLinkLine.tsx} (85%) delete mode 100644 plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayer.tsx create mode 100644 plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx index b7c8d83de..2a487f636 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx @@ -23,7 +23,7 @@ const SelectedLink = ({ linkDetail, errors, }: { - linkDetail: MacToMacLink; + linkDetail: MacToMacLink<"wifi">; errors: ILinkMtoMErrors; }) => { if (linkDetail === undefined || !errors.linkUp) @@ -112,7 +112,7 @@ const LinkFeatureDetail = ({ actual, reference }: LinkMapFeature) => { const [selectedLink, setSelectedLink] = useState(0); const { errors } = usePointToPointErrors({ id: reference.id }); - const tabs = reference.links.map((link: MacToMacLink, i) => { + const tabs = reference.links.map((link: MacToMacLink<"wifi">, i) => { return { key: i, repr: ( @@ -140,7 +140,9 @@ const LinkFeatureDetail = ({ actual, reference }: LinkMapFeature) => { )} {selectedLink !== null && ( + } errors={ errors.macToMacErrors[ actual?.links[selectedLink]?.id diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/WifiLinkLine.tsx similarity index 85% rename from plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx rename to plugins/lime-plugin-mesh-wide/src/components/Map/WifiLinkLine.tsx index 728462fb3..ceee14daa 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/WifiLinkLine.tsx @@ -10,14 +10,14 @@ interface ILinkLineProps { actualLink: PontToPointLink | undefined; } -export const LinkLine = ({ referenceLink, actualLink }: ILinkLineProps) => { +export const WifiLinkLine = ({ referenceLink, actualLink }: ILinkLineProps) => { const { data: selectedMapFeature, setData: setSelectedMapFeature } = useSelectedMapFeature(); const isSelected = selectedMapFeature?.id === referenceLink.id; - const { linksErrors } = useLocatedLinks(); + const { linksErrors } = useLocatedLinks({ type: "wifi" }); - const hasError = linksErrors[referenceLink.id].hasErrors; - const linkUp = linksErrors[referenceLink.id].linkUp; + const hasError = linksErrors[referenceLink.id]?.hasErrors || false; + const linkUp = linksErrors[referenceLink.id]?.linkUp || true; const _setSelectedFeature = () => { setSelectedMapFeature({ @@ -60,4 +60,4 @@ export const LinkLine = ({ referenceLink, actualLink }: ILinkLineProps) => { ); }; -export default LinkLine; +export default WifiLinkLine; diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx index e7172d3df..fb7dfb576 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx @@ -9,13 +9,16 @@ import { } from "react-leaflet"; import { FloatingAlert } from "plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert"; -import { LinksLayer } from "plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayer"; +import { + BatmanLinksLayer, + WifiLinksLayer, +} from "plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers"; import NodesLayer from "plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer"; import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; -const openStreetMapTileString = "http://{s}.tile.osm.org/{z}/{x}/{y}.png"; +const openStreetMapTileString = "https://{s}.tile.osm.org/{z}/{x}/{y}.png"; const openStreetMapAttribution = - '© OpenStreetMap contributors'; + '© OpenStreetMap contributors'; export const MeshWideMap = () => { const { data: selectedMapFeature, setData: setSelectedMapFeature } = @@ -33,13 +36,6 @@ export const MeshWideMap = () => { } }, [mapRef, selectedMapFeature]); - // const { data: meshWideStatus } = useMeshWide({ - // onSuccess: (res) => { - // const geoJson = getCommunityGeoJSON(res.result); // todo(kon): the locate page makes a correction with the own node if is modified - // setCommunityLayer(geoJson as FeatureCollection); - // }, - // }); - return ( <> @@ -60,7 +56,12 @@ export const MeshWideMap = () => { - + + + + + + diff --git a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayer.tsx b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayer.tsx deleted file mode 100644 index fee9a0c7a..000000000 --- a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayer.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import LinkLine from "plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine"; -import { useLocatedLinks } from "plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks"; -import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; - -export const LinksLayer = () => { - const { locatedLinks, locatedLinksReference, linksLoaded } = - useLocatedLinks(); - - return ( - <> - {linksLoaded && - Object.entries(locatedLinksReference).map( - (referenceLink, i) => { - let actualLink: PontToPointLink; - if (locatedLinks) { - actualLink = Object.values(locatedLinks).find( - (value) => value.id === referenceLink[0] - ); - } - return ( - - ); - } - )} - - ); -}; diff --git a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx new file mode 100644 index 000000000..ae0b69fdb --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx @@ -0,0 +1,78 @@ +import { ComponentType } from "preact"; + +import WifiLinkLine from "plugins/lime-plugin-mesh-wide/src/components/Map/WifiLinkLine"; +import { useLocatedLinks } from "plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks"; +import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; +import { LocatedLinkData } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; + +interface ILinkComponentProps { + referenceLink: PontToPointLink; + actualLink: PontToPointLink | undefined; +} + +interface ILinksLayerProps { + links: LocatedLinkData; + linksReference: LocatedLinkData; + linksLoaded: boolean; + LinkComponent: ComponentType; +} + +const LinksLayer = ({ + links, + linksReference, + linksLoaded, + LinkComponent, +}: ILinksLayerProps) => { + return ( + <> + {linksLoaded && + Object.entries(linksReference).map((referenceLink, i) => { + let actualLink: PontToPointLink; + if (links) { + actualLink = Object.values(links).find( + (value) => value.id === referenceLink[0] + ); + } + return ( + + ); + })} + + ); +}; + +export const WifiLinksLayer = () => { + const { locatedLinks, locatedLinksReference, linksLoaded } = + useLocatedLinks({ type: "wifi" }); + + return ( +
+ +
+ ); +}; + +export const BatmanLinksLayer = () => { + const { locatedLinks, locatedLinksReference, linksLoaded } = + useLocatedLinks({ type: "batman" }); + + return ( +
+ +
+ ); +}; diff --git a/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.spec.tsx b/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.spec.tsx index 2ab835fdd..886cc21ce 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.spec.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.spec.tsx @@ -97,7 +97,7 @@ describe("Feature bottom sheet", () => { it.skip("should open BottomSheet with link feature", () => { const name = "LiMe-da4eaa"; - const actual = links()[name]; + const actual = links("wifi")[name]; const reference = linksReferenceState[name]; // todo: fix this test // mockedSelectedMapFeature.mockReturnValue({ diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx index da1debdb4..532ba58f8 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx @@ -5,40 +5,51 @@ import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/Poi import { mergeLinksAndCoordinates } from "plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates"; import { compareLinks } from "plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors"; import { + useMeshWideBatman, + useMeshWideBatmanReference, useMeshWideLinks, useMeshWideLinksReference, } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; import { ILinkErrors, - LocatedWifiLinkData, + LinkType, + LocatedLinkData, PointToPointLinkId, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; -export const useLocatedLinks = () => { - const { data: meshWideLinksReference } = useMeshWideLinksReference({}); - const { data: meshWideLinks } = useMeshWideLinks({}); +export const useLocatedLinks = ({ type }: { type: LinkType }) => { + const fetchData = type === "batman" ? useMeshWideBatman : useMeshWideLinks; + const fetchDataReference = + type === "batman" + ? useMeshWideBatmanReference + : useMeshWideLinksReference; + + const { data: linksReference } = fetchDataReference({}); + const { data: links } = fetchData({}); const { locatedNodes: { locatedNodesReference: meshWideNodesReference }, } = useNodes(); - const locatedLinksReference: LocatedWifiLinkData = useMemo(() => { - if (meshWideNodesReference && meshWideLinksReference) { + const locatedLinksReference: LocatedLinkData = useMemo(() => { + if (meshWideNodesReference && linksReference) { return mergeLinksAndCoordinates( meshWideNodesReference, - meshWideLinksReference + linksReference, + type ); } - }, [meshWideNodesReference, meshWideLinksReference]); + }, [meshWideNodesReference, linksReference, type]); - const locatedLinks: LocatedWifiLinkData = useMemo(() => { - if (meshWideNodesReference && meshWideLinks) { + const locatedLinks: LocatedLinkData = useMemo(() => { + if (links && meshWideNodesReference) { return mergeLinksAndCoordinates( meshWideNodesReference, - meshWideLinks + links, + type ); } - }, [meshWideNodesReference, meshWideLinks]); + }, [links, meshWideNodesReference, type]); const linksLoaded = !!locatedLinksReference && !!locatedLinks; @@ -67,6 +78,6 @@ export const useLocatedLinks = () => { }; export const usePointToPointErrors = ({ id }: { id: PointToPointLinkId }) => { - const { linksErrors } = useLocatedLinks(); + const { linksErrors } = useLocatedLinks({ type: "wifi" }); return { errors: linksErrors[id] }; }; diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts index 4ce9ccf6c..1b4fa1533 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts @@ -1,7 +1,9 @@ import { + BaseMacToMacLink, Coordinates, ILocatedLink, - IWifiLinkData, + LinkData, + LinkType, MacToMacLinkId, PointToPointLinkId, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; @@ -12,7 +14,7 @@ import { * Could store two links between same geo but with different macs */ export class PontToPointLink { - private _links: MacToMacLink[] = []; + private _links: BaseMacToMacLink[] = []; public readonly id: PointToPointLinkId; public readonly coordinates: Coordinates[] = []; @@ -21,7 +23,7 @@ export class PontToPointLink { this.coordinates.push(coord1, coord2); } - addLink(link: MacToMacLink) { + addLink(link: typeof this._links[number]) { this.links.push(link); } @@ -84,13 +86,15 @@ export class PontToPointLink { /** * Store link info between two macs */ -export class MacToMacLink { - private _data: ILocatedLink; +export class MacToMacLink { + private _data: ILocatedLink; private _id: MacToMacLinkId; + public type: T; - constructor(data: ILocatedLink) { + constructor(data: ILocatedLink, type: T) { this._data = data; this._id = MacToMacLink.generateId(data); + this.type = type; } /** @@ -98,7 +102,7 @@ export class MacToMacLink { * are involved on this link * @param data */ - static generateId(data: ILocatedLink): MacToMacLinkId { + static generateId(data: ILocatedLink): MacToMacLinkId { return [ ...Object.entries(data).map(([k, v]) => { return v.src_mac?.toLowerCase().replace(/:/g, ""); @@ -120,7 +124,7 @@ export class MacToMacLink { return [...Object.keys(this._data)]; } - linkByName(name: string): IWifiLinkData { + linkByName(name: string): LinkData[T] { return this._data[name]; } } diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.spec.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.spec.ts index d9b4217cc..97da20b4f 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.spec.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.spec.ts @@ -12,16 +12,16 @@ describe("tests for the algorithm that merge point and links data types", () => it("assert that merged nodes have the correct coordinates", async () => { const locatedLinksReference = mergeLinksAndCoordinates( nodesReferenceState, - linksReferenceState + linksReferenceState, + "wifi" ); // Iterate between merged link objects Object.entries(locatedLinksReference).map(([k, merged], i) => { expect(merged.coordinates.length).toBe(2); // Merged objects haw to be exactly two geo points for (const link of merged.links) { - Object.entries(link).map(([name, linkData], i) => { - // const link = linksReferenceState[name]; + Object.entries(link.data).map(([name, linkData], i) => { const node = nodesReferenceState[name]; - expect(link[name].coordinates).toBe(node.coordinates); + expect(linkData.coordinates).toBe(node.data.coordinates); }); } }); diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts index 50408c8ce..cae45399f 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts @@ -3,84 +3,85 @@ import { PontToPointLink, } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; import { + ILinks, ILocatedLink, INodes, - IWifiLinks, - LocatedWifiLinkData, + LinkData, + LinkType, + LocatedLinkData, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; -export const mergeLinksAndCoordinates = ( +export const mergeLinksAndCoordinates = ( nodes: INodes, - wifiLinks: IWifiLinks -): LocatedWifiLinkData => { - if (!nodes || !wifiLinks) return {}; - const result: LocatedWifiLinkData = {}; + links: ILinks, + type: T +): LocatedLinkData => { + if (!nodes || !links) return {}; + const result: LocatedLinkData = {}; // for every node check all links - for (const wifiNodeName in wifiLinks) { - for (const wifiLinkData of wifiLinks[wifiNodeName].data) { + for (const linkNodeName in links) { + for (const linkData of links[linkNodeName].data) { // Get the nodeName of the destination node const dstNodeName = Object.keys(nodes).find((pid) => { return nodes[pid].data.macs.find( (mac) => - mac.toLowerCase() === wifiLinkData.dst_mac.toLowerCase() + mac.toLowerCase() === linkData.dst_mac.toLowerCase() ); }); if ( dstNodeName && - dstNodeName !== wifiNodeName && - nodes[wifiNodeName] // If is the link for a non geolocated node + dstNodeName !== linkNodeName && + nodes[linkNodeName] // If is the link for a non geolocated node ) { // Generate a unique id of the point to point link based on the coordinates const linkKey = PontToPointLink.generateId( - nodes[wifiNodeName].data.coordinates, + nodes[linkNodeName].data.coordinates, nodes[dstNodeName!].data.coordinates ); // If this point to point link no exists, instantiate it if (!result[linkKey]) { result[linkKey] = new PontToPointLink( - nodes[wifiNodeName].data.coordinates, + nodes[linkNodeName].data.coordinates, nodes[dstNodeName!].data.coordinates ); } // Else if the link is not already added don't do it. else if ( result[linkKey].linkExists( - wifiLinkData.src_mac, - wifiLinkData.dst_mac + linkData.src_mac, + linkData.dst_mac ) || - !wifiLinks[dstNodeName] + !links[dstNodeName] ) { continue; } // Get the destination link info - const destPointData = wifiLinks[dstNodeName].data.find( - (data) => + const destPointData = ( + links[dstNodeName].data as Array + ).find( + (data: LinkData[T]) => data.dst_mac.toLowerCase() === - wifiLinkData.src_mac.toLowerCase() && + linkData.src_mac.toLowerCase() && data.src_mac.toLowerCase() === - wifiLinkData.dst_mac.toLowerCase() + linkData.dst_mac.toLowerCase() ); - const entry: ILocatedLink = { - [wifiNodeName]: { - ...wifiLinkData, - coordinates: nodes[wifiNodeName].data.coordinates, + const entry = { + [linkNodeName]: { + ...linkData, + coordinates: nodes[linkNodeName].data.coordinates, }, [dstNodeName]: { - tx_rate: destPointData?.tx_rate, - dst_mac: destPointData?.dst_mac, - chains: destPointData?.chains, - src_mac: destPointData?.src_mac, - rx_rate: destPointData?.rx_rate, - signal: destPointData?.signal, + ...destPointData, coordinates: nodes[dstNodeName].data.coordinates, }, - }; - result[linkKey].addLink(new MacToMacLink(entry)); + } as ILocatedLink; + + result[linkKey].addLink(new MacToMacLink(entry, type)); } } } diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts index ddd402fd9..dc4eeb067 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts @@ -82,8 +82,8 @@ export const compareLinks = ({ ([nodeNameReference, wifiDataReference]) => { const wifiDataActual = macToMacActual?.data[nodeNameReference]; const wifiErrors = compareWifiData( - wifiDataReference, - wifiDataActual + wifiDataReference as IWifiLinkData, + wifiDataActual as IWifiLinkData ); ptoPErrors.macToMacErrors[macToMacReference.id].linkErrors[ nodeNameReference diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts b/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts index 52a2e92b9..025ac4a0e 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts +++ b/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts @@ -1,16 +1,25 @@ import { + batManReferenceState, links, linksReferenceState, nodes, nodesReferenceState, } from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; +export const getMeshWideBatmanReference = () => { + return batManReferenceState; +}; + +export const getMeshWideBatman = () => { + return links("batman"); +}; + export const getMeshWideLinksReference = () => { return linksReferenceState; }; export const getMeshWideLinks = () => { - return links(); + return links("wifi"); }; export const getMeshWideNodesReference = () => { diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx index ab67fb665..e6c62c16c 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx @@ -1,12 +1,15 @@ import { useQuery } from "@tanstack/react-query"; import { + getMeshWideBatman, + getMeshWideBatmanReference, getMeshWideLinks, getMeshWideLinksReference, getMeshWideNodes, getMeshWideNodesReference, } from "plugins/lime-plugin-mesh-wide/src/mesWideApi"; import { + IBatmanLinks, IMeshWideConfig, INodes, IWifiLinks, @@ -33,6 +36,26 @@ export function useMeshWideLinks(params) { }); } +export function useMeshWideBatmanReference(params) { + return useQuery( + ["lime-meshwide", "batman_reference"], + getMeshWideBatmanReference, + { + ...params, + } + ); +} + +export function useMeshWideBatman(params) { + return useQuery( + ["lime-meshwide", "batman"], + getMeshWideBatman, + { + ...params, + } + ); +} + export function useMeshWideNodesReference(params) { return useQuery( ["lime-meshwide", "nodes_reference"], diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index 1191ee6da..58a399b38 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -1,13 +1,19 @@ -import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; +import { + MacToMacLink, + PontToPointLink, +} from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; /** * Describe a link with a coordinates */ -export type ILocatedLink = { - [key: string]: IWifiLinkData & { +export type LinkData = { wifi: IWifiLinkData; batman: IBatManLinkData }; +export type LinkType = keyof LinkData; +export type ILocatedLink = { + [key: string]: LinkData[T] & { coordinates: Coordinates; }; }; +export type BaseMacToMacLink = MacToMacLink; /** * List of located links. @@ -16,33 +22,49 @@ export type ILocatedLink = { * * The array of classes contain an indeterminated number of links that are from certain point to another. */ -export type LocatedWifiLinkData = { +export type LocatedLinkData = { [key: string]: PontToPointLink; }; +type MacPair = { + dst_mac: string; + src_mac: string; +}; + /** - * Link info retrieved from the API + * Link info retrieved from the API with the wifi data */ -export interface IWifiLinkData { +export type IWifiLinkData = { tx_rate: number; - dst_mac: string; chains: number[]; signal: number; rx_rate: number; - src_mac: string; -} +} & MacPair; + +/** + * Link info retrieved from the API with the batman data + */ +export type IBatManLinkData = { + hard_ifindex: number; + last_seen_msecs: number; + iface: string; +} & MacPair; /** * List of Link info retrieved from the API */ -export interface IWifiLinks { +// export interface ILinks { +export interface ILinks { [key: string]: { bleachTTL: number; - data: IWifiLinkData[]; + data: Array; author: string; }; } +export type IWifiLinks = ILinks<"wifi">; +export type IBatmanLinks = ILinks<"batman">; + export type Coordinates = { lat: string; lon: string; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx index fd57911eb..8193df20b 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx @@ -1,7 +1,12 @@ import { + IBatManLinkData, + IBatmanLinks, + ILinks, IMeshWideConfig, INodes, + IWifiLinkData, IWifiLinks, + LinkType, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; // todo(kon): if a mac disappear from mac list and a link with this mac as src mac disappear also, is not shown on the map. @@ -37,7 +42,13 @@ export const nodesReferenceState: INodes = { lon: "-64.42315", lat: "-31.79461", }, - macs: ["14:cc:20:da:4e:ab", "14:cc:20:da:4e:ac"], + macs: [ + "14:cc:20:da:4e:ab", + "14:cc:20:da:4e:ac", + // Following macs are related to batman links + "02:ab:46:fc:3a:bd", + "02:58:47:fc:3a:bd", + ], ipv4: "192.168.1.2", ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7335", firmware_version: "1.0.1", @@ -55,7 +66,14 @@ export const nodesReferenceState: INodes = { lon: "-64.41609", lat: "-31.80461", }, - macs: ["a8:40:41:1d:f9:35", "a8:40:41:1d:f9:35"], + macs: [ + "a8:40:41:1d:f9:35", + "a8:40:41:1d:f9:35", + // Following macs are related to batman links + "02:db:d6:46:28:95", + "02:ab:46:46:28:95", + "02:58:47:46:28:95", + ], ipv4: "192.168.1.3", ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7336", firmware_version: "1.0.2", @@ -73,7 +91,14 @@ export const nodesReferenceState: INodes = { lon: "-64.43209", lat: "-31.79461", }, - macs: ["a8:40:41:1d:f9:ff", "a8:40:41:1d:f9:aa"], + macs: [ + "a8:40:41:1d:f9:ff", + "a8:40:41:1d:f9:aa", + // Following macs are related to batman links + "02:db:d6:da:4e:aa", + "02:58:47:da:4e:aa", + "02:ab:46:da:4e:aa", + ], ipv4: "192.168.1.3", ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7336", firmware_version: "1.0.2", @@ -127,7 +152,7 @@ export const linksReferenceState: IWifiLinks = { rx_rate: 240000, src_mac: "a8:40:41:1d:f9:aa", }, - ], + ] as IWifiLinkData[], author: "segundo", }, "LiMe-da4eaa": { @@ -165,7 +190,7 @@ export const linksReferenceState: IWifiLinks = { rx_rate: 162000, signal: -64, }, - ], + ] as IWifiLinkData[], author: "LiMe-da4eaa", }, "LiMe-462895": { @@ -203,11 +228,130 @@ export const linksReferenceState: IWifiLinks = { rx_rate: 135000, signal: -65, }, - ], + ] as IWifiLinkData[], author: "LiMe-462895", }, }; +export const batManReferenceState: IBatmanLinks = { + primero: { + bleachTTL: 27, + data: [ + { + hard_ifindex: 18, + last_seen_msecs: 1300, + iface: "eth0-1_250", + dst_mac: "02:db:d6:da:4e:aa", + src_mac: "02:db:d6:46:28:95", + }, + { + hard_ifindex: 26, + last_seen_msecs: 20, + iface: "wlan1-mesh_250", + dst_mac: "02:ab:46:da:4e:aa", + src_mac: "02:ab:46:46:28:95", + }, + { + hard_ifindex: 26, + last_seen_msecs: 40, + iface: "wlan1-mesh_250", + dst_mac: "02:ab:46:fc:3a:bd", + src_mac: "02:ab:46:46:28:95", + }, + { + hard_ifindex: 28, + last_seen_msecs: 1710, + iface: "wlan0-mesh_250", + dst_mac: "02:58:47:fc:3a:bd", + src_mac: "02:58:47:46:28:95", + }, + { + hard_ifindex: 28, + last_seen_msecs: 1450, + iface: "wlan0-mesh_250", + dst_mac: "02:58:47:da:4e:aa", + src_mac: "02:58:47:46:28:95", + }, + ] as IBatManLinkData[], + author: "primero", + }, + "LiMe-da4eaa": { + bleachTTL: 26, + data: [ + { + hard_ifindex: 26, + last_seen_msecs: 1670, + iface: "wlan1-mesh_250", + dst_mac: "02:ab:46:da:4e:aa", + src_mac: "02:ab:46:fc:3a:bd", + }, + { + hard_ifindex: 26, + last_seen_msecs: 1350, + iface: "wlan1-mesh_250", + dst_mac: "02:ab:46:46:28:95", + src_mac: "02:ab:46:fc:3a:bd", + }, + { + hard_ifindex: 28, + last_seen_msecs: 1430, + iface: "wlan0-mesh_250", + dst_mac: "02:58:47:46:28:95", + src_mac: "02:58:47:fc:3a:bd", + }, + { + hard_ifindex: 28, + last_seen_msecs: 1030, + iface: "wlan0-mesh_250", + dst_mac: "02:58:47:da:4e:aa", + src_mac: "02:58:47:fc:3a:bd", + }, + ] as IBatManLinkData[], + author: "tercero", + }, + segundo: { + bleachTTL: 28, + data: [ + { + hard_ifindex: 18, + last_seen_msecs: 1670, + src_mac: "02:db:d6:da:4e:aa", + dst_mac: "02:db:d6:46:28:95", + iface: "eth0-1_250", + }, + { + hard_ifindex: 26, + last_seen_msecs: 550, + src_mac: "02:58:47:da:4e:aa", + dst_mac: "02:58:47:46:28:95", + iface: "wlan0-mesh_250", + }, + { + hard_ifindex: 26, + last_seen_msecs: 260, + src_mac: "02:58:47:da:4e:aa", + dst_mac: "02:58:47:fc:3a:bd", + iface: "wlan0-mesh_250", + }, + { + hard_ifindex: 28, + last_seen_msecs: 340, + src_mac: "02:ab:46:da:4e:aa", + dst_mac: "02:ab:46:fc:3a:bd", + iface: "wlan1-mesh_250", + }, + { + hard_ifindex: 28, + last_seen_msecs: 550, + src_mac: "02:ab:46:da:4e:aa", + dst_mac: "02:ab:46:46:28:95", + iface: "wlan1-mesh_250", + }, + ] as IBatManLinkData[], + author: "segundo", + }, +}; + // Use the same as on the reference state deleting a specific node // const nodeName = "LiMe-462895"; const nodeName = "primero"; @@ -221,11 +365,11 @@ const macToDelete = ""; const linkToDelete = "a0:f3:c1:46:11:97"; // const linkToDelete = ""; -export const links = (): IWifiLinks => { +export const links = (type: T): ILinks => { + const data = type === "wifi" ? linksReferenceState : batManReferenceState; + // Create a deep copy of the state to avoid mutating the original object - const newState: IWifiLinks = JSON.parse( - JSON.stringify(linksReferenceState) - ); + const newState: ILinks = JSON.parse(JSON.stringify(data)); // Get source_macs from the node to be removed const source_macs_to_remove = newState[nodeName].data.map((item: any) => From 790153755316ac97a70eba909ff458219375604d Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 4 Oct 2023 16:19:12 +0200 Subject: [PATCH 075/121] chore(meshwide): implement batman errors --- .../components/FeatureDetail/LinkDetail.tsx | 10 ++++- .../src/hooks/useLocatedLinks.tsx | 10 ++++- .../src/lib/links/PointToPointLink.ts | 4 ++ .../src/lib/links/processLinkErrors.ts | 41 +++++++++++++++---- .../src/mesWideTypes.tsx | 10 ++--- 5 files changed, 59 insertions(+), 16 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx index 2a487f636..bb23b75d8 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx @@ -110,7 +110,10 @@ const SelectedLink = ({ const LinkFeatureDetail = ({ actual, reference }: LinkMapFeature) => { const [selectedLink, setSelectedLink] = useState(0); - const { errors } = usePointToPointErrors({ id: reference.id }); + const { errors } = usePointToPointErrors({ + id: reference.id, + type: reference.type, + }); const tabs = reference.links.map((link: MacToMacLink<"wifi">, i) => { return { @@ -156,7 +159,10 @@ const LinkFeatureDetail = ({ actual, reference }: LinkMapFeature) => { }; export const LinkReferenceStatus = ({ actual, reference }: LinkMapFeature) => { - const { errors } = usePointToPointErrors({ id: reference.id }); + const { errors } = usePointToPointErrors({ + id: reference.id, + type: reference.type, + }); const hasError = errors.hasErrors; diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx index 532ba58f8..a813857a7 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx @@ -77,7 +77,13 @@ export const useLocatedLinks = ({ type }: { type: LinkType }) => { return { locatedLinks, locatedLinksReference, linksLoaded, linksErrors }; }; -export const usePointToPointErrors = ({ id }: { id: PointToPointLinkId }) => { - const { linksErrors } = useLocatedLinks({ type: "wifi" }); +export const usePointToPointErrors = ({ + id, + type, +}: { + id: PointToPointLinkId; + type: LinkType; +}) => { + const { linksErrors } = useLocatedLinks({ type }); return { errors: linksErrors[id] }; }; diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts index 1b4fa1533..cc686d9f3 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts @@ -81,6 +81,10 @@ export class PontToPointLink { return allCoordinates.sort((a, b) => a - b).toString(); } + + get type(): LinkType { + return this._links[0].type; + } } /** diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts index dc4eeb067..1a0e558fc 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts @@ -1,5 +1,7 @@ import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; import { + BatmanLinkErrorCodes, + IBatManLinkData, ILinkPtoPErrors, IWifiLinkData, WifiLinkErrorCodes, @@ -40,6 +42,17 @@ const compareWifiData = (reference: IWifiLinkData, actual: IWifiLinkData) => { return errors; }; +const compareBatmanData = ( + reference: IBatManLinkData, + actual: IBatManLinkData +) => { + const errors: BatmanLinkErrorCodes[] = []; + if (actual === undefined) { + return [BatmanLinkErrorCodes.LINK_DOWN]; + } + return errors; +}; + /** * Function that receive 2 PontToPointLink and iterate over every mac to mac link and its data executing a function * to compare the wifi data. @@ -81,20 +94,34 @@ export const compareLinks = ({ Object.entries(macToMacReference.data).forEach( ([nodeNameReference, wifiDataReference]) => { const wifiDataActual = macToMacActual?.data[nodeNameReference]; - const wifiErrors = compareWifiData( - wifiDataReference as IWifiLinkData, - wifiDataActual as IWifiLinkData - ); + const errors = + referenceLink.type === "wifi" + ? compareWifiData( + wifiDataReference as IWifiLinkData, + wifiDataActual as IWifiLinkData + ) + : compareBatmanData( + wifiDataReference as IBatManLinkData, + wifiDataActual as IBatManLinkData + ); ptoPErrors.macToMacErrors[macToMacReference.id].linkErrors[ nodeNameReference - ] = wifiErrors; - if (wifiErrors.length) { + ] = errors; + if (errors.length) { ptoPErrors.macToMacErrors[macToMacReference.id].hasErrors = true; ptoPErrors.hasErrors = true; } - if (wifiErrors.includes(WifiLinkErrorCodes.LINK_DOWN)) + if ( + (errors as WifiLinkErrorCodes[]).includes( + WifiLinkErrorCodes.LINK_DOWN + ) || + (errors as BatmanLinkErrorCodes[]).includes( + BatmanLinkErrorCodes.LINK_DOWN + ) + ) { setLinkIsDown(); + } } ); }); diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index 58a399b38..76805c6fb 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -86,10 +86,6 @@ export interface INodeInfo { }; } -export type INamedNodeInfo = { - name: string; -} & INodeInfo; - export type INodes = { [key: string]: INodeInfo }; export type LinkMapFeature = { @@ -134,6 +130,10 @@ export enum WifiLinkErrorCodes { CHAIN_LOSS = "CHAIN_LOSS", } +export enum BatmanLinkErrorCodes { + LINK_DOWN = "LINK_DOWN", +} + export enum NodeErrorCodes { NODE_DOWN = "NODE_DOWN", MACS_MISSMATCH = "MACS_MISSMATCH", @@ -144,7 +144,7 @@ export enum NodeErrorCodes { */ export type ILinkMtoMErrors = { linkErrors: { - [nodeName: string]: WifiLinkErrorCodes[]; + [nodeName: string]: WifiLinkErrorCodes[] | BatmanLinkErrorCodes[]; }; hasErrors: boolean; linkUp: boolean; From 083a70ae2db5d39e9fecc2d201c6f625b39af340 Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 5 Oct 2023 17:04:48 +0200 Subject: [PATCH 076/121] chore(meshwide): implement batman links visualization --- .../components/FeatureDetail/LinkDetail.tsx | 191 +++++++++++------- .../Map/{WifiLinkLine.tsx => LinkLine.tsx} | 11 +- .../src/containers/Map.tsx | 10 +- .../src/containers/MapLayers/LinksLayers.tsx | 15 +- 4 files changed, 136 insertions(+), 91 deletions(-) rename plugins/lime-plugin-mesh-wide/src/components/Map/{WifiLinkLine.tsx => LinkLine.tsx} (85%) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx index bb23b75d8..798e1daf8 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx @@ -12,18 +12,106 @@ import { PowerIcon } from "plugins/lime-plugin-mesh-wide/src/icons/power"; import { MacToMacLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; import { readableBytes } from "plugins/lime-plugin-mesh-wide/src/lib/utils"; import { + BaseMacToMacLink, + BatmanLinkErrorCodes, + IBatManLinkData, ILinkMtoMErrors, + IWifiLinkData, LinkMapFeature, WifiLinkErrorCodes, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; import { Row, TitleAndText } from "./index"; +const BatmanDetail = ({ + name, + errorsArray, + node, +}: { + name: string; + errorsArray: BatmanLinkErrorCodes[]; + node: IBatManLinkData; +}) => { + return ( + <> + +
+ {name}{" "} + {errorsArray.length > 0 && } +
+
+ + Iface
}> + {node?.iface} + + Last seen}> + <>{node?.last_seen_msecs} ms + + + + ); +}; + +const WifiDetail = ({ + name, + errorsArray, + node, +}: { + name: string; + errorsArray: WifiLinkErrorCodes[]; + node: IWifiLinkData; +}) => { + return ( +
+ +
+ {name}{" "} + {errorsArray.length > 0 && } +
+
+ + Signal} + error={ + errorsArray.includes(WifiLinkErrorCodes.SIGNAL_LOSS) ? ( + + The signal is X below the reference state + + ) : null + } + > + {node?.signal?.toString() ?? "0"} + + Chains} + error={ + errorsArray.includes(WifiLinkErrorCodes.CHAIN_LOSS) ? ( + + The difference between chains is too big + + ) : null + } + > + {node?.chains?.toString() ?? "0/0"} + + + + TxRate}> + {`${readableBytes(node.tx_rate)}`} + + RxRate}> + {`${readableBytes(node.rx_rate)}`} + + +
+ ); +}; + const SelectedLink = ({ linkDetail, errors, }: { - linkDetail: MacToMacLink<"wifi">; + linkDetail: BaseMacToMacLink; errors: ILinkMtoMErrors; }) => { if (linkDetail === undefined || !errors.linkUp) @@ -34,6 +122,7 @@ const SelectedLink = ({ ); const names = linkDetail?.names; + const linkType = linkDetail.type; return ( <> @@ -53,55 +142,20 @@ const SelectedLink = ({ {names.map((name, i) => { const node = linkDetail.linkByName(name); const errorsArray = errors.linkErrors[name]; - return ( -
- -
- {name}{" "} - {errorsArray.length > 0 && } -
-
- - Signal} - error={ - errorsArray.includes( - WifiLinkErrorCodes.SIGNAL_LOSS - ) ? ( - - The signal is X below the reference - state - - ) : null - } - > - {node?.signal?.toString() ?? "0"} - - Chains} - error={ - errorsArray.includes( - WifiLinkErrorCodes.CHAIN_LOSS - ) ? ( - - The difference between chains is too - big - - ) : null - } - > - {node?.chains?.toString() ?? "0/0"} - - - - TxRate}> - {`${readableBytes(node.tx_rate)}`} - - RxRate}> - {`${readableBytes(node.rx_rate)}`} - - -
+ return linkType === "wifi" ? ( + + ) : ( + ); })} @@ -114,22 +168,25 @@ const LinkFeatureDetail = ({ actual, reference }: LinkMapFeature) => { id: reference.id, type: reference.type, }); + const linkType = reference.type; - const tabs = reference.links.map((link: MacToMacLink<"wifi">, i) => { - return { - key: i, - repr: ( -
- - Link {i + 1}{" "} - {errors.macToMacErrors[link.id].hasErrors ? ( - - ) : null} - -
- ), - }; - }); + const tabs = reference.links.map( + (link: MacToMacLink, i) => { + return { + key: i, + repr: ( +
+ + Link {i + 1}{" "} + {errors.macToMacErrors[link.id].hasErrors ? ( + + ) : null} + +
+ ), + }; + } + ); return ( <> @@ -143,9 +200,7 @@ const LinkFeatureDetail = ({ actual, reference }: LinkMapFeature) => { )} {selectedLink !== null && ( - } + linkDetail={actual?.links[selectedLink]} errors={ errors.macToMacErrors[ actual?.links[selectedLink]?.id diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/WifiLinkLine.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx similarity index 85% rename from plugins/lime-plugin-mesh-wide/src/components/Map/WifiLinkLine.tsx rename to plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx index ceee14daa..d1216290d 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/WifiLinkLine.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx @@ -10,14 +10,15 @@ interface ILinkLineProps { actualLink: PontToPointLink | undefined; } -export const WifiLinkLine = ({ referenceLink, actualLink }: ILinkLineProps) => { +export const LinkLine = ({ referenceLink, actualLink }: ILinkLineProps) => { + const type = referenceLink.type; const { data: selectedMapFeature, setData: setSelectedMapFeature } = useSelectedMapFeature(); const isSelected = selectedMapFeature?.id === referenceLink.id; - const { linksErrors } = useLocatedLinks({ type: "wifi" }); + const { linksErrors } = useLocatedLinks({ type }); - const hasError = linksErrors[referenceLink.id]?.hasErrors || false; - const linkUp = linksErrors[referenceLink.id]?.linkUp || true; + const hasError = linksErrors[referenceLink.id]?.hasErrors ?? false; + const linkUp = linksErrors[referenceLink.id]?.linkUp ?? true; const _setSelectedFeature = () => { setSelectedMapFeature({ @@ -60,4 +61,4 @@ export const WifiLinkLine = ({ referenceLink, actualLink }: ILinkLineProps) => { ); }; -export default WifiLinkLine; +export default LinkLine; diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx index fb7dfb576..c6875c8da 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx @@ -54,6 +54,11 @@ export const MeshWideMap = () => { url={openStreetMapTileString} /> + + + + + @@ -64,11 +69,6 @@ export const MeshWideMap = () => { - - - - - diff --git a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx index ae0b69fdb..409eac78b 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx @@ -1,27 +1,18 @@ -import { ComponentType } from "preact"; - -import WifiLinkLine from "plugins/lime-plugin-mesh-wide/src/components/Map/WifiLinkLine"; +import LinkLine from "plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine"; import { useLocatedLinks } from "plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks"; import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; import { LocatedLinkData } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; -interface ILinkComponentProps { - referenceLink: PontToPointLink; - actualLink: PontToPointLink | undefined; -} - interface ILinksLayerProps { links: LocatedLinkData; linksReference: LocatedLinkData; linksLoaded: boolean; - LinkComponent: ComponentType; } const LinksLayer = ({ links, linksReference, linksLoaded, - LinkComponent, }: ILinksLayerProps) => { return ( <> @@ -34,7 +25,7 @@ const LinksLayer = ({ ); } return ( - { links={locatedLinks} linksReference={locatedLinksReference} linksLoaded={linksLoaded} - LinkComponent={WifiLinkLine} />
); @@ -71,7 +61,6 @@ export const BatmanLinksLayer = () => { links={locatedLinks} linksReference={locatedLinksReference} linksLoaded={linksLoaded} - LinkComponent={WifiLinkLine} />
); From 045fbbad057a7669997b5a85240183566fab64ae Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 5 Oct 2023 17:06:37 +0200 Subject: [PATCH 077/121] chore(meshwide): fix mocks --- .../lime-plugin-mesh-wide/src/meshWideMocks.tsx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx index 8193df20b..10d962a42 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx @@ -371,13 +371,16 @@ export const links = (type: T): ILinks => { // Create a deep copy of the state to avoid mutating the original object const newState: ILinks = JSON.parse(JSON.stringify(data)); - // Get source_macs from the node to be removed - const source_macs_to_remove = newState[nodeName].data.map((item: any) => - item.src_mac.toLowerCase() - ); + let source_macs_to_remove = []; + if (nodeName) { + // Get source_macs from the node to be removed + source_macs_to_remove = newState[nodeName].data.map((item: any) => + item.src_mac.toLowerCase() + ); - // Remove the specified node - delete newState[nodeName]; + // Remove the specified node + delete newState[nodeName]; + } // Remove data items with matching dest_mac in other objects Object.keys(newState).forEach((key: string) => { From 9d457e14cec806333400dca5cfc3ae937fca84e6 Mon Sep 17 00:00:00 2001 From: selankon Date: Mon, 16 Oct 2023 15:33:11 +0200 Subject: [PATCH 078/121] chore(meshwide): add tests --- jest.config.js | 3 ++ .../src/components/Map/FloatingAlert.tsx | 27 +++++++------- .../src/containers/Map.spec.tsx | 35 +++++++++++++++++++ .../src/containers/Map.tsx | 30 ++++++++++++---- .../src/containers/MapLayers/LinksLayers.tsx | 4 +-- .../src/containers/MapLayers/NodesLayer.tsx | 4 +-- .../src/mesWideTypes.tsx | 3 +- 7 files changed, 78 insertions(+), 28 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/containers/Map.spec.tsx diff --git a/jest.config.js b/jest.config.js index 822a0cd07..8cfa47396 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,6 +1,8 @@ /* eslint @typescript-eslint/no-var-requires: "off" */ const preactPreset = require("jest-preset-preact"); +const esModules = ["@react-leaflet", "react-leaflet"].join("|"); + /** @returns {Promise} */ module.exports = { preset: "jest-preset-preact", @@ -22,4 +24,5 @@ module.exports = { "^.+\\.[tj]sx?$": "babel-jest", }, clearMocks: true, + transformIgnorePatterns: [`/node_modules/(?!${esModules})`], }; diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx index 9fdde9133..75873ae7e 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx @@ -23,20 +23,17 @@ export const FloatingAlert = () => { type: "invalidNodes", feature: list, }); - }, [invalidNodesActual, invalidNodesReference]); + }, [invalidNodesActual, invalidNodesReference, setSelectedFeature]); - return ( - <> - {hasInvalidNodes ? ( -
-
- -
-
- ) : null} - - ); + return hasInvalidNodes ? ( +
+
+ +
+
+ ) : null; }; diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map.spec.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map.spec.tsx new file mode 100644 index 000000000..02824e4b4 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map.spec.tsx @@ -0,0 +1,35 @@ +import "@testing-library/jest-dom"; +// import "@testing-library/jest-dom/extend-expect"; +import { screen } from "@testing-library/preact"; + +import { MeshWideMap } from "plugins/lime-plugin-mesh-wide/src/containers/Map"; +import { + getMeshWideNodes, + getMeshWideNodesReference, +} from "plugins/lime-plugin-mesh-wide/src/mesWideApi"; +import { nodesReferenceState } from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; + +import { render } from "utils/test_utils"; + +jest.mock("plugins/lime-plugin-mesh-wide/src/mesWideApi.ts"); +jest.mock("leaflet"); +const mockedMeshWideNodes = jest.mocked(getMeshWideNodes); +const mockedMeshWideNodesReference = jest.mocked(getMeshWideNodesReference); + +describe("Map component", () => { + it("should show nodes alert when a node has not configured properly the coordinates", async () => { + nodesReferenceState["primero"].data.coordinates = { + lon: "FIXME", + lat: "FIXME", + }; + mockedMeshWideNodesReference.mockReturnValue(nodesReferenceState); + mockedMeshWideNodesReference.mockReturnValue(nodesReferenceState); + + render( + + ); + expect( + await screen.findByTestId("has-invalid-nodes") + ).toBeInTheDocument(); + }); +}); diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx index c6875c8da..868ab6034 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx @@ -20,7 +20,17 @@ const openStreetMapTileString = "https://{s}.tile.osm.org/{z}/{x}/{y}.png"; const openStreetMapAttribution = '© OpenStreetMap contributors'; -export const MeshWideMap = () => { +interface ILayersChecked { + nodes?: boolean; + wifiLinks?: boolean; + batmanLinks?: boolean; +} + +export const MeshWideMap = ({ + nodes = true, + wifiLinks = true, + batmanLinks = false, +}: ILayersChecked) => { const { data: selectedMapFeature, setData: setSelectedMapFeature } = useSelectedMapFeature(); @@ -34,10 +44,10 @@ export const MeshWideMap = () => { } }); } - }, [mapRef, selectedMapFeature]); + }, [mapRef, selectedMapFeature, setSelectedMapFeature]); return ( - <> +
{ url={openStreetMapTileString} /> - + - + - + - +
); }; diff --git a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx index 409eac78b..19bff79f4 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx @@ -15,7 +15,7 @@ const LinksLayer = ({ linksLoaded, }: ILinksLayerProps) => { return ( - <> +
{linksLoaded && Object.entries(linksReference).map((referenceLink, i) => { let actualLink: PontToPointLink; @@ -32,7 +32,7 @@ const LinksLayer = ({ /> ); })} - +
); }; diff --git a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx index 0b08b5561..0a89a6d28 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx @@ -11,7 +11,7 @@ const NodesLayer = () => { } = useNodes(); return ( - <> +
{meshWideNodesReference && Object.entries(meshWideNodesReference).map(([k, v], i) => { let actualNode: INodeInfo; @@ -27,7 +27,7 @@ const NodesLayer = () => { /> ); })} - +
); }; diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index 76805c6fb..20e027770 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -20,7 +20,7 @@ export type BaseMacToMacLink = MacToMacLink; * * Are grouped by id based on their coordinates * - * The array of classes contain an indeterminated number of links that are from certain point to another. + * The array of classes contains an indeterminated number of links that are from certain point to another. */ export type LocatedLinkData = { [key: string]: PontToPointLink; @@ -53,7 +53,6 @@ export type IBatManLinkData = { /** * List of Link info retrieved from the API */ -// export interface ILinks { export interface ILinks { [key: string]: { bleachTTL: number; From c9b6239f9949e5a4d29d3d73823eb64fa0487d2b Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 12 Dec 2023 15:52:38 +0100 Subject: [PATCH 079/121] chore(meshwide): fix test regression --- plugins/lime-plugin-mesh-wide/src/containers/Map.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx index 868ab6034..311e7136b 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx @@ -47,7 +47,7 @@ export const MeshWideMap = ({ }, [mapRef, selectedMapFeature, setSelectedMapFeature]); return ( -
+ <> -
+ ); }; From 26ea46731a3024c785ddd34bdbd55c47f96f91fa Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 26 Mar 2024 08:35:57 +0100 Subject: [PATCH 080/121] chore(meshwide): fix rebase --- tsconfig.json | 1 + 1 file changed, 1 insertion(+) diff --git a/tsconfig.json b/tsconfig.json index 33de5df08..a24c42f47 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,6 +15,7 @@ /* Module Resolution Options */ "moduleResolution": "node", + "module": "esnext", "esModuleInterop": true, "baseUrl": ".", "paths": { From 9b6f7a8ebaf7134a9e20a103ac05b984526a6006 Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 26 Mar 2024 16:27:36 +0100 Subject: [PATCH 081/121] chore(meshwide): handle error --- .../src/meshWidePage.tsx | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx index 4414bc811..8948d9500 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx @@ -1,3 +1,4 @@ +import { Trans } from "@lingui/macro"; import { route } from "preact-router"; import React from "react"; @@ -19,20 +20,27 @@ const MeshWidePage = () => { const loading = isLoadingAssets; + if (loading) { + return ( +
+ +
+ ); + } + + if (isAssetError) { + return ( +
+ Error loading leaflet +
+ ); + } + return ( <> - {loading && ( -
- -
- )} - {!loading && ( - <> - - - route("/meshwide/config")} /> - - )} + + + route("/meshwide/config")} /> ); }; From fa748cb0c893cbb4eae7cb12cf736990a3062c21 Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 26 Mar 2024 17:45:12 +0100 Subject: [PATCH 082/121] chore(meshwide): create mesh wide query keys --- .../lime-plugin-mesh-wide/src/mesWideApi.ts | 40 +++++++----------- .../src/mesWideQueries.tsx | 30 ++++++++----- .../src/mesWideQueriesKeys.tsx | 42 +++++++++++++++++++ 3 files changed, 76 insertions(+), 36 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/mesWideQueriesKeys.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts b/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts index 025ac4a0e..eb0e50ed2 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts +++ b/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts @@ -1,31 +1,21 @@ -import { - batManReferenceState, - links, - linksReferenceState, - nodes, - nodesReferenceState, -} from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; +import { meshUpgradeQueryKeys } from "plugins/lime-plugin-mesh-wide/src/mesWideQueriesKeys"; -export const getMeshWideBatmanReference = () => { - return batManReferenceState; -}; +import api from "utils/uhttpd.service"; -export const getMeshWideBatman = () => { - return links("batman"); -}; +export const getMeshWideBatmanReference = () => + api.call(...meshUpgradeQueryKeys.batHostsRef); -export const getMeshWideLinksReference = () => { - return linksReferenceState; -}; +export const getMeshWideBatman = () => + api.call(...meshUpgradeQueryKeys.batHosts); -export const getMeshWideLinks = () => { - return links("wifi"); -}; +export const getMeshWideLinksReference = () => + api.call(...meshUpgradeQueryKeys.wifiLinksInfoRef); -export const getMeshWideNodesReference = () => { - return nodesReferenceState; -}; +export const getMeshWideLinks = () => + api.call(...meshUpgradeQueryKeys.wifiLinksInfo); -export const getMeshWideNodes = () => { - return nodes(); -}; +export const getMeshWideNodesReference = () => + api.call(...meshUpgradeQueryKeys.meshWideNodesRef); + +export const getMeshWideNodes = () => + api.call(...meshUpgradeQueryKeys.meshWideNodes); diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx index e6c62c16c..e5129dd8d 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx @@ -8,6 +8,7 @@ import { getMeshWideNodes, getMeshWideNodesReference, } from "plugins/lime-plugin-mesh-wide/src/mesWideApi"; +import { meshUpgradeQueryKeys } from "plugins/lime-plugin-mesh-wide/src/mesWideQueriesKeys"; import { IBatmanLinks, IMeshWideConfig, @@ -19,10 +20,9 @@ import { getMeshWideConfig } from "plugins/lime-plugin-mesh-wide/src/meshWideMoc import { useSharedData } from "utils/useSharedData"; -// todo(kon): this is a mock export function useMeshWideLinksReference(params) { return useQuery( - ["lime-meshwide", "links_reference"], + meshUpgradeQueryKeys.wifiLinksInfoRef, getMeshWideLinksReference, { ...params, @@ -31,14 +31,18 @@ export function useMeshWideLinksReference(params) { } export function useMeshWideLinks(params) { - return useQuery(["lime-meshwide", "links"], getMeshWideLinks, { - ...params, - }); + return useQuery( + meshUpgradeQueryKeys.wifiLinksInfo, + getMeshWideLinks, + { + ...params, + } + ); } export function useMeshWideBatmanReference(params) { return useQuery( - ["lime-meshwide", "batman_reference"], + meshUpgradeQueryKeys.batHostsRef, getMeshWideBatmanReference, { ...params, @@ -48,7 +52,7 @@ export function useMeshWideBatmanReference(params) { export function useMeshWideBatman(params) { return useQuery( - ["lime-meshwide", "batman"], + meshUpgradeQueryKeys.batHosts, getMeshWideBatman, { ...params, @@ -58,7 +62,7 @@ export function useMeshWideBatman(params) { export function useMeshWideNodesReference(params) { return useQuery( - ["lime-meshwide", "nodes_reference"], + meshUpgradeQueryKeys.meshWideNodesRef, getMeshWideNodesReference, { ...params, @@ -67,9 +71,13 @@ export function useMeshWideNodesReference(params) { } export function useMeshWideNodes(params) { - return useQuery(["lime-meshwide", "nodes"], getMeshWideNodes, { - ...params, - }); + return useQuery( + meshUpgradeQueryKeys.meshWideNodes, + getMeshWideNodes, + { + ...params, + } + ); } export function useMeshWideConfig(params) { diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideQueriesKeys.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideQueriesKeys.tsx new file mode 100644 index 000000000..62fe56b7e --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/mesWideQueriesKeys.tsx @@ -0,0 +1,42 @@ +import { QueryKey } from "@tanstack/react-query"; + +interface MeshWideQueryKeysProps { + [key: string]: QueryKey; +} + +const MeshWideQueryKeys: MeshWideQueryKeysProps = { + meshWideNodes: [{ data_type: "node_info" }], + wifiLinksInfo: [{ data_type: "wifi_links_info" }], + nodesAndLinks: [{ data_type: "nodes_and_links" }], + batHosts: [{ data_type: "bat-hosts" }], +}; + +const getFromSharedState = ["shared-state", "getFromSharedState"]; +const getFromSharedStateMultiWriter = [ + "shared-state", + "getFromSharedStateMultiWriter", +]; +const getFromSharedStateAsync = ["shared-state-async", "get"]; + +export const meshUpgradeQueryKeys = { + meshWideNodes: [...getFromSharedState, ...MeshWideQueryKeys.meshWideNodes], + meshWideNodesRef: [ + ...getFromSharedStateMultiWriter, + ...MeshWideQueryKeys.meshWideNodes, + ], + wifiLinksInfo: [...getFromSharedState, ...MeshWideQueryKeys.wifiLinksInfo], + wifiLinksInfoRef: [ + ...getFromSharedStateMultiWriter, + ...MeshWideQueryKeys.wifiLinksInfo, + ], + nodesAndLinks: [...getFromSharedState, ...MeshWideQueryKeys.nodesAndLinks], + nodesAndLinksRef: [ + ...getFromSharedStateMultiWriter, + ...MeshWideQueryKeys.nodesAndLinks, + ], + batHosts: [...getFromSharedStateAsync, ...MeshWideQueryKeys.batHosts], + batHostsRef: [ + ...getFromSharedStateMultiWriter, + ...MeshWideQueryKeys.batHosts, + ], +}; From da51d5a521393df5ce8c7974719cc0dae5a60f9e Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 3 Apr 2024 15:07:51 +0200 Subject: [PATCH 083/121] chore(meshwide): fix rebase --- package-lock.json | 7984 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 6275 insertions(+), 1709 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0e84e6a09..dbe932a19 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@tanstack/react-query-devtools": "^4.6.0", "compressorjs": "^1.1.1", "history": "^5.3.0", + "leaflet": "^1.9.3", "preact": "^10.11.0", "preact-i18nline": "^2.0.0", "preact-router": "^4.1.0", @@ -20,6 +21,7 @@ "react-leaflet": "^4.2.1", "react-redux": "^8.0.4", "react-router-redux": "^4.0.8", + "react-spring": "^9.7.1", "react-use": "^17.4.0", "redux": "^4.2.0", "redux-observable": "^2.0.0", @@ -91,7 +93,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.1.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -101,119 +102,45 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", - "dev": true, + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@babel/highlight": "^7.24.2", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/code-frame/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/code-frame/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/code-frame/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/compat-data": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.1.tgz", - "integrity": "sha512-72a9ghR0gnESIa7jBN53U32FOVCEoztyIlKaNoU05zRhEecduGK9L9c3ww7Mp06JiR+0ls0GBPFJQwwtjn9ksg==", - "dev": true, + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.1.tgz", + "integrity": "sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.1.tgz", - "integrity": "sha512-1H8VgqXme4UXCRv7/Wa1bq7RVymKOzC7znjyFM8KiEzwFqcKUKYNoQef4GhdklgNvoBXyW4gYhuBNCM5o1zImw==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.0", - "@babel/helper-compilation-targets": "^7.19.1", - "@babel/helper-module-transforms": "^7.19.0", - "@babel/helpers": "^7.19.0", - "@babel/parser": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0", - "convert-source-map": "^1.7.0", + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.3.tgz", + "integrity": "sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.2", + "@babel/generator": "^7.24.1", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.24.1", + "@babel/parser": "^7.24.1", + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.1", + "@babel/types": "^7.24.0", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -223,11 +150,15 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -269,14 +200,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", - "dev": true, + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.1.tgz", + "integrity": "sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==", "dependencies": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", + "@babel/types": "^7.24.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" }, "engines": { @@ -284,26 +214,24 @@ } }, "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", - "dev": true, + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -313,7 +241,6 @@ "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", - "dev": true, "dependencies": { "@babel/helper-explode-assignable-expression": "^7.18.6", "@babel/types": "^7.18.9" @@ -323,45 +250,55 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.1.tgz", - "integrity": "sha512-LlLkkqhCMyz2lkQPvJNdIYU7O5YjWRgC2R4omjCTpZd8u8KMQzZvX4qce+/BluN1rcQiV7BoGUpmQ0LeHerbhg==", - "dev": true, + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", "dependencies": { - "@babel/compat-data": "^7.19.1", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": { + "yallist": "^3.0.2" } }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "bin": { "semver": "bin/semver.js" } }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz", - "integrity": "sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw==", - "dev": true, + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.1.tgz", + "integrity": "sha512-1yJa9dX9g//V6fDebXoEfEsxkZHk3Hcbm+zLhyu6qVgYFLvmTALTeV+jNU9e5RnYtioBrGEOdoI2joMSNQ/+aA==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.9", - "@babel/helper-split-export-declaration": "^7.18.6" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.24.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -370,11 +307,18 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/helper-create-regexp-features-plugin": { "version": "7.19.0", "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==", - "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "regexpu-core": "^5.1.0" @@ -390,7 +334,6 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", - "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.17.7", "@babel/helper-plugin-utils": "^7.16.7", @@ -407,7 +350,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -416,7 +358,6 @@ "version": "7.22.20", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -425,7 +366,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", - "dev": true, "dependencies": { "@babel/types": "^7.18.6" }, @@ -437,7 +377,6 @@ "version": "7.23.0", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dev": true, "dependencies": { "@babel/template": "^7.22.15", "@babel/types": "^7.23.0" @@ -450,7 +389,6 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dev": true, "dependencies": { "@babel/types": "^7.22.5" }, @@ -459,79 +397,72 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", - "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", - "dev": true, + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", "dependencies": { - "@babel/types": "^7.18.9" + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", - "dev": true, + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", + "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.24.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", - "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==", - "dev": true, + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.18.6", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", - "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", - "dev": true, + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", - "dev": true, + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", + "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", - "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", - "dev": true, + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-wrap-function": "^7.18.9", - "@babel/types": "^7.18.9" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" }, "engines": { "node": ">=6.9.0" @@ -541,40 +472,38 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", - "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", - "dev": true, + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz", + "integrity": "sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==", "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", - "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", - "dev": true, + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz", - "integrity": "sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==", - "dev": true, + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", "dependencies": { - "@babel/types": "^7.18.9" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -584,7 +513,6 @@ "version": "7.22.6", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "dev": true, "dependencies": { "@babel/types": "^7.22.5" }, @@ -596,7 +524,6 @@ "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -605,7 +532,6 @@ "version": "7.22.20", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -614,49 +540,45 @@ "version": "7.23.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", - "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", - "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==", - "dev": true, + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", "dependencies": { - "@babel/helper-function-name": "^7.19.0", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.0.tgz", - "integrity": "sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==", - "dev": true, + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.1.tgz", + "integrity": "sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg==", "dependencies": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.1", + "@babel/types": "^7.24.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", - "dev": true, + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" @@ -666,7 +588,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -678,7 +599,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -692,7 +612,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -700,14 +619,12 @@ "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, "engines": { "node": ">=0.8.0" } @@ -716,7 +633,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, "engines": { "node": ">=4" } @@ -725,7 +641,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -734,10 +649,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", - "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", - "dev": true, + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", + "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==", "bin": { "parser": "bin/babel-parser.js" }, @@ -749,7 +663,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -764,7 +677,6 @@ "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.9", "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", @@ -781,7 +693,6 @@ "version": "7.19.1", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.1.tgz", "integrity": "sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q==", - "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-plugin-utils": "^7.19.0", @@ -799,7 +710,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "dev": true, "dependencies": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -815,7 +725,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", - "dev": true, "dependencies": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6", @@ -851,7 +760,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-dynamic-import": "^7.8.3" @@ -867,7 +775,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.23.3.tgz", "integrity": "sha512-Q23MpLZfSGZL1kU7fWqV262q65svLSCIP5kZ/JCW/rKTCm/FrLjpvEd2kfUYMVeHh4QhV/xzyoRAHWrAZJrE3Q==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-export-default-from": "^7.23.3" @@ -883,7 +790,6 @@ "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.9", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" @@ -899,7 +805,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-json-strings": "^7.8.3" @@ -915,7 +820,6 @@ "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.9", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" @@ -931,7 +835,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" @@ -947,7 +850,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-numeric-separator": "^7.10.4" @@ -960,16 +862,16 @@ } }, "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz", - "integrity": "sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q==", - "dev": true, + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", + "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.", "dependencies": { - "@babel/compat-data": "^7.18.8", - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9", + "@babel/compat-data": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.18.8" + "@babel/plugin-transform-parameters": "^7.20.7" }, "engines": { "node": ">=6.9.0" @@ -982,7 +884,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" @@ -995,13 +896,13 @@ } }, "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", - "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", - "dev": true, + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "engines": { @@ -1015,7 +916,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", - "dev": true, "dependencies": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -1031,7 +931,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", - "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-create-class-features-plugin": "^7.18.6", @@ -1049,7 +948,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", - "dev": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -1065,7 +963,6 @@ "version": "7.8.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1089,7 +986,6 @@ "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, @@ -1101,7 +997,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -1131,7 +1026,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1143,7 +1037,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.23.3.tgz", "integrity": "sha512-KeENO5ck1IeZ/l2lFZNy+mpobV3D2Zy5C1YFnWm+YuY5mQiAWc4yAp13dqgguwsBsFVLh4LPCEqCa5qW13N+hw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1158,7 +1051,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.3" }, @@ -1170,7 +1062,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.23.3.tgz", "integrity": "sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1185,7 +1076,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz", "integrity": "sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -1212,7 +1102,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1224,7 +1113,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -1239,7 +1127,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -1251,7 +1138,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1263,7 +1149,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -1275,7 +1160,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1287,7 +1171,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1299,7 +1182,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -1311,7 +1193,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -1326,7 +1207,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -1341,7 +1221,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -1356,7 +1235,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -1368,14 +1246,13 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", - "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", - "dev": true, + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.1.tgz", + "integrity": "sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==", "dependencies": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-remap-async-to-generator": "^7.18.6" + "@babel/helper-module-imports": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-remap-async-to-generator": "^7.22.20" }, "engines": { "node": ">=6.9.0" @@ -1388,7 +1265,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -1403,7 +1279,6 @@ "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz", "integrity": "sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.9" }, @@ -1418,7 +1293,6 @@ "version": "7.19.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz", "integrity": "sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A==", - "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-compilation-targets": "^7.19.0", @@ -1441,7 +1315,6 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, "engines": { "node": ">=4" } @@ -1450,7 +1323,6 @@ "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.9" }, @@ -1462,12 +1334,11 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.13.tgz", - "integrity": "sha512-TodpQ29XekIsex2A+YJPj5ax2plkGa8YYY6mFjCohk/IG9IY42Rtuj1FuDeemfg2ipxIFLzPeA83SIBnlhSIow==", - "dev": true, + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.1.tgz", + "integrity": "sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1480,7 +1351,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", - "dev": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -1496,7 +1366,6 @@ "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.9" }, @@ -1511,7 +1380,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", - "dev": true, "dependencies": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -1527,7 +1395,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.23.3.tgz", "integrity": "sha512-26/pQTf9nQSNVJCrLB1IkHUKyPxR+lMrH2QDPG89+Znu9rAMbtrybdbWeE9bb7gzjmE5iXHEY+e0HUwM6Co93Q==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-flow": "^7.23.3" @@ -1543,7 +1410,6 @@ "version": "7.18.8", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -1558,7 +1424,6 @@ "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", - "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.18.9", "@babel/helper-function-name": "^7.18.9", @@ -1575,7 +1440,6 @@ "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.9" }, @@ -1590,7 +1454,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -1605,7 +1468,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz", "integrity": "sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg==", - "dev": true, "dependencies": { "@babel/helper-module-transforms": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6", @@ -1622,7 +1484,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz", "integrity": "sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q==", - "dev": true, "dependencies": { "@babel/helper-module-transforms": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6", @@ -1640,7 +1501,6 @@ "version": "7.19.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.0.tgz", "integrity": "sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A==", - "dev": true, "dependencies": { "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-module-transforms": "^7.19.0", @@ -1659,7 +1519,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", - "dev": true, "dependencies": { "@babel/helper-module-transforms": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -1675,7 +1534,6 @@ "version": "7.19.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", "integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==", - "dev": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.19.0", "@babel/helper-plugin-utils": "^7.19.0" @@ -1691,7 +1549,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -1721,7 +1578,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/helper-replace-supers": "^7.18.6" @@ -1734,12 +1590,45 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz", - "integrity": "sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg==", - "dev": true, + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.1.tgz", + "integrity": "sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz", + "integrity": "sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==", + "peer": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.1.tgz", + "integrity": "sha512-pTHxDVa0BpUbvAgX3Gat+7cSciXqUcY9j2VZKTbSB6+VQGpNgNO9ailxTGHSXlqOnX1Hcx1Enme2+yv7VqP9bg==", + "peer": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { "node": ">=6.9.0" @@ -1752,7 +1641,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -1767,7 +1655,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz", "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -1782,7 +1669,6 @@ "version": "7.19.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz", "integrity": "sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==", - "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-module-imports": "^7.18.6", @@ -1812,6 +1698,36 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.1.tgz", + "integrity": "sha512-kDJgnPujTmAZ/9q2CN4m2/lRsUUPDvsG3+tSHWUJIzMGTt5U/b/fwWd3RO3n+5mjLrsBrVa5eKFRVSQbi3dF1w==", + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.1.tgz", + "integrity": "sha512-1v202n7aUq4uXAieRTKcwPzNyphlCuqHHDcdSNc+vdhoTEZcFMh+L5yZuCmGaIO7bs1nJUNfHB89TZyoL48xNA==", + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-react-pure-annotations": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz", @@ -1832,7 +1748,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "regenerator-transform": "^0.15.0" @@ -1848,7 +1763,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -1859,11 +1773,94 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.3.tgz", + "integrity": "sha512-J0BuRPNlNqlMTRJ72eVptpt9VcInbxO6iP3jaxr+1NPhC0UkKL+6oeX6VXMEYdADnuqmMmsBspt4d5w8Y/TCbQ==", + "peer": true, + "dependencies": { + "@babel/helper-module-imports": "^7.24.3", + "@babel/helper-plugin-utils": "^7.24.0", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.1", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz", + "integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==", + "peer": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz", + "integrity": "sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==", + "peer": true, + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.1", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", + "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", + "peer": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.1", + "core-js-compat": "^3.36.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.1.tgz", + "integrity": "sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g==", + "peer": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/plugin-transform-shorthand-properties": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -1878,7 +1875,6 @@ "version": "7.19.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.19.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" @@ -1894,7 +1890,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -1909,7 +1904,6 @@ "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.9" }, @@ -1924,7 +1918,6 @@ "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.9" }, @@ -1939,7 +1932,6 @@ "version": "7.19.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.19.1.tgz", "integrity": "sha512-+ILcOU+6mWLlvCwnL920m2Ow3wWx3Wo8n2t5aROQmV55GZt+hOiLvBaa3DNzRjSEHa1aauRs4/YLmkCfFkhhRQ==", - "dev": true, "dependencies": { "@babel/helper-create-class-features-plugin": "^7.19.0", "@babel/helper-plugin-utils": "^7.19.0", @@ -1956,7 +1948,6 @@ "version": "7.18.10", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.9" }, @@ -1971,7 +1962,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", - "dev": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -1987,7 +1977,6 @@ "version": "7.19.1", "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.19.1.tgz", "integrity": "sha512-c8B2c6D16Lp+Nt6HcD+nHl0VbPKVnNPTpszahuxJJnurfMtKeZ80A+qUv48Y7wqvS+dTFuLuaM9oYxyNHbCLWA==", - "dev": true, "dependencies": { "@babel/compat-data": "^7.19.1", "@babel/helper-compilation-targets": "^7.19.1", @@ -2076,7 +2065,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -2085,7 +2073,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.23.3.tgz", "integrity": "sha512-7yn6hl8RIv+KNk6iIrGZ+D06VhVY35wLVf23Cz/mMu1zOr7u4MMP4j0nZ9tLf8+4ZFpnib8cFYgB/oYg9hfswA==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-option": "^7.22.15", @@ -2102,7 +2089,6 @@ "version": "0.1.5", "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", @@ -2138,7 +2124,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz", "integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==", - "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/helper-validator-option": "^7.18.6", @@ -2155,7 +2140,6 @@ "version": "7.23.7", "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.23.7.tgz", "integrity": "sha512-EjJeB6+kvpk+Y5DAkEAmbOBEFkh9OASx0huoEkqYTFxAZHzOAX2Oh5uwAUuL2rUddqfM0SA+KPXV2TbzoZ2kvQ==", - "dev": true, "dependencies": { "clone-deep": "^4.0.1", "find-cache-dir": "^2.0.0", @@ -2174,7 +2158,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, "dependencies": { "commondir": "^1.0.1", "make-dir": "^2.0.0", @@ -2188,7 +2171,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, "dependencies": { "locate-path": "^3.0.0" }, @@ -2200,7 +2182,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" @@ -2213,7 +2194,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, "dependencies": { "pify": "^4.0.1", "semver": "^5.6.0" @@ -2226,7 +2206,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, "dependencies": { "p-try": "^2.0.0" }, @@ -2241,7 +2220,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, "dependencies": { "p-limit": "^2.0.0" }, @@ -2253,7 +2231,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, "engines": { "node": ">=4" } @@ -2262,7 +2239,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, "engines": { "node": ">=6" } @@ -2271,7 +2247,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, "dependencies": { "find-up": "^3.0.0" }, @@ -2283,7 +2258,6 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, "bin": { "semver": "bin/semver" } @@ -2300,33 +2274,31 @@ } }, "node_modules/@babel/template": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz", - "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==", - "dev": true, + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", + "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", "dependencies": { "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9" + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz", - "integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==", - "dev": true, + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", + "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", + "@babel/code-frame": "^7.24.1", + "@babel/generator": "^7.24.1", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9", + "@babel/parser": "^7.24.1", + "@babel/types": "^7.24.0", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -2338,16 +2310,14 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, "engines": { "node": ">=4" } }, "node_modules/@babel/types": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz", - "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==", - "dev": true, + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", "dependencies": { "@babel/helper-string-parser": "^7.23.4", "@babel/helper-validator-identifier": "^7.22.20", @@ -2445,6 +2415,21 @@ "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", "dev": true }, + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", + "peer": true + }, + "node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "peer": true, + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.10.5", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.5.tgz", @@ -2497,6 +2482,15 @@ "node": ">=6.9.0" } }, + "node_modules/@isaacs/ttlcache": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@isaacs/ttlcache/-/ttlcache-1.4.1.tgz", + "integrity": "sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==", + "peer": true, + "engines": { + "node": ">=12" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -2857,6 +2851,18 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, + "node_modules/@jest/create-cache-key-function": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz", + "integrity": "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==", + "peer": true, + "dependencies": { + "@jest/types": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/@jest/environment": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", @@ -3261,12 +3267,11 @@ } }, "node_modules/@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", - "dev": true, + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dependencies": { - "@sinclair/typebox": "^0.25.16" + "@sinclair/typebox": "^0.27.8" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -3410,12 +3415,11 @@ } }, "node_modules/@jest/types": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", - "dev": true, + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dependencies": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -3430,7 +3434,6 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, "dependencies": { "@jridgewell/set-array": "^1.0.0", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -3443,16 +3446,14 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "engines": { "node": ">=6.0.0" } @@ -3461,7 +3462,6 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", - "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -3471,7 +3471,6 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -3484,14 +3483,12 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", - "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", - "dev": true, + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -4172,6 +4169,999 @@ "react-dom": "^18.0.0" } }, + "node_modules/@react-native-community/cli": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-12.3.6.tgz", + "integrity": "sha512-647OSi6xBb8FbwFqX9zsJxOzu685AWtrOUWHfOkbKD+5LOpGORw+GQo0F9rWZnB68rLQyfKUZWJeaD00pGv5fw==", + "peer": true, + "dependencies": { + "@react-native-community/cli-clean": "12.3.6", + "@react-native-community/cli-config": "12.3.6", + "@react-native-community/cli-debugger-ui": "12.3.6", + "@react-native-community/cli-doctor": "12.3.6", + "@react-native-community/cli-hermes": "12.3.6", + "@react-native-community/cli-plugin-metro": "12.3.6", + "@react-native-community/cli-server-api": "12.3.6", + "@react-native-community/cli-tools": "12.3.6", + "@react-native-community/cli-types": "12.3.6", + "chalk": "^4.1.2", + "commander": "^9.4.1", + "deepmerge": "^4.3.0", + "execa": "^5.0.0", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "graceful-fs": "^4.1.3", + "prompts": "^2.4.2", + "semver": "^7.5.2" + }, + "bin": { + "react-native": "build/bin.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@react-native-community/cli-clean": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-clean/-/cli-clean-12.3.6.tgz", + "integrity": "sha512-gUU29ep8xM0BbnZjwz9MyID74KKwutq9x5iv4BCr2im6nly4UMf1B1D+V225wR7VcDGzbgWjaezsJShLLhC5ig==", + "peer": true, + "dependencies": { + "@react-native-community/cli-tools": "12.3.6", + "chalk": "^4.1.2", + "execa": "^5.0.0" + } + }, + "node_modules/@react-native-community/cli-config": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-config/-/cli-config-12.3.6.tgz", + "integrity": "sha512-JGWSYQ9EAK6m2v0abXwFLEfsqJ1zkhzZ4CV261QZF9MoUNB6h57a274h1MLQR9mG6Tsh38wBUuNfEPUvS1vYew==", + "peer": true, + "dependencies": { + "@react-native-community/cli-tools": "12.3.6", + "chalk": "^4.1.2", + "cosmiconfig": "^5.1.0", + "deepmerge": "^4.3.0", + "glob": "^7.1.3", + "joi": "^17.2.1" + } + }, + "node_modules/@react-native-community/cli-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "peer": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@react-native-community/cli-config/node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "peer": true, + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@react-native-community/cli-config/node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", + "peer": true, + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@react-native-community/cli-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "peer": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@react-native-community/cli-config/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "peer": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@react-native-community/cli-config/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@react-native-community/cli-debugger-ui": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-12.3.6.tgz", + "integrity": "sha512-SjUKKsx5FmcK9G6Pb6UBFT0s9JexVStK5WInmANw75Hm7YokVvHEgtprQDz2Uvy5znX5g2ujzrkIU//T15KQzA==", + "peer": true, + "dependencies": { + "serve-static": "^1.13.1" + } + }, + "node_modules/@react-native-community/cli-doctor": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-doctor/-/cli-doctor-12.3.6.tgz", + "integrity": "sha512-fvBDv2lTthfw4WOQKkdTop2PlE9GtfrlNnpjB818MhcdEnPjfQw5YaTUcnNEGsvGomdCs1MVRMgYXXwPSN6OvQ==", + "peer": true, + "dependencies": { + "@react-native-community/cli-config": "12.3.6", + "@react-native-community/cli-platform-android": "12.3.6", + "@react-native-community/cli-platform-ios": "12.3.6", + "@react-native-community/cli-tools": "12.3.6", + "chalk": "^4.1.2", + "command-exists": "^1.2.8", + "deepmerge": "^4.3.0", + "envinfo": "^7.10.0", + "execa": "^5.0.0", + "hermes-profile-transformer": "^0.0.6", + "node-stream-zip": "^1.9.1", + "ora": "^5.4.1", + "semver": "^7.5.2", + "strip-ansi": "^5.2.0", + "wcwidth": "^1.0.1", + "yaml": "^2.2.1" + } + }, + "node_modules/@react-native-community/cli-doctor/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@react-native-community/cli-doctor/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "peer": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@react-native-community/cli-doctor/node_modules/yaml": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", + "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", + "peer": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@react-native-community/cli-hermes": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-hermes/-/cli-hermes-12.3.6.tgz", + "integrity": "sha512-sNGwfOCl8OAIjWCkwuLpP8NZbuO0dhDI/2W7NeOGDzIBsf4/c4MptTrULWtGIH9okVPLSPX0NnRyGQ+mSwWyuQ==", + "peer": true, + "dependencies": { + "@react-native-community/cli-platform-android": "12.3.6", + "@react-native-community/cli-tools": "12.3.6", + "chalk": "^4.1.2", + "hermes-profile-transformer": "^0.0.6" + } + }, + "node_modules/@react-native-community/cli-platform-android": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-12.3.6.tgz", + "integrity": "sha512-DeDDAB8lHpuGIAPXeeD9Qu2+/wDTFPo99c8uSW49L0hkmZJixzvvvffbGQAYk32H0TmaI7rzvzH+qzu7z3891g==", + "peer": true, + "dependencies": { + "@react-native-community/cli-tools": "12.3.6", + "chalk": "^4.1.2", + "execa": "^5.0.0", + "fast-xml-parser": "^4.2.4", + "glob": "^7.1.3", + "logkitty": "^0.7.1" + } + }, + "node_modules/@react-native-community/cli-platform-ios": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-ios/-/cli-platform-ios-12.3.6.tgz", + "integrity": "sha512-3eZ0jMCkKUO58wzPWlvAPRqezVKm9EPZyaPyHbRPWU8qw7JqkvnRlWIaYDGpjCJgVW4k2hKsEursLtYKb188tg==", + "peer": true, + "dependencies": { + "@react-native-community/cli-tools": "12.3.6", + "chalk": "^4.1.2", + "execa": "^5.0.0", + "fast-xml-parser": "^4.0.12", + "glob": "^7.1.3", + "ora": "^5.4.1" + } + }, + "node_modules/@react-native-community/cli-plugin-metro": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-12.3.6.tgz", + "integrity": "sha512-3jxSBQt4fkS+KtHCPSyB5auIT+KKIrPCv9Dk14FbvOaEh9erUWEm/5PZWmtboW1z7CYeNbFMeXm9fM2xwtVOpg==", + "peer": true + }, + "node_modules/@react-native-community/cli-server-api": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-server-api/-/cli-server-api-12.3.6.tgz", + "integrity": "sha512-80NIMzo8b2W+PL0Jd7NjiJW9mgaT8Y8wsIT/lh6mAvYH7mK0ecDJUYUTAAv79Tbo1iCGPAr3T295DlVtS8s4yQ==", + "peer": true, + "dependencies": { + "@react-native-community/cli-debugger-ui": "12.3.6", + "@react-native-community/cli-tools": "12.3.6", + "compression": "^1.7.1", + "connect": "^3.6.5", + "errorhandler": "^1.5.1", + "nocache": "^3.0.1", + "pretty-format": "^26.6.2", + "serve-static": "^1.13.1", + "ws": "^7.5.1" + } + }, + "node_modules/@react-native-community/cli-server-api/node_modules/@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "peer": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@react-native-community/cli-server-api/node_modules/@types/yargs": { + "version": "15.0.19", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.19.tgz", + "integrity": "sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA==", + "peer": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@react-native-community/cli-server-api/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "peer": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@react-native-community/cli-server-api/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "peer": true + }, + "node_modules/@react-native-community/cli-server-api/node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "peer": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@react-native-community/cli-tools": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-12.3.6.tgz", + "integrity": "sha512-FPEvZn19UTMMXUp/piwKZSh8cMEfO8G3KDtOwo53O347GTcwNrKjgZGtLSPELBX2gr+YlzEft3CoRv2Qmo83fQ==", + "peer": true, + "dependencies": { + "appdirsjs": "^1.2.4", + "chalk": "^4.1.2", + "find-up": "^5.0.0", + "mime": "^2.4.1", + "node-fetch": "^2.6.0", + "open": "^6.2.0", + "ora": "^5.4.1", + "semver": "^7.5.2", + "shell-quote": "^1.7.3", + "sudo-prompt": "^9.0.0" + } + }, + "node_modules/@react-native-community/cli-tools/node_modules/is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==", + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@react-native-community/cli-tools/node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "peer": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/@react-native-community/cli-tools/node_modules/open": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", + "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", + "peer": true, + "dependencies": { + "is-wsl": "^1.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@react-native-community/cli-types": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-types/-/cli-types-12.3.6.tgz", + "integrity": "sha512-xPqTgcUtZowQ8WKOkI9TLGBwH2bGggOC4d2FFaIRST3gTcjrEeGRNeR5aXCzJFIgItIft8sd7p2oKEdy90+01Q==", + "peer": true, + "dependencies": { + "joi": "^17.2.1" + } + }, + "node_modules/@react-native-community/cli/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "peer": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/@react-native-community/cli/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "peer": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@react-native-community/cli/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "peer": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@react-native-community/cli/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "peer": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@react-native-community/cli/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "peer": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@react-native/assets-registry": { + "version": "0.73.1", + "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.73.1.tgz", + "integrity": "sha512-2FgAbU7uKM5SbbW9QptPPZx8N9Ke2L7bsHb+EhAanZjFZunA9PaYtyjUQ1s7HD+zDVqOQIvjkpXSv7Kejd2tqg==", + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@react-native/babel-plugin-codegen": { + "version": "0.73.4", + "resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.73.4.tgz", + "integrity": "sha512-XzRd8MJGo4Zc5KsphDHBYJzS1ryOHg8I2gOZDAUCGcwLFhdyGu1zBNDJYH2GFyDrInn9TzAbRIf3d4O+eltXQQ==", + "peer": true, + "dependencies": { + "@react-native/codegen": "0.73.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@react-native/babel-preset": { + "version": "0.73.21", + "resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.73.21.tgz", + "integrity": "sha512-WlFttNnySKQMeujN09fRmrdWqh46QyJluM5jdtDNrkl/2Hx6N4XeDUGhABvConeK95OidVO7sFFf7sNebVXogA==", + "peer": true, + "dependencies": { + "@babel/core": "^7.20.0", + "@babel/plugin-proposal-async-generator-functions": "^7.0.0", + "@babel/plugin-proposal-class-properties": "^7.18.0", + "@babel/plugin-proposal-export-default-from": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.0", + "@babel/plugin-proposal-numeric-separator": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.20.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.20.0", + "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "@babel/plugin-syntax-export-default-from": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.18.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-syntax-optional-chaining": "^7.0.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-async-to-generator": "^7.20.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.20.0", + "@babel/plugin-transform-flow-strip-types": "^7.20.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-private-methods": "^7.22.5", + "@babel/plugin-transform-private-property-in-object": "^7.22.11", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-react-jsx-self": "^7.0.0", + "@babel/plugin-transform-react-jsx-source": "^7.0.0", + "@babel/plugin-transform-runtime": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-sticky-regex": "^7.0.0", + "@babel/plugin-transform-typescript": "^7.5.0", + "@babel/plugin-transform-unicode-regex": "^7.0.0", + "@babel/template": "^7.0.0", + "@react-native/babel-plugin-codegen": "0.73.4", + "babel-plugin-transform-flow-enums": "^0.0.2", + "react-refresh": "^0.14.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@babel/core": "*" + } + }, + "node_modules/@react-native/babel-preset/node_modules/react-refresh": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", + "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@react-native/codegen": { + "version": "0.73.3", + "resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.73.3.tgz", + "integrity": "sha512-sxslCAAb8kM06vGy9Jyh4TtvjhcP36k/rvj2QE2Jdhdm61KvfafCATSIsOfc0QvnduWFcpXUPvAVyYwuv7PYDg==", + "peer": true, + "dependencies": { + "@babel/parser": "^7.20.0", + "flow-parser": "^0.206.0", + "glob": "^7.1.1", + "invariant": "^2.2.4", + "jscodeshift": "^0.14.0", + "mkdirp": "^0.5.1", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@babel/preset-env": "^7.1.6" + } + }, + "node_modules/@react-native/codegen/node_modules/ast-types": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.15.2.tgz", + "integrity": "sha512-c27loCv9QkZinsa5ProX751khO9DJl/AcB5c2KNtA6NRvHKS0PgLfcftz72KVq504vB0Gku5s2kUZzDBvQWvHg==", + "peer": true, + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@react-native/codegen/node_modules/flow-parser": { + "version": "0.206.0", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.206.0.tgz", + "integrity": "sha512-HVzoK3r6Vsg+lKvlIZzaWNBVai+FXTX1wdYhz/wVlH13tb/gOdLXmlTqy6odmTBhT5UoWUbq0k8263Qhr9d88w==", + "peer": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/@react-native/codegen/node_modules/jscodeshift": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.14.0.tgz", + "integrity": "sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==", + "peer": true, + "dependencies": { + "@babel/core": "^7.13.16", + "@babel/parser": "^7.13.16", + "@babel/plugin-proposal-class-properties": "^7.13.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", + "@babel/plugin-proposal-optional-chaining": "^7.13.12", + "@babel/plugin-transform-modules-commonjs": "^7.13.8", + "@babel/preset-flow": "^7.13.13", + "@babel/preset-typescript": "^7.13.0", + "@babel/register": "^7.13.16", + "babel-core": "^7.0.0-bridge.0", + "chalk": "^4.1.2", + "flow-parser": "0.*", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.4", + "neo-async": "^2.5.0", + "node-dir": "^0.1.17", + "recast": "^0.21.0", + "temp": "^0.8.4", + "write-file-atomic": "^2.3.0" + }, + "bin": { + "jscodeshift": "bin/jscodeshift.js" + }, + "peerDependencies": { + "@babel/preset-env": "^7.1.6" + } + }, + "node_modules/@react-native/codegen/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "peer": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/@react-native/codegen/node_modules/recast": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.21.5.tgz", + "integrity": "sha512-hjMmLaUXAm1hIuTqOdeYObMslq/q+Xff6QE3Y2P+uoHAg2nmVlLBps2hzh1UJDdMtDTMXOFewK6ky51JQIeECg==", + "peer": true, + "dependencies": { + "ast-types": "0.15.2", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/@react-native/codegen/node_modules/write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "node_modules/@react-native/community-cli-plugin": { + "version": "0.73.17", + "resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.73.17.tgz", + "integrity": "sha512-F3PXZkcHg+1ARIr6FRQCQiB7ZAA+MQXGmq051metRscoLvgYJwj7dgC8pvgy0kexzUkHu5BNKrZeySzUft3xuQ==", + "peer": true, + "dependencies": { + "@react-native-community/cli-server-api": "12.3.6", + "@react-native-community/cli-tools": "12.3.6", + "@react-native/dev-middleware": "0.73.8", + "@react-native/metro-babel-transformer": "0.73.15", + "chalk": "^4.0.0", + "execa": "^5.1.1", + "metro": "^0.80.3", + "metro-config": "^0.80.3", + "metro-core": "^0.80.3", + "node-fetch": "^2.2.0", + "readline": "^1.3.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@react-native/debugger-frontend": { + "version": "0.73.3", + "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.73.3.tgz", + "integrity": "sha512-RgEKnWuoo54dh7gQhV7kvzKhXZEhpF9LlMdZolyhGxHsBqZ2gXdibfDlfcARFFifPIiaZ3lXuOVVa4ei+uPgTw==", + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@react-native/dev-middleware": { + "version": "0.73.8", + "resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.73.8.tgz", + "integrity": "sha512-oph4NamCIxkMfUL/fYtSsE+JbGOnrlawfQ0kKtDQ5xbOjPKotKoXqrs1eGwozNKv7FfQ393stk1by9a6DyASSg==", + "peer": true, + "dependencies": { + "@isaacs/ttlcache": "^1.4.1", + "@react-native/debugger-frontend": "0.73.3", + "chrome-launcher": "^0.15.2", + "chromium-edge-launcher": "^1.0.0", + "connect": "^3.6.5", + "debug": "^2.2.0", + "node-fetch": "^2.2.0", + "open": "^7.0.3", + "serve-static": "^1.13.1", + "temp-dir": "^2.0.0", + "ws": "^6.2.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@react-native/dev-middleware/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/@react-native/dev-middleware/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "peer": true + }, + "node_modules/@react-native/dev-middleware/node_modules/open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "peer": true, + "dependencies": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@react-native/gradle-plugin": { + "version": "0.73.4", + "resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.73.4.tgz", + "integrity": "sha512-PMDnbsZa+tD55Ug+W8CfqXiGoGneSSyrBZCMb5JfiB3AFST3Uj5e6lw8SgI/B6SKZF7lG0BhZ6YHZsRZ5MlXmg==", + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@react-native/js-polyfills": { + "version": "0.73.1", + "resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.73.1.tgz", + "integrity": "sha512-ewMwGcumrilnF87H4jjrnvGZEaPFCAC4ebraEK+CurDDmwST/bIicI4hrOAv+0Z0F7DEK4O4H7r8q9vH7IbN4g==", + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@react-native/metro-babel-transformer": { + "version": "0.73.15", + "resolved": "https://registry.npmjs.org/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.73.15.tgz", + "integrity": "sha512-LlkSGaXCz+xdxc9819plmpsl4P4gZndoFtpjN3GMBIu6f7TBV0GVbyJAU4GE8fuAWPVSVL5ArOcdkWKSbI1klw==", + "peer": true, + "dependencies": { + "@babel/core": "^7.20.0", + "@react-native/babel-preset": "0.73.21", + "hermes-parser": "0.15.0", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@babel/core": "*" + } + }, + "node_modules/@react-native/normalize-colors": { + "version": "0.73.2", + "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.73.2.tgz", + "integrity": "sha512-bRBcb2T+I88aG74LMVHaKms2p/T8aQd8+BZ7LuuzXlRfog1bMWWn/C5i0HVuvW4RPtXQYgIlGiXVDy9Ir1So/w==", + "peer": true + }, + "node_modules/@react-native/virtualized-lists": { + "version": "0.73.4", + "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.73.4.tgz", + "integrity": "sha512-HpmLg1FrEiDtrtAbXiwCgXFYyloK/dOIPIuWW3fsqukwJEWAiTzm1nXGJ7xPU5XTHiWZ4sKup5Ebaj8z7iyWog==", + "peer": true, + "dependencies": { + "invariant": "^2.2.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "react-native": "*" + } + }, + "node_modules/@react-spring/animated": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.3.tgz", + "integrity": "sha512-5CWeNJt9pNgyvuSzQH+uy2pvTg8Y4/OisoscZIR8/ZNLIOI+CatFBhGZpDGTF/OzdNFsAoGk3wiUYTwoJ0YIvw==", + "dependencies": { + "@react-spring/shared": "~9.7.3", + "@react-spring/types": "~9.7.3" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/core": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.3.tgz", + "integrity": "sha512-IqFdPVf3ZOC1Cx7+M0cXf4odNLxDC+n7IN3MDcVCTIOSBfqEcBebSv+vlY5AhM0zw05PDbjKrNmBpzv/AqpjnQ==", + "dependencies": { + "@react-spring/animated": "~9.7.3", + "@react-spring/shared": "~9.7.3", + "@react-spring/types": "~9.7.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-spring/donate" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/konva": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/konva/-/konva-9.7.3.tgz", + "integrity": "sha512-R9sY6SiPGYqz1383P5qppg5z57YfChVknOC1UxxaGxpw+WiZa8fZ4zmZobslrw+os3/+HAXZv8O+EvU/nQpf7g==", + "dependencies": { + "@react-spring/animated": "~9.7.3", + "@react-spring/core": "~9.7.3", + "@react-spring/shared": "~9.7.3", + "@react-spring/types": "~9.7.3" + }, + "peerDependencies": { + "konva": ">=2.6", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-konva": "^16.8.0 || ^16.8.7-0 || ^16.9.0-0 || ^16.10.1-0 || ^16.12.0-0 || ^16.13.0-0 || ^17.0.0-0 || ^17.0.1-0 || ^17.0.2-0 || ^18.0.0-0" + } + }, + "node_modules/@react-spring/native": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/native/-/native-9.7.3.tgz", + "integrity": "sha512-4mpxX3FuEBCUT6ae2fjhxcJW6bhr2FBwFf274eXB7n+U30Gdg8Wo2qYwcUnmiAA0S3dvP8vLTazx3+CYWFShnA==", + "dependencies": { + "@react-spring/animated": "~9.7.3", + "@react-spring/core": "~9.7.3", + "@react-spring/shared": "~9.7.3", + "@react-spring/types": "~9.7.3" + }, + "peerDependencies": { + "react": "^16.8.0 || >=17.0.0 || >=18.0.0", + "react-native": ">=0.58" + } + }, + "node_modules/@react-spring/shared": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.3.tgz", + "integrity": "sha512-NEopD+9S5xYyQ0pGtioacLhL2luflh6HACSSDUZOwLHoxA5eku1UPuqcJqjwSD6luKjjLfiLOspxo43FUHKKSA==", + "dependencies": { + "@react-spring/types": "~9.7.3" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/three": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/three/-/three-9.7.3.tgz", + "integrity": "sha512-Q1p512CqUlmMK8UMBF/Rj79qndhOWq4XUTayxMP9S892jiXzWQuj+xC3Xvm59DP/D4JXusXpxxqfgoH+hmOktA==", + "dependencies": { + "@react-spring/animated": "~9.7.3", + "@react-spring/core": "~9.7.3", + "@react-spring/shared": "~9.7.3", + "@react-spring/types": "~9.7.3" + }, + "peerDependencies": { + "@react-three/fiber": ">=6.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "three": ">=0.126" + } + }, + "node_modules/@react-spring/types": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.3.tgz", + "integrity": "sha512-Kpx/fQ/ZFX31OtlqVEFfgaD1ACzul4NksrvIgYfIFq9JpDHFwQkMVZ10tbo0FU/grje4rcL4EIrjekl3kYwgWw==" + }, + "node_modules/@react-spring/web": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.3.tgz", + "integrity": "sha512-BXt6BpS9aJL/QdVqEIX9YoUy8CE6TJrU0mNCqSoxdXlIeNcEBWOfIyE6B14ENNsyQKS3wOWkiJfco0tCr/9tUg==", + "dependencies": { + "@react-spring/animated": "~9.7.3", + "@react-spring/core": "~9.7.3", + "@react-spring/shared": "~9.7.3", + "@react-spring/types": "~9.7.3" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/zdog": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/zdog/-/zdog-9.7.3.tgz", + "integrity": "sha512-L+yK/1PvNi9n8cldiJ309k4LdxcPkeWE0W18l1zrP1IBIyd5NB5EPA8DMsGr9gtNnnIujtEzZk+4JIOjT8u/tw==", + "dependencies": { + "@react-spring/animated": "~9.7.3", + "@react-spring/core": "~9.7.3", + "@react-spring/shared": "~9.7.3", + "@react-spring/types": "~9.7.3" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-zdog": ">=1.0", + "zdog": ">=1.0" + } + }, + "node_modules/@react-three/fiber": { + "version": "8.16.1", + "resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-8.16.1.tgz", + "integrity": "sha512-Rgjn+xcR+6Do2Ic4b6RROIvCGs3RhoVJEamfmtMSfkgIRH3PeiPdqRxcfJlO9y6KDvYA5fIUGruz9h/sTeLlpw==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.17.8", + "@types/react-reconciler": "^0.26.7", + "@types/webxr": "*", + "base64-js": "^1.5.1", + "buffer": "^6.0.3", + "its-fine": "^1.0.6", + "react-reconciler": "^0.27.0", + "react-use-measure": "^2.1.1", + "scheduler": "^0.21.0", + "suspend-react": "^0.1.3", + "zustand": "^3.7.1" + }, + "peerDependencies": { + "expo": ">=43.0", + "expo-asset": ">=8.4", + "expo-file-system": ">=11.0", + "expo-gl": ">=11.0", + "react": ">=18.0", + "react-dom": ">=18.0", + "react-native": ">=0.64", + "three": ">=0.133" + }, + "peerDependenciesMeta": { + "expo": { + "optional": true + }, + "expo-asset": { + "optional": true + }, + "expo-file-system": { + "optional": true + }, + "expo-gl": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/@react-three/fiber/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "peer": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/@react-three/fiber/node_modules/scheduler": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", + "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0" + } + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -4245,11 +5235,31 @@ "rollup": "^1.20.0||^2.0.0" } }, + "node_modules/@sideway/address": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "peer": true, + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", + "peer": true + }, + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", + "peer": true + }, "node_modules/@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", - "dev": true + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" }, "node_modules/@sindresorhus/is": { "version": "0.14.0", @@ -8144,14 +9154,12 @@ "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==" }, "node_modules/@types/istanbul-lib-report": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "*" } @@ -8160,7 +9168,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" } @@ -8237,8 +9244,7 @@ "node_modules/@types/node": { "version": "18.7.21", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.21.tgz", - "integrity": "sha512-rLFzK5bhM0YPyCoTC8bolBjMk7bwnZ8qeZUBslBfjZQou2ssJdWslx9CZ8DGM+Dx7QXQiiTVZ/6QO6kwtHkZCA==", - "dev": true + "integrity": "sha512-rLFzK5bhM0YPyCoTC8bolBjMk7bwnZ8qeZUBslBfjZQou2ssJdWslx9CZ8DGM+Dx7QXQiiTVZ/6QO6kwtHkZCA==" }, "node_modules/@types/node-fetch": { "version": "2.6.11", @@ -8336,6 +9342,15 @@ "csstype": "^3.0.2" } }, + "node_modules/@types/react-reconciler": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.26.7.tgz", + "integrity": "sha512-mBDYl8x+oyPX/VBb3E638N0B7xG+SPk/EAMcVPeexqus/5aTpTphQi0curhhshOqRrc9t6OPoJfEUkbymse/lQ==", + "peer": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -8399,8 +9414,7 @@ "node_modules/@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" }, "node_modules/@types/tapable": { "version": "1.0.8", @@ -8483,6 +9497,12 @@ "node": ">= 8" } }, + "node_modules/@types/webxr": { + "version": "0.5.14", + "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.14.tgz", + "integrity": "sha512-UEMMm/Xn3DtEa+gpzUrOcDj+SJS1tk5YodjwOxcqStNhCfPcwgyC5Srg2ToVKyg2Fhq16Ffpb0UWUQHqoT9AMA==", + "peer": true + }, "node_modules/@types/ws": { "version": "8.5.3", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", @@ -8496,7 +9516,6 @@ "version": "17.0.13", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz", "integrity": "sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==", - "dev": true, "dependencies": { "@types/yargs-parser": "*" } @@ -8504,8 +9523,7 @@ "node_modules/@types/yargs-parser": { "version": "21.0.0", "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", - "dev": true + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "5.46.0", @@ -9336,11 +10354,22 @@ "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", "dev": true }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "peer": true, + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -9353,7 +10382,6 @@ "version": "8.8.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", - "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -9574,6 +10602,12 @@ "integrity": "sha512-0FcBfdcmaumGPQ0qPn7Q5qTgz/ooXgIyp1rf8ik5bGX8mpE2YHjC0P/eyQvxu1GURYQgq9ozf2mteQ5ZD9YiyQ==", "dev": true }, + "node_modules/anser": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz", + "integrity": "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==", + "peer": true + }, "node_modules/ansi-align": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", @@ -9619,6 +10653,103 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ansi-fragments": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ansi-fragments/-/ansi-fragments-0.2.1.tgz", + "integrity": "sha512-DykbNHxuXQwUDRv5ibc2b0x7uw7wmwOGLBUd5RmaQ5z8Lhx19vwvKV+FAsM5rEA6dEcHxX+/Ad5s9eF2k2bB+w==", + "peer": true, + "dependencies": { + "colorette": "^1.0.7", + "slice-ansi": "^2.0.0", + "strip-ansi": "^5.0.0" + } + }, + "node_modules/ansi-fragments/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-fragments/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "peer": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ansi-fragments/node_modules/astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ansi-fragments/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "peer": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/ansi-fragments/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "peer": true + }, + "node_modules/ansi-fragments/node_modules/colorette": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", + "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", + "peer": true + }, + "node_modules/ansi-fragments/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ansi-fragments/node_modules/slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "peer": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-fragments/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "peer": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", @@ -9635,7 +10766,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -9644,7 +10774,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -9674,7 +10803,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -9689,6 +10817,12 @@ "integrity": "sha512-jlpIfsOoNoafl92Sz//64uQHGSyMrD2vYG5d8o2a4qGvyNCvXur7bzIsWtAC/6flI2RYAp3kv8rsfBtaLm7w0g==", "dev": true }, + "node_modules/appdirsjs": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/appdirsjs/-/appdirsjs-1.2.7.tgz", + "integrity": "sha512-Quji6+8kLBC3NnBeo14nPDq0+2jUs5s3/xEye+udFHumHhRk4M7aAMXp/PBJqkKYGuuyR9M/6Dq7d2AViiGmhw==", + "peer": true + }, "node_modules/aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", @@ -9941,6 +11075,12 @@ "node": ">=8" } }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "peer": true + }, "node_modules/asn1": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", @@ -10056,8 +11196,7 @@ "node_modules/async-limiter": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" }, "node_modules/asynckit": { "version": "0.4.0", @@ -10235,7 +11374,6 @@ "version": "7.0.0-bridge.0", "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==", - "dev": true, "peerDependencies": { "@babel/core": "^7.0.0-0" } @@ -10424,7 +11562,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "dev": true, "dependencies": { "object.assign": "^4.1.0" } @@ -10507,7 +11644,6 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", - "dev": true, "dependencies": { "@babel/compat-data": "^7.17.7", "@babel/helper-define-polyfill-provider": "^0.3.3", @@ -10521,7 +11657,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -10530,7 +11665,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", - "dev": true, "dependencies": { "@babel/helper-define-polyfill-provider": "^0.3.3", "core-js-compat": "^3.25.1" @@ -10543,7 +11677,6 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", - "dev": true, "dependencies": { "@babel/helper-define-polyfill-provider": "^0.3.3" }, @@ -10557,6 +11690,15 @@ "integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==", "dev": true }, + "node_modules/babel-plugin-transform-flow-enums": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-enums/-/babel-plugin-transform-flow-enums-0.0.2.tgz", + "integrity": "sha512-g4aaCrDDOsWjbm0PUUeVnkcVd6AKJsVc/MbnPhEotEpkeJQP6b8nzewohQi7+QS8UyPehOhGWn0nOwjvWpmMvQ==", + "peer": true, + "dependencies": { + "@babel/plugin-syntax-flow": "^7.12.1" + } + }, "node_modules/babel-plugin-transform-react-remove-prop-types": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", @@ -10702,8 +11844,7 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/base": { "version": "0.11.2", @@ -10739,7 +11880,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, "funding": [ { "type": "github", @@ -10855,7 +11995,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -11020,7 +12159,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -11030,7 +12168,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -11150,7 +12287,6 @@ "version": "4.23.0", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", - "dev": true, "funding": [ { "type": "opencollective", @@ -11182,7 +12318,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, "dependencies": { "node-int64": "^0.4.0" } @@ -11191,7 +12326,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, "funding": [ { "type": "github", @@ -11223,8 +12357,7 @@ "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, "node_modules/buffer-xor": { "version": "1.0.3", @@ -11263,7 +12396,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -11372,7 +12504,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -11397,7 +12528,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", - "dev": true, "dependencies": { "callsites": "^2.0.0" }, @@ -11409,7 +12539,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", - "dev": true, "engines": { "node": ">=4" } @@ -11418,7 +12547,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", - "dev": true, "dependencies": { "caller-callsite": "^2.0.0" }, @@ -11449,7 +12577,6 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, "engines": { "node": ">=6" } @@ -11503,7 +12630,6 @@ "version": "1.0.30001588", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001588.tgz", "integrity": "sha512-+hVY9jE44uKLkH0SrUTqxjxqNTOWHsbnQDIKjwkZ3lNTzUUVdBLBGXtj/q5Mp5u98r3droaZAewQuEDzjQdZlQ==", - "dev": true, "funding": [ { "type": "opencollective", @@ -11560,7 +12686,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -11665,6 +12790,24 @@ "node": ">=10" } }, + "node_modules/chrome-launcher": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.2.tgz", + "integrity": "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==", + "peer": true, + "dependencies": { + "@types/node": "*", + "escape-string-regexp": "^4.0.0", + "is-wsl": "^2.2.0", + "lighthouse-logger": "^1.0.0" + }, + "bin": { + "print-chrome-path": "bin/print-chrome-path.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, "node_modules/chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", @@ -11674,6 +12817,20 @@ "node": ">=6.0" } }, + "node_modules/chromium-edge-launcher": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/chromium-edge-launcher/-/chromium-edge-launcher-1.0.0.tgz", + "integrity": "sha512-pgtgjNKZ7i5U++1g1PWv75umkHvhVTDOQIZ+sjeUX9483S7Y6MUvO0lrd7ShGlQlFHMN4SwKTCq/X8hWrbv2KA==", + "peer": true, + "dependencies": { + "@types/node": "*", + "escape-string-regexp": "^4.0.0", + "is-wsl": "^2.2.0", + "lighthouse-logger": "^1.0.0", + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + } + }, "node_modules/ci-env": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/ci-env/-/ci-env-1.17.0.tgz", @@ -11683,8 +12840,7 @@ "node_modules/ci-info": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.4.0.tgz", - "integrity": "sha512-t5QdPT5jq3o262DOQ8zA6E1tlH2upmUc4Hlvrbx1pGYJuiiHl7O7rvVNI+l8HTVhd/q3Qc9vqimkNk5yiXsAug==", - "dev": true + "integrity": "sha512-t5QdPT5jq3o262DOQ8zA6E1tlH2upmUc4Hlvrbx1pGYJuiiHl7O7rvVNI+l8HTVhd/q3Qc9vqimkNk5yiXsAug==" }, "node_modules/cipher-base": { "version": "1.0.4", @@ -11837,7 +12993,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, "dependencies": { "restore-cursor": "^3.1.0" }, @@ -11849,7 +13004,6 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==", - "dev": true, "engines": { "node": ">=6" }, @@ -12014,7 +13168,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true, "engines": { "node": ">=0.8" } @@ -12023,7 +13176,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, "dependencies": { "is-plain-object": "^2.0.4", "kind-of": "^6.0.2", @@ -12037,7 +13189,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, "dependencies": { "isobject": "^3.0.1" }, @@ -12195,7 +13346,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -12206,8 +13356,7 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/color-string": { "version": "1.9.1", @@ -12286,11 +13435,16 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", + "peer": true + }, "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, "node_modules/common-tags": { "version": "1.8.2", @@ -12304,8 +13458,7 @@ "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" }, "node_modules/compare-func": { "version": "2.0.0", @@ -12327,7 +13480,6 @@ "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dev": true, "dependencies": { "mime-db": ">= 1.43.0 < 2" }, @@ -12339,7 +13491,6 @@ "version": "1.7.4", "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dev": true, "dependencies": { "accepts": "~1.3.5", "bytes": "3.0.0", @@ -12398,7 +13549,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "dependencies": { "ms": "2.0.0" } @@ -12406,8 +13556,7 @@ "node_modules/compression/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/compressorjs": { "version": "1.1.1", @@ -12421,8 +13570,7 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/concat-stream": { "version": "1.6.2", @@ -12480,6 +13628,21 @@ "node": ">=8" } }, + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "peer": true, + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, "node_modules/connect-history-api-fallback": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", @@ -12489,6 +13652,60 @@ "node": ">=0.8" } }, + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/connect/node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "peer": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "peer": true + }, + "node_modules/connect/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "peer": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/connect/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/console-browserify": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", @@ -13508,12 +14725,11 @@ "hasInstallScript": true }, "node_modules/core-js-compat": { - "version": "3.25.3", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.3.tgz", - "integrity": "sha512-xVtYpJQ5grszDHEUU9O7XbjjcZ0ccX3LgQsyqSvTnjX97ZqEgn9F5srmrwwwMtbKzDllyFPL+O+2OFMl1lU4TQ==", - "dev": true, + "version": "3.36.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz", + "integrity": "sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==", "dependencies": { - "browserslist": "^4.21.4" + "browserslist": "^4.23.0" }, "funding": { "type": "opencollective", @@ -13983,7 +15199,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -14612,11 +15827,22 @@ "node": "*" } }, + "node_modules/dayjs": { + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==", + "peer": true + }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "peer": true + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -14633,7 +15859,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -14712,10 +15937,9 @@ } }, "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true, + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "engines": { "node": ">=0.10.0" } @@ -14754,7 +15978,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", "integrity": "sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA==", - "dev": true, "dependencies": { "clone": "^1.0.2" } @@ -14769,7 +15992,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -14795,7 +16017,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -14845,15 +16066,34 @@ "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", "dev": true }, + "node_modules/denodeify": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz", + "integrity": "sha512-KNTihKNmQENUZeKu5fzfpzRqR5S2VMp4gl9RFHiWzj9DfvYQPMJ6XHKNaQxaGCXwPk6y9yme3aUoaiAe+KX+vg==", + "peer": true + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, "engines": { "node": ">= 0.8" } }, + "node_modules/deprecated-react-native-prop-types": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-5.0.0.tgz", + "integrity": "sha512-cIK8KYiiGVOFsKdPMmm1L3tA/Gl+JopXL6F5+C7x39MyPsQYnP57Im/D6bNUzcborD7fcMwiwZqcBdBXXZucYQ==", + "peer": true, + "dependencies": { + "@react-native/normalize-colors": "^0.73.0", + "invariant": "^2.2.4", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/des.js": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", @@ -14868,7 +16108,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true, "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -15335,8 +16574,7 @@ "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/ejs": { "version": "3.1.8", @@ -15366,8 +16604,7 @@ "node_modules/electron-to-chromium": { "version": "1.4.677", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.677.tgz", - "integrity": "sha512-erDa3CaDzwJOpyvfKhOiJjBVNnMM0qxHq47RheVVwsSQrgBA9ZSGV9kdaOfZDPXcHzhG7lBxhj6A7KvfLJBd6Q==", - "dev": true + "integrity": "sha512-erDa3CaDzwJOpyvfKhOiJjBVNnMM0qxHq47RheVVwsSQrgBA9ZSGV9kdaOfZDPXcHzhG7lBxhj6A7KvfLJBd6Q==" }, "node_modules/elliptic": { "version": "6.5.4", @@ -15411,8 +16648,7 @@ "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/emojis-list": { "version": "3.0.0", @@ -15427,7 +16663,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -15502,10 +16737,9 @@ } }, "node_modules/envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", - "dev": true, + "version": "7.11.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.1.tgz", + "integrity": "sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg==", "bin": { "envinfo": "dist/cli.js" }, @@ -15529,7 +16763,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, "dependencies": { "is-arrayish": "^0.2.1" } @@ -15542,6 +16775,19 @@ "stackframe": "^1.3.4" } }, + "node_modules/errorhandler": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.5.1.tgz", + "integrity": "sha512-rcOwbfvP1WTViVoUjcfZicVzjhjTuhSMntHh6mW3IrEiyE6mJyXvsToJUJGlGlw/2xU9P5whlWNGlIDVeCiT4A==", + "peer": true, + "dependencies": { + "accepts": "~1.3.7", + "escape-html": "~1.0.3" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/es-abstract": { "version": "1.22.4", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.4.tgz", @@ -15607,7 +16853,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, "dependencies": { "get-intrinsic": "^1.2.4" }, @@ -15619,7 +16864,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, "engines": { "node": ">= 0.4" } @@ -15709,7 +16953,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, "engines": { "node": ">=6" } @@ -15726,14 +16969,12 @@ "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, "engines": { "node": ">=10" }, @@ -16233,11 +17474,19 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "dev": true, "engines": { "node": ">= 0.6" } }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", @@ -16273,7 +17522,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -16755,6 +18003,28 @@ "resolved": "https://registry.npmjs.org/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz", "integrity": "sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==" }, + "node_modules/fast-xml-parser": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.6.tgz", + "integrity": "sha512-M2SovcRxD4+vC493Uc2GZVcZaj66CCJhWurC4viynVSTvrpErCShNcDz1lAho6n9REQKvL/ll4A4/fw6Y9z8nw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + ], + "peer": true, + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, "node_modules/fastest-stable-stringify": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz", @@ -16785,7 +18055,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, "dependencies": { "bser": "2.1.1" } @@ -17068,7 +18337,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -17130,7 +18398,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -17161,6 +18428,12 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "node_modules/flow-enums-runtime": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/flow-enums-runtime/-/flow-enums-runtime-0.0.6.tgz", + "integrity": "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==", + "peer": true + }, "node_modules/flow-parser": { "version": "0.229.0", "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.229.0.tgz", @@ -17412,7 +18685,6 @@ "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -17455,7 +18727,6 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", @@ -17522,14 +18793,12 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -17543,7 +18812,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -17605,7 +18873,6 @@ "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -17614,7 +18881,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -17623,7 +18889,6 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", @@ -17709,7 +18974,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, "engines": { "node": ">=10" }, @@ -18214,7 +19478,6 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -18351,7 +19614,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -18396,8 +19658,7 @@ "node_modules/graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "node_modules/grapheme-splitter": { "version": "1.0.4", @@ -18489,7 +19750,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -18529,7 +19789,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "engines": { "node": ">=8" } @@ -18562,7 +19821,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, "dependencies": { "es-define-property": "^1.0.0" }, @@ -18574,7 +19832,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -18586,7 +19843,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -18735,7 +19991,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", - "dev": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -18861,6 +20116,42 @@ "he": "bin/he" } }, + "node_modules/hermes-estree": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.15.0.tgz", + "integrity": "sha512-lLYvAd+6BnOqWdnNbP/Q8xfl8LOGw4wVjfrNd9Gt8eoFzhNBRVD95n4l2ksfMVOoxuVyegs85g83KS9QOsxbVQ==", + "peer": true + }, + "node_modules/hermes-parser": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.15.0.tgz", + "integrity": "sha512-Q1uks5rjZlE9RjMMjSUCkGrEIPI5pKJILeCtK1VmTj7U4pf3wVPoo+cxfu+s4cBAPy2JzikIIdCZgBoR6x7U1Q==", + "peer": true, + "dependencies": { + "hermes-estree": "0.15.0" + } + }, + "node_modules/hermes-profile-transformer": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/hermes-profile-transformer/-/hermes-profile-transformer-0.0.6.tgz", + "integrity": "sha512-cnN7bQUm65UWOy6cbGcCcZ3rpwW8Q/j4OP5aWRhEry4Z2t2aR1cjrbp0BS+KiBN0smvP1caBgAuxutvyvJILzQ==", + "peer": true, + "dependencies": { + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/hermes-profile-transformer/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "peer": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/hex-color-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", @@ -19189,7 +20480,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -19321,7 +20611,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, "engines": { "node": ">=10.17.0" } @@ -19495,7 +20784,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, "funding": [ { "type": "github", @@ -19578,7 +20866,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, "engines": { "node": ">=0.8.19" } @@ -19608,7 +20895,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -19807,8 +21093,7 @@ "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "node_modules/is-bigint": { "version": "1.0.4", @@ -19915,7 +21200,6 @@ "version": "2.10.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", - "dev": true, "dependencies": { "has": "^1.0.3" }, @@ -19978,7 +21262,6 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -19987,7 +21270,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, "bin": { "is-docker": "cli.js" }, @@ -20058,7 +21340,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "engines": { "node": ">=8" } @@ -20120,7 +21401,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true, "engines": { "node": ">=8" } @@ -20168,7 +21448,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "engines": { "node": ">=0.12.0" } @@ -20286,7 +21565,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, "engines": { "node": ">=8" }, @@ -20367,7 +21645,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, "engines": { "node": ">=10" }, @@ -20432,7 +21709,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, "dependencies": { "is-docker": "^2.0.0" }, @@ -20454,8 +21730,7 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/isobject": { "version": "3.0.1", @@ -20578,6 +21853,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/its-fine": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/its-fine/-/its-fine-1.1.3.tgz", + "integrity": "sha512-mncCA+yb6tuh5zK26cHqKlsSyxm4zdm4YgJpxycyx6p9fgxgK5PLu3iDVpKhzTn57Yrv3jk/r0aK0RFTT1OjFw==", + "peer": true, + "dependencies": { + "@types/react-reconciler": "^0.28.0" + }, + "peerDependencies": { + "react": ">=18.0" + } + }, + "node_modules/its-fine/node_modules/@types/react-reconciler": { + "version": "0.28.8", + "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.8.tgz", + "integrity": "sha512-SN9c4kxXZonFhbX4hJrZy37yw9e7EIxcpHCxQv5JUS18wDE5ovkQKlqQEkufdJCCMfuI9BnjUJvhYeJ9x5Ra7g==", + "peer": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/jake": { "version": "10.8.5", "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", @@ -21744,10 +23040,9 @@ } }, "node_modules/jest-get-type": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.0.0.tgz", - "integrity": "sha512-83X19z/HuLKYXYHskZlBAShO7UfLFXu/vWajw9ZNJASN32li8yHMaVGAQqxFW1RCFOkB7cubaL6FaJVQqqJLSw==", - "dev": true, + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } @@ -22097,18 +23392,17 @@ } }, "node_modules/jest-message-util": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.2.1.tgz", - "integrity": "sha512-Dx5nEjw9V8C1/Yj10S/8ivA8F439VS8vTq1L7hEgwHFn9ovSKNpYW/kwNh7UglaEgXO42XxzKJB+2x0nSglFVw==", - "dev": true, + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.2.1", + "@jest/types": "^29.6.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.2.1", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -22839,12 +24133,11 @@ "dev": true }, "node_modules/jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", - "dev": true, + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -23060,6 +24353,19 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/joi": { + "version": "17.12.3", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.3.tgz", + "integrity": "sha512-2RRziagf555owrm9IRVtdKynOBeITiDpuZqIpgwqXShPncPKNiRQoiGsl/T8SQdq+8ugRzH2LqY67irr2y/d+g==", + "peer": true, + "dependencies": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, "node_modules/js-cookie": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", @@ -23103,6 +24409,18 @@ "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", "dev": true }, + "node_modules/jsc-android": { + "version": "250231.0.0", + "resolved": "https://registry.npmjs.org/jsc-android/-/jsc-android-250231.0.0.tgz", + "integrity": "sha512-rS46PvsjYmdmuz1OAWXY/1kCYG7pnf1TBqeTiOJr1iDz7s5DLxxC9n/ZMknLDxzYzNVfI7R95MH10emSSG1Wuw==", + "peer": true + }, + "node_modules/jsc-safe-url": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/jsc-safe-url/-/jsc-safe-url-0.2.4.tgz", + "integrity": "sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q==", + "peer": true + }, "node_modules/jscodeshift": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.13.1.tgz", @@ -23362,7 +24680,6 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, "bin": { "jsesc": "bin/jsesc" }, @@ -23379,8 +24696,7 @@ "node_modules/json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", @@ -23416,7 +24732,6 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, "bin": { "json5": "lib/cli.js" }, @@ -23428,7 +24743,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -23517,7 +24831,6 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -23526,7 +24839,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, "engines": { "node": ">=6" } @@ -23540,6 +24852,26 @@ "node": ">= 8" } }, + "node_modules/konva": { + "version": "9.3.6", + "resolved": "https://registry.npmjs.org/konva/-/konva-9.3.6.tgz", + "integrity": "sha512-dqR8EbcM0hjuilZCBP6xauQ5V3kH3m9kBcsDkqPypQuRgsXbcXUrxqYxhNbdvKZpYNW8Amq94jAD/C0NY3qfBQ==", + "funding": [ + { + "type": "patreon", + "url": "https://www.patreon.com/lavrton" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/konva" + }, + { + "type": "github", + "url": "https://github.com/sponsors/lavrton" + } + ], + "peer": true + }, "node_modules/last-call-webpack-plugin": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz", @@ -23603,8 +24935,7 @@ "node_modules/leaflet": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.3.tgz", - "integrity": "sha512-iB2cR9vAkDOu5l3HAay2obcUHZ7xwUBBjph8+PGtmW/2lYhbLizWtG7nTeYht36WfOslixQF9D/uSIzhZgGMfQ==", - "peer": true + "integrity": "sha512-iB2cR9vAkDOu5l3HAay2obcUHZ7xwUBBjph8+PGtmW/2lYhbLizWtG7nTeYht36WfOslixQF9D/uSIzhZgGMfQ==" }, "node_modules/less": { "version": "4.1.3", @@ -23710,7 +25041,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, "engines": { "node": ">=6" } @@ -23728,6 +25058,31 @@ "node": ">= 0.8.0" } }, + "node_modules/lighthouse-logger": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz", + "integrity": "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==", + "peer": true, + "dependencies": { + "debug": "^2.6.9", + "marky": "^1.2.2" + } + }, + "node_modules/lighthouse-logger/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/lighthouse-logger/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "peer": true + }, "node_modules/lilconfig": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", @@ -24031,7 +25386,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -24050,8 +25404,7 @@ "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, "node_modules/lodash.get": { "version": "4.4.2", @@ -24089,6 +25442,12 @@ "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", "dev": true }, + "node_modules/lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==", + "peer": true + }, "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -24099,7 +25458,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -24143,6 +25501,138 @@ "node": ">=8" } }, + "node_modules/logkitty": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/logkitty/-/logkitty-0.7.1.tgz", + "integrity": "sha512-/3ER20CTTbahrCrpYfPn7Xavv9diBROZpoXGVZDWMw4b/X4uuUwAC0ki85tgsdMRONURyIJbcOvS94QsUBYPbQ==", + "peer": true, + "dependencies": { + "ansi-fragments": "^0.2.1", + "dayjs": "^1.8.15", + "yargs": "^15.1.0" + }, + "bin": { + "logkitty": "bin/logkitty.js" + } + }, + "node_modules/logkitty/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "peer": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/logkitty/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "peer": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/logkitty/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "peer": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/logkitty/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "peer": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/logkitty/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "peer": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/logkitty/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "peer": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/logkitty/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "peer": true + }, + "node_modules/logkitty/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "peer": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/logkitty/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "peer": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -24173,7 +25663,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -24239,7 +25728,6 @@ "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, "dependencies": { "tmpl": "1.0.5" } @@ -24290,6 +25778,12 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/marky": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/marky/-/marky-1.2.5.tgz", + "integrity": "sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==", + "peer": true + }, "node_modules/md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -24389,6 +25883,12 @@ "node": ">= 4.0.0" } }, + "node_modules/memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==", + "peer": true + }, "node_modules/memoizerific": { "version": "1.11.3", "resolved": "https://registry.npmjs.org/memoizerific/-/memoizerific-1.11.3.tgz", @@ -24485,8 +25985,7 @@ "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, "node_modules/merge2": { "version": "1.4.1", @@ -24512,6 +26011,602 @@ "node": ">= 0.6" } }, + "node_modules/metro": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro/-/metro-0.80.8.tgz", + "integrity": "sha512-in7S0W11mg+RNmcXw+2d9S3zBGmCARDxIwoXJAmLUQOQoYsRP3cpGzyJtc7WOw8+FXfpgXvceD0u+PZIHXEL7g==", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@babel/core": "^7.20.0", + "@babel/generator": "^7.20.0", + "@babel/parser": "^7.20.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.20.0", + "@babel/types": "^7.20.0", + "accepts": "^1.3.7", + "chalk": "^4.0.0", + "ci-info": "^2.0.0", + "connect": "^3.6.5", + "debug": "^2.2.0", + "denodeify": "^1.2.1", + "error-stack-parser": "^2.0.6", + "graceful-fs": "^4.2.4", + "hermes-parser": "0.20.1", + "image-size": "^1.0.2", + "invariant": "^2.2.4", + "jest-worker": "^29.6.3", + "jsc-safe-url": "^0.2.2", + "lodash.throttle": "^4.1.1", + "metro-babel-transformer": "0.80.8", + "metro-cache": "0.80.8", + "metro-cache-key": "0.80.8", + "metro-config": "0.80.8", + "metro-core": "0.80.8", + "metro-file-map": "0.80.8", + "metro-resolver": "0.80.8", + "metro-runtime": "0.80.8", + "metro-source-map": "0.80.8", + "metro-symbolicate": "0.80.8", + "metro-transform-plugins": "0.80.8", + "metro-transform-worker": "0.80.8", + "mime-types": "^2.1.27", + "node-fetch": "^2.2.0", + "nullthrows": "^1.1.1", + "rimraf": "^3.0.2", + "serialize-error": "^2.1.0", + "source-map": "^0.5.6", + "strip-ansi": "^6.0.0", + "throat": "^5.0.0", + "ws": "^7.5.1", + "yargs": "^17.6.2" + }, + "bin": { + "metro": "src/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/metro-babel-transformer": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.80.8.tgz", + "integrity": "sha512-TTzNwRZb2xxyv4J/+yqgtDAP2qVqH3sahsnFu6Xv4SkLqzrivtlnyUbaeTdJ9JjtADJUEjCbgbFgUVafrXdR9Q==", + "peer": true, + "dependencies": { + "@babel/core": "^7.20.0", + "hermes-parser": "0.20.1", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/metro-babel-transformer/node_modules/hermes-estree": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.20.1.tgz", + "integrity": "sha512-SQpZK4BzR48kuOg0v4pb3EAGNclzIlqMj3Opu/mu7bbAoFw6oig6cEt/RAi0zTFW/iW6Iz9X9ggGuZTAZ/yZHg==", + "peer": true + }, + "node_modules/metro-babel-transformer/node_modules/hermes-parser": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.20.1.tgz", + "integrity": "sha512-BL5P83cwCogI8D7rrDCgsFY0tdYUtmFP9XaXtl2IQjC+2Xo+4okjfXintlTxcIwl4qeGddEl28Z11kbVIw0aNA==", + "peer": true, + "dependencies": { + "hermes-estree": "0.20.1" + } + }, + "node_modules/metro-cache": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.80.8.tgz", + "integrity": "sha512-5svz+89wSyLo7BxdiPDlwDTgcB9kwhNMfNhiBZPNQQs1vLFXxOkILwQiV5F2EwYT9DEr6OPZ0hnJkZfRQ8lDYQ==", + "peer": true, + "dependencies": { + "metro-core": "0.80.8", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/metro-cache-key": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.80.8.tgz", + "integrity": "sha512-qWKzxrLsRQK5m3oH8ePecqCc+7PEhR03cJE6Z6AxAj0idi99dHOSitTmY0dclXVB9vP2tQIAE8uTd8xkYGk8fA==", + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/metro-config": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.80.8.tgz", + "integrity": "sha512-VGQJpfJawtwRzGzGXVUoohpIkB0iPom4DmSbAppKfumdhtLA8uVeEPp2GM61kL9hRvdbMhdWA7T+hZFDlo4mJA==", + "peer": true, + "dependencies": { + "connect": "^3.6.5", + "cosmiconfig": "^5.0.5", + "jest-validate": "^29.6.3", + "metro": "0.80.8", + "metro-cache": "0.80.8", + "metro-core": "0.80.8", + "metro-runtime": "0.80.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/metro-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "peer": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/metro-config/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/metro-config/node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "peer": true, + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/metro-config/node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", + "peer": true, + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/metro-config/node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "peer": true, + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/metro-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "peer": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/metro-config/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "peer": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/metro-config/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/metro-core": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.80.8.tgz", + "integrity": "sha512-g6lud55TXeISRTleW6SHuPFZHtYrpwNqbyFIVd9j9Ofrb5IReiHp9Zl8xkAfZQp8v6ZVgyXD7c130QTsCz+vBw==", + "peer": true, + "dependencies": { + "lodash.throttle": "^4.1.1", + "metro-resolver": "0.80.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/metro-file-map": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.80.8.tgz", + "integrity": "sha512-eQXMFM9ogTfDs2POq7DT2dnG7rayZcoEgRbHPXvhUWkVwiKkro2ngcBE++ck/7A36Cj5Ljo79SOkYwHaWUDYDw==", + "peer": true, + "dependencies": { + "anymatch": "^3.0.3", + "debug": "^2.2.0", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.4", + "invariant": "^2.2.4", + "jest-worker": "^29.6.3", + "micromatch": "^4.0.4", + "node-abort-controller": "^3.1.1", + "nullthrows": "^1.1.1", + "walker": "^1.0.7" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/metro-file-map/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/metro-file-map/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "peer": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/metro-file-map/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "peer": true + }, + "node_modules/metro-file-map/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/metro-minify-terser": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.80.8.tgz", + "integrity": "sha512-y8sUFjVvdeUIINDuW1sejnIjkZfEF+7SmQo0EIpYbWmwh+kq/WMj74yVaBWuqNjirmUp1YNfi3alT67wlbBWBQ==", + "peer": true, + "dependencies": { + "terser": "^5.15.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/metro-resolver": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.80.8.tgz", + "integrity": "sha512-JdtoJkP27GGoZ2HJlEsxs+zO7jnDUCRrmwXJozTlIuzLHMRrxgIRRby9fTCbMhaxq+iA9c+wzm3iFb4NhPmLbQ==", + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/metro-runtime": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.80.8.tgz", + "integrity": "sha512-2oScjfv6Yb79PelU1+p8SVrCMW9ZjgEiipxq7jMRn8mbbtWzyv3g8Mkwr+KwOoDFI/61hYPUbY8cUnu278+x1g==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/metro-source-map": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.80.8.tgz", + "integrity": "sha512-+OVISBkPNxjD4eEKhblRpBf463nTMk3KMEeYS8Z4xM/z3qujGJGSsWUGRtH27+c6zElaSGtZFiDMshEb8mMKQg==", + "peer": true, + "dependencies": { + "@babel/traverse": "^7.20.0", + "@babel/types": "^7.20.0", + "invariant": "^2.2.4", + "metro-symbolicate": "0.80.8", + "nullthrows": "^1.1.1", + "ob1": "0.80.8", + "source-map": "^0.5.6", + "vlq": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/metro-source-map/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/metro-symbolicate": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.80.8.tgz", + "integrity": "sha512-nwhYySk79jQhwjL9QmOUo4wS+/0Au9joEryDWw7uj4kz2yvw1uBjwmlql3BprQCBzRdB3fcqOP8kO8Es+vE31g==", + "peer": true, + "dependencies": { + "invariant": "^2.2.4", + "metro-source-map": "0.80.8", + "nullthrows": "^1.1.1", + "source-map": "^0.5.6", + "through2": "^2.0.1", + "vlq": "^1.0.0" + }, + "bin": { + "metro-symbolicate": "src/index.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/metro-symbolicate/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/metro-transform-plugins": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.80.8.tgz", + "integrity": "sha512-sSu8VPL9Od7w98MftCOkQ1UDeySWbsIAS5I54rW22BVpPnI3fQ42srvqMLaJUQPjLehUanq8St6OMBCBgH/UWw==", + "peer": true, + "dependencies": { + "@babel/core": "^7.20.0", + "@babel/generator": "^7.20.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.20.0", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/metro-transform-worker": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.80.8.tgz", + "integrity": "sha512-+4FG3TQk3BTbNqGkFb2uCaxYTfsbuFOCKMMURbwu0ehCP8ZJuTUramkaNZoATS49NSAkRgUltgmBa4YaKZ5mqw==", + "peer": true, + "dependencies": { + "@babel/core": "^7.20.0", + "@babel/generator": "^7.20.0", + "@babel/parser": "^7.20.0", + "@babel/types": "^7.20.0", + "metro": "0.80.8", + "metro-babel-transformer": "0.80.8", + "metro-cache": "0.80.8", + "metro-cache-key": "0.80.8", + "metro-minify-terser": "0.80.8", + "metro-source-map": "0.80.8", + "metro-transform-plugins": "0.80.8", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/metro/node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "peer": true + }, + "node_modules/metro/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "peer": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/metro/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/metro/node_modules/hermes-estree": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.20.1.tgz", + "integrity": "sha512-SQpZK4BzR48kuOg0v4pb3EAGNclzIlqMj3Opu/mu7bbAoFw6oig6cEt/RAi0zTFW/iW6Iz9X9ggGuZTAZ/yZHg==", + "peer": true + }, + "node_modules/metro/node_modules/hermes-parser": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.20.1.tgz", + "integrity": "sha512-BL5P83cwCogI8D7rrDCgsFY0tdYUtmFP9XaXtl2IQjC+2Xo+4okjfXintlTxcIwl4qeGddEl28Z11kbVIw0aNA==", + "peer": true, + "dependencies": { + "hermes-estree": "0.20.1" + } + }, + "node_modules/metro/node_modules/image-size": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", + "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==", + "peer": true, + "dependencies": { + "queue": "6.0.2" + }, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=16.x" + } + }, + "node_modules/metro/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "peer": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/metro/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "peer": true + }, + "node_modules/metro/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/metro/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/metro/node_modules/throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "peer": true + }, + "node_modules/metro/node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "peer": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/metro/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "peer": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/metro/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "peer": true, + "engines": { + "node": ">=12" + } + }, "node_modules/microevent.ts": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/microevent.ts/-/microevent.ts-0.1.1.tgz", @@ -24522,7 +26617,6 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -24554,7 +26648,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, "bin": { "mime": "cli.js" }, @@ -24566,7 +26659,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -24575,7 +26667,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "dependencies": { "mime-db": "1.52.0" }, @@ -24587,7 +26678,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, "engines": { "node": ">=6" } @@ -24674,7 +26764,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -24818,7 +26907,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, "bin": { "mkdirp": "bin/cmd.js" }, @@ -24894,8 +26982,7 @@ "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==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/multicast-dns": { "version": "7.2.5", @@ -25035,7 +27122,6 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -25043,8 +27129,7 @@ "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "node_modules/nested-error-stacks": { "version": "2.1.1", @@ -25067,11 +27152,25 @@ "lower-case": "^1.1.1" } }, + "node_modules/nocache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/nocache/-/nocache-3.0.4.tgz", + "integrity": "sha512-WDD0bdg9mbq6F4mRxEYcPWwfA1vxd0mrvKOyxI7Xj/atfRHVeutzuWByG//jfm4uPzp0y4Kj051EORCBSQMycw==", + "peer": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/node-abort-controller": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", + "peer": true + }, "node_modules/node-dir": { "version": "0.1.17", "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", "integrity": "sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==", - "dev": true, "dependencies": { "minimatch": "^3.0.2" }, @@ -25083,7 +27182,6 @@ "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dev": true, "dependencies": { "whatwg-url": "^5.0.0" }, @@ -25102,20 +27200,17 @@ "node_modules/node-fetch/node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/node-fetch/node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/node-fetch/node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -25142,8 +27237,7 @@ "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" }, "node_modules/node-libs-browser": { "version": "2.2.1", @@ -25220,8 +27314,20 @@ "node_modules/node-releases": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + }, + "node_modules/node-stream-zip": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.15.0.tgz", + "integrity": "sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw==", + "peer": true, + "engines": { + "node": ">=0.12.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/antelle" + } }, "node_modules/normalize-package-data": { "version": "2.5.0", @@ -25248,7 +27354,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -25275,7 +27380,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, "dependencies": { "path-key": "^3.0.0" }, @@ -25307,6 +27411,12 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, + "node_modules/nullthrows": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", + "peer": true + }, "node_modules/num2fraction": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", @@ -25328,11 +27438,19 @@ "node": "*" } }, + "node_modules/ob1": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.80.8.tgz", + "integrity": "sha512-QHJQk/lXMmAW8I7AIM3in1MSlwe1umR72Chhi8B7Xnq6mzjhBKkA6Fy/zAhQnGkA4S912EPCEvTij5yh+EQTAA==", + "peer": true, + "engines": { + "node": ">=18" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -25444,7 +27562,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, "engines": { "node": ">= 0.4" } @@ -25465,7 +27582,6 @@ "version": "4.1.5", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", @@ -25581,7 +27697,6 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, "dependencies": { "ee-first": "1.1.1" }, @@ -25593,7 +27708,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -25602,7 +27716,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "dependencies": { "wrappy": "1" } @@ -25611,7 +27724,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, "dependencies": { "mimic-fn": "^2.1.0" }, @@ -26222,7 +28334,6 @@ "version": "5.4.1", "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "dev": true, "dependencies": { "bl": "^4.1.0", "chalk": "^4.1.0", @@ -26345,7 +28456,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, "dependencies": { "yocto-queue": "^0.1.0" }, @@ -26360,7 +28470,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -26415,7 +28524,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, "engines": { "node": ">=6" } @@ -26580,7 +28688,6 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -26639,7 +28746,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, "engines": { "node": ">=8" } @@ -26648,7 +28754,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -26657,7 +28762,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "engines": { "node": ">=8" } @@ -26665,8 +28769,7 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-to-regexp": { "version": "0.1.7", @@ -26714,14 +28817,12 @@ "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, "engines": { "node": ">=8.6" }, @@ -26775,7 +28876,6 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dev": true, "engines": { "node": ">= 6" } @@ -28831,12 +30931,11 @@ } }, "node_modules/pretty-format": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.2.1.tgz", - "integrity": "sha512-Y41Sa4aLCtKAXvwuIpTvcFBkyeYp2gdFWzXGA+ZNES3VwURIB165XO/z7CjETwzCCS53MjW/rLMyyqEnTtaOfA==", - "dev": true, + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dependencies": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -28848,7 +30947,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, "engines": { "node": ">=10" }, @@ -28922,6 +31020,15 @@ "node": ">=8" } }, + "node_modules/promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "peer": true, + "dependencies": { + "asap": "~2.0.6" + } + }, "node_modules/promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", @@ -28977,7 +31084,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" @@ -28990,7 +31096,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -29000,8 +31105,7 @@ "node_modules/prop-types/node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/property-information": { "version": "5.6.0", @@ -29232,6 +31336,15 @@ "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", "dev": true }, + "node_modules/queue": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", + "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", + "peer": true, + "dependencies": { + "inherits": "~2.0.3" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -29293,7 +31406,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -29408,6 +31520,37 @@ "node": ">=0.10.0" } }, + "node_modules/react-devtools-core": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.28.5.tgz", + "integrity": "sha512-cq/o30z9W2Wb4rzBefjv5fBalHU0rJGZCHAkf/RHSBWSSYwh8PlQTqqOJmgIIbBtpj27T6FIPXeomIjZtCNVqA==", + "peer": true, + "dependencies": { + "shell-quote": "^1.6.1", + "ws": "^7" + } + }, + "node_modules/react-devtools-core/node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "peer": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -29441,6 +31584,62 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, + "node_modules/react-konva": { + "version": "18.2.10", + "resolved": "https://registry.npmjs.org/react-konva/-/react-konva-18.2.10.tgz", + "integrity": "sha512-ohcX1BJINL43m4ynjZ24MxFI1syjBdrXhqVxYVDw2rKgr3yuS0x/6m1Y2Z4sl4T/gKhfreBx8KHisd0XC6OT1g==", + "funding": [ + { + "type": "patreon", + "url": "https://www.patreon.com/lavrton" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/konva" + }, + { + "type": "github", + "url": "https://github.com/sponsors/lavrton" + } + ], + "peer": true, + "dependencies": { + "@types/react-reconciler": "^0.28.2", + "its-fine": "^1.1.1", + "react-reconciler": "~0.29.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "konva": "^8.0.1 || ^7.2.5 || ^9.0.0", + "react": ">=18.0.0", + "react-dom": ">=18.0.0" + } + }, + "node_modules/react-konva/node_modules/@types/react-reconciler": { + "version": "0.28.8", + "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.8.tgz", + "integrity": "sha512-SN9c4kxXZonFhbX4hJrZy37yw9e7EIxcpHCxQv5JUS18wDE5ovkQKlqQEkufdJCCMfuI9BnjUJvhYeJ9x5Ra7g==", + "peer": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/react-konva/node_modules/react-reconciler": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.29.0.tgz", + "integrity": "sha512-wa0fGj7Zht1EYMRhKWwoo1H9GApxYLBuhoAuXN0TlltESAjDssB+Apf0T/DngVqaMyPypDmabL37vw/2aRM98Q==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, "node_modules/react-leaflet": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-4.2.1.tgz", @@ -29454,6 +31653,284 @@ "react-dom": "^18.0.0" } }, + "node_modules/react-native": { + "version": "0.73.6", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.73.6.tgz", + "integrity": "sha512-oqmZe8D2/VolIzSPZw+oUd6j/bEmeRHwsLn1xLA5wllEYsZ5zNuMsDus235ONOnCRwexqof/J3aztyQswSmiaA==", + "peer": true, + "dependencies": { + "@jest/create-cache-key-function": "^29.6.3", + "@react-native-community/cli": "12.3.6", + "@react-native-community/cli-platform-android": "12.3.6", + "@react-native-community/cli-platform-ios": "12.3.6", + "@react-native/assets-registry": "0.73.1", + "@react-native/codegen": "0.73.3", + "@react-native/community-cli-plugin": "0.73.17", + "@react-native/gradle-plugin": "0.73.4", + "@react-native/js-polyfills": "0.73.1", + "@react-native/normalize-colors": "0.73.2", + "@react-native/virtualized-lists": "0.73.4", + "abort-controller": "^3.0.0", + "anser": "^1.4.9", + "ansi-regex": "^5.0.0", + "base64-js": "^1.5.1", + "chalk": "^4.0.0", + "deprecated-react-native-prop-types": "^5.0.0", + "event-target-shim": "^5.0.1", + "flow-enums-runtime": "^0.0.6", + "invariant": "^2.2.4", + "jest-environment-node": "^29.6.3", + "jsc-android": "^250231.0.0", + "memoize-one": "^5.0.0", + "metro-runtime": "^0.80.3", + "metro-source-map": "^0.80.3", + "mkdirp": "^0.5.1", + "nullthrows": "^1.1.1", + "pretty-format": "^26.5.2", + "promise": "^8.3.0", + "react-devtools-core": "^4.27.7", + "react-refresh": "^0.14.0", + "react-shallow-renderer": "^16.15.0", + "regenerator-runtime": "^0.13.2", + "scheduler": "0.24.0-canary-efb381bbf-20230505", + "stacktrace-parser": "^0.1.10", + "whatwg-fetch": "^3.0.0", + "ws": "^6.2.2", + "yargs": "^17.6.2" + }, + "bin": { + "react-native": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "react": "18.2.0" + } + }, + "node_modules/react-native/node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "peer": true, + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/react-native/node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "peer": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/react-native/node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "peer": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/react-native/node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "peer": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/react-native/node_modules/@types/yargs": { + "version": "15.0.19", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.19.tgz", + "integrity": "sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA==", + "peer": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/react-native/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "peer": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/react-native/node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "peer": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/react-native/node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "peer": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/react-native/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "peer": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/react-native/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "peer": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/react-native/node_modules/pretty-format/node_modules/@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "peer": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/react-native/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "peer": true + }, + "node_modules/react-native/node_modules/react-refresh": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", + "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-native/node_modules/scheduler": { + "version": "0.24.0-canary-efb381bbf-20230505", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.24.0-canary-efb381bbf-20230505.tgz", + "integrity": "sha512-ABvovCDe/k9IluqSh4/ISoq8tIJnW8euVAWYt5j/bg6dRnqwQwiGO1F/V4AyK96NGF/FB04FhOUDuWj8IKfABA==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/react-native/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "peer": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/react-native/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/react-reconciler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.27.0.tgz", + "integrity": "sha512-HmMDKciQjYmBRGuuhIaKA1ba/7a+UsM5FzOZsMO2JYHt9Jh8reCb7j1eDC95NOyUlKM9KRyvdx0flBuDvYSBoA==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.21.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "react": "^18.0.0" + } + }, + "node_modules/react-reconciler/node_modules/scheduler": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", + "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0" + } + }, "node_modules/react-redux": { "version": "8.0.4", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.4.tgz", @@ -29506,6 +31983,36 @@ "resolved": "https://registry.npmjs.org/react-router-redux/-/react-router-redux-4.0.8.tgz", "integrity": "sha512-lzlK+S6jZnn17BZbzBe6F8ok3YAhGAUlyWgRu3cz5mT199gKxfem5lNu3qcgzRiVhNEOFVG0/pdT+1t4aWhoQw==" }, + "node_modules/react-shallow-renderer": { + "version": "16.15.0", + "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz", + "integrity": "sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA==", + "peer": true, + "dependencies": { + "object-assign": "^4.1.1", + "react-is": "^16.12.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependencies": { + "react": "^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-spring": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/react-spring/-/react-spring-9.7.3.tgz", + "integrity": "sha512-oTxDpFV5gzq7jQX6+bU0SVq+vX8VnuuT5c8Zwn6CpDErOPvCmV+DRkPiEBtaL3Ozgzwiy5yFx83N0h303j/r3A==", + "dependencies": { + "@react-spring/core": "~9.7.3", + "@react-spring/konva": "~9.7.3", + "@react-spring/native": "~9.7.3", + "@react-spring/three": "~9.7.3", + "@react-spring/web": "~9.7.3", + "@react-spring/zdog": "~9.7.3" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-universal-interface": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/react-universal-interface/-/react-universal-interface-0.6.2.tgz", @@ -29540,6 +32047,30 @@ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-use-measure": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.1.tgz", + "integrity": "sha512-nocZhN26cproIiIduswYpV5y5lQpSQS1y/4KuvUCjSKmw7ZWIS/+g3aFnX3WdBkyuGUtTLif3UTqnLLhbDoQig==", + "peer": true, + "dependencies": { + "debounce": "^1.2.1" + }, + "peerDependencies": { + "react": ">=16.13", + "react-dom": ">=16.13" + } + }, + "node_modules/react-zdog": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/react-zdog/-/react-zdog-1.2.2.tgz", + "integrity": "sha512-Ix7ALha91aOEwiHuxumCeYbARS5XNpc/w0v145oGkM6poF/CvhKJwzLhM5sEZbtrghMA+psAhOJkCTzJoseicA==", + "peer": true, + "dependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0", + "resize-observer-polyfill": "^1.5.1" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -29655,7 +32186,6 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -29677,6 +32207,12 @@ "node": ">=8.10.0" } }, + "node_modules/readline": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/readline/-/readline-1.3.0.tgz", + "integrity": "sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg==", + "peer": true + }, "node_modules/recast": { "version": "0.14.7", "resolved": "https://registry.npmjs.org/recast/-/recast-0.14.7.tgz", @@ -29744,14 +32280,12 @@ "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" }, "node_modules/regenerate-unicode-properties": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", - "dev": true, "dependencies": { "regenerate": "^1.4.2" }, @@ -29768,7 +32302,6 @@ "version": "0.15.0", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz", "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", - "dev": true, "dependencies": { "@babel/runtime": "^7.8.4" } @@ -29820,7 +32353,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.1.tgz", "integrity": "sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ==", - "dev": true, "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.1.0", @@ -29860,14 +32392,12 @@ "node_modules/regjsgen": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", - "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==", - "dev": true + "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==" }, "node_modules/regjsparser": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "dev": true, "dependencies": { "jsesc": "~0.5.0" }, @@ -29879,7 +32409,6 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "dev": true, "bin": { "jsesc": "bin/jsesc" } @@ -30235,7 +32764,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -30249,6 +32777,12 @@ "node": ">=0.10.0" } }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "peer": true + }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -30264,7 +32798,6 @@ "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, "dependencies": { "is-core-module": "^2.9.0", "path-parse": "^1.0.7", @@ -30336,7 +32869,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" @@ -30395,7 +32927,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, "dependencies": { "glob": "^7.1.3" }, @@ -30980,7 +33511,6 @@ "version": "7.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -31016,7 +33546,6 @@ "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dev": true, "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -31040,7 +33569,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "dependencies": { "ms": "2.0.0" } @@ -31048,14 +33576,21 @@ "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serialize-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz", + "integrity": "sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw==", + "peer": true, + "engines": { + "node": ">=0.10.0" + } }, "node_modules/serialize-javascript": { "version": "5.0.1", @@ -31176,7 +33711,6 @@ "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dev": true, "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -31190,14 +33724,12 @@ "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, "node_modules/set-function-length": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", - "dev": true, "dependencies": { "define-data-property": "^1.1.2", "es-errors": "^1.3.0", @@ -31290,8 +33822,7 @@ "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, "node_modules/sha.js": { "version": "2.4.11", @@ -31310,7 +33841,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, "dependencies": { "kind-of": "^6.0.2" }, @@ -31322,7 +33852,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -31334,11 +33863,19 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "engines": { "node": ">=8" } }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/shelljs": { "version": "0.8.5", "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", @@ -31382,8 +33919,7 @@ "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "node_modules/simple-color-scale": { "version": "1.0.1", @@ -31422,8 +33958,7 @@ "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" }, "node_modules/size-plugin": { "version": "3.0.0", @@ -31531,7 +34066,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, "engines": { "node": ">=8" } @@ -31853,7 +34387,6 @@ "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -31987,8 +34520,7 @@ "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "node_modules/sshpk": { "version": "1.17.0", @@ -32055,7 +34587,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", - "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" }, @@ -32067,7 +34598,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, "engines": { "node": ">=8" } @@ -32104,6 +34634,27 @@ "stacktrace-gps": "^3.0.4" } }, + "node_modules/stacktrace-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", + "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", + "peer": true, + "dependencies": { + "type-fest": "^0.7.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stacktrace-parser/node_modules/type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", + "peer": true, + "engines": { + "node": ">=8" + } + }, "node_modules/standard-version": { "version": "9.5.0", "resolved": "https://registry.npmjs.org/standard-version/-/standard-version-9.5.0.tgz", @@ -32313,7 +34864,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -32453,7 +35003,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, "dependencies": { "safe-buffer": "~5.2.0" } @@ -32462,7 +35011,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, "funding": [ { "type": "github", @@ -32504,7 +35052,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -32646,7 +35193,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -32685,7 +35231,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, "engines": { "node": ">=6" } @@ -32735,6 +35280,12 @@ "node": ">=0.8.0" } }, + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "peer": true + }, "node_modules/style-loader": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-2.0.0.tgz", @@ -32838,11 +35389,16 @@ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.2.tgz", "integrity": "sha512-Nn2CCrG2ZaFziDxaZPN43CXqn+j7tcdjPFCkRBkFue8QYXC2HdEwnw5TCBo4yQZ2WxKYeSi0fdoOrtEqgDrXbA==" }, + "node_modules/sudo-prompt": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-9.2.1.tgz", + "integrity": "sha512-Mu7R0g4ig9TUuGSxJavny5Rv0egCEtpZRNMrZaYS1vxkiIxGiGUwoezU3LazIQ+KE04hTrTfNPgxU5gzi7F5Pw==", + "peer": true + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -32867,7 +35423,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -32875,6 +35430,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/suspend-react": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/suspend-react/-/suspend-react-0.1.3.tgz", + "integrity": "sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ==", + "peer": true, + "peerDependencies": { + "react": ">=17.0" + } + }, "node_modules/svgo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", @@ -33219,7 +35783,6 @@ "version": "0.8.4", "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.4.tgz", "integrity": "sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg==", - "dev": true, "dependencies": { "rimraf": "~2.6.2" }, @@ -33231,7 +35794,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", - "dev": true, "engines": { "node": ">=8" } @@ -33240,7 +35802,6 @@ "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, "dependencies": { "glob": "^7.1.3" }, @@ -33298,7 +35859,6 @@ "version": "5.15.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.0.tgz", "integrity": "sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA==", - "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.2", "acorn": "^8.5.0", @@ -33400,6 +35960,12 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/three": { + "version": "0.163.0", + "resolved": "https://registry.npmjs.org/three/-/three-0.163.0.tgz", + "integrity": "sha512-HlMgCb2TF/dTLRtknBnjUTsR8FsDqBY43itYop2+Zg822I+Kd0Ua2vs8CvfBVefXkBdNDrLMoRTGCIIpfCuDew==", + "peer": true + }, "node_modules/throat": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", @@ -33495,8 +36061,7 @@ "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" }, "node_modules/to-arraybuffer": { "version": "1.0.1", @@ -33508,7 +36073,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, "engines": { "node": ">=4" } @@ -33565,7 +36129,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -33582,7 +36145,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true, "engines": { "node": ">=0.6" } @@ -33801,7 +36363,6 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, "engines": { "node": ">=4" } @@ -34006,7 +36567,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "dev": true, "engines": { "node": ">=4" } @@ -34015,7 +36575,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dev": true, "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" @@ -34028,7 +36587,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", - "dev": true, "engines": { "node": ">=4" } @@ -34037,7 +36595,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "dev": true, "engines": { "node": ">=4" } @@ -34261,7 +36818,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, "engines": { "node": ">= 4.0.0" } @@ -34270,7 +36826,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -34356,7 +36911,6 @@ "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", - "dev": true, "funding": [ { "type": "opencollective", @@ -34591,7 +37145,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true, "engines": { "node": ">= 0.4.0" } @@ -34661,7 +37214,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -34753,6 +37305,12 @@ "node": ">=4" } }, + "node_modules/vlq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz", + "integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==", + "peer": true + }, "node_modules/vm-browserify": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", @@ -34790,7 +37348,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, "dependencies": { "makeerror": "1.0.12" } @@ -35126,7 +37683,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, "dependencies": { "defaults": "^1.0.3" } @@ -36100,6 +38656,12 @@ "node": ">=0.10.0" } }, + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", + "peer": true + }, "node_modules/whatwg-mimetype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", @@ -36121,7 +38683,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -36148,6 +38709,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "peer": true + }, "node_modules/which-typed-array": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", @@ -36552,7 +39119,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -36568,8 +39134,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/write-file-atomic": { "version": "3.0.3", @@ -36587,7 +39152,6 @@ "version": "6.2.2", "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", - "dev": true, "dependencies": { "async-limiter": "~1.0.0" } @@ -36647,7 +39211,6 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, "engines": { "node": ">=10" } @@ -36655,8 +39218,7 @@ "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/yaml": { "version": "1.10.2", @@ -36717,7 +39279,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, "engines": { "node": ">=10" }, @@ -36725,6 +39286,29 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zdog": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/zdog/-/zdog-1.1.3.tgz", + "integrity": "sha512-raRj6r0gPzopFm5XWBJZr/NuV4EEnT4iE+U3dp5FV5pCb588Gmm3zLIp/j9yqqcMiHH8VNQlerLTgOqL7krh6w==", + "peer": true + }, + "node_modules/zustand": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz", + "integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==", + "peer": true, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + } + } + }, "node_modules/zwitch": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", @@ -36747,114 +39331,56 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, "requires": { "@jridgewell/gen-mapping": "^0.1.0", "@jridgewell/trace-mapping": "^0.3.9" } }, "@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", - "dev": true, + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", "requires": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "@babel/highlight": "^7.24.2", + "picocolors": "^1.0.0" } }, "@babel/compat-data": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.1.tgz", - "integrity": "sha512-72a9ghR0gnESIa7jBN53U32FOVCEoztyIlKaNoU05zRhEecduGK9L9c3ww7Mp06JiR+0ls0GBPFJQwwtjn9ksg==", - "dev": true + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.1.tgz", + "integrity": "sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA==" }, "@babel/core": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.1.tgz", - "integrity": "sha512-1H8VgqXme4UXCRv7/Wa1bq7RVymKOzC7znjyFM8KiEzwFqcKUKYNoQef4GhdklgNvoBXyW4gYhuBNCM5o1zImw==", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.0", - "@babel/helper-compilation-targets": "^7.19.1", - "@babel/helper-module-transforms": "^7.19.0", - "@babel/helpers": "^7.19.0", - "@babel/parser": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0", - "convert-source-map": "^1.7.0", + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.3.tgz", + "integrity": "sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==", + "requires": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.2", + "@babel/generator": "^7.24.1", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.24.1", + "@babel/parser": "^7.24.1", + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.1", + "@babel/types": "^7.24.0", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" }, "dependencies": { + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, "semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" } } }, @@ -36884,89 +39410,104 @@ } }, "@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", - "dev": true, + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.1.tgz", + "integrity": "sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==", "requires": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", + "@babel/types": "^7.24.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" }, "dependencies": { "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "requires": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" } } } }, "@babel/helper-annotate-as-pure": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", - "dev": true, + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", - "dev": true, "requires": { "@babel/helper-explode-assignable-expression": "^7.18.6", "@babel/types": "^7.18.9" } }, "@babel/helper-compilation-targets": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.1.tgz", - "integrity": "sha512-LlLkkqhCMyz2lkQPvJNdIYU7O5YjWRgC2R4omjCTpZd8u8KMQzZvX4qce+/BluN1rcQiV7BoGUpmQ0LeHerbhg==", - "dev": true, + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", "requires": { - "@babel/compat-data": "^7.19.1", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "dependencies": { + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "requires": { + "yallist": "^3.0.2" + } + }, "semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" } } }, "@babel/helper-create-class-features-plugin": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz", - "integrity": "sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw==", - "dev": true, + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.1.tgz", + "integrity": "sha512-1yJa9dX9g//V6fDebXoEfEsxkZHk3Hcbm+zLhyu6qVgYFLvmTALTeV+jNU9e5RnYtioBrGEOdoI2joMSNQ/+aA==", "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.9", - "@babel/helper-split-export-declaration": "^7.18.6" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.24.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + } } }, "@babel/helper-create-regexp-features-plugin": { "version": "7.19.0", "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==", - "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", "regexpu-core": "^5.1.0" @@ -36976,7 +39517,6 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", - "dev": true, "requires": { "@babel/helper-compilation-targets": "^7.17.7", "@babel/helper-plugin-utils": "^7.16.7", @@ -36989,22 +39529,19 @@ "semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" } } }, "@babel/helper-environment-visitor": { "version": "7.22.20", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==" }, "@babel/helper-explode-assignable-expression": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", - "dev": true, "requires": { "@babel/types": "^7.18.6" } @@ -37013,7 +39550,6 @@ "version": "7.23.0", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dev": true, "requires": { "@babel/template": "^7.22.15", "@babel/types": "^7.23.0" @@ -37023,108 +39559,91 @@ "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dev": true, "requires": { "@babel/types": "^7.22.5" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", - "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", - "dev": true, + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", "requires": { - "@babel/types": "^7.18.9" + "@babel/types": "^7.23.0" } }, "@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", - "dev": true, + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", + "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.24.0" } }, "@babel/helper-module-transforms": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", - "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==", - "dev": true, + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.18.6", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" } }, "@babel/helper-optimise-call-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", - "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", - "dev": true, + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" } }, "@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", - "dev": true + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", + "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==" }, "@babel/helper-remap-async-to-generator": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", - "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", - "dev": true, + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-wrap-function": "^7.18.9", - "@babel/types": "^7.18.9" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" } }, "@babel/helper-replace-supers": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", - "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", - "dev": true, + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz", + "integrity": "sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==", "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5" } }, "@babel/helper-simple-access": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", - "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", - "dev": true, + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" } }, "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz", - "integrity": "sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==", - "dev": true, + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", "requires": { - "@babel/types": "^7.18.9" + "@babel/types": "^7.22.5" } }, "@babel/helper-split-export-declaration": { "version": "7.22.6", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "dev": true, "requires": { "@babel/types": "^7.22.5" } @@ -37132,60 +39651,53 @@ "@babel/helper-string-parser": { "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", - "dev": true + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==" }, "@babel/helper-validator-identifier": { "version": "7.22.20", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "dev": true + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==" }, "@babel/helper-validator-option": { "version": "7.23.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", - "dev": true + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==" }, "@babel/helper-wrap-function": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", - "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==", - "dev": true, + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", "requires": { - "@babel/helper-function-name": "^7.19.0", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" } }, "@babel/helpers": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.0.tgz", - "integrity": "sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==", - "dev": true, + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.1.tgz", + "integrity": "sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg==", "requires": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.1", + "@babel/types": "^7.24.0" } }, "@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", - "dev": true, + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", "requires": { "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "dependencies": { "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -37194,7 +39706,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -37205,7 +39716,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -37213,26 +39723,22 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -37240,16 +39746,14 @@ } }, "@babel/parser": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", - "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", - "dev": true + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", + "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==" }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6" } @@ -37258,7 +39762,6 @@ "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.9", "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", @@ -37269,7 +39772,6 @@ "version": "7.19.1", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.1.tgz", "integrity": "sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q==", - "dev": true, "requires": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-plugin-utils": "^7.19.0", @@ -37281,7 +39783,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "dev": true, "requires": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -37291,7 +39792,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", - "dev": true, "requires": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6", @@ -37315,7 +39815,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-dynamic-import": "^7.8.3" @@ -37325,7 +39824,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.23.3.tgz", "integrity": "sha512-Q23MpLZfSGZL1kU7fWqV262q65svLSCIP5kZ/JCW/rKTCm/FrLjpvEd2kfUYMVeHh4QhV/xzyoRAHWrAZJrE3Q==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-export-default-from": "^7.23.3" @@ -37335,7 +39833,6 @@ "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.9", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" @@ -37345,7 +39842,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-json-strings": "^7.8.3" @@ -37355,7 +39851,6 @@ "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.9", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" @@ -37365,7 +39860,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" @@ -37375,43 +39869,39 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-numeric-separator": "^7.10.4" } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz", - "integrity": "sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q==", - "dev": true, + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", + "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", "requires": { - "@babel/compat-data": "^7.18.8", - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9", + "@babel/compat-data": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.18.8" + "@babel/plugin-transform-parameters": "^7.20.7" } }, "@babel/plugin-proposal-optional-catch-binding": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", - "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", - "dev": true, + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", "@babel/plugin-syntax-optional-chaining": "^7.8.3" } }, @@ -37419,7 +39909,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", - "dev": true, "requires": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -37429,7 +39918,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", - "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-create-class-features-plugin": "^7.18.6", @@ -37441,7 +39929,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", - "dev": true, "requires": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -37451,7 +39938,6 @@ "version": "7.8.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" } @@ -37469,7 +39955,6 @@ "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.12.13" } @@ -37478,7 +39963,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" } @@ -37496,7 +39980,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" } @@ -37505,7 +39988,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.23.3.tgz", "integrity": "sha512-KeENO5ck1IeZ/l2lFZNy+mpobV3D2Zy5C1YFnWm+YuY5mQiAWc4yAp13dqgguwsBsFVLh4LPCEqCa5qW13N+hw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.22.5" } @@ -37514,7 +39996,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" } @@ -37523,7 +40004,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.23.3.tgz", "integrity": "sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.22.5" } @@ -37532,7 +40012,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz", "integrity": "sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6" } @@ -37550,7 +40029,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" } @@ -37559,7 +40037,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6" } @@ -37568,7 +40045,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } @@ -37577,7 +40053,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" } @@ -37586,7 +40061,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } @@ -37595,7 +40069,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" } @@ -37604,7 +40077,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" } @@ -37613,7 +40085,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" } @@ -37622,7 +40093,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" } @@ -37631,7 +40101,6 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.14.5" } @@ -37640,7 +40109,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6" } @@ -37649,27 +40117,24 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", - "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", - "dev": true, + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.1.tgz", + "integrity": "sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==", "requires": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-remap-async-to-generator": "^7.18.6" + "@babel/helper-module-imports": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-remap-async-to-generator": "^7.22.20" } }, "@babel/plugin-transform-block-scoped-functions": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6" } @@ -37678,7 +40143,6 @@ "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz", "integrity": "sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.9" } @@ -37687,7 +40151,6 @@ "version": "7.19.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz", "integrity": "sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A==", - "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-compilation-targets": "^7.19.0", @@ -37703,8 +40166,7 @@ "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" } } }, @@ -37712,25 +40174,22 @@ "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.9" } }, "@babel/plugin-transform-destructuring": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.13.tgz", - "integrity": "sha512-TodpQ29XekIsex2A+YJPj5ax2plkGa8YYY6mFjCohk/IG9IY42Rtuj1FuDeemfg2ipxIFLzPeA83SIBnlhSIow==", - "dev": true, + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.1.tgz", + "integrity": "sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-dotall-regex": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", - "dev": true, "requires": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -37740,7 +40199,6 @@ "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.9" } @@ -37749,7 +40207,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", - "dev": true, "requires": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -37759,7 +40216,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.23.3.tgz", "integrity": "sha512-26/pQTf9nQSNVJCrLB1IkHUKyPxR+lMrH2QDPG89+Znu9rAMbtrybdbWeE9bb7gzjmE5iXHEY+e0HUwM6Co93Q==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-flow": "^7.23.3" @@ -37769,7 +40225,6 @@ "version": "7.18.8", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6" } @@ -37778,7 +40233,6 @@ "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", - "dev": true, "requires": { "@babel/helper-compilation-targets": "^7.18.9", "@babel/helper-function-name": "^7.18.9", @@ -37789,7 +40243,6 @@ "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.9" } @@ -37798,7 +40251,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6" } @@ -37807,7 +40259,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz", "integrity": "sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg==", - "dev": true, "requires": { "@babel/helper-module-transforms": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6", @@ -37818,7 +40269,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz", "integrity": "sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q==", - "dev": true, "requires": { "@babel/helper-module-transforms": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6", @@ -37830,7 +40280,6 @@ "version": "7.19.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.0.tgz", "integrity": "sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A==", - "dev": true, "requires": { "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-module-transforms": "^7.19.0", @@ -37843,7 +40292,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", - "dev": true, "requires": { "@babel/helper-module-transforms": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -37853,7 +40301,6 @@ "version": "7.19.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", "integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==", - "dev": true, "requires": { "@babel/helper-create-regexp-features-plugin": "^7.19.0", "@babel/helper-plugin-utils": "^7.19.0" @@ -37863,7 +40310,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6" } @@ -37881,26 +40327,45 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/helper-replace-supers": "^7.18.6" } }, "@babel/plugin-transform-parameters": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz", - "integrity": "sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg==", - "dev": true, + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.1.tgz", + "integrity": "sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.0" + } + }, + "@babel/plugin-transform-private-methods": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz", + "integrity": "sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==", + "peer": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0" + } + }, + "@babel/plugin-transform-private-property-in-object": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.1.tgz", + "integrity": "sha512-pTHxDVa0BpUbvAgX3Gat+7cSciXqUcY9j2VZKTbSB6+VQGpNgNO9ailxTGHSXlqOnX1Hcx1Enme2+yv7VqP9bg==", + "peer": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" } }, "@babel/plugin-transform-property-literals": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6" } @@ -37909,7 +40374,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz", "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6" } @@ -37918,7 +40382,6 @@ "version": "7.19.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz", "integrity": "sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==", - "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-module-imports": "^7.18.6", @@ -37936,6 +40399,24 @@ "@babel/plugin-transform-react-jsx": "^7.18.6" } }, + "@babel/plugin-transform-react-jsx-self": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.1.tgz", + "integrity": "sha512-kDJgnPujTmAZ/9q2CN4m2/lRsUUPDvsG3+tSHWUJIzMGTt5U/b/fwWd3RO3n+5mjLrsBrVa5eKFRVSQbi3dF1w==", + "peer": true, + "requires": { + "@babel/helper-plugin-utils": "^7.24.0" + } + }, + "@babel/plugin-transform-react-jsx-source": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.1.tgz", + "integrity": "sha512-1v202n7aUq4uXAieRTKcwPzNyphlCuqHHDcdSNc+vdhoTEZcFMh+L5yZuCmGaIO7bs1nJUNfHB89TZyoL48xNA==", + "peer": true, + "requires": { + "@babel/helper-plugin-utils": "^7.24.0" + } + }, "@babel/plugin-transform-react-pure-annotations": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz", @@ -37950,7 +40431,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6", "regenerator-transform": "^0.15.0" @@ -37960,16 +40440,79 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6" } }, + "@babel/plugin-transform-runtime": { + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.3.tgz", + "integrity": "sha512-J0BuRPNlNqlMTRJ72eVptpt9VcInbxO6iP3jaxr+1NPhC0UkKL+6oeX6VXMEYdADnuqmMmsBspt4d5w8Y/TCbQ==", + "peer": true, + "requires": { + "@babel/helper-module-imports": "^7.24.3", + "@babel/helper-plugin-utils": "^7.24.0", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.1", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" + }, + "dependencies": { + "@babel/helper-define-polyfill-provider": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz", + "integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==", + "peer": true, + "requires": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + } + }, + "babel-plugin-polyfill-corejs2": { + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz", + "integrity": "sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==", + "peer": true, + "requires": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.1", + "semver": "^6.3.1" + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", + "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", + "peer": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.6.1", + "core-js-compat": "^3.36.1" + } + }, + "babel-plugin-polyfill-regenerator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.1.tgz", + "integrity": "sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g==", + "peer": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.6.1" + } + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "peer": true + } + } + }, "@babel/plugin-transform-shorthand-properties": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6" } @@ -37978,7 +40521,6 @@ "version": "7.19.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.19.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" @@ -37988,7 +40530,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6" } @@ -37997,7 +40538,6 @@ "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.9" } @@ -38006,7 +40546,6 @@ "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.9" } @@ -38015,7 +40554,6 @@ "version": "7.19.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.19.1.tgz", "integrity": "sha512-+ILcOU+6mWLlvCwnL920m2Ow3wWx3Wo8n2t5aROQmV55GZt+hOiLvBaa3DNzRjSEHa1aauRs4/YLmkCfFkhhRQ==", - "dev": true, "requires": { "@babel/helper-create-class-features-plugin": "^7.19.0", "@babel/helper-plugin-utils": "^7.19.0", @@ -38026,7 +40564,6 @@ "version": "7.18.10", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.9" } @@ -38035,7 +40572,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", - "dev": true, "requires": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -38045,7 +40581,6 @@ "version": "7.19.1", "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.19.1.tgz", "integrity": "sha512-c8B2c6D16Lp+Nt6HcD+nHl0VbPKVnNPTpszahuxJJnurfMtKeZ80A+qUv48Y7wqvS+dTFuLuaM9oYxyNHbCLWA==", - "dev": true, "requires": { "@babel/compat-data": "^7.19.1", "@babel/helper-compilation-targets": "^7.19.1", @@ -38127,8 +40662,7 @@ "semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" } } }, @@ -38136,7 +40670,6 @@ "version": "7.23.3", "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.23.3.tgz", "integrity": "sha512-7yn6hl8RIv+KNk6iIrGZ+D06VhVY35wLVf23Cz/mMu1zOr7u4MMP4j0nZ9tLf8+4ZFpnib8cFYgB/oYg9hfswA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-option": "^7.22.15", @@ -38147,7 +40680,6 @@ "version": "0.1.5", "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", @@ -38174,7 +40706,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz", "integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/helper-validator-option": "^7.18.6", @@ -38185,7 +40716,6 @@ "version": "7.23.7", "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.23.7.tgz", "integrity": "sha512-EjJeB6+kvpk+Y5DAkEAmbOBEFkh9OASx0huoEkqYTFxAZHzOAX2Oh5uwAUuL2rUddqfM0SA+KPXV2TbzoZ2kvQ==", - "dev": true, "requires": { "clone-deep": "^4.0.1", "find-cache-dir": "^2.0.0", @@ -38198,7 +40728,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, "requires": { "commondir": "^1.0.1", "make-dir": "^2.0.0", @@ -38209,7 +40738,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, "requires": { "locate-path": "^3.0.0" } @@ -38218,7 +40746,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" @@ -38228,7 +40755,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, "requires": { "pify": "^4.0.1", "semver": "^5.6.0" @@ -38238,7 +40764,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, "requires": { "p-try": "^2.0.0" } @@ -38247,7 +40772,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, "requires": { "p-limit": "^2.0.0" } @@ -38255,20 +40779,17 @@ "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==" }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" }, "pkg-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, "requires": { "find-up": "^3.0.0" } @@ -38276,8 +40797,7 @@ "semver": { "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==" } } }, @@ -38290,30 +40810,28 @@ } }, "@babel/template": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz", - "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==", - "dev": true, + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", + "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", "requires": { "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9" + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0" } }, "@babel/traverse": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz", - "integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==", - "dev": true, + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", + "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", "requires": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", + "@babel/code-frame": "^7.24.1", + "@babel/generator": "^7.24.1", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9", + "@babel/parser": "^7.24.1", + "@babel/types": "^7.24.0", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -38321,16 +40839,14 @@ "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" } } }, "@babel/types": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz", - "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==", - "dev": true, + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", "requires": { "@babel/helper-string-parser": "^7.23.4", "@babel/helper-validator-identifier": "^7.22.20", @@ -38401,6 +40917,21 @@ "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", "dev": true }, + "@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", + "peer": true + }, + "@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "peer": true, + "requires": { + "@hapi/hoek": "^9.0.0" + } + }, "@humanwhocodes/config-array": { "version": "0.10.5", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.5.tgz", @@ -38436,6 +40967,12 @@ "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", "dev": true }, + "@isaacs/ttlcache": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@isaacs/ttlcache/-/ttlcache-1.4.1.tgz", + "integrity": "sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==", + "peer": true + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -38725,6 +41262,15 @@ } } }, + "@jest/create-cache-key-function": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz", + "integrity": "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==", + "peer": true, + "requires": { + "@jest/types": "^29.6.3" + } + }, "@jest/environment": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", @@ -39057,12 +41603,11 @@ } }, "@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", - "dev": true, + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "requires": { - "@sinclair/typebox": "^0.25.16" + "@sinclair/typebox": "^0.27.8" } }, "@jest/source-map": { @@ -39186,12 +41731,11 @@ } }, "@jest/types": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", - "dev": true, + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "requires": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -39203,7 +41747,6 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, "requires": { "@jridgewell/set-array": "^1.0.0", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -39212,20 +41755,17 @@ "@jridgewell/resolve-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" }, "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==" }, "@jridgewell/source-map": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", - "dev": true, "requires": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -39235,7 +41775,6 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, "requires": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -39247,14 +41786,12 @@ "@jridgewell/sourcemap-codec": { "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "@jridgewell/trace-mapping": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", - "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", - "dev": true, + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "requires": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -39543,252 +42080,1027 @@ "ramda": "^0.27.1" } }, - "@lingui/react": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/@lingui/react/-/react-3.14.0.tgz", - "integrity": "sha512-ow9Mtru7f0T2S9AwnPWRejppcucCW0LmoDR3P4wqHjL+eH5f8a6nxd2doxGieC91/2i4qqW88y4K/zXJxwRSQw==", - "dev": true, + "@lingui/react": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/@lingui/react/-/react-3.14.0.tgz", + "integrity": "sha512-ow9Mtru7f0T2S9AwnPWRejppcucCW0LmoDR3P4wqHjL+eH5f8a6nxd2doxGieC91/2i4qqW88y4K/zXJxwRSQw==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.11.2", + "@lingui/core": "^3.14.0" + } + }, + "@mdn/browser-compat-data": { + "version": "5.5.11", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.5.11.tgz", + "integrity": "sha512-4o1ZaGmvqoDx3QLyEAcZvGDKmdVXLB0aiANuPDumgue/7iH67KUBsKejLX7wrdxEdyNYfXUKtjFQYhGwVUBXGw==", + "dev": true + }, + "@mdx-js/mdx": { + "version": "1.6.22", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.6.22.tgz", + "integrity": "sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA==", + "dev": true, + "requires": { + "@babel/core": "7.12.9", + "@babel/plugin-syntax-jsx": "7.12.1", + "@babel/plugin-syntax-object-rest-spread": "7.8.3", + "@mdx-js/util": "1.6.22", + "babel-plugin-apply-mdx-type-prop": "1.6.22", + "babel-plugin-extract-import-names": "1.6.22", + "camelcase-css": "2.0.1", + "detab": "2.0.4", + "hast-util-raw": "6.0.1", + "lodash.uniq": "4.5.0", + "mdast-util-to-hast": "10.0.1", + "remark-footnotes": "2.0.0", + "remark-mdx": "1.6.22", + "remark-parse": "8.0.3", + "remark-squeeze-paragraphs": "4.0.0", + "style-to-object": "0.3.0", + "unified": "9.2.0", + "unist-builder": "2.0.3", + "unist-util-visit": "2.0.3" + }, + "dependencies": { + "@babel/core": { + "version": "7.12.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.9.tgz", + "integrity": "sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.12.5", + "@babel/helper-module-transforms": "^7.12.1", + "@babel/helpers": "^7.12.5", + "@babel/parser": "^7.12.7", + "@babel/template": "^7.12.7", + "@babel/traverse": "^7.12.9", + "@babel/types": "^7.12.7", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.19", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz", + "integrity": "sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true + } + } + }, + "@mdx-js/util": { + "version": "1.6.22", + "resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-1.6.22.tgz", + "integrity": "sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==", + "dev": true + }, + "@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dev": true, + "requires": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + }, + "dependencies": { + "glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==", + "dev": true + } + } + }, + "@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "dev": true, + "requires": { + "eslint-scope": "5.1.1" + }, + "dependencies": { + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + } + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@npmcli/fs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", + "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", + "dev": true, + "requires": { + "@gar/promisify": "^1.0.1", + "semver": "^7.3.5" + } + }, + "@npmcli/move-file": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", + "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", + "dev": true, + "requires": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + } + }, + "@polka/url": { + "version": "1.0.0-next.21", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", + "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==", + "dev": true + }, + "@preact/async-loader": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@preact/async-loader/-/async-loader-3.0.2.tgz", + "integrity": "sha512-nYIdlAGbZ0+0/u5VJxQdLDgNFgEJmNLzctuqnCBZxW/EpLPMg8lcsnRsoXVl+O28ZZYhVhos3XiWM3KtuN0C3Q==", + "dev": true, + "requires": { + "kleur": "^4.1.4", + "loader-utils": "^2.0.0" + }, + "dependencies": { + "kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true + } + } + }, + "@prefresh/babel-plugin": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@prefresh/babel-plugin/-/babel-plugin-0.4.3.tgz", + "integrity": "sha512-fYAWbU1WDSLn108kKY4eDaaeUcnszFqXjgaGKYXNZ5NLulpRTpsrY+Sbfo9q8LDpWrBpqIgzjrwNnvglWI1xNQ==", + "dev": true + }, + "@prefresh/core": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@prefresh/core/-/core-1.4.1.tgz", + "integrity": "sha512-og1vaBj3LMJagVncNrDb37Gqc0cWaUcDbpVt5hZtsN4i2Iwzd/5hyTsDHvlMirhSym3wL9ihU0Xa2VhSaOue7g==", + "dev": true, + "requires": {} + }, + "@prefresh/utils": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@prefresh/utils/-/utils-1.1.3.tgz", + "integrity": "sha512-Mb9abhJTOV4yCfkXrMrcgFiFT7MfNOw8sDa+XyZBdq/Ai2p4Zyxqsb3EgHLOEdHpMj6J9aiZ54W8H6FTam1u+A==", + "dev": true + }, + "@prefresh/webpack": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@prefresh/webpack/-/webpack-3.3.4.tgz", + "integrity": "sha512-RiXS/hvXDup5cQw/267kxkKie81kxaAB7SFbkr8ppshobDEzwgUN1tbGbHNx6Uari0Ql2XByC6HIgQGpaq2Q7w==", + "dev": true, + "requires": { + "@prefresh/core": "^1.3.3", + "@prefresh/utils": "^1.1.2" + } + }, + "@react-leaflet/core": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-2.1.0.tgz", + "integrity": "sha512-Qk7Pfu8BSarKGqILj4x7bCSZ1pjuAPZ+qmRwH5S7mDS91VSbVVsJSrW4qA+GPrro8t69gFYVMWb1Zc4yFmPiVg==", + "requires": {} + }, + "@react-native-community/cli": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-12.3.6.tgz", + "integrity": "sha512-647OSi6xBb8FbwFqX9zsJxOzu685AWtrOUWHfOkbKD+5LOpGORw+GQo0F9rWZnB68rLQyfKUZWJeaD00pGv5fw==", + "peer": true, + "requires": { + "@react-native-community/cli-clean": "12.3.6", + "@react-native-community/cli-config": "12.3.6", + "@react-native-community/cli-debugger-ui": "12.3.6", + "@react-native-community/cli-doctor": "12.3.6", + "@react-native-community/cli-hermes": "12.3.6", + "@react-native-community/cli-plugin-metro": "12.3.6", + "@react-native-community/cli-server-api": "12.3.6", + "@react-native-community/cli-tools": "12.3.6", + "@react-native-community/cli-types": "12.3.6", + "chalk": "^4.1.2", + "commander": "^9.4.1", + "deepmerge": "^4.3.0", + "execa": "^5.0.0", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "graceful-fs": "^4.1.3", + "prompts": "^2.4.2", + "semver": "^7.5.2" + }, + "dependencies": { + "commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "peer": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "peer": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "peer": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "peer": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "peer": true, + "requires": { + "p-limit": "^2.2.0" + } + } + } + }, + "@react-native-community/cli-clean": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-clean/-/cli-clean-12.3.6.tgz", + "integrity": "sha512-gUU29ep8xM0BbnZjwz9MyID74KKwutq9x5iv4BCr2im6nly4UMf1B1D+V225wR7VcDGzbgWjaezsJShLLhC5ig==", + "peer": true, + "requires": { + "@react-native-community/cli-tools": "12.3.6", + "chalk": "^4.1.2", + "execa": "^5.0.0" + } + }, + "@react-native-community/cli-config": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-config/-/cli-config-12.3.6.tgz", + "integrity": "sha512-JGWSYQ9EAK6m2v0abXwFLEfsqJ1zkhzZ4CV261QZF9MoUNB6h57a274h1MLQR9mG6Tsh38wBUuNfEPUvS1vYew==", + "peer": true, + "requires": { + "@react-native-community/cli-tools": "12.3.6", + "chalk": "^4.1.2", + "cosmiconfig": "^5.1.0", + "deepmerge": "^4.3.0", + "glob": "^7.1.3", + "joi": "^17.2.1" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "peer": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "peer": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", + "peer": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "peer": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "peer": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "peer": true + } + } + }, + "@react-native-community/cli-debugger-ui": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-12.3.6.tgz", + "integrity": "sha512-SjUKKsx5FmcK9G6Pb6UBFT0s9JexVStK5WInmANw75Hm7YokVvHEgtprQDz2Uvy5znX5g2ujzrkIU//T15KQzA==", + "peer": true, + "requires": { + "serve-static": "^1.13.1" + } + }, + "@react-native-community/cli-doctor": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-doctor/-/cli-doctor-12.3.6.tgz", + "integrity": "sha512-fvBDv2lTthfw4WOQKkdTop2PlE9GtfrlNnpjB818MhcdEnPjfQw5YaTUcnNEGsvGomdCs1MVRMgYXXwPSN6OvQ==", + "peer": true, + "requires": { + "@react-native-community/cli-config": "12.3.6", + "@react-native-community/cli-platform-android": "12.3.6", + "@react-native-community/cli-platform-ios": "12.3.6", + "@react-native-community/cli-tools": "12.3.6", + "chalk": "^4.1.2", + "command-exists": "^1.2.8", + "deepmerge": "^4.3.0", + "envinfo": "^7.10.0", + "execa": "^5.0.0", + "hermes-profile-transformer": "^0.0.6", + "node-stream-zip": "^1.9.1", + "ora": "^5.4.1", + "semver": "^7.5.2", + "strip-ansi": "^5.2.0", + "wcwidth": "^1.0.1", + "yaml": "^2.2.1" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "peer": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "peer": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "yaml": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", + "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", + "peer": true + } + } + }, + "@react-native-community/cli-hermes": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-hermes/-/cli-hermes-12.3.6.tgz", + "integrity": "sha512-sNGwfOCl8OAIjWCkwuLpP8NZbuO0dhDI/2W7NeOGDzIBsf4/c4MptTrULWtGIH9okVPLSPX0NnRyGQ+mSwWyuQ==", + "peer": true, + "requires": { + "@react-native-community/cli-platform-android": "12.3.6", + "@react-native-community/cli-tools": "12.3.6", + "chalk": "^4.1.2", + "hermes-profile-transformer": "^0.0.6" + } + }, + "@react-native-community/cli-platform-android": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-12.3.6.tgz", + "integrity": "sha512-DeDDAB8lHpuGIAPXeeD9Qu2+/wDTFPo99c8uSW49L0hkmZJixzvvvffbGQAYk32H0TmaI7rzvzH+qzu7z3891g==", + "peer": true, + "requires": { + "@react-native-community/cli-tools": "12.3.6", + "chalk": "^4.1.2", + "execa": "^5.0.0", + "fast-xml-parser": "^4.2.4", + "glob": "^7.1.3", + "logkitty": "^0.7.1" + } + }, + "@react-native-community/cli-platform-ios": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-ios/-/cli-platform-ios-12.3.6.tgz", + "integrity": "sha512-3eZ0jMCkKUO58wzPWlvAPRqezVKm9EPZyaPyHbRPWU8qw7JqkvnRlWIaYDGpjCJgVW4k2hKsEursLtYKb188tg==", + "peer": true, + "requires": { + "@react-native-community/cli-tools": "12.3.6", + "chalk": "^4.1.2", + "execa": "^5.0.0", + "fast-xml-parser": "^4.0.12", + "glob": "^7.1.3", + "ora": "^5.4.1" + } + }, + "@react-native-community/cli-plugin-metro": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-12.3.6.tgz", + "integrity": "sha512-3jxSBQt4fkS+KtHCPSyB5auIT+KKIrPCv9Dk14FbvOaEh9erUWEm/5PZWmtboW1z7CYeNbFMeXm9fM2xwtVOpg==", + "peer": true + }, + "@react-native-community/cli-server-api": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-server-api/-/cli-server-api-12.3.6.tgz", + "integrity": "sha512-80NIMzo8b2W+PL0Jd7NjiJW9mgaT8Y8wsIT/lh6mAvYH7mK0ecDJUYUTAAv79Tbo1iCGPAr3T295DlVtS8s4yQ==", + "peer": true, + "requires": { + "@react-native-community/cli-debugger-ui": "12.3.6", + "@react-native-community/cli-tools": "12.3.6", + "compression": "^1.7.1", + "connect": "^3.6.5", + "errorhandler": "^1.5.1", + "nocache": "^3.0.1", + "pretty-format": "^26.6.2", + "serve-static": "^1.13.1", + "ws": "^7.5.1" + }, + "dependencies": { + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "peer": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "15.0.19", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.19.tgz", + "integrity": "sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA==", + "peer": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "peer": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "peer": true + }, + "ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "peer": true, + "requires": {} + } + } + }, + "@react-native-community/cli-tools": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-12.3.6.tgz", + "integrity": "sha512-FPEvZn19UTMMXUp/piwKZSh8cMEfO8G3KDtOwo53O347GTcwNrKjgZGtLSPELBX2gr+YlzEft3CoRv2Qmo83fQ==", + "peer": true, + "requires": { + "appdirsjs": "^1.2.4", + "chalk": "^4.1.2", + "find-up": "^5.0.0", + "mime": "^2.4.1", + "node-fetch": "^2.6.0", + "open": "^6.2.0", + "ora": "^5.4.1", + "semver": "^7.5.2", + "shell-quote": "^1.7.3", + "sudo-prompt": "^9.0.0" + }, + "dependencies": { + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==", + "peer": true + }, + "mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "peer": true + }, + "open": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", + "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", + "peer": true, + "requires": { + "is-wsl": "^1.1.0" + } + } + } + }, + "@react-native-community/cli-types": { + "version": "12.3.6", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-types/-/cli-types-12.3.6.tgz", + "integrity": "sha512-xPqTgcUtZowQ8WKOkI9TLGBwH2bGggOC4d2FFaIRST3gTcjrEeGRNeR5aXCzJFIgItIft8sd7p2oKEdy90+01Q==", + "peer": true, + "requires": { + "joi": "^17.2.1" + } + }, + "@react-native/assets-registry": { + "version": "0.73.1", + "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.73.1.tgz", + "integrity": "sha512-2FgAbU7uKM5SbbW9QptPPZx8N9Ke2L7bsHb+EhAanZjFZunA9PaYtyjUQ1s7HD+zDVqOQIvjkpXSv7Kejd2tqg==", + "peer": true + }, + "@react-native/babel-plugin-codegen": { + "version": "0.73.4", + "resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.73.4.tgz", + "integrity": "sha512-XzRd8MJGo4Zc5KsphDHBYJzS1ryOHg8I2gOZDAUCGcwLFhdyGu1zBNDJYH2GFyDrInn9TzAbRIf3d4O+eltXQQ==", "peer": true, "requires": { - "@babel/runtime": "^7.11.2", - "@lingui/core": "^3.14.0" + "@react-native/codegen": "0.73.3" } }, - "@mdn/browser-compat-data": { - "version": "5.5.11", - "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.5.11.tgz", - "integrity": "sha512-4o1ZaGmvqoDx3QLyEAcZvGDKmdVXLB0aiANuPDumgue/7iH67KUBsKejLX7wrdxEdyNYfXUKtjFQYhGwVUBXGw==", - "dev": true + "@react-native/babel-preset": { + "version": "0.73.21", + "resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.73.21.tgz", + "integrity": "sha512-WlFttNnySKQMeujN09fRmrdWqh46QyJluM5jdtDNrkl/2Hx6N4XeDUGhABvConeK95OidVO7sFFf7sNebVXogA==", + "peer": true, + "requires": { + "@babel/core": "^7.20.0", + "@babel/plugin-proposal-async-generator-functions": "^7.0.0", + "@babel/plugin-proposal-class-properties": "^7.18.0", + "@babel/plugin-proposal-export-default-from": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.0", + "@babel/plugin-proposal-numeric-separator": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.20.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.20.0", + "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "@babel/plugin-syntax-export-default-from": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.18.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-syntax-optional-chaining": "^7.0.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-async-to-generator": "^7.20.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.20.0", + "@babel/plugin-transform-flow-strip-types": "^7.20.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-private-methods": "^7.22.5", + "@babel/plugin-transform-private-property-in-object": "^7.22.11", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-react-jsx-self": "^7.0.0", + "@babel/plugin-transform-react-jsx-source": "^7.0.0", + "@babel/plugin-transform-runtime": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-sticky-regex": "^7.0.0", + "@babel/plugin-transform-typescript": "^7.5.0", + "@babel/plugin-transform-unicode-regex": "^7.0.0", + "@babel/template": "^7.0.0", + "@react-native/babel-plugin-codegen": "0.73.4", + "babel-plugin-transform-flow-enums": "^0.0.2", + "react-refresh": "^0.14.0" + }, + "dependencies": { + "react-refresh": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", + "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", + "peer": true + } + } }, - "@mdx-js/mdx": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.6.22.tgz", - "integrity": "sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA==", - "dev": true, + "@react-native/codegen": { + "version": "0.73.3", + "resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.73.3.tgz", + "integrity": "sha512-sxslCAAb8kM06vGy9Jyh4TtvjhcP36k/rvj2QE2Jdhdm61KvfafCATSIsOfc0QvnduWFcpXUPvAVyYwuv7PYDg==", + "peer": true, "requires": { - "@babel/core": "7.12.9", - "@babel/plugin-syntax-jsx": "7.12.1", - "@babel/plugin-syntax-object-rest-spread": "7.8.3", - "@mdx-js/util": "1.6.22", - "babel-plugin-apply-mdx-type-prop": "1.6.22", - "babel-plugin-extract-import-names": "1.6.22", - "camelcase-css": "2.0.1", - "detab": "2.0.4", - "hast-util-raw": "6.0.1", - "lodash.uniq": "4.5.0", - "mdast-util-to-hast": "10.0.1", - "remark-footnotes": "2.0.0", - "remark-mdx": "1.6.22", - "remark-parse": "8.0.3", - "remark-squeeze-paragraphs": "4.0.0", - "style-to-object": "0.3.0", - "unified": "9.2.0", - "unist-builder": "2.0.3", - "unist-util-visit": "2.0.3" + "@babel/parser": "^7.20.0", + "flow-parser": "^0.206.0", + "glob": "^7.1.1", + "invariant": "^2.2.4", + "jscodeshift": "^0.14.0", + "mkdirp": "^0.5.1", + "nullthrows": "^1.1.1" }, "dependencies": { - "@babel/core": { - "version": "7.12.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.9.tgz", - "integrity": "sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==", - "dev": true, + "ast-types": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.15.2.tgz", + "integrity": "sha512-c27loCv9QkZinsa5ProX751khO9DJl/AcB5c2KNtA6NRvHKS0PgLfcftz72KVq504vB0Gku5s2kUZzDBvQWvHg==", + "peer": true, "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.5", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helpers": "^7.12.5", - "@babel/parser": "^7.12.7", - "@babel/template": "^7.12.7", - "@babel/traverse": "^7.12.9", - "@babel/types": "^7.12.7", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.19", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" + "tslib": "^2.0.1" } }, - "@babel/plugin-syntax-jsx": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz", - "integrity": "sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==", - "dev": true, + "flow-parser": { + "version": "0.206.0", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.206.0.tgz", + "integrity": "sha512-HVzoK3r6Vsg+lKvlIZzaWNBVai+FXTX1wdYhz/wVlH13tb/gOdLXmlTqy6odmTBhT5UoWUbq0k8263Qhr9d88w==", + "peer": true + }, + "jscodeshift": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.14.0.tgz", + "integrity": "sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==", + "peer": true, + "requires": { + "@babel/core": "^7.13.16", + "@babel/parser": "^7.13.16", + "@babel/plugin-proposal-class-properties": "^7.13.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", + "@babel/plugin-proposal-optional-chaining": "^7.13.12", + "@babel/plugin-transform-modules-commonjs": "^7.13.8", + "@babel/preset-flow": "^7.13.13", + "@babel/preset-typescript": "^7.13.0", + "@babel/register": "^7.13.16", + "babel-core": "^7.0.0-bridge.0", + "chalk": "^4.1.2", + "flow-parser": "0.*", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.4", + "neo-async": "^2.5.0", + "node-dir": "^0.1.17", + "recast": "^0.21.0", + "temp": "^0.8.4", + "write-file-atomic": "^2.3.0" + } + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "peer": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "minimist": "^1.2.6" } }, - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true + "recast": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.21.5.tgz", + "integrity": "sha512-hjMmLaUXAm1hIuTqOdeYObMslq/q+Xff6QE3Y2P+uoHAg2nmVlLBps2hzh1UJDdMtDTMXOFewK6ky51JQIeECg==", + "peer": true, + "requires": { + "ast-types": "0.15.2", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tslib": "^2.0.1" + } }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true + "write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "peer": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } } } }, - "@mdx-js/util": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-1.6.22.tgz", - "integrity": "sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==", - "dev": true - }, - "@mrmlnc/readdir-enhanced": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "dev": true, + "@react-native/community-cli-plugin": { + "version": "0.73.17", + "resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.73.17.tgz", + "integrity": "sha512-F3PXZkcHg+1ARIr6FRQCQiB7ZAA+MQXGmq051metRscoLvgYJwj7dgC8pvgy0kexzUkHu5BNKrZeySzUft3xuQ==", + "peer": true, "requires": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" - }, - "dependencies": { - "glob-to-regexp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==", - "dev": true - } - } + "@react-native-community/cli-server-api": "12.3.6", + "@react-native-community/cli-tools": "12.3.6", + "@react-native/dev-middleware": "0.73.8", + "@react-native/metro-babel-transformer": "0.73.15", + "chalk": "^4.0.0", + "execa": "^5.1.1", + "metro": "^0.80.3", + "metro-config": "^0.80.3", + "metro-core": "^0.80.3", + "node-fetch": "^2.2.0", + "readline": "^1.3.0" + } + }, + "@react-native/debugger-frontend": { + "version": "0.73.3", + "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.73.3.tgz", + "integrity": "sha512-RgEKnWuoo54dh7gQhV7kvzKhXZEhpF9LlMdZolyhGxHsBqZ2gXdibfDlfcARFFifPIiaZ3lXuOVVa4ei+uPgTw==", + "peer": true }, - "@nicolo-ribaudo/eslint-scope-5-internals": { - "version": "5.1.1-v1", - "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", - "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", - "dev": true, + "@react-native/dev-middleware": { + "version": "0.73.8", + "resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.73.8.tgz", + "integrity": "sha512-oph4NamCIxkMfUL/fYtSsE+JbGOnrlawfQ0kKtDQ5xbOjPKotKoXqrs1eGwozNKv7FfQ393stk1by9a6DyASSg==", + "peer": true, "requires": { - "eslint-scope": "5.1.1" + "@isaacs/ttlcache": "^1.4.1", + "@react-native/debugger-frontend": "0.73.3", + "chrome-launcher": "^0.15.2", + "chromium-edge-launcher": "^1.0.0", + "connect": "^3.6.5", + "debug": "^2.2.0", + "node-fetch": "^2.2.0", + "open": "^7.0.3", + "serve-static": "^1.13.1", + "temp-dir": "^2.0.0", + "ws": "^6.2.2" }, "dependencies": { - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "peer": true, "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "ms": "2.0.0" } }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "peer": true + }, + "open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "peer": true, + "requires": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + } } } }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, + "@react-native/gradle-plugin": { + "version": "0.73.4", + "resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.73.4.tgz", + "integrity": "sha512-PMDnbsZa+tD55Ug+W8CfqXiGoGneSSyrBZCMb5JfiB3AFST3Uj5e6lw8SgI/B6SKZF7lG0BhZ6YHZsRZ5MlXmg==", + "peer": true + }, + "@react-native/js-polyfills": { + "version": "0.73.1", + "resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.73.1.tgz", + "integrity": "sha512-ewMwGcumrilnF87H4jjrnvGZEaPFCAC4ebraEK+CurDDmwST/bIicI4hrOAv+0Z0F7DEK4O4H7r8q9vH7IbN4g==", + "peer": true + }, + "@react-native/metro-babel-transformer": { + "version": "0.73.15", + "resolved": "https://registry.npmjs.org/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.73.15.tgz", + "integrity": "sha512-LlkSGaXCz+xdxc9819plmpsl4P4gZndoFtpjN3GMBIu6f7TBV0GVbyJAU4GE8fuAWPVSVL5ArOcdkWKSbI1klw==", + "peer": true, "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "@babel/core": "^7.20.0", + "@react-native/babel-preset": "0.73.21", + "hermes-parser": "0.15.0", + "nullthrows": "^1.1.1" } }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true + "@react-native/normalize-colors": { + "version": "0.73.2", + "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.73.2.tgz", + "integrity": "sha512-bRBcb2T+I88aG74LMVHaKms2p/T8aQd8+BZ7LuuzXlRfog1bMWWn/C5i0HVuvW4RPtXQYgIlGiXVDy9Ir1So/w==", + "peer": true }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, + "@react-native/virtualized-lists": { + "version": "0.73.4", + "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.73.4.tgz", + "integrity": "sha512-HpmLg1FrEiDtrtAbXiwCgXFYyloK/dOIPIuWW3fsqukwJEWAiTzm1nXGJ7xPU5XTHiWZ4sKup5Ebaj8z7iyWog==", + "peer": true, "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "invariant": "^2.2.4", + "nullthrows": "^1.1.1" } }, - "@npmcli/fs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", - "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", - "dev": true, + "@react-spring/animated": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.3.tgz", + "integrity": "sha512-5CWeNJt9pNgyvuSzQH+uy2pvTg8Y4/OisoscZIR8/ZNLIOI+CatFBhGZpDGTF/OzdNFsAoGk3wiUYTwoJ0YIvw==", "requires": { - "@gar/promisify": "^1.0.1", - "semver": "^7.3.5" + "@react-spring/shared": "~9.7.3", + "@react-spring/types": "~9.7.3" } }, - "@npmcli/move-file": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", - "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", - "dev": true, + "@react-spring/core": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.3.tgz", + "integrity": "sha512-IqFdPVf3ZOC1Cx7+M0cXf4odNLxDC+n7IN3MDcVCTIOSBfqEcBebSv+vlY5AhM0zw05PDbjKrNmBpzv/AqpjnQ==", "requires": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" + "@react-spring/animated": "~9.7.3", + "@react-spring/shared": "~9.7.3", + "@react-spring/types": "~9.7.3" } }, - "@polka/url": { - "version": "1.0.0-next.21", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", - "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==", - "dev": true + "@react-spring/konva": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/konva/-/konva-9.7.3.tgz", + "integrity": "sha512-R9sY6SiPGYqz1383P5qppg5z57YfChVknOC1UxxaGxpw+WiZa8fZ4zmZobslrw+os3/+HAXZv8O+EvU/nQpf7g==", + "requires": { + "@react-spring/animated": "~9.7.3", + "@react-spring/core": "~9.7.3", + "@react-spring/shared": "~9.7.3", + "@react-spring/types": "~9.7.3" + } }, - "@preact/async-loader": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@preact/async-loader/-/async-loader-3.0.2.tgz", - "integrity": "sha512-nYIdlAGbZ0+0/u5VJxQdLDgNFgEJmNLzctuqnCBZxW/EpLPMg8lcsnRsoXVl+O28ZZYhVhos3XiWM3KtuN0C3Q==", - "dev": true, + "@react-spring/native": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/native/-/native-9.7.3.tgz", + "integrity": "sha512-4mpxX3FuEBCUT6ae2fjhxcJW6bhr2FBwFf274eXB7n+U30Gdg8Wo2qYwcUnmiAA0S3dvP8vLTazx3+CYWFShnA==", "requires": { - "kleur": "^4.1.4", - "loader-utils": "^2.0.0" - }, - "dependencies": { - "kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", - "dev": true - } + "@react-spring/animated": "~9.7.3", + "@react-spring/core": "~9.7.3", + "@react-spring/shared": "~9.7.3", + "@react-spring/types": "~9.7.3" } }, - "@prefresh/babel-plugin": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@prefresh/babel-plugin/-/babel-plugin-0.4.3.tgz", - "integrity": "sha512-fYAWbU1WDSLn108kKY4eDaaeUcnszFqXjgaGKYXNZ5NLulpRTpsrY+Sbfo9q8LDpWrBpqIgzjrwNnvglWI1xNQ==", - "dev": true + "@react-spring/shared": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.3.tgz", + "integrity": "sha512-NEopD+9S5xYyQ0pGtioacLhL2luflh6HACSSDUZOwLHoxA5eku1UPuqcJqjwSD6luKjjLfiLOspxo43FUHKKSA==", + "requires": { + "@react-spring/types": "~9.7.3" + } }, - "@prefresh/core": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@prefresh/core/-/core-1.4.1.tgz", - "integrity": "sha512-og1vaBj3LMJagVncNrDb37Gqc0cWaUcDbpVt5hZtsN4i2Iwzd/5hyTsDHvlMirhSym3wL9ihU0Xa2VhSaOue7g==", - "dev": true, - "requires": {} + "@react-spring/three": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/three/-/three-9.7.3.tgz", + "integrity": "sha512-Q1p512CqUlmMK8UMBF/Rj79qndhOWq4XUTayxMP9S892jiXzWQuj+xC3Xvm59DP/D4JXusXpxxqfgoH+hmOktA==", + "requires": { + "@react-spring/animated": "~9.7.3", + "@react-spring/core": "~9.7.3", + "@react-spring/shared": "~9.7.3", + "@react-spring/types": "~9.7.3" + } }, - "@prefresh/utils": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@prefresh/utils/-/utils-1.1.3.tgz", - "integrity": "sha512-Mb9abhJTOV4yCfkXrMrcgFiFT7MfNOw8sDa+XyZBdq/Ai2p4Zyxqsb3EgHLOEdHpMj6J9aiZ54W8H6FTam1u+A==", - "dev": true + "@react-spring/types": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.3.tgz", + "integrity": "sha512-Kpx/fQ/ZFX31OtlqVEFfgaD1ACzul4NksrvIgYfIFq9JpDHFwQkMVZ10tbo0FU/grje4rcL4EIrjekl3kYwgWw==" }, - "@prefresh/webpack": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@prefresh/webpack/-/webpack-3.3.4.tgz", - "integrity": "sha512-RiXS/hvXDup5cQw/267kxkKie81kxaAB7SFbkr8ppshobDEzwgUN1tbGbHNx6Uari0Ql2XByC6HIgQGpaq2Q7w==", - "dev": true, + "@react-spring/web": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.3.tgz", + "integrity": "sha512-BXt6BpS9aJL/QdVqEIX9YoUy8CE6TJrU0mNCqSoxdXlIeNcEBWOfIyE6B14ENNsyQKS3wOWkiJfco0tCr/9tUg==", "requires": { - "@prefresh/core": "^1.3.3", - "@prefresh/utils": "^1.1.2" + "@react-spring/animated": "~9.7.3", + "@react-spring/core": "~9.7.3", + "@react-spring/shared": "~9.7.3", + "@react-spring/types": "~9.7.3" } }, - "@react-leaflet/core": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-2.1.0.tgz", - "integrity": "sha512-Qk7Pfu8BSarKGqILj4x7bCSZ1pjuAPZ+qmRwH5S7mDS91VSbVVsJSrW4qA+GPrro8t69gFYVMWb1Zc4yFmPiVg==", - "requires": {} + "@react-spring/zdog": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/@react-spring/zdog/-/zdog-9.7.3.tgz", + "integrity": "sha512-L+yK/1PvNi9n8cldiJ309k4LdxcPkeWE0W18l1zrP1IBIyd5NB5EPA8DMsGr9gtNnnIujtEzZk+4JIOjT8u/tw==", + "requires": { + "@react-spring/animated": "~9.7.3", + "@react-spring/core": "~9.7.3", + "@react-spring/shared": "~9.7.3", + "@react-spring/types": "~9.7.3" + } + }, + "@react-three/fiber": { + "version": "8.16.1", + "resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-8.16.1.tgz", + "integrity": "sha512-Rgjn+xcR+6Do2Ic4b6RROIvCGs3RhoVJEamfmtMSfkgIRH3PeiPdqRxcfJlO9y6KDvYA5fIUGruz9h/sTeLlpw==", + "peer": true, + "requires": { + "@babel/runtime": "^7.17.8", + "@types/react-reconciler": "^0.26.7", + "@types/webxr": "*", + "base64-js": "^1.5.1", + "buffer": "^6.0.3", + "its-fine": "^1.0.6", + "react-reconciler": "^0.27.0", + "react-use-measure": "^2.1.1", + "scheduler": "^0.21.0", + "suspend-react": "^0.1.3", + "zustand": "^3.7.1" + }, + "dependencies": { + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "peer": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "scheduler": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", + "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", + "peer": true, + "requires": { + "loose-envify": "^1.1.0" + } + } + } }, "@rollup/plugin-babel": { "version": "5.3.1", @@ -39835,11 +43147,31 @@ "picomatch": "^2.2.2" } }, + "@sideway/address": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "peer": true, + "requires": { + "@hapi/hoek": "^9.0.0" + } + }, + "@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", + "peer": true + }, + "@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", + "peer": true + }, "@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", - "dev": true + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" }, "@sindresorhus/is": { "version": "0.14.0", @@ -42669,14 +46001,12 @@ "@types/istanbul-lib-coverage": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==" }, "@types/istanbul-lib-report": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, "requires": { "@types/istanbul-lib-coverage": "*" } @@ -42685,7 +46015,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, "requires": { "@types/istanbul-lib-report": "*" } @@ -42762,8 +46091,7 @@ "@types/node": { "version": "18.7.21", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.21.tgz", - "integrity": "sha512-rLFzK5bhM0YPyCoTC8bolBjMk7bwnZ8qeZUBslBfjZQou2ssJdWslx9CZ8DGM+Dx7QXQiiTVZ/6QO6kwtHkZCA==", - "dev": true + "integrity": "sha512-rLFzK5bhM0YPyCoTC8bolBjMk7bwnZ8qeZUBslBfjZQou2ssJdWslx9CZ8DGM+Dx7QXQiiTVZ/6QO6kwtHkZCA==" }, "@types/node-fetch": { "version": "2.6.11", @@ -42860,6 +46188,15 @@ "csstype": "^3.0.2" } }, + "@types/react-reconciler": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.26.7.tgz", + "integrity": "sha512-mBDYl8x+oyPX/VBb3E638N0B7xG+SPk/EAMcVPeexqus/5aTpTphQi0curhhshOqRrc9t6OPoJfEUkbymse/lQ==", + "peer": true, + "requires": { + "@types/react": "*" + } + }, "@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -42923,8 +46260,7 @@ "@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" }, "@types/tapable": { "version": "1.0.8", @@ -43006,6 +46342,12 @@ } } }, + "@types/webxr": { + "version": "0.5.14", + "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.14.tgz", + "integrity": "sha512-UEMMm/Xn3DtEa+gpzUrOcDj+SJS1tk5YodjwOxcqStNhCfPcwgyC5Srg2ToVKyg2Fhq16Ffpb0UWUQHqoT9AMA==", + "peer": true + }, "@types/ws": { "version": "8.5.3", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", @@ -43019,7 +46361,6 @@ "version": "17.0.13", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz", "integrity": "sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==", - "dev": true, "requires": { "@types/yargs-parser": "*" } @@ -43027,8 +46368,7 @@ "@types/yargs-parser": { "version": "21.0.0", "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", - "dev": true + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" }, "@typescript-eslint/eslint-plugin": { "version": "5.46.0", @@ -43637,11 +46977,19 @@ "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", "dev": true }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "peer": true, + "requires": { + "event-target-shim": "^5.0.0" + } + }, "accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, "requires": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -43650,8 +46998,7 @@ "acorn": { "version": "8.8.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", - "dev": true + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==" }, "acorn-globals": { "version": "4.3.4", @@ -43823,6 +47170,12 @@ "integrity": "sha512-0FcBfdcmaumGPQ0qPn7Q5qTgz/ooXgIyp1rf8ik5bGX8mpE2YHjC0P/eyQvxu1GURYQgq9ozf2mteQ5ZD9YiyQ==", "dev": true }, + "anser": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz", + "integrity": "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==", + "peer": true + }, "ansi-align": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", @@ -43855,6 +47208,87 @@ } } }, + "ansi-fragments": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ansi-fragments/-/ansi-fragments-0.2.1.tgz", + "integrity": "sha512-DykbNHxuXQwUDRv5ibc2b0x7uw7wmwOGLBUd5RmaQ5z8Lhx19vwvKV+FAsM5rEA6dEcHxX+/Ad5s9eF2k2bB+w==", + "peer": true, + "requires": { + "colorette": "^1.0.7", + "slice-ansi": "^2.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "peer": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "peer": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "peer": true + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "peer": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "peer": true + }, + "colorette": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", + "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", + "peer": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "peer": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "peer": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "peer": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, "ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", @@ -43864,14 +47298,12 @@ "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -43889,7 +47321,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -43901,6 +47332,12 @@ "integrity": "sha512-jlpIfsOoNoafl92Sz//64uQHGSyMrD2vYG5d8o2a4qGvyNCvXur7bzIsWtAC/6flI2RYAp3kv8rsfBtaLm7w0g==", "dev": true }, + "appdirsjs": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/appdirsjs/-/appdirsjs-1.2.7.tgz", + "integrity": "sha512-Quji6+8kLBC3NnBeo14nPDq0+2jUs5s3/xEye+udFHumHhRk4M7aAMXp/PBJqkKYGuuyR9M/6Dq7d2AViiGmhw==", + "peer": true + }, "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", @@ -44084,6 +47521,12 @@ "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", "dev": true }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "peer": true + }, "asn1": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", @@ -44191,8 +47634,7 @@ "async-limiter": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" }, "asynckit": { "version": "0.4.0", @@ -44317,7 +47759,6 @@ "version": "7.0.0-bridge.0", "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==", - "dev": true, "requires": {} }, "babel-jest": { @@ -44465,7 +47906,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "dev": true, "requires": { "object.assign": "^4.1.0" } @@ -44536,7 +47976,6 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", - "dev": true, "requires": { "@babel/compat-data": "^7.17.7", "@babel/helper-define-polyfill-provider": "^0.3.3", @@ -44546,8 +47985,7 @@ "semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" } } }, @@ -44555,7 +47993,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", - "dev": true, "requires": { "@babel/helper-define-polyfill-provider": "^0.3.3", "core-js-compat": "^3.25.1" @@ -44565,7 +48002,6 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", - "dev": true, "requires": { "@babel/helper-define-polyfill-provider": "^0.3.3" } @@ -44576,6 +48012,15 @@ "integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==", "dev": true }, + "babel-plugin-transform-flow-enums": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-enums/-/babel-plugin-transform-flow-enums-0.0.2.tgz", + "integrity": "sha512-g4aaCrDDOsWjbm0PUUeVnkcVd6AKJsVc/MbnPhEotEpkeJQP6b8nzewohQi7+QS8UyPehOhGWn0nOwjvWpmMvQ==", + "peer": true, + "requires": { + "@babel/plugin-syntax-flow": "^7.12.1" + } + }, "babel-plugin-transform-react-remove-prop-types": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", @@ -44705,8 +48150,7 @@ "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "base": { "version": "0.11.2", @@ -44737,8 +48181,7 @@ "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "batch": { "version": "0.6.1", @@ -44820,7 +48263,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, "requires": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -44961,7 +48403,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -44971,7 +48412,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -45073,7 +48513,6 @@ "version": "4.23.0", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", - "dev": true, "requires": { "caniuse-lite": "^1.0.30001587", "electron-to-chromium": "^1.4.668", @@ -45085,7 +48524,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, "requires": { "node-int64": "^0.4.0" } @@ -45094,7 +48532,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, "requires": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -45109,8 +48546,7 @@ "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, "buffer-xor": { "version": "1.0.3", @@ -45142,8 +48578,7 @@ "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "dev": true + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==" }, "cacache": { "version": "15.3.0", @@ -45230,7 +48665,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, "requires": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -45249,7 +48683,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", - "dev": true, "requires": { "callsites": "^2.0.0" }, @@ -45257,8 +48690,7 @@ "callsites": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", - "dev": true + "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==" } } }, @@ -45266,7 +48698,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", - "dev": true, "requires": { "caller-callsite": "^2.0.0" } @@ -45290,8 +48721,7 @@ "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "camelcase-css": { "version": "2.0.1", @@ -45334,8 +48764,7 @@ "caniuse-lite": { "version": "1.0.30001588", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001588.tgz", - "integrity": "sha512-+hVY9jE44uKLkH0SrUTqxjxqNTOWHsbnQDIKjwkZ3lNTzUUVdBLBGXtj/q5Mp5u98r3droaZAewQuEDzjQdZlQ==", - "dev": true + "integrity": "sha512-+hVY9jE44uKLkH0SrUTqxjxqNTOWHsbnQDIKjwkZ3lNTzUUVdBLBGXtj/q5Mp5u98r3droaZAewQuEDzjQdZlQ==" }, "capture-exit": { "version": "2.0.0", @@ -45368,7 +48797,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -45437,12 +48865,38 @@ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "dev": true }, + "chrome-launcher": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.2.tgz", + "integrity": "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==", + "peer": true, + "requires": { + "@types/node": "*", + "escape-string-regexp": "^4.0.0", + "is-wsl": "^2.2.0", + "lighthouse-logger": "^1.0.0" + } + }, "chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "dev": true }, + "chromium-edge-launcher": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/chromium-edge-launcher/-/chromium-edge-launcher-1.0.0.tgz", + "integrity": "sha512-pgtgjNKZ7i5U++1g1PWv75umkHvhVTDOQIZ+sjeUX9483S7Y6MUvO0lrd7ShGlQlFHMN4SwKTCq/X8hWrbv2KA==", + "peer": true, + "requires": { + "@types/node": "*", + "escape-string-regexp": "^4.0.0", + "is-wsl": "^2.2.0", + "lighthouse-logger": "^1.0.0", + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + } + }, "ci-env": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/ci-env/-/ci-env-1.17.0.tgz", @@ -45452,8 +48906,7 @@ "ci-info": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.4.0.tgz", - "integrity": "sha512-t5QdPT5jq3o262DOQ8zA6E1tlH2upmUc4Hlvrbx1pGYJuiiHl7O7rvVNI+l8HTVhd/q3Qc9vqimkNk5yiXsAug==", - "dev": true + "integrity": "sha512-t5QdPT5jq3o262DOQ8zA6E1tlH2upmUc4Hlvrbx1pGYJuiiHl7O7rvVNI+l8HTVhd/q3Qc9vqimkNk5yiXsAug==" }, "cipher-base": { "version": "1.0.4", @@ -45576,7 +49029,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, "requires": { "restore-cursor": "^3.1.0" } @@ -45584,8 +49036,7 @@ "cli-spinners": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", - "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==", - "dev": true + "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==" }, "cli-table": { "version": "0.3.6", @@ -45692,14 +49143,12 @@ "clone": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==" }, "clone-deep": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, "requires": { "is-plain-object": "^2.0.4", "kind-of": "^6.0.2", @@ -45710,7 +49159,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, "requires": { "isobject": "^3.0.1" } @@ -45854,7 +49302,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "requires": { "color-name": "~1.1.4" } @@ -45862,8 +49309,7 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "color-string": { "version": "1.9.1", @@ -45914,11 +49360,16 @@ "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", "dev": true }, + "command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", + "peer": true + }, "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, "common-tags": { "version": "1.8.2", @@ -45929,8 +49380,7 @@ "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" }, "compare-func": { "version": "2.0.0", @@ -45952,7 +49402,6 @@ "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dev": true, "requires": { "mime-db": ">= 1.43.0 < 2" } @@ -45961,7 +49410,6 @@ "version": "1.7.4", "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dev": true, "requires": { "accepts": "~1.3.5", "bytes": "3.0.0", @@ -45976,7 +49424,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -45984,8 +49431,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" } } }, @@ -46027,8 +49473,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "concat-stream": { "version": "1.6.2", @@ -46082,6 +49527,65 @@ "xdg-basedir": "^4.0.0" } }, + "connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "peer": true, + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "peer": true, + "requires": { + "ms": "2.0.0" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "peer": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "peer": true + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "peer": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "peer": true + } + } + }, "connect-history-api-fallback": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", @@ -46858,12 +50362,11 @@ "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==" }, "core-js-compat": { - "version": "3.25.3", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.3.tgz", - "integrity": "sha512-xVtYpJQ5grszDHEUU9O7XbjjcZ0ccX3LgQsyqSvTnjX97ZqEgn9F5srmrwwwMtbKzDllyFPL+O+2OFMl1lU4TQ==", - "dev": true, + "version": "3.36.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz", + "integrity": "sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==", "requires": { - "browserslist": "^4.21.4" + "browserslist": "^4.23.0" } }, "core-util-is": { @@ -47257,7 +50760,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -47751,11 +51253,22 @@ "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", "dev": true }, + "dayjs": { + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==", + "peer": true + }, + "debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "peer": true + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "requires": { "ms": "2.1.2" } @@ -47763,8 +51276,7 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==" }, "decamelize-keys": { "version": "1.1.1", @@ -47825,10 +51337,9 @@ } }, "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==" }, "default-browser-id": { "version": "1.0.4", @@ -47855,7 +51366,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", "integrity": "sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA==", - "dev": true, "requires": { "clone": "^1.0.2" } @@ -47870,7 +51380,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, "requires": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -47887,7 +51396,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, "requires": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -47922,11 +51430,27 @@ "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", "dev": true }, + "denodeify": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz", + "integrity": "sha512-KNTihKNmQENUZeKu5fzfpzRqR5S2VMp4gl9RFHiWzj9DfvYQPMJ6XHKNaQxaGCXwPk6y9yme3aUoaiAe+KX+vg==", + "peer": true + }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "deprecated-react-native-prop-types": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-5.0.0.tgz", + "integrity": "sha512-cIK8KYiiGVOFsKdPMmm1L3tA/Gl+JopXL6F5+C7x39MyPsQYnP57Im/D6bNUzcborD7fcMwiwZqcBdBXXZucYQ==", + "peer": true, + "requires": { + "@react-native/normalize-colors": "^0.73.0", + "invariant": "^2.2.4", + "prop-types": "^15.8.1" + } }, "des.js": { "version": "1.0.1", @@ -47941,8 +51465,7 @@ "destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" }, "detab": { "version": "2.0.4", @@ -48326,8 +51849,7 @@ "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "ejs": { "version": "3.1.8", @@ -48351,8 +51873,7 @@ "electron-to-chromium": { "version": "1.4.677", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.677.tgz", - "integrity": "sha512-erDa3CaDzwJOpyvfKhOiJjBVNnMM0qxHq47RheVVwsSQrgBA9ZSGV9kdaOfZDPXcHzhG7lBxhj6A7KvfLJBd6Q==", - "dev": true + "integrity": "sha512-erDa3CaDzwJOpyvfKhOiJjBVNnMM0qxHq47RheVVwsSQrgBA9ZSGV9kdaOfZDPXcHzhG7lBxhj6A7KvfLJBd6Q==" }, "elliptic": { "version": "6.5.4", @@ -48392,8 +51913,7 @@ "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "emojis-list": { "version": "3.0.0", @@ -48404,8 +51924,7 @@ "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" }, "end-of-stream": { "version": "1.4.4", @@ -48470,10 +51989,9 @@ "dev": true }, "envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", - "dev": true + "version": "7.11.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.1.tgz", + "integrity": "sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg==" }, "errno": { "version": "0.1.8", @@ -48488,7 +52006,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, "requires": { "is-arrayish": "^0.2.1" } @@ -48501,6 +52018,16 @@ "stackframe": "^1.3.4" } }, + "errorhandler": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.5.1.tgz", + "integrity": "sha512-rcOwbfvP1WTViVoUjcfZicVzjhjTuhSMntHh6mW3IrEiyE6mJyXvsToJUJGlGlw/2xU9P5whlWNGlIDVeCiT4A==", + "peer": true, + "requires": { + "accepts": "~1.3.7", + "escape-html": "~1.0.3" + } + }, "es-abstract": { "version": "1.22.4", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.4.tgz", @@ -48560,7 +52087,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, "requires": { "get-intrinsic": "^1.2.4" } @@ -48568,8 +52094,7 @@ "es-errors": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" }, "es-get-iterator": { "version": "1.1.3", @@ -48642,8 +52167,7 @@ "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, "escape-goat": { "version": "2.1.1", @@ -48654,14 +52178,12 @@ "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" }, "escodegen": { "version": "1.14.3", @@ -48997,8 +52519,13 @@ "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "dev": true + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" + }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "peer": true }, "eventemitter3": { "version": "4.0.7", @@ -49032,7 +52559,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, "requires": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -49429,6 +52955,15 @@ "resolved": "https://registry.npmjs.org/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz", "integrity": "sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==" }, + "fast-xml-parser": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.6.tgz", + "integrity": "sha512-M2SovcRxD4+vC493Uc2GZVcZaj66CCJhWurC4viynVSTvrpErCShNcDz1lAho6n9REQKvL/ll4A4/fw6Y9z8nw==", + "peer": true, + "requires": { + "strnum": "^1.0.5" + } + }, "fastest-stable-stringify": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz", @@ -49456,7 +52991,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, "requires": { "bser": "2.1.1" } @@ -49676,7 +53210,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "requires": { "to-regex-range": "^5.0.1" } @@ -49728,7 +53261,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, "requires": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -49750,6 +53282,12 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "flow-enums-runtime": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/flow-enums-runtime/-/flow-enums-runtime-0.0.6.tgz", + "integrity": "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==", + "peer": true + }, "flow-parser": { "version": "0.229.0", "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.229.0.tgz", @@ -49929,8 +53467,7 @@ "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" }, "from2": { "version": "2.3.0", @@ -49972,7 +53509,6 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, "requires": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", @@ -50035,21 +53571,18 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "optional": true }, "function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" }, "function.prototype.name": { "version": "1.1.6", @@ -50095,20 +53628,17 @@ "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, "requires": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", @@ -50168,8 +53698,7 @@ "get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" }, "get-symbol-description": { "version": "1.0.2", @@ -50543,7 +54072,6 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -50640,7 +54168,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, "requires": { "get-intrinsic": "^1.1.3" } @@ -50678,8 +54205,7 @@ "graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "grapheme-splitter": { "version": "1.0.4", @@ -50747,7 +54273,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -50776,8 +54301,7 @@ "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "has-glob": { "version": "1.0.0", @@ -50803,7 +54327,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, "requires": { "es-define-property": "^1.0.0" } @@ -50811,14 +54334,12 @@ "has-proto": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==" }, "has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, "has-tostringtag": { "version": "1.0.2", @@ -50926,7 +54447,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", - "dev": true, "requires": { "function-bind": "^1.1.2" } @@ -51024,6 +54544,38 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, + "hermes-estree": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.15.0.tgz", + "integrity": "sha512-lLYvAd+6BnOqWdnNbP/Q8xfl8LOGw4wVjfrNd9Gt8eoFzhNBRVD95n4l2ksfMVOoxuVyegs85g83KS9QOsxbVQ==", + "peer": true + }, + "hermes-parser": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.15.0.tgz", + "integrity": "sha512-Q1uks5rjZlE9RjMMjSUCkGrEIPI5pKJILeCtK1VmTj7U4pf3wVPoo+cxfu+s4cBAPy2JzikIIdCZgBoR6x7U1Q==", + "peer": true, + "requires": { + "hermes-estree": "0.15.0" + } + }, + "hermes-profile-transformer": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/hermes-profile-transformer/-/hermes-profile-transformer-0.0.6.tgz", + "integrity": "sha512-cnN7bQUm65UWOy6cbGcCcZ3rpwW8Q/j4OP5aWRhEry4Z2t2aR1cjrbp0BS+KiBN0smvP1caBgAuxutvyvJILzQ==", + "peer": true, + "requires": { + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "peer": true + } + } + }, "hex-color-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", @@ -51313,7 +54865,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, "requires": { "depd": "2.0.0", "inherits": "2.0.4", @@ -51412,8 +54963,7 @@ "human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" }, "husky": { "version": "8.0.1", @@ -51544,8 +55094,7 @@ "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "iferr": { "version": "0.1.5", @@ -51589,8 +55138,7 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" }, "indent-string": { "version": "4.0.0", @@ -51614,7 +55162,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -51774,8 +55321,7 @@ "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "is-bigint": { "version": "1.0.4", @@ -51857,7 +55403,6 @@ "version": "2.10.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", - "dev": true, "requires": { "has": "^1.0.3" } @@ -51900,14 +55445,12 @@ "is-directory": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", - "dev": true + "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==" }, "is-docker": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==" }, "is-dom": { "version": "1.1.0", @@ -51955,8 +55498,7 @@ "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, "is-function": { "version": "1.0.2", @@ -51998,8 +55540,7 @@ "is-interactive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==" }, "is-map": { "version": "2.0.2", @@ -52028,8 +55569,7 @@ "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, "is-number-object": { "version": "1.0.7", @@ -52110,8 +55650,7 @@ "is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" }, "is-string": { "version": "1.0.7", @@ -52164,8 +55703,7 @@ "is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" }, "is-weakref": { "version": "1.0.2", @@ -52210,7 +55748,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, "requires": { "is-docker": "^2.0.0" } @@ -52229,8 +55766,7 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "isobject": { "version": "3.0.1", @@ -52328,6 +55864,26 @@ "iterate-iterator": "^1.0.1" } }, + "its-fine": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/its-fine/-/its-fine-1.1.3.tgz", + "integrity": "sha512-mncCA+yb6tuh5zK26cHqKlsSyxm4zdm4YgJpxycyx6p9fgxgK5PLu3iDVpKhzTn57Yrv3jk/r0aK0RFTT1OjFw==", + "peer": true, + "requires": { + "@types/react-reconciler": "^0.28.0" + }, + "dependencies": { + "@types/react-reconciler": { + "version": "0.28.8", + "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.8.tgz", + "integrity": "sha512-SN9c4kxXZonFhbX4hJrZy37yw9e7EIxcpHCxQv5JUS18wDE5ovkQKlqQEkufdJCCMfuI9BnjUJvhYeJ9x5Ra7g==", + "peer": true, + "requires": { + "@types/react": "*" + } + } + } + }, "jake": { "version": "10.8.5", "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", @@ -53242,10 +56798,9 @@ } }, "jest-get-type": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.0.0.tgz", - "integrity": "sha512-83X19z/HuLKYXYHskZlBAShO7UfLFXu/vWajw9ZNJASN32li8yHMaVGAQqxFW1RCFOkB7cubaL6FaJVQqqJLSw==", - "dev": true + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==" }, "jest-haste-map": { "version": "27.5.1", @@ -53527,18 +57082,17 @@ } }, "jest-message-util": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.2.1.tgz", - "integrity": "sha512-Dx5nEjw9V8C1/Yj10S/8ivA8F439VS8vTq1L7hEgwHFn9ovSKNpYW/kwNh7UglaEgXO42XxzKJB+2x0nSglFVw==", - "dev": true, + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.2.1", + "@jest/types": "^29.6.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.2.1", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" } @@ -54142,12 +57696,11 @@ } }, "jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", - "dev": true, + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "requires": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -54318,6 +57871,19 @@ } } }, + "joi": { + "version": "17.12.3", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.3.tgz", + "integrity": "sha512-2RRziagf555owrm9IRVtdKynOBeITiDpuZqIpgwqXShPncPKNiRQoiGsl/T8SQdq+8ugRzH2LqY67irr2y/d+g==", + "peer": true, + "requires": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, "js-cookie": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", @@ -54355,6 +57921,18 @@ "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", "dev": true }, + "jsc-android": { + "version": "250231.0.0", + "resolved": "https://registry.npmjs.org/jsc-android/-/jsc-android-250231.0.0.tgz", + "integrity": "sha512-rS46PvsjYmdmuz1OAWXY/1kCYG7pnf1TBqeTiOJr1iDz7s5DLxxC9n/ZMknLDxzYzNVfI7R95MH10emSSG1Wuw==", + "peer": true + }, + "jsc-safe-url": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/jsc-safe-url/-/jsc-safe-url-0.2.4.tgz", + "integrity": "sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q==", + "peer": true + }, "jscodeshift": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.13.1.tgz", @@ -54575,8 +58153,7 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" }, "json-buffer": { "version": "3.0.0", @@ -54587,8 +58164,7 @@ "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" }, "json-parse-even-better-errors": { "version": "2.3.1", @@ -54623,14 +58199,12 @@ "json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, "requires": { "graceful-fs": "^4.1.6" } @@ -54697,14 +58271,12 @@ "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" }, "kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" }, "klona": { "version": "2.0.5", @@ -54712,6 +58284,12 @@ "integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==", "dev": true }, + "konva": { + "version": "9.3.6", + "resolved": "https://registry.npmjs.org/konva/-/konva-9.3.6.tgz", + "integrity": "sha512-dqR8EbcM0hjuilZCBP6xauQ5V3kH3m9kBcsDkqPypQuRgsXbcXUrxqYxhNbdvKZpYNW8Amq94jAD/C0NY3qfBQ==", + "peer": true + }, "last-call-webpack-plugin": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz", @@ -54761,8 +58339,7 @@ "leaflet": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.3.tgz", - "integrity": "sha512-iB2cR9vAkDOu5l3HAay2obcUHZ7xwUBBjph8+PGtmW/2lYhbLizWtG7nTeYht36WfOslixQF9D/uSIzhZgGMfQ==", - "peer": true + "integrity": "sha512-iB2cR9vAkDOu5l3HAay2obcUHZ7xwUBBjph8+PGtmW/2lYhbLizWtG7nTeYht36WfOslixQF9D/uSIzhZgGMfQ==" }, "less": { "version": "4.1.3", @@ -54836,8 +58413,7 @@ "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" }, "levn": { "version": "0.4.1", @@ -54849,6 +58425,33 @@ "type-check": "~0.4.0" } }, + "lighthouse-logger": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz", + "integrity": "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==", + "peer": true, + "requires": { + "debug": "^2.6.9", + "marky": "^1.2.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "peer": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "peer": true + } + } + }, "lilconfig": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", @@ -55057,7 +58660,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, "requires": { "p-locate": "^5.0.0" } @@ -55070,8 +58672,7 @@ "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, "lodash.get": { "version": "4.4.2", @@ -55109,6 +58710,12 @@ "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", "dev": true }, + "lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==", + "peer": true + }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -55119,7 +58726,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, "requires": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -55150,6 +58756,113 @@ } } }, + "logkitty": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/logkitty/-/logkitty-0.7.1.tgz", + "integrity": "sha512-/3ER20CTTbahrCrpYfPn7Xavv9diBROZpoXGVZDWMw4b/X4uuUwAC0ki85tgsdMRONURyIJbcOvS94QsUBYPbQ==", + "peer": true, + "requires": { + "ansi-fragments": "^0.2.1", + "dayjs": "^1.8.15", + "yargs": "^15.1.0" + }, + "dependencies": { + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "peer": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "peer": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "peer": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "peer": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "peer": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "peer": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "peer": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "peer": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "peer": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -55174,7 +58887,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "requires": { "yallist": "^4.0.0" } @@ -55227,7 +58939,6 @@ "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, "requires": { "tmpl": "1.0.5" } @@ -55265,6 +58976,12 @@ "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", "dev": true }, + "marky": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/marky/-/marky-1.2.5.tgz", + "integrity": "sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==", + "peer": true + }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -55342,6 +59059,12 @@ "fs-monkey": "^1.0.3" } }, + "memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==", + "peer": true + }, "memoizerific": { "version": "1.11.3", "resolved": "https://registry.npmjs.org/memoizerific/-/memoizerific-1.11.3.tgz", @@ -55430,8 +59153,7 @@ "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, "merge2": { "version": "1.4.1", @@ -55451,6 +59173,484 @@ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "dev": true }, + "metro": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro/-/metro-0.80.8.tgz", + "integrity": "sha512-in7S0W11mg+RNmcXw+2d9S3zBGmCARDxIwoXJAmLUQOQoYsRP3cpGzyJtc7WOw8+FXfpgXvceD0u+PZIHXEL7g==", + "peer": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/core": "^7.20.0", + "@babel/generator": "^7.20.0", + "@babel/parser": "^7.20.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.20.0", + "@babel/types": "^7.20.0", + "accepts": "^1.3.7", + "chalk": "^4.0.0", + "ci-info": "^2.0.0", + "connect": "^3.6.5", + "debug": "^2.2.0", + "denodeify": "^1.2.1", + "error-stack-parser": "^2.0.6", + "graceful-fs": "^4.2.4", + "hermes-parser": "0.20.1", + "image-size": "^1.0.2", + "invariant": "^2.2.4", + "jest-worker": "^29.6.3", + "jsc-safe-url": "^0.2.2", + "lodash.throttle": "^4.1.1", + "metro-babel-transformer": "0.80.8", + "metro-cache": "0.80.8", + "metro-cache-key": "0.80.8", + "metro-config": "0.80.8", + "metro-core": "0.80.8", + "metro-file-map": "0.80.8", + "metro-resolver": "0.80.8", + "metro-runtime": "0.80.8", + "metro-source-map": "0.80.8", + "metro-symbolicate": "0.80.8", + "metro-transform-plugins": "0.80.8", + "metro-transform-worker": "0.80.8", + "mime-types": "^2.1.27", + "node-fetch": "^2.2.0", + "nullthrows": "^1.1.1", + "rimraf": "^3.0.2", + "serialize-error": "^2.1.0", + "source-map": "^0.5.6", + "strip-ansi": "^6.0.0", + "throat": "^5.0.0", + "ws": "^7.5.1", + "yargs": "^17.6.2" + }, + "dependencies": { + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "peer": true + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "peer": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "peer": true, + "requires": { + "ms": "2.0.0" + } + }, + "hermes-estree": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.20.1.tgz", + "integrity": "sha512-SQpZK4BzR48kuOg0v4pb3EAGNclzIlqMj3Opu/mu7bbAoFw6oig6cEt/RAi0zTFW/iW6Iz9X9ggGuZTAZ/yZHg==", + "peer": true + }, + "hermes-parser": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.20.1.tgz", + "integrity": "sha512-BL5P83cwCogI8D7rrDCgsFY0tdYUtmFP9XaXtl2IQjC+2Xo+4okjfXintlTxcIwl4qeGddEl28Z11kbVIw0aNA==", + "peer": true, + "requires": { + "hermes-estree": "0.20.1" + } + }, + "image-size": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", + "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==", + "peer": true, + "requires": { + "queue": "6.0.2" + } + }, + "jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "peer": true, + "requires": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "peer": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "peer": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "peer": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "peer": true + }, + "ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "peer": true, + "requires": {} + }, + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "peer": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "peer": true + } + } + }, + "metro-babel-transformer": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.80.8.tgz", + "integrity": "sha512-TTzNwRZb2xxyv4J/+yqgtDAP2qVqH3sahsnFu6Xv4SkLqzrivtlnyUbaeTdJ9JjtADJUEjCbgbFgUVafrXdR9Q==", + "peer": true, + "requires": { + "@babel/core": "^7.20.0", + "hermes-parser": "0.20.1", + "nullthrows": "^1.1.1" + }, + "dependencies": { + "hermes-estree": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.20.1.tgz", + "integrity": "sha512-SQpZK4BzR48kuOg0v4pb3EAGNclzIlqMj3Opu/mu7bbAoFw6oig6cEt/RAi0zTFW/iW6Iz9X9ggGuZTAZ/yZHg==", + "peer": true + }, + "hermes-parser": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.20.1.tgz", + "integrity": "sha512-BL5P83cwCogI8D7rrDCgsFY0tdYUtmFP9XaXtl2IQjC+2Xo+4okjfXintlTxcIwl4qeGddEl28Z11kbVIw0aNA==", + "peer": true, + "requires": { + "hermes-estree": "0.20.1" + } + } + } + }, + "metro-cache": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.80.8.tgz", + "integrity": "sha512-5svz+89wSyLo7BxdiPDlwDTgcB9kwhNMfNhiBZPNQQs1vLFXxOkILwQiV5F2EwYT9DEr6OPZ0hnJkZfRQ8lDYQ==", + "peer": true, + "requires": { + "metro-core": "0.80.8", + "rimraf": "^3.0.2" + } + }, + "metro-cache-key": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.80.8.tgz", + "integrity": "sha512-qWKzxrLsRQK5m3oH8ePecqCc+7PEhR03cJE6Z6AxAj0idi99dHOSitTmY0dclXVB9vP2tQIAE8uTd8xkYGk8fA==", + "peer": true + }, + "metro-config": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.80.8.tgz", + "integrity": "sha512-VGQJpfJawtwRzGzGXVUoohpIkB0iPom4DmSbAppKfumdhtLA8uVeEPp2GM61kL9hRvdbMhdWA7T+hZFDlo4mJA==", + "peer": true, + "requires": { + "connect": "^3.6.5", + "cosmiconfig": "^5.0.5", + "jest-validate": "^29.6.3", + "metro": "0.80.8", + "metro-cache": "0.80.8", + "metro-core": "0.80.8", + "metro-runtime": "0.80.8" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "peer": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "peer": true + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "peer": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", + "peer": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "peer": true, + "requires": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "peer": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "peer": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "peer": true + } + } + }, + "metro-core": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.80.8.tgz", + "integrity": "sha512-g6lud55TXeISRTleW6SHuPFZHtYrpwNqbyFIVd9j9Ofrb5IReiHp9Zl8xkAfZQp8v6ZVgyXD7c130QTsCz+vBw==", + "peer": true, + "requires": { + "lodash.throttle": "^4.1.1", + "metro-resolver": "0.80.8" + } + }, + "metro-file-map": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.80.8.tgz", + "integrity": "sha512-eQXMFM9ogTfDs2POq7DT2dnG7rayZcoEgRbHPXvhUWkVwiKkro2ngcBE++ck/7A36Cj5Ljo79SOkYwHaWUDYDw==", + "peer": true, + "requires": { + "anymatch": "^3.0.3", + "debug": "^2.2.0", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.4", + "invariant": "^2.2.4", + "jest-worker": "^29.6.3", + "micromatch": "^4.0.4", + "node-abort-controller": "^3.1.1", + "nullthrows": "^1.1.1", + "walker": "^1.0.7" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "peer": true, + "requires": { + "ms": "2.0.0" + } + }, + "jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "peer": true, + "requires": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "peer": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "peer": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "metro-minify-terser": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.80.8.tgz", + "integrity": "sha512-y8sUFjVvdeUIINDuW1sejnIjkZfEF+7SmQo0EIpYbWmwh+kq/WMj74yVaBWuqNjirmUp1YNfi3alT67wlbBWBQ==", + "peer": true, + "requires": { + "terser": "^5.15.0" + } + }, + "metro-resolver": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.80.8.tgz", + "integrity": "sha512-JdtoJkP27GGoZ2HJlEsxs+zO7jnDUCRrmwXJozTlIuzLHMRrxgIRRby9fTCbMhaxq+iA9c+wzm3iFb4NhPmLbQ==", + "peer": true + }, + "metro-runtime": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.80.8.tgz", + "integrity": "sha512-2oScjfv6Yb79PelU1+p8SVrCMW9ZjgEiipxq7jMRn8mbbtWzyv3g8Mkwr+KwOoDFI/61hYPUbY8cUnu278+x1g==", + "peer": true, + "requires": { + "@babel/runtime": "^7.0.0" + } + }, + "metro-source-map": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.80.8.tgz", + "integrity": "sha512-+OVISBkPNxjD4eEKhblRpBf463nTMk3KMEeYS8Z4xM/z3qujGJGSsWUGRtH27+c6zElaSGtZFiDMshEb8mMKQg==", + "peer": true, + "requires": { + "@babel/traverse": "^7.20.0", + "@babel/types": "^7.20.0", + "invariant": "^2.2.4", + "metro-symbolicate": "0.80.8", + "nullthrows": "^1.1.1", + "ob1": "0.80.8", + "source-map": "^0.5.6", + "vlq": "^1.0.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "peer": true + } + } + }, + "metro-symbolicate": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.80.8.tgz", + "integrity": "sha512-nwhYySk79jQhwjL9QmOUo4wS+/0Au9joEryDWw7uj4kz2yvw1uBjwmlql3BprQCBzRdB3fcqOP8kO8Es+vE31g==", + "peer": true, + "requires": { + "invariant": "^2.2.4", + "metro-source-map": "0.80.8", + "nullthrows": "^1.1.1", + "source-map": "^0.5.6", + "through2": "^2.0.1", + "vlq": "^1.0.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "peer": true + } + } + }, + "metro-transform-plugins": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.80.8.tgz", + "integrity": "sha512-sSu8VPL9Od7w98MftCOkQ1UDeySWbsIAS5I54rW22BVpPnI3fQ42srvqMLaJUQPjLehUanq8St6OMBCBgH/UWw==", + "peer": true, + "requires": { + "@babel/core": "^7.20.0", + "@babel/generator": "^7.20.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.20.0", + "nullthrows": "^1.1.1" + } + }, + "metro-transform-worker": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.80.8.tgz", + "integrity": "sha512-+4FG3TQk3BTbNqGkFb2uCaxYTfsbuFOCKMMURbwu0ehCP8ZJuTUramkaNZoATS49NSAkRgUltgmBa4YaKZ5mqw==", + "peer": true, + "requires": { + "@babel/core": "^7.20.0", + "@babel/generator": "^7.20.0", + "@babel/parser": "^7.20.0", + "@babel/types": "^7.20.0", + "metro": "0.80.8", + "metro-babel-transformer": "0.80.8", + "metro-cache": "0.80.8", + "metro-cache-key": "0.80.8", + "metro-minify-terser": "0.80.8", + "metro-source-map": "0.80.8", + "metro-transform-plugins": "0.80.8", + "nullthrows": "^1.1.1" + } + }, "microevent.ts": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/microevent.ts/-/microevent.ts-0.1.1.tgz", @@ -55461,7 +59661,6 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, "requires": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -55488,20 +59687,17 @@ "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" }, "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" }, "mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "requires": { "mime-db": "1.52.0" } @@ -55509,8 +59705,7 @@ "mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, "mimic-response": { "version": "1.0.1", @@ -55573,7 +59768,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -55685,8 +59879,7 @@ "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" }, "modify-values": { "version": "1.0.1", @@ -55743,8 +59936,7 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "multicast-dns": { "version": "7.2.5", @@ -55857,14 +60049,12 @@ "negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, "neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "nested-error-stacks": { "version": "2.1.1", @@ -55887,11 +60077,22 @@ "lower-case": "^1.1.1" } }, + "nocache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/nocache/-/nocache-3.0.4.tgz", + "integrity": "sha512-WDD0bdg9mbq6F4mRxEYcPWwfA1vxd0mrvKOyxI7Xj/atfRHVeutzuWByG//jfm4uPzp0y4Kj051EORCBSQMycw==", + "peer": true + }, + "node-abort-controller": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", + "peer": true + }, "node-dir": { "version": "0.1.17", "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", "integrity": "sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==", - "dev": true, "requires": { "minimatch": "^3.0.2" } @@ -55900,7 +60101,6 @@ "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dev": true, "requires": { "whatwg-url": "^5.0.0" }, @@ -55908,20 +60108,17 @@ "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, "requires": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -55947,8 +60144,7 @@ "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" }, "node-libs-browser": { "version": "2.2.1", @@ -56027,8 +60223,13 @@ "node-releases": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + }, + "node-stream-zip": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.15.0.tgz", + "integrity": "sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw==", + "peer": true }, "normalize-package-data": { "version": "2.5.0", @@ -56053,8 +60254,7 @@ "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "normalize-range": { "version": "0.1.2", @@ -56072,7 +60272,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, "requires": { "path-key": "^3.0.0" } @@ -56098,6 +60297,12 @@ "boolbase": "^1.0.0" } }, + "nullthrows": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", + "peer": true + }, "num2fraction": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", @@ -56116,11 +60321,16 @@ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true }, + "ob1": { + "version": "0.80.8", + "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.80.8.tgz", + "integrity": "sha512-QHJQk/lXMmAW8I7AIM3in1MSlwe1umR72Chhi8B7Xnq6mzjhBKkA6Fy/zAhQnGkA4S912EPCEvTij5yh+EQTAA==", + "peer": true + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-copy": { "version": "0.1.0", @@ -56205,8 +60415,7 @@ "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, "object-visit": { "version": "1.0.1", @@ -56221,7 +60430,6 @@ "version": "4.1.5", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, "requires": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", @@ -56304,7 +60512,6 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, "requires": { "ee-first": "1.1.1" } @@ -56312,14 +60519,12 @@ "on-headers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "requires": { "wrappy": "1" } @@ -56328,7 +60533,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, "requires": { "mimic-fn": "^2.1.0" } @@ -56724,7 +60928,6 @@ "version": "5.4.1", "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "dev": true, "requires": { "bl": "^4.1.0", "chalk": "^4.1.0", @@ -56815,7 +61018,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, "requires": { "yocto-queue": "^0.1.0" } @@ -56824,7 +61026,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, "requires": { "p-limit": "^3.0.2" } @@ -56860,8 +61061,7 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "package-json": { "version": "6.5.0", @@ -57004,8 +61204,7 @@ "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, "pascal-case": { "version": "3.1.2", @@ -57059,26 +61258,22 @@ "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" }, "path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "path-to-regexp": { "version": "0.1.7", @@ -57120,14 +61315,12 @@ "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" }, "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" }, "pidtree": { "version": "0.6.0", @@ -57159,8 +61352,7 @@ "pirates": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dev": true + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==" }, "pkg-dir": { "version": "4.2.0", @@ -58730,12 +62922,11 @@ } }, "pretty-format": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.2.1.tgz", - "integrity": "sha512-Y41Sa4aLCtKAXvwuIpTvcFBkyeYp2gdFWzXGA+ZNES3VwURIB165XO/z7CjETwzCCS53MjW/rLMyyqEnTtaOfA==", - "dev": true, + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "requires": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -58743,8 +62934,7 @@ "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" } } }, @@ -58798,6 +62988,15 @@ } } }, + "promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "peer": true, + "requires": { + "asap": "~2.0.6" + } + }, "promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", @@ -58841,7 +63040,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, "requires": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" @@ -58851,7 +63049,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "requires": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -58861,8 +63058,7 @@ "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" } } }, @@ -59061,6 +63257,15 @@ "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", "dev": true }, + "queue": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", + "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", + "peer": true, + "requires": { + "inherits": "~2.0.3" + } + }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -59101,8 +63306,7 @@ "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, "raw-body": { "version": "2.5.1", @@ -59185,6 +63389,25 @@ "loose-envify": "^1.1.0" } }, + "react-devtools-core": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.28.5.tgz", + "integrity": "sha512-cq/o30z9W2Wb4rzBefjv5fBalHU0rJGZCHAkf/RHSBWSSYwh8PlQTqqOJmgIIbBtpj27T6FIPXeomIjZtCNVqA==", + "peer": true, + "requires": { + "shell-quote": "^1.6.1", + "ws": "^7" + }, + "dependencies": { + "ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "peer": true, + "requires": {} + } + } + }, "react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -59206,6 +63429,39 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, + "react-konva": { + "version": "18.2.10", + "resolved": "https://registry.npmjs.org/react-konva/-/react-konva-18.2.10.tgz", + "integrity": "sha512-ohcX1BJINL43m4ynjZ24MxFI1syjBdrXhqVxYVDw2rKgr3yuS0x/6m1Y2Z4sl4T/gKhfreBx8KHisd0XC6OT1g==", + "peer": true, + "requires": { + "@types/react-reconciler": "^0.28.2", + "its-fine": "^1.1.1", + "react-reconciler": "~0.29.0", + "scheduler": "^0.23.0" + }, + "dependencies": { + "@types/react-reconciler": { + "version": "0.28.8", + "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.8.tgz", + "integrity": "sha512-SN9c4kxXZonFhbX4hJrZy37yw9e7EIxcpHCxQv5JUS18wDE5ovkQKlqQEkufdJCCMfuI9BnjUJvhYeJ9x5Ra7g==", + "peer": true, + "requires": { + "@types/react": "*" + } + }, + "react-reconciler": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.29.0.tgz", + "integrity": "sha512-wa0fGj7Zht1EYMRhKWwoo1H9GApxYLBuhoAuXN0TlltESAjDssB+Apf0T/DngVqaMyPypDmabL37vw/2aRM98Q==", + "peer": true, + "requires": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + } + } + } + }, "react-leaflet": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-4.2.1.tgz", @@ -59214,6 +63470,242 @@ "@react-leaflet/core": "^2.1.0" } }, + "react-native": { + "version": "0.73.6", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.73.6.tgz", + "integrity": "sha512-oqmZe8D2/VolIzSPZw+oUd6j/bEmeRHwsLn1xLA5wllEYsZ5zNuMsDus235ONOnCRwexqof/J3aztyQswSmiaA==", + "peer": true, + "requires": { + "@jest/create-cache-key-function": "^29.6.3", + "@react-native-community/cli": "12.3.6", + "@react-native-community/cli-platform-android": "12.3.6", + "@react-native-community/cli-platform-ios": "12.3.6", + "@react-native/assets-registry": "0.73.1", + "@react-native/codegen": "0.73.3", + "@react-native/community-cli-plugin": "0.73.17", + "@react-native/gradle-plugin": "0.73.4", + "@react-native/js-polyfills": "0.73.1", + "@react-native/normalize-colors": "0.73.2", + "@react-native/virtualized-lists": "0.73.4", + "abort-controller": "^3.0.0", + "anser": "^1.4.9", + "ansi-regex": "^5.0.0", + "base64-js": "^1.5.1", + "chalk": "^4.0.0", + "deprecated-react-native-prop-types": "^5.0.0", + "event-target-shim": "^5.0.1", + "flow-enums-runtime": "^0.0.6", + "invariant": "^2.2.4", + "jest-environment-node": "^29.6.3", + "jsc-android": "^250231.0.0", + "memoize-one": "^5.0.0", + "metro-runtime": "^0.80.3", + "metro-source-map": "^0.80.3", + "mkdirp": "^0.5.1", + "nullthrows": "^1.1.1", + "pretty-format": "^26.5.2", + "promise": "^8.3.0", + "react-devtools-core": "^4.27.7", + "react-refresh": "^0.14.0", + "react-shallow-renderer": "^16.15.0", + "regenerator-runtime": "^0.13.2", + "scheduler": "0.24.0-canary-efb381bbf-20230505", + "stacktrace-parser": "^0.1.10", + "whatwg-fetch": "^3.0.0", + "ws": "^6.2.2", + "yargs": "^17.6.2" + }, + "dependencies": { + "@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "peer": true, + "requires": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + } + }, + "@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "peer": true, + "requires": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + } + }, + "@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "peer": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "peer": true, + "requires": { + "@sinonjs/commons": "^3.0.0" + } + }, + "@types/yargs": { + "version": "15.0.19", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.19.tgz", + "integrity": "sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA==", + "peer": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "peer": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "peer": true, + "requires": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + } + }, + "jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "peer": true, + "requires": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + } + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "peer": true, + "requires": { + "minimist": "^1.2.6" + } + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "peer": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "dependencies": { + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "peer": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + } + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "peer": true + }, + "react-refresh": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", + "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", + "peer": true + }, + "scheduler": { + "version": "0.24.0-canary-efb381bbf-20230505", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.24.0-canary-efb381bbf-20230505.tgz", + "integrity": "sha512-ABvovCDe/k9IluqSh4/ISoq8tIJnW8euVAWYt5j/bg6dRnqwQwiGO1F/V4AyK96NGF/FB04FhOUDuWj8IKfABA==", + "peer": true, + "requires": { + "loose-envify": "^1.1.0" + } + }, + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "peer": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "peer": true + } + } + }, + "react-reconciler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.27.0.tgz", + "integrity": "sha512-HmMDKciQjYmBRGuuhIaKA1ba/7a+UsM5FzOZsMO2JYHt9Jh8reCb7j1eDC95NOyUlKM9KRyvdx0flBuDvYSBoA==", + "peer": true, + "requires": { + "loose-envify": "^1.1.0", + "scheduler": "^0.21.0" + }, + "dependencies": { + "scheduler": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", + "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", + "peer": true, + "requires": { + "loose-envify": "^1.1.0" + } + } + } + }, "react-redux": { "version": "8.0.4", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.4.tgz", @@ -59238,6 +63730,29 @@ "resolved": "https://registry.npmjs.org/react-router-redux/-/react-router-redux-4.0.8.tgz", "integrity": "sha512-lzlK+S6jZnn17BZbzBe6F8ok3YAhGAUlyWgRu3cz5mT199gKxfem5lNu3qcgzRiVhNEOFVG0/pdT+1t4aWhoQw==" }, + "react-shallow-renderer": { + "version": "16.15.0", + "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz", + "integrity": "sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA==", + "peer": true, + "requires": { + "object-assign": "^4.1.1", + "react-is": "^16.12.0 || ^17.0.0 || ^18.0.0" + } + }, + "react-spring": { + "version": "9.7.3", + "resolved": "https://registry.npmjs.org/react-spring/-/react-spring-9.7.3.tgz", + "integrity": "sha512-oTxDpFV5gzq7jQX6+bU0SVq+vX8VnuuT5c8Zwn6CpDErOPvCmV+DRkPiEBtaL3Ozgzwiy5yFx83N0h303j/r3A==", + "requires": { + "@react-spring/core": "~9.7.3", + "@react-spring/konva": "~9.7.3", + "@react-spring/native": "~9.7.3", + "@react-spring/three": "~9.7.3", + "@react-spring/web": "~9.7.3", + "@react-spring/zdog": "~9.7.3" + } + }, "react-universal-interface": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/react-universal-interface/-/react-universal-interface-0.6.2.tgz", @@ -59265,6 +63780,26 @@ "tslib": "^2.1.0" } }, + "react-use-measure": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.1.tgz", + "integrity": "sha512-nocZhN26cproIiIduswYpV5y5lQpSQS1y/4KuvUCjSKmw7ZWIS/+g3aFnX3WdBkyuGUtTLif3UTqnLLhbDoQig==", + "peer": true, + "requires": { + "debounce": "^1.2.1" + } + }, + "react-zdog": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/react-zdog/-/react-zdog-1.2.2.tgz", + "integrity": "sha512-Ix7ALha91aOEwiHuxumCeYbARS5XNpc/w0v145oGkM6poF/CvhKJwzLhM5sEZbtrghMA+psAhOJkCTzJoseicA==", + "peer": true, + "requires": { + "react": "^18.2.0", + "react-dom": "^18.2.0", + "resize-observer-polyfill": "^1.5.1" + } + }, "read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -59354,7 +63889,6 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -59370,6 +63904,12 @@ "picomatch": "^2.2.1" } }, + "readline": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/readline/-/readline-1.3.0.tgz", + "integrity": "sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg==", + "peer": true + }, "recast": { "version": "0.14.7", "resolved": "https://registry.npmjs.org/recast/-/recast-0.14.7.tgz", @@ -59427,14 +63967,12 @@ "regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" }, "regenerate-unicode-properties": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", - "dev": true, "requires": { "regenerate": "^1.4.2" } @@ -59448,7 +63986,6 @@ "version": "0.15.0", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz", "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", - "dev": true, "requires": { "@babel/runtime": "^7.8.4" } @@ -59485,7 +64022,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.1.tgz", "integrity": "sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ==", - "dev": true, "requires": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.1.0", @@ -59516,14 +64052,12 @@ "regjsgen": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", - "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==", - "dev": true + "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==" }, "regjsparser": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "dev": true, "requires": { "jsesc": "~0.5.0" }, @@ -59531,8 +64065,7 @@ "jsesc": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "dev": true + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==" } } }, @@ -59807,8 +64340,7 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" }, "require-from-string": { "version": "2.0.2", @@ -59816,6 +64348,12 @@ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "peer": true + }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -59831,7 +64369,6 @@ "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, "requires": { "is-core-module": "^2.9.0", "path-parse": "^1.0.7", @@ -59886,7 +64423,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, "requires": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" @@ -59932,7 +64468,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, "requires": { "glob": "^7.1.3" } @@ -60390,7 +64925,6 @@ "version": "7.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, "requires": { "lru-cache": "^6.0.0" } @@ -60416,7 +64950,6 @@ "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dev": true, "requires": { "debug": "2.6.9", "depd": "2.0.0", @@ -60437,7 +64970,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" }, @@ -60445,19 +64977,23 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" } } }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, + "serialize-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz", + "integrity": "sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw==", + "peer": true + }, "serialize-javascript": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", @@ -60566,7 +65102,6 @@ "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dev": true, "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -60577,14 +65112,12 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, "set-function-length": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", - "dev": true, "requires": { "define-data-property": "^1.1.2", "es-errors": "^1.3.0", @@ -60658,8 +65191,7 @@ "setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, "sha.js": { "version": "2.4.11", @@ -60675,7 +65207,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, "requires": { "kind-of": "^6.0.2" } @@ -60684,7 +65215,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "requires": { "shebang-regex": "^3.0.0" } @@ -60692,8 +65222,13 @@ "shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "peer": true }, "shelljs": { "version": "0.8.5", @@ -60728,8 +65263,7 @@ "signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "simple-color-scale": { "version": "1.0.1", @@ -60767,8 +65301,7 @@ "sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" }, "size-plugin": { "version": "3.0.0", @@ -60853,8 +65386,7 @@ "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, "slice-ansi": { "version": "4.0.0", @@ -61109,7 +65641,6 @@ "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -61226,8 +65757,7 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "sshpk": { "version": "1.17.0", @@ -61279,7 +65809,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", - "dev": true, "requires": { "escape-string-regexp": "^2.0.0" }, @@ -61287,8 +65816,7 @@ "escape-string-regexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" } } }, @@ -61323,6 +65851,23 @@ "stacktrace-gps": "^3.0.4" } }, + "stacktrace-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", + "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", + "peer": true, + "requires": { + "type-fest": "^0.7.1" + }, + "dependencies": { + "type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", + "peer": true + } + } + }, "standard-version": { "version": "9.5.0", "resolved": "https://registry.npmjs.org/standard-version/-/standard-version-9.5.0.tgz", @@ -61490,8 +66035,7 @@ "statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" }, "stealthy-require": { "version": "1.1.1", @@ -61618,7 +66162,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, "requires": { "safe-buffer": "~5.2.0" }, @@ -61626,8 +66169,7 @@ "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" } } }, @@ -61651,7 +66193,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -61758,7 +66299,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "requires": { "ansi-regex": "^5.0.1" } @@ -61784,8 +66324,7 @@ "strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" }, "strip-indent": { "version": "3.0.0", @@ -61819,6 +66358,12 @@ } } }, + "strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "peer": true + }, "style-loader": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-2.0.0.tgz", @@ -61896,11 +66441,16 @@ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.2.tgz", "integrity": "sha512-Nn2CCrG2ZaFziDxaZPN43CXqn+j7tcdjPFCkRBkFue8QYXC2HdEwnw5TCBo4yQZ2WxKYeSi0fdoOrtEqgDrXbA==" }, + "sudo-prompt": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-9.2.1.tgz", + "integrity": "sha512-Mu7R0g4ig9TUuGSxJavny5Rv0egCEtpZRNMrZaYS1vxkiIxGiGUwoezU3LazIQ+KE04hTrTfNPgxU5gzi7F5Pw==", + "peer": true + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -61918,8 +66468,14 @@ "supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "suspend-react": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/suspend-react/-/suspend-react-0.1.3.tgz", + "integrity": "sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ==", + "peer": true, + "requires": {} }, "svgo": { "version": "1.3.2", @@ -62211,7 +66767,6 @@ "version": "0.8.4", "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.4.tgz", "integrity": "sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg==", - "dev": true, "requires": { "rimraf": "~2.6.2" }, @@ -62220,7 +66775,6 @@ "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, "requires": { "glob": "^7.1.3" } @@ -62230,8 +66784,7 @@ "temp-dir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", - "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", - "dev": true + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==" }, "tempy": { "version": "0.6.0", @@ -62267,7 +66820,6 @@ "version": "5.15.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.0.tgz", "integrity": "sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA==", - "dev": true, "requires": { "@jridgewell/source-map": "^0.3.2", "acorn": "^8.5.0", @@ -62339,6 +66891,12 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "three": { + "version": "0.163.0", + "resolved": "https://registry.npmjs.org/three/-/three-0.163.0.tgz", + "integrity": "sha512-HlMgCb2TF/dTLRtknBnjUTsR8FsDqBY43itYop2+Zg822I+Kd0Ua2vs8CvfBVefXkBdNDrLMoRTGCIIpfCuDew==", + "peer": true + }, "throat": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", @@ -62427,8 +66985,7 @@ "tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" }, "to-arraybuffer": { "version": "1.0.1", @@ -62439,8 +66996,7 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" }, "to-object-path": { "version": "0.3.0", @@ -62484,7 +67040,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "requires": { "is-number": "^7.0.0" } @@ -62497,8 +67052,7 @@ "toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" }, "toposort": { "version": "1.0.7", @@ -62658,8 +67212,7 @@ "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" }, "type-fest": { "version": "0.20.2", @@ -62809,14 +67362,12 @@ "unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "dev": true + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==" }, "unicode-match-property-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dev": true, "requires": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" @@ -62825,14 +67376,12 @@ "unicode-match-property-value-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", - "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", - "dev": true + "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==" }, "unicode-property-aliases-ecmascript": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "dev": true + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==" }, "unified": { "version": "9.2.0", @@ -62990,14 +67539,12 @@ "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" }, "unquote": { "version": "1.1.1", @@ -63065,7 +67612,6 @@ "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", - "dev": true, "requires": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -63242,8 +67788,7 @@ "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" }, "uuid": { "version": "3.4.0", @@ -63298,8 +67843,7 @@ "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" }, "vendors": { "version": "1.0.4", @@ -63354,6 +67898,12 @@ "unist-util-stringify-position": "^2.0.0" } }, + "vlq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz", + "integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==", + "peer": true + }, "vm-browserify": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", @@ -63388,7 +67938,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, "requires": { "makeerror": "1.0.12" } @@ -63681,7 +68230,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, "requires": { "defaults": "^1.0.3" } @@ -64420,6 +68968,12 @@ } } }, + "whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", + "peer": true + }, "whatwg-mimetype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", @@ -64441,7 +68995,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "requires": { "isexe": "^2.0.0" } @@ -64459,6 +69012,12 @@ "is-symbol": "^1.0.3" } }, + "which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "peer": true + }, "which-typed-array": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", @@ -64813,7 +69372,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -64823,8 +69381,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "write-file-atomic": { "version": "3.0.3", @@ -64842,7 +69399,6 @@ "version": "6.2.2", "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", - "dev": true, "requires": { "async-limiter": "~1.0.0" } @@ -64892,14 +69448,12 @@ "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "yaml": { "version": "1.10.2", @@ -64947,8 +69501,20 @@ "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" + }, + "zdog": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/zdog/-/zdog-1.1.3.tgz", + "integrity": "sha512-raRj6r0gPzopFm5XWBJZr/NuV4EEnT4iE+U3dp5FV5pCb588Gmm3zLIp/j9yqqcMiHH8VNQlerLTgOqL7krh6w==", + "peer": true + }, + "zustand": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz", + "integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==", + "peer": true, + "requires": {} }, "zwitch": { "version": "1.0.5", From 34d8a9c2124bec333c3662115fc476a5a90d24a7 Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 3 Apr 2024 15:19:07 +0200 Subject: [PATCH 084/121] chore(meshwide): fix alert position --- .../src/components/Map/FloatingAlert.tsx | 2 +- .../src/containers/Map.tsx | 72 +++++++++---------- .../src/meshWidePage.tsx | 2 + 3 files changed, 35 insertions(+), 41 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx index 75873ae7e..f7f2acc2c 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx @@ -29,7 +29,7 @@ export const FloatingAlert = () => {
diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx index 311e7136b..60590b796 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx @@ -47,46 +47,38 @@ export const MeshWideMap = ({ }, [mapRef, selectedMapFeature, setSelectedMapFeature]); return ( - <> + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + ); }; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx index 8948d9500..c271398ca 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx @@ -6,6 +6,7 @@ import FloatingButton from "components/buttons/floatting-button"; import Loading from "components/loading"; import { useLoadLeaflet } from "plugins/lime-plugin-locate/src/locateQueries"; +import { FloatingAlert } from "plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert"; import { MeshWideMap } from "plugins/lime-plugin-mesh-wide/src/containers/Map"; import { SelectedFeatureBottomSheet } from "plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet"; @@ -38,6 +39,7 @@ const MeshWidePage = () => { return ( <> + route("/meshwide/config")} /> From 193fbe203ab52cf0cab96c0bbdf5403a0991f028 Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 3 Apr 2024 15:33:35 +0200 Subject: [PATCH 085/121] chore(meshwide): fix center map --- .../src/containers/Map.tsx | 39 ++++++++++++++++--- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx index 60590b796..3ef5bf1a4 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx @@ -8,6 +8,10 @@ import { TileLayer, } from "react-leaflet"; +import { + useLoadLeaflet, + useLocation, +} from "plugins/lime-plugin-locate/src/locateQueries"; import { FloatingAlert } from "plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert"; import { BatmanLinksLayer, @@ -34,7 +38,17 @@ export const MeshWideMap = ({ const { data: selectedMapFeature, setData: setSelectedMapFeature } = useSelectedMapFeature(); + const { isLoading: assetsLoading, isFetchedAfterMount: assetsLoaded } = + useLoadLeaflet({ + refetchOnWindowFocus: false, + }); + + const { data: nodeLocation, isLoading: isLoadingLocation } = useLocation({ + enabled: assetsLoaded, + }); + const mapRef = useRef(); + const loading = assetsLoading || isLoadingLocation; useEffect(() => { if (mapRef) { @@ -46,13 +60,28 @@ export const MeshWideMap = ({ } }, [mapRef, selectedMapFeature, setSelectedMapFeature]); + // Set map position when map is available or location gets updated + useEffect(() => { + const mapInstance = mapRef.current; + if ( + !loading && + mapInstance && + nodeLocation && + nodeLocation.location && + (nodeLocation.location.lat !== "FIXME" || + nodeLocation.location.lon !== "FIXME") + ) { + mapInstance.setView( + [+nodeLocation.location.lat, +nodeLocation.location.lon], + 13 + ); + } + }, [loading, nodeLocation]); + return ( Date: Thu, 4 Apr 2024 09:23:28 +0200 Subject: [PATCH 086/121] chore(meshwide): fix floating alert --- .../src/components/FeatureDetail/InvalidNodesDetail.tsx | 4 ++-- .../src/components/Map/FloatingAlert.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/InvalidNodesDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/InvalidNodesDetail.tsx index 7fc9edd29..c3761f62a 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/InvalidNodesDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/InvalidNodesDetail.tsx @@ -13,8 +13,8 @@ export const InvalidNodesDetail = ({ nodes }: { nodes: InvalidNodes }) => { - The following nodes are not located. Please, set their - location to see them on the map: + The following nodes are not located or have not reference + state. Please, set their location to see them on the map: {[...nodes].map((name, k) => ( diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx index f7f2acc2c..2b5463dc5 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx @@ -15,8 +15,8 @@ export const FloatingAlert = () => { const callback = useCallback(() => { const list: InvalidNodes = new Set([ - ...Object.keys(invalidNodesReference), - ...Object.keys(invalidNodesActual), + ...Object.keys(invalidNodesReference ?? []), + ...Object.keys(invalidNodesActual ?? []), ]); setSelectedFeature({ id: "invalidNodes", From c82f5958c0cb931ba33f24ff355ac56d64858835 Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 4 Apr 2024 09:55:00 +0200 Subject: [PATCH 087/121] chore(meshwide): prevent empty shared state --- .../src/lib/links/getLinksCoordinates.ts | 5 +++- .../lime-plugin-mesh-wide/src/mesWideApi.ts | 23 ++++++++++++++----- src/utils/utils.tsx | 3 +++ 3 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 src/utils/utils.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts index cae45399f..b40acf53a 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts @@ -11,12 +11,15 @@ import { LocatedLinkData, } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +import { isEmpty } from "utils/utils"; + export const mergeLinksAndCoordinates = ( nodes: INodes, links: ILinks, type: T ): LocatedLinkData => { - if (!nodes || !links) return {}; + if (!nodes || isEmpty(nodes) || !links || isEmpty(links)) return {}; + const result: LocatedLinkData = {}; // for every node check all links diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts b/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts index eb0e50ed2..336e40360 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts +++ b/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts @@ -2,20 +2,31 @@ import { meshUpgradeQueryKeys } from "plugins/lime-plugin-mesh-wide/src/mesWideQ import api from "utils/uhttpd.service"; +const sharedStateApiCall = async (queryKey) => { + try { + return await api.call(...queryKey); + } catch (e) { + // Prevent the whole page from crashing if the API call fails + // It can happen either because the package is not installed or reference state is not available + console.error(e); + return {}; + } +}; + export const getMeshWideBatmanReference = () => - api.call(...meshUpgradeQueryKeys.batHostsRef); + sharedStateApiCall(meshUpgradeQueryKeys.batHostsRef); export const getMeshWideBatman = () => - api.call(...meshUpgradeQueryKeys.batHosts); + sharedStateApiCall(meshUpgradeQueryKeys.batHosts); export const getMeshWideLinksReference = () => - api.call(...meshUpgradeQueryKeys.wifiLinksInfoRef); + sharedStateApiCall(meshUpgradeQueryKeys.wifiLinksInfoRef); export const getMeshWideLinks = () => - api.call(...meshUpgradeQueryKeys.wifiLinksInfo); + sharedStateApiCall(meshUpgradeQueryKeys.wifiLinksInfo); export const getMeshWideNodesReference = () => - api.call(...meshUpgradeQueryKeys.meshWideNodesRef); + sharedStateApiCall(meshUpgradeQueryKeys.meshWideNodesRef); export const getMeshWideNodes = () => - api.call(...meshUpgradeQueryKeys.meshWideNodes); + sharedStateApiCall(meshUpgradeQueryKeys.meshWideNodes); diff --git a/src/utils/utils.tsx b/src/utils/utils.tsx new file mode 100644 index 000000000..68b889a4a --- /dev/null +++ b/src/utils/utils.tsx @@ -0,0 +1,3 @@ +export function isEmpty(obj: object): boolean { + return Object.keys(obj).length === 0; +} From 383b4ac6f6421977a5fba4460c0a827b94a81cd7 Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 4 Apr 2024 10:04:06 +0200 Subject: [PATCH 088/121] chore(meshwide): fix leaflet load --- plugins/lime-plugin-mesh-wide/src/containers/Map.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx index 3ef5bf1a4..a981e464c 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx @@ -38,13 +38,12 @@ export const MeshWideMap = ({ const { data: selectedMapFeature, setData: setSelectedMapFeature } = useSelectedMapFeature(); - const { isLoading: assetsLoading, isFetchedAfterMount: assetsLoaded } = - useLoadLeaflet({ - refetchOnWindowFocus: false, - }); + const { isLoading: assetsLoading, data: leafletData } = useLoadLeaflet({ + refetchOnWindowFocus: false, + }); const { data: nodeLocation, isLoading: isLoadingLocation } = useLocation({ - enabled: assetsLoaded, + enabled: !!leafletData, }); const mapRef = useRef(); From ee610c1af81df393de81121887cd56588497317e Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 5 Apr 2024 09:24:41 +0200 Subject: [PATCH 089/121] chore(meshwide): implement check query errors by timer --- .../src/components/Map/FloatingAlert.tsx | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx index 2b5463dc5..0ac5d20db 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx @@ -1,10 +1,36 @@ +import { useQuery } from "@tanstack/react-query"; import { useCallback } from "react"; import { useNodes } from "plugins/lime-plugin-mesh-wide/src/hooks/useNodes"; import { WarningIcon } from "plugins/lime-plugin-mesh-wide/src/icons/warningIcon"; import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; +import { meshUpgradeQueryKeys } from "plugins/lime-plugin-mesh-wide/src/mesWideQueriesKeys"; import { InvalidNodes } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +import queryCache from "utils/queryCache"; + +const checkErrors = () => { + const errors = Object.keys(meshUpgradeQueryKeys).reduce((acc, key) => { + const queryKey = meshUpgradeQueryKeys[key]; + const queryState = queryCache.getQueryState(queryKey); + + if (queryState?.error) { + acc[key] = { queryKey, error: queryState.error }; + } + + return acc; + }, {}); + + return errors; +}; + +export function useMeshWideDataErrors(params) { + return useQuery(["lime-meshwide", "mesh_wide_errors"], checkErrors, { + refetchInterval: 6000, // Fetch data every 6 seconds + ...params, + }); +} + export const FloatingAlert = () => { const { hasInvalidNodes, @@ -13,6 +39,9 @@ export const FloatingAlert = () => { const { setData: setSelectedFeature } = useSelectedMapFeature(); + const { data: errors } = useMeshWideDataErrors({}); + + console.log("errors", errors); const callback = useCallback(() => { const list: InvalidNodes = new Set([ ...Object.keys(invalidNodesReference ?? []), @@ -23,7 +52,12 @@ export const FloatingAlert = () => { type: "invalidNodes", feature: list, }); - }, [invalidNodesActual, invalidNodesReference, setSelectedFeature]); + }, [ + // checkErrors, + invalidNodesActual, + invalidNodesReference, + setSelectedFeature, + ]); return hasInvalidNodes ? (
Date: Fri, 5 Apr 2024 11:10:32 +0200 Subject: [PATCH 090/121] chore(meshwide): implement meshWide errors show --- .../FeatureDetail/InvalidNodesDetail.tsx | 25 ------- .../FeatureDetail/ShowErrorsDetail.tsx | 71 ++++++++++++++++++ .../src/components/FeatureDetail/index.tsx | 6 +- .../src/components/Map/FloatingAlert.tsx | 53 +++++-------- .../src/hooks/useMeshWideDataErrors.tsx | 74 +++++++++++++++++++ .../src/mesWideTypes.tsx | 14 +++- 6 files changed, 178 insertions(+), 65 deletions(-) delete mode 100644 plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/InvalidNodesDetail.tsx create mode 100644 plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx create mode 100644 plugins/lime-plugin-mesh-wide/src/hooks/useMeshWideDataErrors.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/InvalidNodesDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/InvalidNodesDetail.tsx deleted file mode 100644 index c3761f62a..000000000 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/InvalidNodesDetail.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { Trans } from "@lingui/macro"; - -import { Row } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index"; -import { InvalidNodes } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; - -export const InvalidNodesDetail = ({ nodes }: { nodes: InvalidNodes }) => { - return ( -
- -
- Invalid Nodes -
-
- - - The following nodes are not located or have not reference - state. Please, set their location to see them on the map: - - - {[...nodes].map((name, k) => ( -
{name}
- ))} -
- ); -}; diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx new file mode 100644 index 000000000..3a01bac06 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx @@ -0,0 +1,71 @@ +import { Trans } from "@lingui/macro"; + +import { Row } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index"; +import { ErrorsDetails } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; + +export const ShowErrorsDetail = ({ errors }: { errors: ErrorsDetails }) => { + return ( +
+ {errors.invalidNodes && ( +
+ +
+ Invalid Nodes +
+
+ + + The following nodes are not located or have not + reference state. Please, set their location to see + them on the map: + + + {[...errors.invalidNodes].map((name, k) => ( +
{name}
+ ))} +
+ )} + {errors.dataNotSetErrors.length > 0 && ( +
+ +
+ Reference State is not set +
+
+ + + The following shared states packages have not data + set + + + {[...errors.dataNotSetErrors].map((data, k) => ( +
+ {JSON.stringify(data.queryKey, null, 2)} +
+ ))} +
+ )} + {errors.meshWideDataErrors.length > 0 && ( +
+ +
+ Shared state error +
+
+ + + The following shared states packages have errors. + Are they installed or properly initialized? + + + {[...errors.meshWideDataErrors].map((data, k) => ( +
+ {JSON.stringify(data.queryKey, null, 2)}:{" "} + {data?.error?.toString()} +
+ ))} +
+ )} +
+ ); +}; diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx index f3718cd6d..86fbe16bd 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx @@ -1,12 +1,12 @@ import { VNode } from "preact"; -import { InvalidNodesDetail } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/InvalidNodesDetail"; import LinkFeatureDetail, { LinkReferenceStatus, } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail"; import NodeDetails, { NodeReferenceStatus, } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail"; +import { ShowErrorsDetail } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail"; import { LinkMapFeature, NodeMapFeature, @@ -50,8 +50,8 @@ export const FeatureDetail = ({ return ; case "node": return ; - case "invalidNodes": - return ; + case "errorsDetails": + return ; default: return <>; } diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx index 0ac5d20db..4ccb90997 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx @@ -1,65 +1,46 @@ -import { useQuery } from "@tanstack/react-query"; import { useCallback } from "react"; +import { useMeshWideDataErrors } from "plugins/lime-plugin-mesh-wide/src/hooks/useMeshWideDataErrors"; import { useNodes } from "plugins/lime-plugin-mesh-wide/src/hooks/useNodes"; import { WarningIcon } from "plugins/lime-plugin-mesh-wide/src/icons/warningIcon"; import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; -import { meshUpgradeQueryKeys } from "plugins/lime-plugin-mesh-wide/src/mesWideQueriesKeys"; import { InvalidNodes } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; -import queryCache from "utils/queryCache"; - -const checkErrors = () => { - const errors = Object.keys(meshUpgradeQueryKeys).reduce((acc, key) => { - const queryKey = meshUpgradeQueryKeys[key]; - const queryState = queryCache.getQueryState(queryKey); - - if (queryState?.error) { - acc[key] = { queryKey, error: queryState.error }; - } - - return acc; - }, {}); - - return errors; -}; - -export function useMeshWideDataErrors(params) { - return useQuery(["lime-meshwide", "mesh_wide_errors"], checkErrors, { - refetchInterval: 6000, // Fetch data every 6 seconds - ...params, - }); -} - export const FloatingAlert = () => { + const { setData: setSelectedFeature } = useSelectedMapFeature(); + const { hasInvalidNodes, invalidNodes: { invalidNodesReference, invalidNodesActual }, } = useNodes(); + const { meshWideDataErrors, dataNotSetErrors } = useMeshWideDataErrors(); - const { setData: setSelectedFeature } = useSelectedMapFeature(); - - const { data: errors } = useMeshWideDataErrors({}); + const hasErrors = + hasInvalidNodes || meshWideDataErrors.length || dataNotSetErrors.length; - console.log("errors", errors); const callback = useCallback(() => { - const list: InvalidNodes = new Set([ + const invalidNodes: InvalidNodes = new Set([ ...Object.keys(invalidNodesReference ?? []), ...Object.keys(invalidNodesActual ?? []), ]); setSelectedFeature({ - id: "invalidNodes", - type: "invalidNodes", - feature: list, + id: "errorsDetails", + type: "errorsDetails", + feature: { + invalidNodes, + meshWideDataErrors, + dataNotSetErrors, + }, }); }, [ - // checkErrors, + dataNotSetErrors, invalidNodesActual, invalidNodesReference, + meshWideDataErrors, setSelectedFeature, ]); - return hasInvalidNodes ? ( + return hasErrors ? (
{ + const meshWideDataErrors: MeshWideDataError[] = []; + const dataNotSetErrors: MeshWideDataError[] = []; + + const addError = (queryKey: QueryKey, error?: unknown, data?: object) => { + if (data && isEmpty(data)) { + dataNotSetErrors.push({ queryKey, error }); + } + if (error) { + meshWideDataErrors.push({ queryKey, error }); + } + }; + + const { data: linksReferenceData, error: linksReferenceError } = + useMeshWideLinksReference({}); + addError( + meshUpgradeQueryKeys.wifiLinksInfoRef, + linksReferenceError, + linksReferenceData + ); + + const { error: linksError } = useMeshWideLinks({}); + addError(meshUpgradeQueryKeys.wifiLinksInfo, linksError); + + const { data: batmanReferenceData, error: batmanReferenceError } = + useMeshWideBatmanReference({}); + addError( + meshUpgradeQueryKeys.batHostsRef, + batmanReferenceError, + batmanReferenceData + ); + + const { error: batmanError } = useMeshWideBatman({}); + addError(meshUpgradeQueryKeys.batHosts, batmanError); + + const { data: nodesReferenceData, error: nodesReferenceError } = + useMeshWideNodesReference({}); + addError( + meshUpgradeQueryKeys.nodesAndLinksRef, + nodesReferenceError, + nodesReferenceData + ); + + const { error: nodesError } = useMeshWideNodes({}); + addError(meshUpgradeQueryKeys.nodesAndLinks, nodesError); + + return { meshWideDataErrors, dataNotSetErrors }; +}; diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index 20e027770..7587ea6ba 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -1,3 +1,5 @@ +import { QueryKey } from "@tanstack/react-query"; + import { MacToMacLink, PontToPointLink, @@ -98,12 +100,22 @@ export type NodeMapFeature = { name: string; }; +export type MeshWideDataError = { + queryKey: QueryKey; + error?: unknown; +}; + export type InvalidNodes = Set; +export type ErrorsDetails = { + invalidNodes: Set; + meshWideDataErrors: MeshWideDataError[]; + dataNotSetErrors: MeshWideDataError[]; +}; type FeatureMap = { node: NodeMapFeature; link: LinkMapFeature; - invalidNodes: InvalidNodes; + errorsDetails: ErrorsDetails; }; type FeatureType = keyof FeatureMap; From ce1e34187ae8765e7f2c8c885db13acc477f9dae Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 5 Apr 2024 15:16:45 +0200 Subject: [PATCH 091/121] chore(meshwide): disable nodes_and_links keys --- .../src/hooks/useMeshWideDataErrors.tsx | 4 ++-- plugins/lime-plugin-mesh-wide/src/mesWideQueriesKeys.tsx | 6 ------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useMeshWideDataErrors.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useMeshWideDataErrors.tsx index 71b58a77e..c0874b04c 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useMeshWideDataErrors.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useMeshWideDataErrors.tsx @@ -62,13 +62,13 @@ export const useMeshWideDataErrors = () => { const { data: nodesReferenceData, error: nodesReferenceError } = useMeshWideNodesReference({}); addError( - meshUpgradeQueryKeys.nodesAndLinksRef, + meshUpgradeQueryKeys.meshWideNodesRef, nodesReferenceError, nodesReferenceData ); const { error: nodesError } = useMeshWideNodes({}); - addError(meshUpgradeQueryKeys.nodesAndLinks, nodesError); + addError(meshUpgradeQueryKeys.meshWideNodes, nodesError); return { meshWideDataErrors, dataNotSetErrors }; }; diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideQueriesKeys.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideQueriesKeys.tsx index 62fe56b7e..eaaf5b569 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideQueriesKeys.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideQueriesKeys.tsx @@ -7,7 +7,6 @@ interface MeshWideQueryKeysProps { const MeshWideQueryKeys: MeshWideQueryKeysProps = { meshWideNodes: [{ data_type: "node_info" }], wifiLinksInfo: [{ data_type: "wifi_links_info" }], - nodesAndLinks: [{ data_type: "nodes_and_links" }], batHosts: [{ data_type: "bat-hosts" }], }; @@ -29,11 +28,6 @@ export const meshUpgradeQueryKeys = { ...getFromSharedStateMultiWriter, ...MeshWideQueryKeys.wifiLinksInfo, ], - nodesAndLinks: [...getFromSharedState, ...MeshWideQueryKeys.nodesAndLinks], - nodesAndLinksRef: [ - ...getFromSharedStateMultiWriter, - ...MeshWideQueryKeys.nodesAndLinks, - ], batHosts: [...getFromSharedStateAsync, ...MeshWideQueryKeys.batHosts], batHostsRef: [ ...getFromSharedStateMultiWriter, From 67dfbf3f746630508ef4cbeac81ed71ee8a5923a Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 5 Apr 2024 15:30:50 +0200 Subject: [PATCH 092/121] chore(meshwide): refactor to new schema type --- .../components/FeatureDetail/NodeDetail.tsx | 16 +- .../src/components/Map/LinkLine.tsx | 2 +- .../src/components/Map/NodeMarker.tsx | 5 +- .../SelectedFeatureBottomSheet.spec.tsx | 37 ++--- .../src/hooks/useNodes.tsx | 4 +- .../src/lib/links/PointToPointLink.ts | 4 +- .../src/lib/links/getLinksCoordinates.ts | 14 +- .../src/lib/nodes/processErrors.ts | 6 +- .../src/mesWideTypes.tsx | 22 ++- .../src/meshWideMocks.tsx | 142 ++++++++---------- 10 files changed, 118 insertions(+), 134 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx index 95b344bce..93e7294e1 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx @@ -17,17 +17,17 @@ import { } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; const NodeDetails = ({ actual, reference, name }: NodeMapFeature) => { - const uptime = reference.data.uptime; - const firmware = reference.data.firmware_version; - const ipv6 = reference.data.ipv6; - const ipv4 = reference.data.ipv4; - const device = reference.data.device; - const { errors, hasErrors, isDown } = useNodeErrors({ actual, reference }); + const uptime = reference.uptime; + const firmware = reference.firmware_version; + const ipv6 = reference.ipv6; + const ipv4 = reference.ipv4; + const device = reference.device; + const { errors, isDown } = useNodeErrors({ actual, reference }); if (isDown) { return This node seems down; } - const macs = actual.data.macs; + const macs = actual.macs; return (
@@ -76,7 +76,7 @@ const NodeDetails = ({ actual, reference, name }: NodeMapFeature) => { } > <> - {getArrayDifference(reference.data.macs, macs).map( + {getArrayDifference(reference.macs, macs).map( (mac, k) => (
{mac}
) diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx index d1216290d..f0865b2a5 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx @@ -37,7 +37,7 @@ export const LinkLine = ({ referenceLink, actualLink }: ILinkLineProps) => { }; }; - const coordinates = referenceLink.coordinates.map((c) => [c.lat, c.lon]); + const coordinates = referenceLink.coordinates.map((c) => [c.lat, c.long]); return ( { ).toBeLessThan(0); }); - it("should open BottomSheet with invalid nodes feature", () => { - const invalid = "invalid_node"; - mockedSelectedMapFeature.mockReturnValue({ - data: { - type: "invalidNodes", - feature: new Set([invalid]), - id: "invalidNodes", - }, - setData: () => {}, - }); - - render(); - expect( - pxToNumber(screen.queryByTestId("bottom-sheet-body").style.height) - ).toBeGreaterThan(0); - expect(screen.getByText(invalid)).toBeInTheDocument(); - expect(screen.getByText("Invalid Nodes")).toBeInTheDocument(); - }); + // todo(kon): refactor this test because this feautre is changed + // it("should open BottomSheet with invalid nodes feature", () => { + // const invalid = "invalid_node"; + // mockedSelectedMapFeature.mockReturnValue({ + // data: { + // type: "invalidNodes", + // feature: new Set([invalid]), + // id: "invalidNodes", + // }, + // setData: () => {}, + // }); + // + // render(); + // expect( + // pxToNumber(screen.queryByTestId("bottom-sheet-body").style.height) + // ).toBeGreaterThan(0); + // expect(screen.getByText(invalid)).toBeInTheDocument(); + // expect(screen.getByText("Invalid Nodes")).toBeInTheDocument(); + // }); it("should open BottomSheet with node feature", () => { const name = "LiMe-da4eaa"; diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx index b5d593ee6..72ba18710 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx @@ -21,8 +21,8 @@ export const useNodes = () => { try { if ( isValidCoordinate( - nodeInfo.data.coordinates.lat, - nodeInfo.data.coordinates.lon + nodeInfo.coordinates.lat, + nodeInfo.coordinates.long ) ) { validNodes[key] = nodeInfo; diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts index cc686d9f3..e06bcebbb 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts @@ -73,9 +73,9 @@ export class PontToPointLink { parseFloat(coord.replace("-", "").replace(".", "")); const allCoordinates = [ - _prepareCoord(coord1.lon), + _prepareCoord(coord1.long), _prepareCoord(coord1.lat), - _prepareCoord(coord2.lon), + _prepareCoord(coord2.long), _prepareCoord(coord2.lat), ]; diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts index b40acf53a..9a3c3c870 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts @@ -27,7 +27,7 @@ export const mergeLinksAndCoordinates = ( for (const linkData of links[linkNodeName].data) { // Get the nodeName of the destination node const dstNodeName = Object.keys(nodes).find((pid) => { - return nodes[pid].data.macs.find( + return nodes[pid].macs.find( (mac) => mac.toLowerCase() === linkData.dst_mac.toLowerCase() ); @@ -40,15 +40,15 @@ export const mergeLinksAndCoordinates = ( ) { // Generate a unique id of the point to point link based on the coordinates const linkKey = PontToPointLink.generateId( - nodes[linkNodeName].data.coordinates, - nodes[dstNodeName!].data.coordinates + nodes[linkNodeName].coordinates, + nodes[dstNodeName!].coordinates ); // If this point to point link no exists, instantiate it if (!result[linkKey]) { result[linkKey] = new PontToPointLink( - nodes[linkNodeName].data.coordinates, - nodes[dstNodeName!].data.coordinates + nodes[linkNodeName].coordinates, + nodes[dstNodeName!].coordinates ); } // Else if the link is not already added don't do it. @@ -76,11 +76,11 @@ export const mergeLinksAndCoordinates = ( const entry = { [linkNodeName]: { ...linkData, - coordinates: nodes[linkNodeName].data.coordinates, + coordinates: nodes[linkNodeName].coordinates, }, [dstNodeName]: { ...destPointData, - coordinates: nodes[dstNodeName].data.coordinates, + coordinates: nodes[dstNodeName].coordinates, }, } as ILocatedLink; diff --git a/plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts b/plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts index a9e46ef30..8ecbe7aa2 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts @@ -14,11 +14,11 @@ export const processNodeErrors = ( if (!actual) return [NodeErrorCodes.NODE_DOWN]; // Check mac list are equal - if (reference.data.macs.length !== actual.data.macs.length) { + if (reference.macs.length !== actual.macs.length) { errors.push(NodeErrorCodes.MACS_MISSMATCH); } - const sortedRefMacs = reference.data.macs.slice().sort(); - const sortedActualMacs = actual.data.macs.slice().sort(); + const sortedRefMacs = reference.macs.slice().sort(); + const sortedActualMacs = actual.macs.slice().sort(); for (let i = 0; i < sortedRefMacs.length; i++) { if (sortedRefMacs[i] !== sortedActualMacs[i]) { diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index 7587ea6ba..2ddfd2af7 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -68,23 +68,21 @@ export type IBatmanLinks = ILinks<"batman">; export type Coordinates = { lat: string; - lon: string; + long: string; }; export interface INodeInfo { bleachTTL: number; author: string; - data: { - coordinates?: Coordinates; // Coordinates may not be set - board: string; - device: string; - macs: string[]; - hostname: string; - ipv4: string; - ipv6: string; - firmware_version: string; - uptime: number; - }; + coordinates?: Coordinates; // Coordinates may not be set + board: string; + device: string; + macs: string[]; + hostname: string; + ipv4: string; + ipv6: string; + firmware_version: string; + uptime: number; } export type INodes = { [key: string]: INodeInfo }; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx index 10d962a42..f45f3fb4b 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx @@ -15,98 +15,86 @@ export const nodesReferenceState: INodes = { "LiMe-462895": { bleachTTL: 12, author: "LiMe-462895", - data: { - coordinates: { - lon: "-64.42703", - lat: "-31.80874", - }, - macs: [ - "a0:f3:c1:46:28:96", - "a0:f3:c1:46:28:97", - "a0:f3:c1:46:11:97", - ], - ipv4: "192.168.1.1", - ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", - firmware_version: "1.0.0", - uptime: 1010.03, - device: "Router", - board: "", - hostname: "", + coordinates: { + long: "-64.42703", + lat: "-31.80874", }, + macs: ["a0:f3:c1:46:28:96", "a0:f3:c1:46:28:97", "a0:f3:c1:46:11:97"], + ipv4: "192.168.1.1", + ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", + firmware_version: "1.0.0", + uptime: 1010.03, + device: "Router", + board: "", + hostname: "", }, "LiMe-da4eaa": { bleachTTL: 12, author: "LiMe-da4eaa", - data: { - coordinates: { - lon: "-64.42315", - lat: "-31.79461", - }, - macs: [ - "14:cc:20:da:4e:ab", - "14:cc:20:da:4e:ac", - // Following macs are related to batman links - "02:ab:46:fc:3a:bd", - "02:58:47:fc:3a:bd", - ], - ipv4: "192.168.1.2", - ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7335", - firmware_version: "1.0.1", - uptime: 37.89, - device: "Switch", - board: "", - hostname: "", + coordinates: { + long: "-64.42315", + lat: "-31.79461", }, + macs: [ + "14:cc:20:da:4e:ab", + "14:cc:20:da:4e:ac", + // Following macs are related to batman links + "02:ab:46:fc:3a:bd", + "02:58:47:fc:3a:bd", + ], + ipv4: "192.168.1.2", + ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7335", + firmware_version: "1.0.1", + uptime: 37.89, + device: "Switch", + board: "", + hostname: "", }, primero: { bleachTTL: 12, author: "primero", - data: { - coordinates: { - lon: "-64.41609", - lat: "-31.80461", - }, - macs: [ - "a8:40:41:1d:f9:35", - "a8:40:41:1d:f9:35", - // Following macs are related to batman links - "02:db:d6:46:28:95", - "02:ab:46:46:28:95", - "02:58:47:46:28:95", - ], - ipv4: "192.168.1.3", - ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7336", - firmware_version: "1.0.2", - uptime: 37.89, - device: "Hub", - board: "", - hostname: "", + coordinates: { + long: "-64.41609", + lat: "-31.80461", }, + macs: [ + "a8:40:41:1d:f9:35", + "a8:40:41:1d:f9:35", + // Following macs are related to batman links + "02:db:d6:46:28:95", + "02:ab:46:46:28:95", + "02:58:47:46:28:95", + ], + ipv4: "192.168.1.3", + ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7336", + firmware_version: "1.0.2", + uptime: 37.89, + device: "Hub", + board: "", + hostname: "", }, segundo: { bleachTTL: 12, author: "segundo", - data: { - coordinates: { - lon: "-64.43209", - lat: "-31.79461", - }, - macs: [ - "a8:40:41:1d:f9:ff", - "a8:40:41:1d:f9:aa", - // Following macs are related to batman links - "02:db:d6:da:4e:aa", - "02:58:47:da:4e:aa", - "02:ab:46:da:4e:aa", - ], - ipv4: "192.168.1.3", - ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7336", - firmware_version: "1.0.2", - uptime: 37.89, - device: "Hub", - board: "", - hostname: "", + coordinates: { + long: "-64.43209", + lat: "-31.79461", }, + macs: [ + "a8:40:41:1d:f9:ff", + "a8:40:41:1d:f9:aa", + // Following macs are related to batman links + "02:db:d6:da:4e:aa", + "02:58:47:da:4e:aa", + "02:ab:46:da:4e:aa", + ], + ipv4: "192.168.1.3", + ipv6: "2001:0db8:85a3:0000:0000:8a2e:0370:7336", + firmware_version: "1.0.2", + uptime: 37.89, + device: "Hub", + board: "", + hostname: "", }, }; @@ -402,7 +390,7 @@ export const nodes = (): INodes => { // This only delete a particular mac from the list of macs for (const [k, v] of Object.entries(newState)) { - v.data.macs = v.data.macs.filter((mac) => mac !== macToDelete); + v.macs = v.macs.filter((mac) => mac !== macToDelete); } // This delete an entire node From 99cc4d493dec708c9b89d0ff22d569dda653c988 Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 5 Apr 2024 15:39:01 +0200 Subject: [PATCH 093/121] chore(meshwide): hide error --- .../src/components/FeatureDetail/ShowErrorsDetail.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx index 3a01bac06..b7ef71d88 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx @@ -6,7 +6,7 @@ import { ErrorsDetails } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; export const ShowErrorsDetail = ({ errors }: { errors: ErrorsDetails }) => { return (
- {errors.invalidNodes && ( + {errors.invalidNodes.size > 0 && (
From 4f8c857aad4b16a499bc28095da552582a88d956 Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 5 Apr 2024 15:43:21 +0200 Subject: [PATCH 094/121] chore(meshwide): prevent empty reference state --- .../src/containers/MapLayers/LinksLayers.tsx | 10 +++++++++- .../src/containers/MapLayers/NodesLayer.tsx | 12 ++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx index 19bff79f4..5db32b1a0 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx @@ -3,6 +3,8 @@ import { useLocatedLinks } from "plugins/lime-plugin-mesh-wide/src/hooks/useLoca import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; import { LocatedLinkData } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +import { isEmpty } from "utils/utils"; + interface ILinksLayerProps { links: LocatedLinkData; linksReference: LocatedLinkData; @@ -11,9 +13,15 @@ interface ILinksLayerProps { const LinksLayer = ({ links, - linksReference, + linksReference: originalLinksReference, linksLoaded, }: ILinksLayerProps) => { + // If reference is not set or empty, use actual nodes + const linksReference = + originalLinksReference && isEmpty(originalLinksReference) + ? links + : originalLinksReference; + return (
{linksLoaded && diff --git a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx index 0a89a6d28..cbf260b68 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx @@ -2,6 +2,8 @@ import NodeMarker from "plugins/lime-plugin-mesh-wide/src/components/Map/NodeMar import { useNodes } from "plugins/lime-plugin-mesh-wide/src/hooks/useNodes"; import { INodeInfo } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +import { isEmpty } from "utils/utils"; + const NodesLayer = () => { const { locatedNodes: { @@ -10,10 +12,16 @@ const NodesLayer = () => { }, } = useNodes(); + // If reference is not set or empty, use actual nodes + const referenceNodes = + meshWideNodesReference && isEmpty(meshWideNodesReference) + ? meshWideNodesActual + : meshWideNodesReference; + return (
- {meshWideNodesReference && - Object.entries(meshWideNodesReference).map(([k, v], i) => { + {referenceNodes && + Object.entries(referenceNodes).map(([k, v], i) => { let actualNode: INodeInfo; if (meshWideNodesActual) { actualNode = meshWideNodesActual[k]; From 3ba117a38bd4b0c3d8ca455657b87ade15ac5daf Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 5 Apr 2024 15:52:14 +0200 Subject: [PATCH 095/121] chore(meshwide): fix lint --- .../src/lib/links/getLinksCoordinates.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.spec.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.spec.ts index 97da20b4f..df4a0a1d0 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.spec.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.spec.ts @@ -21,7 +21,7 @@ describe("tests for the algorithm that merge point and links data types", () => for (const link of merged.links) { Object.entries(link.data).map(([name, linkData], i) => { const node = nodesReferenceState[name]; - expect(linkData.coordinates).toBe(node.data.coordinates); + expect(linkData.coordinates).toBe(node.coordinates); }); } }); From 9ed8abbc65c99845e1b68eb1f78b8b18fd9bea77 Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 9 Apr 2024 15:19:11 +0200 Subject: [PATCH 096/121] chore(meshwide): use the new mesh wide response type --- .../lime-plugin-mesh-wide/src/mesWideApi.ts | 50 ++++++++++++------- .../src/mesWideTypes.tsx | 6 +++ 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts b/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts index 336e40360..6ff17ffe0 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts +++ b/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts @@ -1,32 +1,46 @@ import { meshUpgradeQueryKeys } from "plugins/lime-plugin-mesh-wide/src/mesWideQueriesKeys"; +import { + IBatmanLinks, + INodes, + IWifiLinks, + SharedStateReturnType, +} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; import api from "utils/uhttpd.service"; -const sharedStateApiCall = async (queryKey) => { - try { - return await api.call(...queryKey); - } catch (e) { - // Prevent the whole page from crashing if the API call fails - // It can happen either because the package is not installed or reference state is not available - console.error(e); - return {}; - } +/** + * Map the query keys to a specific type + */ +interface MeshUpgradeQueryKeyTypes { + meshWideNodes: INodes; + meshWideNodesRef: INodes; + wifiLinksInfo: IWifiLinks; + wifiLinksInfoRef: IWifiLinks; + batHosts: IBatmanLinks; + batHostsRef: IBatmanLinks; +} + +const sharedStateApiCall = async ( + queryKey: K +) => { + const res = (await api.call( + ...meshUpgradeQueryKeys[queryKey] + )) as SharedStateReturnType; + if (res.error !== 0) throw Error(`Shared state error: ${res.error}`); + return res.data; }; export const getMeshWideBatmanReference = () => - sharedStateApiCall(meshUpgradeQueryKeys.batHostsRef); + sharedStateApiCall("batHostsRef"); -export const getMeshWideBatman = () => - sharedStateApiCall(meshUpgradeQueryKeys.batHosts); +export const getMeshWideBatman = () => sharedStateApiCall("batHosts"); export const getMeshWideLinksReference = () => - sharedStateApiCall(meshUpgradeQueryKeys.wifiLinksInfoRef); + sharedStateApiCall("wifiLinksInfoRef"); -export const getMeshWideLinks = () => - sharedStateApiCall(meshUpgradeQueryKeys.wifiLinksInfo); +export const getMeshWideLinks = () => sharedStateApiCall("wifiLinksInfo"); export const getMeshWideNodesReference = () => - sharedStateApiCall(meshUpgradeQueryKeys.meshWideNodesRef); + sharedStateApiCall("meshWideNodesRef"); -export const getMeshWideNodes = () => - sharedStateApiCall(meshUpgradeQueryKeys.meshWideNodes); +export const getMeshWideNodes = async () => sharedStateApiCall("meshWideNodes"); diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index 2ddfd2af7..727d50f61 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -87,6 +87,12 @@ export interface INodeInfo { export type INodes = { [key: string]: INodeInfo }; +export type SharedStateTypes = INodes | IWifiLinks | IBatmanLinks; +export type SharedStateReturnType = { + data: T; + error: number; +}; + export type LinkMapFeature = { actual: PontToPointLink; reference: PontToPointLink; From 24fede71409ab4a97c1066ce0a4126e7f4df8238 Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 9 Apr 2024 15:56:07 +0200 Subject: [PATCH 097/121] chore(meshwide): implement close feature --- .../src/components/Map/FloatingAlert.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx index 4ccb90997..95f393a1b 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx @@ -7,7 +7,8 @@ import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWide import { InvalidNodes } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; export const FloatingAlert = () => { - const { setData: setSelectedFeature } = useSelectedMapFeature(); + const { setData: setSelectedFeature, data: selectedMapFeature } = + useSelectedMapFeature(); const { hasInvalidNodes, @@ -19,10 +20,15 @@ export const FloatingAlert = () => { hasInvalidNodes || meshWideDataErrors.length || dataNotSetErrors.length; const callback = useCallback(() => { + if (selectedMapFeature && selectedMapFeature.id === "errorsDetails") { + setSelectedFeature(null); + return; + } const invalidNodes: InvalidNodes = new Set([ ...Object.keys(invalidNodesReference ?? []), ...Object.keys(invalidNodesActual ?? []), ]); + setSelectedFeature({ id: "errorsDetails", type: "errorsDetails", From 201c1c2f308eabc67e219ad0941c5c8616ce8838 Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 9 Apr 2024 15:57:09 +0200 Subject: [PATCH 098/121] chore(meshwide): fix types Also prevent null types --- .../src/hooks/useLocatedLinks.tsx | 5 +- .../src/hooks/useNodes.tsx | 1 + .../src/lib/links/getLinksCoordinates.ts | 6 +- .../src/mesWideTypes.tsx | 6 +- .../src/meshWideMocks.tsx | 448 ++++++++---------- 5 files changed, 220 insertions(+), 246 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx index a813857a7..93a9bab0a 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx @@ -28,9 +28,12 @@ export const useLocatedLinks = ({ type }: { type: LinkType }) => { const { data: links } = fetchData({}); const { - locatedNodes: { locatedNodesReference: meshWideNodesReference }, + locatedNodes: { locatedNodesReference, locatedNodesActual }, } = useNodes(); + const meshWideNodesReference = + locatedNodesReference || locatedNodesActual || {}; + const locatedLinksReference: LocatedLinkData = useMemo(() => { if (meshWideNodesReference && linksReference) { return mergeLinksAndCoordinates( diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx index 72ba18710..776466347 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx @@ -7,6 +7,7 @@ import { } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; import { INodes } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +// todo(kon): this should be inside a provider to don't repeat the calculations export const useNodes = () => { const { data: meshWideNodesReference } = useMeshWideNodesReference({}); const { data: meshWideNodesActual } = useMeshWideNodes({}); diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts index 9a3c3c870..4db6a4b6c 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts @@ -24,7 +24,9 @@ export const mergeLinksAndCoordinates = ( // for every node check all links for (const linkNodeName in links) { - for (const linkData of links[linkNodeName].data) { + if (isEmpty(links[linkNodeName])) continue; + for (const linkData of links[linkNodeName]) { + if (!linkData.dst_mac) continue; // Get the nodeName of the destination node const dstNodeName = Object.keys(nodes).find((pid) => { return nodes[pid].macs.find( @@ -64,7 +66,7 @@ export const mergeLinksAndCoordinates = ( // Get the destination link info const destPointData = ( - links[dstNodeName].data as Array + links[dstNodeName] as Array ).find( (data: LinkData[T]) => data.dst_mac.toLowerCase() === diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx index 727d50f61..a065b1123 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx @@ -56,11 +56,7 @@ export type IBatManLinkData = { * List of Link info retrieved from the API */ export interface ILinks { - [key: string]: { - bleachTTL: number; - data: Array; - author: string; - }; + [key: string]: Array; } export type IWifiLinks = ILinks<"wifi">; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx index f45f3fb4b..e83c9bc61 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx @@ -99,245 +99,217 @@ export const nodesReferenceState: INodes = { }; export const linksReferenceState: IWifiLinks = { - primero: { - bleachTTL: 30, - data: [ - { - tx_rate: 150000, - dst_mac: "A0:F3:C1:46:28:97", - chains: [-63, -59], - signal: -58, - rx_rate: 180000, - src_mac: "a8:40:41:1d:f9:35", - }, - { - tx_rate: 162000, - dst_mac: "14:CC:20:DA:4E:AC", - chains: [-57, -51], - signal: -50, - rx_rate: 240000, - src_mac: "a8:40:41:1d:f9:35", - }, - ], - author: "primero", - }, - segundo: { - bleachTTL: 30, - data: [ - { - tx_rate: 150000, - dst_mac: "A0:F3:C1:46:11:97", - chains: [-58, -59], - signal: -58, - rx_rate: 180000, - src_mac: "a8:40:41:1d:f9:ff", - }, - { - tx_rate: 162000, - dst_mac: "14:CC:20:DA:4E:AC", - chains: [-52, -51], - signal: -50, - rx_rate: 240000, - src_mac: "a8:40:41:1d:f9:aa", - }, - ] as IWifiLinkData[], - author: "segundo", - }, - "LiMe-da4eaa": { - bleachTTL: 30, - data: [ - { - tx_rate: 65000, - dst_mac: "A0:F3:C1:46:28:96", - chains: [-25, -25], - src_mac: "14:cc:20:da:4e:ab", - rx_rate: 65000, - signal: -25, - }, - { - tx_rate: 270000, - dst_mac: "A0:F3:C1:46:28:97", - chains: [-50, -47], - src_mac: "14:cc:20:da:4e:ac", - rx_rate: 150000, - signal: -45, - }, - { - tx_rate: 243000, - dst_mac: "A8:40:41:1D:F9:35", - chains: [-75, -64], - src_mac: "14:cc:20:da:4e:ac", - rx_rate: 162000, - signal: -64, - }, - { - tx_rate: 243000, - dst_mac: "A8:40:41:1D:F9:aa", - chains: [-75, -64], - src_mac: "14:cc:20:da:4e:ac", - rx_rate: 162000, - signal: -64, - }, - ] as IWifiLinkData[], - author: "LiMe-da4eaa", - }, - "LiMe-462895": { - bleachTTL: 28, - data: [ - { - tx_rate: 78000, - dst_mac: "14:CC:20:DA:4E:AB", - chains: [-43, -46], - src_mac: "a0:f3:c1:46:28:96", - rx_rate: 78000, - signal: 2, - }, - { - tx_rate: 243000, - dst_mac: "14:CC:20:DA:4E:AC", - chains: [-68, -41], - src_mac: "a0:f3:c1:46:28:97", - rx_rate: 216000, - signal: -41, - }, - { - tx_rate: 240000, - dst_mac: "A8:40:41:1D:F9:35", - chains: [-77, -65], - src_mac: "a0:f3:c1:46:28:97", - rx_rate: 135000, - signal: -65, - }, - { - tx_rate: 240000, - dst_mac: "A8:40:41:1D:F9:ff", - chains: [-64, -65], - src_mac: "a0:f3:c1:46:11:97", - rx_rate: 135000, - signal: -65, - }, - ] as IWifiLinkData[], - author: "LiMe-462895", - }, + primero: [ + { + tx_rate: 150000, + dst_mac: "A0:F3:C1:46:28:97", + chains: [-63, -59], + signal: -58, + rx_rate: 180000, + src_mac: "a8:40:41:1d:f9:35", + }, + { + tx_rate: 162000, + dst_mac: "14:CC:20:DA:4E:AC", + chains: [-57, -51], + signal: -50, + rx_rate: 240000, + src_mac: "a8:40:41:1d:f9:35", + }, + ], + segundo: [ + { + tx_rate: 150000, + dst_mac: "A0:F3:C1:46:11:97", + chains: [-58, -59], + signal: -58, + rx_rate: 180000, + src_mac: "a8:40:41:1d:f9:ff", + }, + { + tx_rate: 162000, + dst_mac: "14:CC:20:DA:4E:AC", + chains: [-52, -51], + signal: -50, + rx_rate: 240000, + src_mac: "a8:40:41:1d:f9:aa", + }, + ] as IWifiLinkData[], + "LiMe-da4eaa": [ + { + tx_rate: 65000, + dst_mac: "A0:F3:C1:46:28:96", + chains: [-25, -25], + src_mac: "14:cc:20:da:4e:ab", + rx_rate: 65000, + signal: -25, + }, + { + tx_rate: 270000, + dst_mac: "A0:F3:C1:46:28:97", + chains: [-50, -47], + src_mac: "14:cc:20:da:4e:ac", + rx_rate: 150000, + signal: -45, + }, + { + tx_rate: 243000, + dst_mac: "A8:40:41:1D:F9:35", + chains: [-75, -64], + src_mac: "14:cc:20:da:4e:ac", + rx_rate: 162000, + signal: -64, + }, + { + tx_rate: 243000, + dst_mac: "A8:40:41:1D:F9:aa", + chains: [-75, -64], + src_mac: "14:cc:20:da:4e:ac", + rx_rate: 162000, + signal: -64, + }, + ] as IWifiLinkData[], + "LiMe-462895": [ + { + tx_rate: 78000, + dst_mac: "14:CC:20:DA:4E:AB", + chains: [-43, -46], + src_mac: "a0:f3:c1:46:28:96", + rx_rate: 78000, + signal: 2, + }, + { + tx_rate: 243000, + dst_mac: "14:CC:20:DA:4E:AC", + chains: [-68, -41], + src_mac: "a0:f3:c1:46:28:97", + rx_rate: 216000, + signal: -41, + }, + { + tx_rate: 240000, + dst_mac: "A8:40:41:1D:F9:35", + chains: [-77, -65], + src_mac: "a0:f3:c1:46:28:97", + rx_rate: 135000, + signal: -65, + }, + { + tx_rate: 240000, + dst_mac: "A8:40:41:1D:F9:ff", + chains: [-64, -65], + src_mac: "a0:f3:c1:46:11:97", + rx_rate: 135000, + signal: -65, + }, + ] as IWifiLinkData[], }; export const batManReferenceState: IBatmanLinks = { - primero: { - bleachTTL: 27, - data: [ - { - hard_ifindex: 18, - last_seen_msecs: 1300, - iface: "eth0-1_250", - dst_mac: "02:db:d6:da:4e:aa", - src_mac: "02:db:d6:46:28:95", - }, - { - hard_ifindex: 26, - last_seen_msecs: 20, - iface: "wlan1-mesh_250", - dst_mac: "02:ab:46:da:4e:aa", - src_mac: "02:ab:46:46:28:95", - }, - { - hard_ifindex: 26, - last_seen_msecs: 40, - iface: "wlan1-mesh_250", - dst_mac: "02:ab:46:fc:3a:bd", - src_mac: "02:ab:46:46:28:95", - }, - { - hard_ifindex: 28, - last_seen_msecs: 1710, - iface: "wlan0-mesh_250", - dst_mac: "02:58:47:fc:3a:bd", - src_mac: "02:58:47:46:28:95", - }, - { - hard_ifindex: 28, - last_seen_msecs: 1450, - iface: "wlan0-mesh_250", - dst_mac: "02:58:47:da:4e:aa", - src_mac: "02:58:47:46:28:95", - }, - ] as IBatManLinkData[], - author: "primero", - }, - "LiMe-da4eaa": { - bleachTTL: 26, - data: [ - { - hard_ifindex: 26, - last_seen_msecs: 1670, - iface: "wlan1-mesh_250", - dst_mac: "02:ab:46:da:4e:aa", - src_mac: "02:ab:46:fc:3a:bd", - }, - { - hard_ifindex: 26, - last_seen_msecs: 1350, - iface: "wlan1-mesh_250", - dst_mac: "02:ab:46:46:28:95", - src_mac: "02:ab:46:fc:3a:bd", - }, - { - hard_ifindex: 28, - last_seen_msecs: 1430, - iface: "wlan0-mesh_250", - dst_mac: "02:58:47:46:28:95", - src_mac: "02:58:47:fc:3a:bd", - }, - { - hard_ifindex: 28, - last_seen_msecs: 1030, - iface: "wlan0-mesh_250", - dst_mac: "02:58:47:da:4e:aa", - src_mac: "02:58:47:fc:3a:bd", - }, - ] as IBatManLinkData[], - author: "tercero", - }, - segundo: { - bleachTTL: 28, - data: [ - { - hard_ifindex: 18, - last_seen_msecs: 1670, - src_mac: "02:db:d6:da:4e:aa", - dst_mac: "02:db:d6:46:28:95", - iface: "eth0-1_250", - }, - { - hard_ifindex: 26, - last_seen_msecs: 550, - src_mac: "02:58:47:da:4e:aa", - dst_mac: "02:58:47:46:28:95", - iface: "wlan0-mesh_250", - }, - { - hard_ifindex: 26, - last_seen_msecs: 260, - src_mac: "02:58:47:da:4e:aa", - dst_mac: "02:58:47:fc:3a:bd", - iface: "wlan0-mesh_250", - }, - { - hard_ifindex: 28, - last_seen_msecs: 340, - src_mac: "02:ab:46:da:4e:aa", - dst_mac: "02:ab:46:fc:3a:bd", - iface: "wlan1-mesh_250", - }, - { - hard_ifindex: 28, - last_seen_msecs: 550, - src_mac: "02:ab:46:da:4e:aa", - dst_mac: "02:ab:46:46:28:95", - iface: "wlan1-mesh_250", - }, - ] as IBatManLinkData[], - author: "segundo", - }, + primero: [ + { + hard_ifindex: 18, + last_seen_msecs: 1300, + iface: "eth0-1_250", + dst_mac: "02:db:d6:da:4e:aa", + src_mac: "02:db:d6:46:28:95", + }, + { + hard_ifindex: 26, + last_seen_msecs: 20, + iface: "wlan1-mesh_250", + dst_mac: "02:ab:46:da:4e:aa", + src_mac: "02:ab:46:46:28:95", + }, + { + hard_ifindex: 26, + last_seen_msecs: 40, + iface: "wlan1-mesh_250", + dst_mac: "02:ab:46:fc:3a:bd", + src_mac: "02:ab:46:46:28:95", + }, + { + hard_ifindex: 28, + last_seen_msecs: 1710, + iface: "wlan0-mesh_250", + dst_mac: "02:58:47:fc:3a:bd", + src_mac: "02:58:47:46:28:95", + }, + { + hard_ifindex: 28, + last_seen_msecs: 1450, + iface: "wlan0-mesh_250", + dst_mac: "02:58:47:da:4e:aa", + src_mac: "02:58:47:46:28:95", + }, + ] as IBatManLinkData[], + "LiMe-da4eaa": [ + { + hard_ifindex: 26, + last_seen_msecs: 1670, + iface: "wlan1-mesh_250", + dst_mac: "02:ab:46:da:4e:aa", + src_mac: "02:ab:46:fc:3a:bd", + }, + { + hard_ifindex: 26, + last_seen_msecs: 1350, + iface: "wlan1-mesh_250", + dst_mac: "02:ab:46:46:28:95", + src_mac: "02:ab:46:fc:3a:bd", + }, + { + hard_ifindex: 28, + last_seen_msecs: 1430, + iface: "wlan0-mesh_250", + dst_mac: "02:58:47:46:28:95", + src_mac: "02:58:47:fc:3a:bd", + }, + { + hard_ifindex: 28, + last_seen_msecs: 1030, + iface: "wlan0-mesh_250", + dst_mac: "02:58:47:da:4e:aa", + src_mac: "02:58:47:fc:3a:bd", + }, + ], + segundo: [ + { + hard_ifindex: 18, + last_seen_msecs: 1670, + src_mac: "02:db:d6:da:4e:aa", + dst_mac: "02:db:d6:46:28:95", + iface: "eth0-1_250", + }, + { + hard_ifindex: 26, + last_seen_msecs: 550, + src_mac: "02:58:47:da:4e:aa", + dst_mac: "02:58:47:46:28:95", + iface: "wlan0-mesh_250", + }, + { + hard_ifindex: 26, + last_seen_msecs: 260, + src_mac: "02:58:47:da:4e:aa", + dst_mac: "02:58:47:fc:3a:bd", + iface: "wlan0-mesh_250", + }, + { + hard_ifindex: 28, + last_seen_msecs: 340, + src_mac: "02:ab:46:da:4e:aa", + dst_mac: "02:ab:46:fc:3a:bd", + iface: "wlan1-mesh_250", + }, + { + hard_ifindex: 28, + last_seen_msecs: 550, + src_mac: "02:ab:46:da:4e:aa", + dst_mac: "02:ab:46:46:28:95", + iface: "wlan1-mesh_250", + }, + ] as IBatManLinkData[], }; // Use the same as on the reference state deleting a specific node @@ -362,7 +334,7 @@ export const links = (type: T): ILinks => { let source_macs_to_remove = []; if (nodeName) { // Get source_macs from the node to be removed - source_macs_to_remove = newState[nodeName].data.map((item: any) => + source_macs_to_remove = newState[nodeName].map((item: any) => item.src_mac.toLowerCase() ); @@ -372,7 +344,7 @@ export const links = (type: T): ILinks => { // Remove data items with matching dest_mac in other objects Object.keys(newState).forEach((key: string) => { - newState[key].data = newState[key].data.filter((item) => { + newState[key] = newState[key].filter((item) => { return ( !source_macs_to_remove.includes(item.dst_mac.toLowerCase()) || // Added to delete a specific link of a node and not an entire node From 3bc18d0290a899cd17615cffa95c7b80424ad3da Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 10 Apr 2024 08:45:20 +0200 Subject: [PATCH 099/121] chore(meshwide): fix reference state errors --- .../src/containers/MapLayers/LinksLayers.tsx | 2 +- .../src/containers/MapLayers/NodesLayer.tsx | 2 +- plugins/lime-plugin-mesh-wide/src/mesWideApi.ts | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx index 5db32b1a0..69617179d 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx @@ -18,7 +18,7 @@ const LinksLayer = ({ }: ILinksLayerProps) => { // If reference is not set or empty, use actual nodes const linksReference = - originalLinksReference && isEmpty(originalLinksReference) + !originalLinksReference || isEmpty(originalLinksReference) ? links : originalLinksReference; diff --git a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx index cbf260b68..303363655 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx @@ -14,7 +14,7 @@ const NodesLayer = () => { // If reference is not set or empty, use actual nodes const referenceNodes = - meshWideNodesReference && isEmpty(meshWideNodesReference) + !meshWideNodesReference || isEmpty(meshWideNodesReference) ? meshWideNodesActual : meshWideNodesReference; diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts b/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts index 6ff17ffe0..dcba0a14e 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts +++ b/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts @@ -26,7 +26,9 @@ const sharedStateApiCall = async ( const res = (await api.call( ...meshUpgradeQueryKeys[queryKey] )) as SharedStateReturnType; - if (res.error !== 0) throw Error(`Shared state error: ${res.error}`); + if (res.error !== 0 && res.error !== 404) { + throw Error(`Shared state error: ${res.error}`); + } return res.data; }; From 37a24851c270adae5798d96d3ad833e18b833e6e Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 10 Apr 2024 08:46:40 +0200 Subject: [PATCH 100/121] chore(meshwide): fix typo --- .../src/components/FeatureDetail/LinkDetail.tsx | 2 +- .../src/components/FeatureDetail/NodeDetail.tsx | 2 +- .../src/components/FeatureDetail/ShowErrorsDetail.tsx | 2 +- .../src/components/FeatureDetail/index.tsx | 2 +- .../src/components/Map/FloatingAlert.tsx | 4 ++-- .../src/components/Map/LinkLine.tsx | 2 +- .../src/components/Map/NodeMarker.tsx | 4 ++-- .../src/components/configPage/ConfigSection.tsx | 2 +- .../lime-plugin-mesh-wide/src/containers/Map.spec.tsx | 9 ++------- plugins/lime-plugin-mesh-wide/src/containers/Map.tsx | 2 +- .../src/containers/MapLayers/LinksLayers.tsx | 2 +- .../src/containers/MapLayers/NodesLayer.tsx | 2 +- .../src/containers/SelectedFeatureBottomSheet.spec.tsx | 10 +++++----- .../src/containers/SelectedFeatureBottomSheet.tsx | 2 +- .../src/hooks/useLocatedLinks.tsx | 4 ++-- .../src/hooks/useMeshWideDataErrors.tsx | 6 +++--- .../lime-plugin-mesh-wide/src/hooks/useNodeErrors.tsx | 2 +- plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx | 4 ++-- .../src/lib/links/PointToPointLink.ts | 2 +- .../src/lib/links/getLinksCoordinates.ts | 2 +- .../src/lib/links/processLinkErrors.ts | 2 +- .../src/lib/nodes/processErrors.ts | 2 +- .../src/{mesWideApi.ts => meshWideApi.ts} | 4 ++-- plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx | 2 +- .../src/{mesWideQueries.tsx => meshWideQueries.tsx} | 8 ++++---- ...{mesWideQueriesKeys.tsx => meshWideQueriesKeys.tsx} | 0 .../src/{mesWideTypes.tsx => meshWideTypes.tsx} | 0 .../lime-plugin-mesh-wide/src/screens/configPage.tsx | 2 +- 28 files changed, 41 insertions(+), 46 deletions(-) rename plugins/lime-plugin-mesh-wide/src/{mesWideApi.ts => meshWideApi.ts} (93%) rename plugins/lime-plugin-mesh-wide/src/{mesWideQueries.tsx => meshWideQueries.tsx} (94%) rename plugins/lime-plugin-mesh-wide/src/{mesWideQueriesKeys.tsx => meshWideQueriesKeys.tsx} (100%) rename plugins/lime-plugin-mesh-wide/src/{mesWideTypes.tsx => meshWideTypes.tsx} (100%) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx index 798e1daf8..b64e39dbb 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx @@ -19,7 +19,7 @@ import { IWifiLinkData, LinkMapFeature, WifiLinkErrorCodes, -} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +} from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; import { Row, TitleAndText } from "./index"; diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx index 93e7294e1..a298b4819 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx @@ -14,7 +14,7 @@ import { getArrayDifference } from "plugins/lime-plugin-mesh-wide/src/lib/utils" import { NodeErrorCodes, NodeMapFeature, -} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +} from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; const NodeDetails = ({ actual, reference, name }: NodeMapFeature) => { const uptime = reference.uptime; diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx index b7ef71d88..fd078b9d4 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx @@ -1,7 +1,7 @@ import { Trans } from "@lingui/macro"; import { Row } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index"; -import { ErrorsDetails } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +import { ErrorsDetails } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; export const ShowErrorsDetail = ({ errors }: { errors: ErrorsDetails }) => { return ( diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx index 86fbe16bd..f0ed5c3b4 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx @@ -11,7 +11,7 @@ import { LinkMapFeature, NodeMapFeature, SelectedMapFeature, -} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +} from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; export const TitleAndText = ({ title, diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx index 95f393a1b..0f3748a87 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx @@ -3,8 +3,8 @@ import { useCallback } from "react"; import { useMeshWideDataErrors } from "plugins/lime-plugin-mesh-wide/src/hooks/useMeshWideDataErrors"; import { useNodes } from "plugins/lime-plugin-mesh-wide/src/hooks/useNodes"; import { WarningIcon } from "plugins/lime-plugin-mesh-wide/src/icons/warningIcon"; -import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; -import { InvalidNodes } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; +import { InvalidNodes } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; export const FloatingAlert = () => { const { setData: setSelectedFeature, data: selectedMapFeature } = diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx index f0865b2a5..deb59c76e 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx @@ -3,7 +3,7 @@ import { Polyline } from "react-leaflet"; import { useLocatedLinks } from "plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks"; import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; -import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; +import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; interface ILinkLineProps { referenceLink: PontToPointLink; diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx index 8329c5850..1d694d45c 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx @@ -2,11 +2,11 @@ import L from "leaflet"; import { Marker, Tooltip } from "react-leaflet"; import { useNodeErrors } from "plugins/lime-plugin-mesh-wide/src/hooks/useNodeErrors"; -import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; +import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; import { INodeInfo, NodeMapFeature, -} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +} from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; import style from "./style.less"; diff --git a/plugins/lime-plugin-mesh-wide/src/components/configPage/ConfigSection.tsx b/plugins/lime-plugin-mesh-wide/src/components/configPage/ConfigSection.tsx index 70b5c0726..6c922b13b 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/configPage/ConfigSection.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/configPage/ConfigSection.tsx @@ -11,7 +11,7 @@ import { useDeletePropModal, useEditPropModal, } from "plugins/lime-plugin-mesh-wide/src/components/configPage/modals"; -import { IMeshWideSection } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +import { IMeshWideSection } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; export const ConfigSection = ({ dropdown }: { dropdown: IMeshWideSection }) => { return ( diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map.spec.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map.spec.tsx index 02824e4b4..ec26f6d0c 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/Map.spec.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map.spec.tsx @@ -1,15 +1,10 @@ import "@testing-library/jest-dom"; -// import "@testing-library/jest-dom/extend-expect"; -import { screen } from "@testing-library/preact"; -import { MeshWideMap } from "plugins/lime-plugin-mesh-wide/src/containers/Map"; +// import "@testing-library/jest-dom/extend-expect"; import { getMeshWideNodes, getMeshWideNodesReference, -} from "plugins/lime-plugin-mesh-wide/src/mesWideApi"; -import { nodesReferenceState } from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; - -import { render } from "utils/test_utils"; +} from "plugins/lime-plugin-mesh-wide/src/meshWideApi"; jest.mock("plugins/lime-plugin-mesh-wide/src/mesWideApi.ts"); jest.mock("leaflet"); diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx index a981e464c..d261ed688 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx @@ -18,7 +18,7 @@ import { WifiLinksLayer, } from "plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers"; import NodesLayer from "plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer"; -import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; +import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; const openStreetMapTileString = "https://{s}.tile.osm.org/{z}/{x}/{y}.png"; const openStreetMapAttribution = diff --git a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx index 69617179d..b84c33f2e 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx @@ -1,7 +1,7 @@ import LinkLine from "plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine"; import { useLocatedLinks } from "plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks"; import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; -import { LocatedLinkData } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +import { LocatedLinkData } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; import { isEmpty } from "utils/utils"; diff --git a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx index 303363655..10a42406e 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx @@ -1,6 +1,6 @@ import NodeMarker from "plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker"; import { useNodes } from "plugins/lime-plugin-mesh-wide/src/hooks/useNodes"; -import { INodeInfo } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +import { INodeInfo } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; import { isEmpty } from "utils/utils"; diff --git a/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.spec.tsx b/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.spec.tsx index 3f8c3b08a..f9f52f561 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.spec.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.spec.tsx @@ -3,17 +3,17 @@ import "@testing-library/jest-dom"; import { screen } from "@testing-library/preact"; import { SelectedFeatureBottomSheet } from "plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet"; -import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; -import { - INodeInfo, - NodeMapFeature, -} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; import { links, linksReferenceState, nodes, nodesReferenceState, } from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; +import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; +import { + INodeInfo, + NodeMapFeature, +} from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; import { render } from "utils/test_utils"; diff --git a/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.tsx b/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.tsx index f00392ebe..e1d035b31 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.tsx @@ -6,7 +6,7 @@ import { FeatureDetail, FeatureReferenceStatus, } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail"; -import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; +import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; export const SelectedFeatureBottomSheet = () => { const [isOpen, setIsOpen] = useState(false); diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx index 93a9bab0a..499681644 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx @@ -9,13 +9,13 @@ import { useMeshWideBatmanReference, useMeshWideLinks, useMeshWideLinksReference, -} from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; +} from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; import { ILinkErrors, LinkType, LocatedLinkData, PointToPointLinkId, -} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +} from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; export const useLocatedLinks = ({ type }: { type: LinkType }) => { const fetchData = type === "batman" ? useMeshWideBatman : useMeshWideLinks; diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useMeshWideDataErrors.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useMeshWideDataErrors.tsx index c0874b04c..b2e22eaec 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useMeshWideDataErrors.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useMeshWideDataErrors.tsx @@ -7,9 +7,9 @@ import { useMeshWideLinksReference, useMeshWideNodes, useMeshWideNodesReference, -} from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; -import { meshUpgradeQueryKeys } from "plugins/lime-plugin-mesh-wide/src/mesWideQueriesKeys"; -import { MeshWideDataError } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +} from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; +import { meshUpgradeQueryKeys } from "plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys"; +import { MeshWideDataError } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; import { isEmpty } from "utils/utils"; diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useNodeErrors.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useNodeErrors.tsx index 36c9f6026..900747264 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useNodeErrors.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useNodeErrors.tsx @@ -2,7 +2,7 @@ import { processNodeErrors } from "plugins/lime-plugin-mesh-wide/src/lib/nodes/p import { INodeInfo, NodeErrorCodes, -} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +} from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; export const useNodeErrors = ({ actual, diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx index 776466347..31779197e 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx @@ -4,8 +4,8 @@ import { isValidCoordinate } from "plugins/lime-plugin-mesh-wide/src/lib/utils"; import { useMeshWideNodes, useMeshWideNodesReference, -} from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; -import { INodes } from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +} from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; +import { INodes } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; // todo(kon): this should be inside a provider to don't repeat the calculations export const useNodes = () => { diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts index e06bcebbb..2f91b74e6 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts @@ -6,7 +6,7 @@ import { LinkType, MacToMacLinkId, PointToPointLinkId, -} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +} from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; /** * This class should store a group of links between the same geo coordinates. diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts index 4db6a4b6c..56f9dfa64 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts @@ -9,7 +9,7 @@ import { LinkData, LinkType, LocatedLinkData, -} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +} from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; import { isEmpty } from "utils/utils"; diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts index 1a0e558fc..e0b1edcce 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts @@ -5,7 +5,7 @@ import { ILinkPtoPErrors, IWifiLinkData, WifiLinkErrorCodes, -} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +} from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; import { DEFAULT_COMMUNITY_SETTINGS } from "utils/constants"; diff --git a/plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts b/plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts index 8ecbe7aa2..63b49e5ab 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts @@ -1,7 +1,7 @@ import { INodeInfo, NodeErrorCodes, -} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +} from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; export const processNodeErrors = ( reference: INodeInfo, diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts b/plugins/lime-plugin-mesh-wide/src/meshWideApi.ts similarity index 93% rename from plugins/lime-plugin-mesh-wide/src/mesWideApi.ts rename to plugins/lime-plugin-mesh-wide/src/meshWideApi.ts index dcba0a14e..cf3e680cf 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideApi.ts +++ b/plugins/lime-plugin-mesh-wide/src/meshWideApi.ts @@ -1,10 +1,10 @@ -import { meshUpgradeQueryKeys } from "plugins/lime-plugin-mesh-wide/src/mesWideQueriesKeys"; +import { meshUpgradeQueryKeys } from "plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys"; import { IBatmanLinks, INodes, IWifiLinks, SharedStateReturnType, -} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +} from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; import api from "utils/uhttpd.service"; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx index e83c9bc61..a38e8dcd0 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx @@ -7,7 +7,7 @@ import { IWifiLinkData, IWifiLinks, LinkType, -} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; +} from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; // todo(kon): if a mac disappear from mac list and a link with this mac as src mac disappear also, is not shown on the map. diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx similarity index 94% rename from plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx rename to plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx index e5129dd8d..b9fbbfed9 100644 --- a/plugins/lime-plugin-mesh-wide/src/mesWideQueries.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx @@ -7,16 +7,16 @@ import { getMeshWideLinksReference, getMeshWideNodes, getMeshWideNodesReference, -} from "plugins/lime-plugin-mesh-wide/src/mesWideApi"; -import { meshUpgradeQueryKeys } from "plugins/lime-plugin-mesh-wide/src/mesWideQueriesKeys"; +} from "plugins/lime-plugin-mesh-wide/src/meshWideApi"; +import { getMeshWideConfig } from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; +import { meshUpgradeQueryKeys } from "plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys"; import { IBatmanLinks, IMeshWideConfig, INodes, IWifiLinks, SelectedMapFeature, -} from "plugins/lime-plugin-mesh-wide/src/mesWideTypes"; -import { getMeshWideConfig } from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; +} from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; import { useSharedData } from "utils/useSharedData"; diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideQueriesKeys.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys.tsx similarity index 100% rename from plugins/lime-plugin-mesh-wide/src/mesWideQueriesKeys.tsx rename to plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideTypes.tsx similarity index 100% rename from plugins/lime-plugin-mesh-wide/src/mesWideTypes.tsx rename to plugins/lime-plugin-mesh-wide/src/meshWideTypes.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx b/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx index e7be52b1c..f9348b4d5 100644 --- a/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx +++ b/plugins/lime-plugin-mesh-wide/src/screens/configPage.tsx @@ -8,7 +8,7 @@ import { ConfigSection, } from "plugins/lime-plugin-mesh-wide/src/components/configPage/ConfigSection"; import { MeshStatus } from "plugins/lime-plugin-mesh-wide/src/components/configPage/MeshStatus"; -import { useMeshWideConfig } from "plugins/lime-plugin-mesh-wide/src/mesWideQueries"; +import { useMeshWideConfig } from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; const MeshWideConfigPage = () => { const { data: meshWideConfig, isLoading } = useMeshWideConfig({}); From 39b5ccab359389d6743f45681dd23bfad4739536 Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 11 Apr 2024 13:09:55 +0200 Subject: [PATCH 101/121] chore(meshwide): fix show batman --- .../src/hooks/useLocatedLinks.tsx | 12 +++++++++--- .../src/meshWideQueriesKeys.tsx | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx index 499681644..cab6ed17d 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx @@ -17,6 +17,8 @@ import { PointToPointLinkId, } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; +import { isEmpty } from "utils/utils"; + export const useLocatedLinks = ({ type }: { type: LinkType }) => { const fetchData = type === "batman" ? useMeshWideBatman : useMeshWideLinks; const fetchDataReference = @@ -26,13 +28,17 @@ export const useLocatedLinks = ({ type }: { type: LinkType }) => { const { data: linksReference } = fetchDataReference({}); const { data: links } = fetchData({}); - const { locatedNodes: { locatedNodesReference, locatedNodesActual }, } = useNodes(); - const meshWideNodesReference = - locatedNodesReference || locatedNodesActual || {}; + // If reference is not set or empty, use actual nodes + let meshWideNodesReference = {}; + if (locatedNodesReference && !isEmpty(locatedNodesReference)) { + meshWideNodesReference = locatedNodesReference; + } else if (locatedNodesActual && !isEmpty(locatedNodesActual)) { + meshWideNodesReference = locatedNodesActual; + } const locatedLinksReference: LocatedLinkData = useMemo(() => { if (meshWideNodesReference && linksReference) { diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys.tsx index eaaf5b569..fba2debc4 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys.tsx @@ -7,7 +7,7 @@ interface MeshWideQueryKeysProps { const MeshWideQueryKeys: MeshWideQueryKeysProps = { meshWideNodes: [{ data_type: "node_info" }], wifiLinksInfo: [{ data_type: "wifi_links_info" }], - batHosts: [{ data_type: "bat-hosts" }], + batHosts: [{ data_type: "bat_links_info" }], }; const getFromSharedState = ["shared-state", "getFromSharedState"]; From 7563722854b68c292bedcceec2dea8326601935c Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 11 Apr 2024 13:10:08 +0200 Subject: [PATCH 102/121] chore(meshwide): implement set reference state button --- .../FeatureDetail/ShowErrorsDetail.tsx | 37 ++++++++++++++++--- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx index fd078b9d4..16161417f 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx @@ -1,5 +1,7 @@ import { Trans } from "@lingui/macro"; +import { Button } from "components/buttons/button"; + import { Row } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index"; import { ErrorsDetails } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; @@ -38,11 +40,36 @@ export const ShowErrorsDetail = ({ errors }: { errors: ErrorsDetails }) => { set - {[...errors.dataNotSetErrors].map((data, k) => ( -
- {JSON.stringify(data.queryKey, null, 2)} -
- ))} +
+ {[...errors.dataNotSetErrors].map((data, k) => { + let dataType = data.queryKey[2]["data_type"]; + if (!dataType) { + dataType = JSON.stringify( + data.queryKey, + null, + 2 + ); + } + return ( +
+
{dataType}
+ +
+ ); + })} +
)} {errors.meshWideDataErrors.length > 0 && ( From 6bb10eb3612d1da6122d78077bcb54ff6bb81b5f Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 11 Apr 2024 14:47:52 +0200 Subject: [PATCH 103/121] chore(meshwide): prevent undefined errors --- .../components/FeatureDetail/LinkDetail.tsx | 26 ++++++++++-------- .../src/components/Map/LinkLine.tsx | 9 +++++-- .../src/hooks/useLocatedLinks.tsx | 27 +++++++++++++++---- 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx index b64e39dbb..dc9f84e48 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx @@ -29,7 +29,7 @@ const BatmanDetail = ({ node, }: { name: string; - errorsArray: BatmanLinkErrorCodes[]; + errorsArray: BatmanLinkErrorCodes[] | undefined; node: IBatManLinkData; }) => { return ( @@ -37,7 +37,7 @@ const BatmanDetail = ({
{name}{" "} - {errorsArray.length > 0 && } + {errorsArray?.length > 0 && }
@@ -66,14 +66,16 @@ const WifiDetail = ({
{name}{" "} - {errorsArray.length > 0 && } + {errorsArray?.length > 0 && }
Signal} error={ - errorsArray.includes(WifiLinkErrorCodes.SIGNAL_LOSS) ? ( + errorsArray?.includes( + WifiLinkErrorCodes.SIGNAL_LOSS + ) ? ( The signal is X below the reference state @@ -85,7 +87,7 @@ const WifiDetail = ({ Chains} error={ - errorsArray.includes(WifiLinkErrorCodes.CHAIN_LOSS) ? ( + errorsArray?.includes(WifiLinkErrorCodes.CHAIN_LOSS) ? ( The difference between chains is too big @@ -112,9 +114,9 @@ const SelectedLink = ({ errors, }: { linkDetail: BaseMacToMacLink; - errors: ILinkMtoMErrors; + errors: ILinkMtoMErrors | undefined; }) => { - if (linkDetail === undefined || !errors.linkUp) + if (linkDetail === undefined || (errors && !errors?.linkUp)) return (
This link seems down @@ -141,7 +143,7 @@ const SelectedLink = ({ {names.map((name, i) => { const node = linkDetail.linkByName(name); - const errorsArray = errors.linkErrors[name]; + const errorsArray = errors?.linkErrors[name] ?? []; return linkType === "wifi" ? ( {
Link {i + 1}{" "} - {errors.macToMacErrors[link.id].hasErrors ? ( + {errors && + errors?.macToMacErrors[link.id]?.hasErrors ? ( ) : null} @@ -202,7 +205,7 @@ const LinkFeatureDetail = ({ actual, reference }: LinkMapFeature) => { { type: reference.type, }); - const hasError = errors.hasErrors; + const hasError = errors?.hasErrors ?? false; + // todo(kon): check here if reference state is empty to show reference not set message const txt: VNode = hasError ? ( This link has errors diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx index deb59c76e..823d06457 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx @@ -17,8 +17,13 @@ export const LinkLine = ({ referenceLink, actualLink }: ILinkLineProps) => { const isSelected = selectedMapFeature?.id === referenceLink.id; const { linksErrors } = useLocatedLinks({ type }); - const hasError = linksErrors[referenceLink.id]?.hasErrors ?? false; - const linkUp = linksErrors[referenceLink.id]?.linkUp ?? true; + let hasError = false; + let linkUp = true; + + if (linksErrors && linksErrors[referenceLink.id]) { + hasError = linksErrors[referenceLink.id].hasErrors; + linkUp = linksErrors[referenceLink.id].linkUp; + } const _setSelectedFeature = () => { setSelectedMapFeature({ diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx index cab6ed17d..86e9bc59b 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx @@ -12,6 +12,7 @@ import { } from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; import { ILinkErrors, + ILinkPtoPErrors, LinkType, LocatedLinkData, PointToPointLinkId, @@ -19,7 +20,17 @@ import { import { isEmpty } from "utils/utils"; -export const useLocatedLinks = ({ type }: { type: LinkType }) => { +interface IUselocatedLinks { + locatedLinksReference: LocatedLinkData; + linksErrors: ILinkErrors | undefined; + locatedLinks: LocatedLinkData; + linksLoaded: boolean; +} +export const useLocatedLinks = ({ + type, +}: { + type: LinkType; +}): IUselocatedLinks => { const fetchData = type === "batman" ? useMeshWideBatman : useMeshWideLinks; const fetchDataReference = type === "batman" @@ -63,7 +74,8 @@ export const useLocatedLinks = ({ type }: { type: LinkType }) => { const linksLoaded = !!locatedLinksReference && !!locatedLinks; const linksErrors: ILinkErrors = useMemo(() => { - if (locatedLinksReference) { + // If there are no links reference just drop no errors (because there are no links to compare with) + if (locatedLinksReference && !isEmpty(locatedLinksReference)) { const errors: ILinkErrors = {}; Object.entries(locatedLinksReference).forEach( ([k, referenceLink]) => { @@ -83,7 +95,12 @@ export const useLocatedLinks = ({ type }: { type: LinkType }) => { } }, [locatedLinksReference, locatedLinks]); - return { locatedLinks, locatedLinksReference, linksLoaded, linksErrors }; + return { + locatedLinks, + locatedLinksReference, + linksLoaded, + linksErrors, + } as IUselocatedLinks; }; export const usePointToPointErrors = ({ @@ -92,7 +109,7 @@ export const usePointToPointErrors = ({ }: { id: PointToPointLinkId; type: LinkType; -}) => { +}): { errors: ILinkPtoPErrors | undefined } => { const { linksErrors } = useLocatedLinks({ type }); - return { errors: linksErrors[id] }; + return { errors: linksErrors && linksErrors[id] }; }; From 9c307c4ec0804319efbd199427f208b506ba0dfa Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 12 Apr 2024 08:35:23 +0200 Subject: [PATCH 104/121] chore(meshwide): show reference is not set on feature detail --- .../components/FeatureDetail/LinkDetail.tsx | 36 ++++++++++----- .../components/FeatureDetail/NodeDetail.tsx | 45 ++++++++++++++----- .../src/components/Map/NodeMarker.tsx | 4 +- .../src/hooks/useLocatedLinks.tsx | 33 +++++++++++--- ...NodeErrors.tsx => useSingleNodeErrors.tsx} | 4 +- 5 files changed, 93 insertions(+), 29 deletions(-) rename plugins/lime-plugin-mesh-wide/src/hooks/{useNodeErrors.tsx => useSingleNodeErrors.tsx} (92%) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx index dc9f84e48..d521e62e0 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx @@ -1,12 +1,14 @@ import { Trans } from "@lingui/macro"; -import { VNode } from "preact"; import { useState } from "preact/hooks"; import { Button } from "components/buttons/button"; import Tabs from "components/tabs"; import { StatusAndButton } from "plugins/lime-plugin-mesh-wide/src/components/Components"; -import { usePointToPointErrors } from "plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks"; +import { + getQueryByLinkType, + usePointToPointErrors, +} from "plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks"; import ErrorIcon from "plugins/lime-plugin-mesh-wide/src/icons/errorIcon"; import { PowerIcon } from "plugins/lime-plugin-mesh-wide/src/icons/power"; import { MacToMacLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; @@ -21,6 +23,8 @@ import { WifiLinkErrorCodes, } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; +import { isEmpty } from "utils/utils"; + import { Row, TitleAndText } from "./index"; const BatmanDetail = ({ @@ -222,20 +226,32 @@ export const LinkReferenceStatus = ({ actual, reference }: LinkMapFeature) => { type: reference.type, }); - const hasError = errors?.hasErrors ?? false; - // todo(kon): check here if reference state is empty to show reference not set message - - const txt: VNode = hasError ? ( - This link has errors - ) : ( - Same status as in the reference state + const { reference: fetchDataReference } = getQueryByLinkType( + reference.type ); + // Check if there are errors of global reference state to shown + const { data: referenceData, isError: isReferenceError } = + fetchDataReference({}); + let referenceError = false; + if (!referenceData || isEmpty(referenceData) || isReferenceError) { + referenceError = true; + } + + let errorMessage = Same status as in the reference state; + if (referenceError) { + errorMessage = Reference is not set or has errors; + } else if (errors?.hasErrors) { + errorMessage = This link has errors; + } + + const hasError = errors?.hasErrors || referenceError; + return ( Update this link on reference state} > - {txt} + {errorMessage} ); }; diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx index a298b4819..e7621caba 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx @@ -1,5 +1,4 @@ import { Trans } from "@lingui/macro"; -import { VNode } from "preact"; import { Button } from "components/buttons/button"; @@ -8,21 +7,24 @@ import { Row, TitleAndText, } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index"; -import { useNodeErrors } from "plugins/lime-plugin-mesh-wide/src/hooks/useNodeErrors"; +import { useSingleNodeErrors } from "plugins/lime-plugin-mesh-wide/src/hooks/useSingleNodeErrors"; import { PowerIcon } from "plugins/lime-plugin-mesh-wide/src/icons/power"; import { getArrayDifference } from "plugins/lime-plugin-mesh-wide/src/lib/utils"; +import { useMeshWideNodesReference } from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; import { NodeErrorCodes, NodeMapFeature, } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; +import { isEmpty } from "utils/utils"; + const NodeDetails = ({ actual, reference, name }: NodeMapFeature) => { const uptime = reference.uptime; const firmware = reference.firmware_version; const ipv6 = reference.ipv6; const ipv4 = reference.ipv4; const device = reference.device; - const { errors, isDown } = useNodeErrors({ actual, reference }); + const { errors, isDown } = useSingleNodeErrors({ actual, reference }); if (isDown) { return This node seems down; @@ -90,13 +92,36 @@ const NodeDetails = ({ actual, reference, name }: NodeMapFeature) => { }; export const NodeReferenceStatus = ({ actual, reference }: NodeMapFeature) => { - const { errors, hasErrors, isDown } = useNodeErrors({ actual, reference }); + const { + errors, + hasErrors: hasNodeErrors, + isDown, + } = useSingleNodeErrors({ + actual, + reference, + }); + + // Check if there are errors of global reference state to shown + const { data: meshWideNodesReference, isError: isReferenceError } = + useMeshWideNodesReference({}); + let referenceError = false; + if ( + !meshWideNodesReference || + isEmpty(meshWideNodesReference) || + isReferenceError + ) { + referenceError = true; + } + + let errorMessage = Same status as in the reference state; + if (referenceError) { + errorMessage = Reference is not set or has errors; + } else if (isDown) { + errorMessage = In the reference state this node is on; + } + + const hasErrors = hasNodeErrors || referenceError; - const txt: VNode = isDown ? ( - In the reference state this node is on - ) : ( - Same status as in the reference state - ); return ( { hasErrors && Update this node on reference state } > - {txt} + {errorMessage} ); }; diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx index 1d694d45c..9410b6101 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx @@ -1,7 +1,7 @@ import L from "leaflet"; import { Marker, Tooltip } from "react-leaflet"; -import { useNodeErrors } from "plugins/lime-plugin-mesh-wide/src/hooks/useNodeErrors"; +import { useSingleNodeErrors } from "plugins/lime-plugin-mesh-wide/src/hooks/useSingleNodeErrors"; import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; import { INodeInfo, @@ -22,7 +22,7 @@ const NodeMarker = ({ const { data: selectedMapFeature, setData: setSelectedMapFeature } = useSelectedMapFeature(); - const { hasErrors, isDown } = useNodeErrors({ actual, reference }); + const { hasErrors, isDown } = useSingleNodeErrors({ actual, reference }); const markerClasses = `${ selectedMapFeature?.id === name && style.selectedMarker diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx index 86e9bc59b..f409113aa 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx @@ -1,3 +1,4 @@ +import { UseQueryResult } from "@tanstack/react-query"; import { useMemo } from "preact/compat"; import { useNodes } from "plugins/lime-plugin-mesh-wide/src/hooks/useNodes"; @@ -13,6 +14,7 @@ import { import { ILinkErrors, ILinkPtoPErrors, + ILinks, LinkType, LocatedLinkData, PointToPointLinkId, @@ -20,6 +22,30 @@ import { import { isEmpty } from "utils/utils"; +interface getQueryByLinkTypeReturnType { + // state: (params) => UseQueryResult>; + state: (params) => UseQueryResult>; + reference: (params) => UseQueryResult>; +} +/** + * Util function that returns the correct query based on the link type + * @param type + */ +export const getQueryByLinkType = ( + type: T +): getQueryByLinkTypeReturnType => { + if (type === "batman") { + return { + state: useMeshWideBatman, + reference: useMeshWideBatmanReference, + } as getQueryByLinkTypeReturnType; + } + return { + state: useMeshWideLinks, + reference: useMeshWideLinksReference, + } as getQueryByLinkTypeReturnType; +}; + interface IUselocatedLinks { locatedLinksReference: LocatedLinkData; linksErrors: ILinkErrors | undefined; @@ -31,11 +57,8 @@ export const useLocatedLinks = ({ }: { type: LinkType; }): IUselocatedLinks => { - const fetchData = type === "batman" ? useMeshWideBatman : useMeshWideLinks; - const fetchDataReference = - type === "batman" - ? useMeshWideBatmanReference - : useMeshWideLinksReference; + const { state: fetchData, reference: fetchDataReference } = + getQueryByLinkType(type); const { data: linksReference } = fetchDataReference({}); const { data: links } = fetchData({}); diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useNodeErrors.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useSingleNodeErrors.tsx similarity index 92% rename from plugins/lime-plugin-mesh-wide/src/hooks/useNodeErrors.tsx rename to plugins/lime-plugin-mesh-wide/src/hooks/useSingleNodeErrors.tsx index 900747264..42392db68 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useNodeErrors.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useSingleNodeErrors.tsx @@ -4,7 +4,7 @@ import { NodeErrorCodes, } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; -export const useNodeErrors = ({ +export const useSingleNodeErrors = ({ actual, reference, }: { @@ -12,8 +12,8 @@ export const useNodeErrors = ({ reference: INodeInfo; }) => { const errors = processNodeErrors(reference, actual); - const hasErrors = errors.length > 0; const isDown = errors.includes(NodeErrorCodes.NODE_DOWN); + const hasErrors = errors.length > 0; return { errors, hasErrors, isDown }; }; From cf2a9d726ebbe8f78787517b4fac6028632cc034 Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 12 Apr 2024 08:57:17 +0200 Subject: [PATCH 105/121] chore(meshwide): refactor query names --- .../src/hooks/useMeshWideDataErrors.tsx | 23 ++++-- .../lime-plugin-mesh-wide/src/meshWideApi.ts | 45 +++-------- .../src/meshWideQueries.tsx | 75 +++++++++++++------ .../src/meshWideQueriesKeys.tsx | 50 ++++++------- .../src/meshWideTypes.tsx | 22 ++++-- 5 files changed, 116 insertions(+), 99 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useMeshWideDataErrors.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useMeshWideDataErrors.tsx index b2e22eaec..da9e137ae 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useMeshWideDataErrors.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useMeshWideDataErrors.tsx @@ -8,7 +8,7 @@ import { useMeshWideNodes, useMeshWideNodesReference, } from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; -import { meshUpgradeQueryKeys } from "plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys"; +import { getFromSharedStateKeys } from "plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys"; import { MeshWideDataError } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; import { isEmpty } from "utils/utils"; @@ -40,35 +40,44 @@ export const useMeshWideDataErrors = () => { const { data: linksReferenceData, error: linksReferenceError } = useMeshWideLinksReference({}); addError( - meshUpgradeQueryKeys.wifiLinksInfoRef, + getFromSharedStateKeys.getFromSharedStateMultiWriter("wifi_links_info"), linksReferenceError, linksReferenceData ); const { error: linksError } = useMeshWideLinks({}); - addError(meshUpgradeQueryKeys.wifiLinksInfo, linksError); + addError( + getFromSharedStateKeys.getFromSharedStateAsync("wifi_links_info"), + linksError + ); const { data: batmanReferenceData, error: batmanReferenceError } = useMeshWideBatmanReference({}); addError( - meshUpgradeQueryKeys.batHostsRef, + getFromSharedStateKeys.getFromSharedStateMultiWriter("bat_links_info"), batmanReferenceError, batmanReferenceData ); const { error: batmanError } = useMeshWideBatman({}); - addError(meshUpgradeQueryKeys.batHosts, batmanError); + addError( + getFromSharedStateKeys.getFromSharedStateAsync("bat_links_info"), + batmanError + ); const { data: nodesReferenceData, error: nodesReferenceError } = useMeshWideNodesReference({}); addError( - meshUpgradeQueryKeys.meshWideNodesRef, + getFromSharedStateKeys.getFromSharedStateMultiWriter("node_info"), nodesReferenceError, nodesReferenceData ); const { error: nodesError } = useMeshWideNodes({}); - addError(meshUpgradeQueryKeys.meshWideNodes, nodesError); + addError( + getFromSharedStateKeys.getFromSharedStateAsync("node_info"), + nodesError + ); return { meshWideDataErrors, dataNotSetErrors }; }; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideApi.ts b/plugins/lime-plugin-mesh-wide/src/meshWideApi.ts index cf3e680cf..d43229f05 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideApi.ts +++ b/plugins/lime-plugin-mesh-wide/src/meshWideApi.ts @@ -1,48 +1,21 @@ -import { meshUpgradeQueryKeys } from "plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys"; +import { QueryKey } from "@tanstack/react-query"; + import { - IBatmanLinks, - INodes, - IWifiLinks, + DataTypeMap, + DataTypes, SharedStateReturnType, } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; import api from "utils/uhttpd.service"; -/** - * Map the query keys to a specific type - */ -interface MeshUpgradeQueryKeyTypes { - meshWideNodes: INodes; - meshWideNodesRef: INodes; - wifiLinksInfo: IWifiLinks; - wifiLinksInfoRef: IWifiLinks; - batHosts: IBatmanLinks; - batHostsRef: IBatmanLinks; -} - -const sharedStateApiCall = async ( - queryKey: K +export const getSharedStateApiCall = async ( + queryKey: QueryKey ) => { - const res = (await api.call( - ...meshUpgradeQueryKeys[queryKey] - )) as SharedStateReturnType; + const res = (await api.call(...queryKey)) as SharedStateReturnType< + DataTypeMap[T] + >; if (res.error !== 0 && res.error !== 404) { throw Error(`Shared state error: ${res.error}`); } return res.data; }; - -export const getMeshWideBatmanReference = () => - sharedStateApiCall("batHostsRef"); - -export const getMeshWideBatman = () => sharedStateApiCall("batHosts"); - -export const getMeshWideLinksReference = () => - sharedStateApiCall("wifiLinksInfoRef"); - -export const getMeshWideLinks = () => sharedStateApiCall("wifiLinksInfo"); - -export const getMeshWideNodesReference = () => - sharedStateApiCall("meshWideNodesRef"); - -export const getMeshWideNodes = async () => sharedStateApiCall("meshWideNodes"); diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx index b9fbbfed9..7b4509927 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx @@ -1,16 +1,11 @@ -import { useQuery } from "@tanstack/react-query"; +import { useMutation, useQuery } from "@tanstack/react-query"; -import { - getMeshWideBatman, - getMeshWideBatmanReference, - getMeshWideLinks, - getMeshWideLinksReference, - getMeshWideNodes, - getMeshWideNodesReference, -} from "plugins/lime-plugin-mesh-wide/src/meshWideApi"; +import { getSharedStateApiCall } from "plugins/lime-plugin-mesh-wide/src/meshWideApi"; import { getMeshWideConfig } from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; -import { meshUpgradeQueryKeys } from "plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys"; +import { getFromSharedStateKeys } from "plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys"; import { + DataTypeMap, + DataTypes, IBatmanLinks, IMeshWideConfig, INodes, @@ -21,9 +16,12 @@ import { import { useSharedData } from "utils/useSharedData"; export function useMeshWideLinksReference(params) { + const dataType: DataTypes = "wifi_links_info"; + const queryKey = + getFromSharedStateKeys.getFromSharedStateMultiWriter(dataType); return useQuery( - meshUpgradeQueryKeys.wifiLinksInfoRef, - getMeshWideLinksReference, + queryKey, + () => getSharedStateApiCall(queryKey), { ...params, } @@ -31,9 +29,11 @@ export function useMeshWideLinksReference(params) { } export function useMeshWideLinks(params) { + const dataType: DataTypes = "wifi_links_info"; + const queryKey = getFromSharedStateKeys.getFromSharedStateAsync(dataType); return useQuery( - meshUpgradeQueryKeys.wifiLinksInfo, - getMeshWideLinks, + queryKey, + () => getSharedStateApiCall(queryKey), { ...params, } @@ -41,9 +41,12 @@ export function useMeshWideLinks(params) { } export function useMeshWideBatmanReference(params) { + const dataType: DataTypes = "bat_links_info"; + const queryKey = + getFromSharedStateKeys.getFromSharedStateMultiWriter(dataType); return useQuery( - meshUpgradeQueryKeys.batHostsRef, - getMeshWideBatmanReference, + queryKey, + () => getSharedStateApiCall(queryKey), { ...params, } @@ -51,9 +54,11 @@ export function useMeshWideBatmanReference(params) { } export function useMeshWideBatman(params) { + const dataType: DataTypes = "bat_links_info"; + const queryKey = getFromSharedStateKeys.getFromSharedStateAsync(dataType); return useQuery( - meshUpgradeQueryKeys.batHosts, - getMeshWideBatman, + queryKey, + () => getSharedStateApiCall(queryKey), { ...params, } @@ -61,9 +66,12 @@ export function useMeshWideBatman(params) { } export function useMeshWideNodesReference(params) { + const dataType: DataTypes = "node_info"; + const queryKey = + getFromSharedStateKeys.getFromSharedStateMultiWriter(dataType); return useQuery( - meshUpgradeQueryKeys.meshWideNodesRef, - getMeshWideNodesReference, + queryKey, + () => getSharedStateApiCall(queryKey), { ...params, } @@ -71,9 +79,32 @@ export function useMeshWideNodesReference(params) { } export function useMeshWideNodes(params) { + const dataType: DataTypes = "node_info"; + const queryKey = getFromSharedStateKeys.getFromSharedStateAsync(dataType); return useQuery( - meshUpgradeQueryKeys.meshWideNodes, - getMeshWideNodes, + queryKey, + () => getSharedStateApiCall(queryKey), + { + ...params, + } + ); +} + +/** + * Insert into shared state + */ +export function useInsertIntoSharedState( + type: T, + data: DataTypeMap[T], + params +) { + const queryKey = getFromSharedStateKeys.insertIntoSharedStateKey( + type, + data + ); + return useMutation( + queryKey, + () => getSharedStateApiCall(queryKey), { ...params, } diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys.tsx index fba2debc4..7694f38f5 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys.tsx @@ -1,36 +1,30 @@ -import { QueryKey } from "@tanstack/react-query"; +import { + DataTypeMap, + DataTypes, +} from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; -interface MeshWideQueryKeysProps { - [key: string]: QueryKey; -} - -const MeshWideQueryKeys: MeshWideQueryKeysProps = { - meshWideNodes: [{ data_type: "node_info" }], - wifiLinksInfo: [{ data_type: "wifi_links_info" }], - batHosts: [{ data_type: "bat_links_info" }], -}; - -const getFromSharedState = ["shared-state", "getFromSharedState"]; -const getFromSharedStateMultiWriter = [ +export const getFromSharedStateMultiWriterKey = [ "shared-state", "getFromSharedStateMultiWriter", ]; -const getFromSharedStateAsync = ["shared-state-async", "get"]; +export const getFromSharedStateAsyncKey = ["shared-state-async", "get"]; -export const meshUpgradeQueryKeys = { - meshWideNodes: [...getFromSharedState, ...MeshWideQueryKeys.meshWideNodes], - meshWideNodesRef: [ - ...getFromSharedStateMultiWriter, - ...MeshWideQueryKeys.meshWideNodes, - ], - wifiLinksInfo: [...getFromSharedState, ...MeshWideQueryKeys.wifiLinksInfo], - wifiLinksInfoRef: [ - ...getFromSharedStateMultiWriter, - ...MeshWideQueryKeys.wifiLinksInfo, +export const insertIntoSharedStateKey = [ + "insertIntoSharedStateMultiWriter", + "sync", +]; + +export const getFromSharedStateKeys = { + getFromSharedStateAsync: (dataType: DataTypes) => [ + ...getFromSharedStateAsyncKey, + { data_type: dataType }, ], - batHosts: [...getFromSharedStateAsync, ...MeshWideQueryKeys.batHosts], - batHostsRef: [ - ...getFromSharedStateMultiWriter, - ...MeshWideQueryKeys.batHosts, + getFromSharedStateMultiWriter: (dataType: DataTypes) => [ + ...getFromSharedStateMultiWriterKey, + { data_type: dataType }, ], + insertIntoSharedStateKey: ( + dataType: T, + data: DataTypeMap[T] + ) => [...insertIntoSharedStateKey, { data_type: dataType, json: data }], }; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideTypes.tsx index a065b1123..af67b11f0 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideTypes.tsx @@ -83,12 +83,6 @@ export interface INodeInfo { export type INodes = { [key: string]: INodeInfo }; -export type SharedStateTypes = INodes | IWifiLinks | IBatmanLinks; -export type SharedStateReturnType = { - data: T; - error: number; -}; - export type LinkMapFeature = { actual: PontToPointLink; reference: PontToPointLink; @@ -184,3 +178,19 @@ export type MacToMacLinkId = string; * two geo points of this link */ export type PointToPointLinkId = string; + +/** + * Query keys types + */ + +export type DataTypeMap = { + node_info: INodes; + wifi_links_info: IWifiLinks; + bat_links_info: IBatmanLinks; +}; +export type DataTypes = keyof DataTypeMap; +export type SharedStateTypes = DataTypeMap[keyof DataTypeMap]; +export type SharedStateReturnType = { + data: T; + error: number; +}; From 71bffece93a72be3ca612687fdaa364557586da7 Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 16 Apr 2024 09:40:00 +0200 Subject: [PATCH 106/121] chore(meshwide): refactor keynames --- .../src/components/FeatureDetail/LinkDetail.tsx | 2 +- .../src/containers/Map.spec.tsx | 12 ++++++------ .../src/containers/MapLayers/LinksLayers.tsx | 4 ++-- .../SelectedFeatureBottomSheet.spec.tsx | 2 +- .../src/hooks/useLocatedLinks.tsx | 2 +- .../src/lib/links/PointToPointLink.ts | 4 ++-- .../src/lib/links/getLinksCoordinates.spec.ts | 2 +- .../src/lib/links/getLinksCoordinates.ts | 6 +++--- .../src/lib/links/processLinkErrors.ts | 2 +- .../lime-plugin-mesh-wide/src/meshWideMocks.tsx | 3 ++- .../lime-plugin-mesh-wide/src/meshWideTypes.tsx | 16 ++++++++++------ 11 files changed, 30 insertions(+), 25 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx index d521e62e0..6bd0a6c39 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx @@ -148,7 +148,7 @@ const SelectedLink = ({ {names.map((name, i) => { const node = linkDetail.linkByName(name); const errorsArray = errors?.linkErrors[name] ?? []; - return linkType === "wifi" ? ( + return linkType === "wifi_links_info" ? ( { it("should show nodes alert when a node has not configured properly the coordinates", async () => { diff --git a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx index b84c33f2e..eefb0a03f 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers.tsx @@ -46,7 +46,7 @@ const LinksLayer = ({ export const WifiLinksLayer = () => { const { locatedLinks, locatedLinksReference, linksLoaded } = - useLocatedLinks({ type: "wifi" }); + useLocatedLinks({ type: "wifi_links_info" }); return (
@@ -61,7 +61,7 @@ export const WifiLinksLayer = () => { export const BatmanLinksLayer = () => { const { locatedLinks, locatedLinksReference, linksLoaded } = - useLocatedLinks({ type: "batman" }); + useLocatedLinks({ type: "bat_links_info" }); return (
diff --git a/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.spec.tsx b/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.spec.tsx index f9f52f561..e42ea9aca 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.spec.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet.spec.tsx @@ -98,7 +98,7 @@ describe("Feature bottom sheet", () => { it.skip("should open BottomSheet with link feature", () => { const name = "LiMe-da4eaa"; - const actual = links("wifi")[name]; + const actual = links("wifi_links_info")[name]; const reference = linksReferenceState[name]; // todo: fix this test // mockedSelectedMapFeature.mockReturnValue({ diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx index f409113aa..d769032cf 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx @@ -34,7 +34,7 @@ interface getQueryByLinkTypeReturnType { export const getQueryByLinkType = ( type: T ): getQueryByLinkTypeReturnType => { - if (type === "batman") { + if (type === "bat_links_info") { return { state: useMeshWideBatman, reference: useMeshWideBatmanReference, diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts index 2f91b74e6..508e79728 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts @@ -2,7 +2,7 @@ import { BaseMacToMacLink, Coordinates, ILocatedLink, - LinkData, + LinkDataTypes, LinkType, MacToMacLinkId, PointToPointLinkId, @@ -128,7 +128,7 @@ export class MacToMacLink { return [...Object.keys(this._data)]; } - linkByName(name: string): LinkData[T] { + linkByName(name: string): LinkDataTypes[T] { return this._data[name]; } } diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.spec.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.spec.ts index df4a0a1d0..fad847d38 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.spec.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.spec.ts @@ -13,7 +13,7 @@ describe("tests for the algorithm that merge point and links data types", () => const locatedLinksReference = mergeLinksAndCoordinates( nodesReferenceState, linksReferenceState, - "wifi" + "wifi_links_info" ); // Iterate between merged link objects Object.entries(locatedLinksReference).map(([k, merged], i) => { diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts index 56f9dfa64..ad2158712 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts @@ -6,7 +6,7 @@ import { ILinks, ILocatedLink, INodes, - LinkData, + LinkDataTypes, LinkType, LocatedLinkData, } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; @@ -66,9 +66,9 @@ export const mergeLinksAndCoordinates = ( // Get the destination link info const destPointData = ( - links[dstNodeName] as Array + links[dstNodeName] as Array ).find( - (data: LinkData[T]) => + (data: LinkDataTypes[T]) => data.dst_mac.toLowerCase() === linkData.src_mac.toLowerCase() && data.src_mac.toLowerCase() === diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts index e0b1edcce..655f8e6e1 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/processLinkErrors.ts @@ -95,7 +95,7 @@ export const compareLinks = ({ ([nodeNameReference, wifiDataReference]) => { const wifiDataActual = macToMacActual?.data[nodeNameReference]; const errors = - referenceLink.type === "wifi" + referenceLink.type === "wifi_links_info" ? compareWifiData( wifiDataReference as IWifiLinkData, wifiDataActual as IWifiLinkData diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx index a38e8dcd0..278823f9e 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx @@ -326,7 +326,8 @@ const linkToDelete = "a0:f3:c1:46:11:97"; // const linkToDelete = ""; export const links = (type: T): ILinks => { - const data = type === "wifi" ? linksReferenceState : batManReferenceState; + const data = + type === "wifi_links_info" ? linksReferenceState : batManReferenceState; // Create a deep copy of the state to avoid mutating the original object const newState: ILinks = JSON.parse(JSON.stringify(data)); diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideTypes.tsx index af67b11f0..a73fcd179 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideTypes.tsx @@ -8,10 +8,14 @@ import { /** * Describe a link with a coordinates */ -export type LinkData = { wifi: IWifiLinkData; batman: IBatManLinkData }; -export type LinkType = keyof LinkData; + +export type LinkDataTypes = { + wifi_links_info: IWifiLinkData; + bat_links_info: IBatManLinkData; +}; +export type LinkType = keyof LinkDataTypes; export type ILocatedLink = { - [key: string]: LinkData[T] & { + [key: string]: LinkDataTypes[T] & { coordinates: Coordinates; }; }; @@ -56,11 +60,11 @@ export type IBatManLinkData = { * List of Link info retrieved from the API */ export interface ILinks { - [key: string]: Array; + [key: string]: Array; } -export type IWifiLinks = ILinks<"wifi">; -export type IBatmanLinks = ILinks<"batman">; +export type IWifiLinks = ILinks<"wifi_links_info">; +export type IBatmanLinks = ILinks<"bat_links_info">; export type Coordinates = { lat: string; From ee6dc4a4dd4c907ce0e83eccebfcd5f8597b2f86 Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 6 Mar 2024 15:30:42 +0100 Subject: [PATCH 107/121] chore(meshupgrade): add isLoading no modal --- src/components/Modal/Modal.tsx | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/components/Modal/Modal.tsx b/src/components/Modal/Modal.tsx index 1d8fffc84..cf81ecb4a 100644 --- a/src/components/Modal/Modal.tsx +++ b/src/components/Modal/Modal.tsx @@ -10,22 +10,27 @@ interface ModalContextProps { isModalOpen: boolean; toggleModal: () => void; setModalState: (state?: ModalState) => void; + isLoading: boolean; } +type CallbackFn = () => void | Promise; + interface ModalState { content?: ComponentChildren; title: ComponentChildren | string; cancelBtn?: boolean; - successCb?: (e) => void; + successCb?: CallbackFn; successBtnText?: ComponentChildren; - deleteCb?: (e) => void; + deleteCb?: CallbackFn; deleteBtnText?: ComponentChildren; + isLoading?: boolean; } const ModalContext = createContext({ isModalOpen: false, toggleModal: () => {}, setModalState: () => {}, + isLoading: false, }); export const useModal = () => { @@ -40,6 +45,8 @@ export type ModalActions = "success" | "delete"; export const UseModalProvider = ({ children }) => { const [isModalOpen, setModalOpen] = useState(false); + const [isLoading, setIsLoading] = useState(false); + const [modalState, setModalState] = useState({ content: <>, title: "", @@ -54,12 +61,23 @@ export const UseModalProvider = ({ children }) => { setModalOpen((prevIsModalOpen) => !prevIsModalOpen); }, [isModalOpen]); + const runCb = useCallback( + async (cb: CallbackFn) => { + if (isLoading) return; + setIsLoading(true); + await cb(); + setIsLoading(false); + }, + [isLoading] + ); + return ( {children} @@ -68,9 +86,9 @@ export const UseModalProvider = ({ children }) => { toggleModal={toggleModal} title={modalState.title} cancelBtn={modalState.cancelBtn} - successCb={modalState.successCb} + successCb={() => runCb(modalState.successCb)} successBtnText={modalState.successBtnText} - deleteCb={modalState.deleteCb} + deleteCb={() => runCb(modalState.successCb)} deleteBtnText={modalState.deleteBtnText} > {modalState.content} @@ -89,6 +107,7 @@ const Modal = ({ successBtnText = Success, deleteCb, deleteBtnText = Cancel, + isLoading, }: { isModalOpen: boolean; toggleModal: () => void; From 9ae97d7c991642d83815578433df787f1ad83e47 Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 6 Mar 2024 15:44:48 +0100 Subject: [PATCH 108/121] chore(meshupgrade): create is disabled button --- src/components/Modal/Modal.tsx | 7 ++++++- src/components/buttons/button.tsx | 29 ++++++++++++++++++++++------- tailwind.config.js | 1 + 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/components/Modal/Modal.tsx b/src/components/Modal/Modal.tsx index cf81ecb4a..6d529295c 100644 --- a/src/components/Modal/Modal.tsx +++ b/src/components/Modal/Modal.tsx @@ -160,12 +160,17 @@ const Modal = ({ )} {deleteCb && ( - )} diff --git a/src/components/buttons/button.tsx b/src/components/buttons/button.tsx index 8240491bc..c57255d52 100644 --- a/src/components/buttons/button.tsx +++ b/src/components/buttons/button.tsx @@ -4,9 +4,10 @@ export interface ButtonProps { onClick?: (e) => void; children?: any; // type error with Trans component size?: "sm" | "md" | "lg"; - color?: "primary" | "secondary" | "danger" | "info"; + color?: "primary" | "secondary" | "danger" | "info" | "disabled"; href?: string; outline?: boolean; + disabled?: boolean; } export const Button = ({ @@ -15,6 +16,7 @@ export const Button = ({ onClick, children, href, + disabled, outline = false, ...props }: ButtonProps) => { @@ -32,12 +34,9 @@ export const Button = ({ break; } + color = disabled ? "disabled" : color; + switch (color) { - case "primary": - colorClasses = outline - ? "border-2 border-button-primary text-button-primary hover:bg-button-primary hover:text-white" - : "bg-button-primary text-white hover:bg-button-secondary"; - break; case "secondary": colorClasses = outline ? "border-2 border-button-secondary text-button-secondary hover:bg-button-secondary hover:text-white" @@ -53,12 +52,28 @@ export const Button = ({ ? "border-2 border-button-info text-button-info hover:bg-button-info hover:text-white" : "bg-button-info text-white border-2 border-button-info hover:text-button-info hover:bg-white"; break; + case "disabled": + colorClasses = outline + ? "border-2 border-button-disabled text-button-disabled hover:bg-button-disabled hover:text-white" + : "bg-button-disabled text-white border-2 border-button-disabled hover:text-button-disabled hover:bg-white"; + break; + case "primary": + default: + colorClasses = outline + ? "border-2 border-button-primary text-button-primary hover:bg-button-primary hover:text-white" + : "bg-button-primary text-white hover:bg-button-secondary"; + break; } const cls = `cursor-pointer font-semibold rounded-xl text-center place-content-center transition-all duration-300 justify-center border-0 ${sizeClasses} ${colorClasses}`; const Btn = () => ( -
+
(!disabled ? onClick(e) : null)} + className={cls} + {...props} + > {children}
); diff --git a/tailwind.config.js b/tailwind.config.js index 4b4076d8d..9773ed829 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -23,6 +23,7 @@ module.exports = { primary: "#1BC47D", secondary: "#6BC3AE", info: "#00ADEE", + disabled: "#BABABA", }, danger: "#EB7575", info: "#EAAB7E", From a2f1134b53ac48e498f222c73c83c1e0537cb8de Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 6 Mar 2024 15:56:28 +0100 Subject: [PATCH 109/121] chore(meshupgrade): fix modal callbacks --- src/components/Modal/Modal.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/Modal/Modal.tsx b/src/components/Modal/Modal.tsx index 6d529295c..559753c52 100644 --- a/src/components/Modal/Modal.tsx +++ b/src/components/Modal/Modal.tsx @@ -71,6 +71,11 @@ export const UseModalProvider = ({ children }) => { [isLoading] ); + const successCb = + modalState.successCb != null ? () => runCb(modalState.successCb) : null; + const deleteCb = + modalState.deleteCb != null ? () => runCb(modalState.deleteCb) : null; + return ( { toggleModal={toggleModal} title={modalState.title} cancelBtn={modalState.cancelBtn} - successCb={() => runCb(modalState.successCb)} + successCb={successCb} successBtnText={modalState.successBtnText} - deleteCb={() => runCb(modalState.successCb)} + deleteCb={deleteCb} deleteBtnText={modalState.deleteBtnText} > {modalState.content} From 9d3a46b1a67ee8c7f14f73f5c026327bbc06fa55 Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 17 Apr 2024 15:20:30 +0200 Subject: [PATCH 110/121] chore(meshwide): fix modal isLoading --- src/components/Modal/Modal.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/Modal/Modal.tsx b/src/components/Modal/Modal.tsx index 559753c52..f2a5f54af 100644 --- a/src/components/Modal/Modal.tsx +++ b/src/components/Modal/Modal.tsx @@ -95,6 +95,7 @@ export const UseModalProvider = ({ children }) => { successBtnText={modalState.successBtnText} deleteCb={deleteCb} deleteBtnText={modalState.deleteBtnText} + isLoading={isLoading} > {modalState.content} @@ -132,7 +133,9 @@ const Modal = ({ >
{ + if (!isLoading) toggleModal(); + }} >
Close From c72c12e3882929ccb2485cb1a5632f5b04a99a2b Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 17 Apr 2024 16:04:35 +0200 Subject: [PATCH 111/121] chore(meshwide): implement set reference state --- .../components/FeatureDetail/LinkDetail.tsx | 7 +- .../components/FeatureDetail/NodeDetail.tsx | 10 ++- .../FeatureDetail/SetReferenceStateBtn.tsx | 69 +++++++++++++++++++ .../FeatureDetail/ShowErrorsDetail.tsx | 38 +++++----- .../src/components/configPage/modals.tsx | 25 +++++++ .../src/meshWideQueries.tsx | 51 ++++++++++++-- .../src/meshWideQueriesKeys.tsx | 2 +- 7 files changed, 173 insertions(+), 29 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/SetReferenceStateBtn.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx index 6bd0a6c39..8868788da 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx @@ -5,6 +5,7 @@ import { Button } from "components/buttons/button"; import Tabs from "components/tabs"; import { StatusAndButton } from "plugins/lime-plugin-mesh-wide/src/components/Components"; +import { useSetReferenceState } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/SetReferenceStateBtn"; import { getQueryByLinkType, usePointToPointErrors, @@ -237,6 +238,9 @@ export const LinkReferenceStatus = ({ actual, reference }: LinkMapFeature) => { referenceError = true; } + // Mutation to update the reference state + const { mutate, btnText } = useSetReferenceState(reference.type); + let errorMessage = Same status as in the reference state; if (referenceError) { errorMessage = Reference is not set or has errors; @@ -249,7 +253,8 @@ export const LinkReferenceStatus = ({ actual, reference }: LinkMapFeature) => { return ( Update this link on reference state} + btn={hasError && btnText} + onClick={mutate} > {errorMessage} diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx index e7621caba..f3f2d364e 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx @@ -3,6 +3,7 @@ import { Trans } from "@lingui/macro"; import { Button } from "components/buttons/button"; import { StatusAndButton } from "plugins/lime-plugin-mesh-wide/src/components/Components"; +import { useSetReferenceState } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/SetReferenceStateBtn"; import { Row, TitleAndText, @@ -104,6 +105,10 @@ export const NodeReferenceStatus = ({ actual, reference }: NodeMapFeature) => { // Check if there are errors of global reference state to shown const { data: meshWideNodesReference, isError: isReferenceError } = useMeshWideNodesReference({}); + + // Mutation to update the reference state + const { mutate, btnText } = useSetReferenceState("node_info"); + let referenceError = false; if ( !meshWideNodesReference || @@ -125,9 +130,8 @@ export const NodeReferenceStatus = ({ actual, reference }: NodeMapFeature) => { return ( Update this node on reference state - } + btn={hasErrors && btnText} + onClick={mutate} > {errorMessage} diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/SetReferenceStateBtn.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/SetReferenceStateBtn.tsx new file mode 100644 index 000000000..fda447598 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/SetReferenceStateBtn.tsx @@ -0,0 +1,69 @@ +import { Trans } from "@lingui/macro"; +import { useCallback } from "react"; + +import { useToast } from "components/toast/toastProvider"; + +import { useSetReferenceStateModal } from "plugins/lime-plugin-mesh-wide/src/components/configPage/modals"; +import { + useSetBatmanLinksInfoReferenceState, + useSetNodeInfoReferenceState, + useSetWifiLinksInfoReferenceState, +} from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; +import { DataTypes } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; + +const toastDuration = 5000; + +export const useSetReferenceState = (dataType: T) => { + const { toggleModal, confirmModal, isModalOpen } = + useSetReferenceStateModal(); + const { showToast } = useToast(); + + const mutationOpts = { + onSuccess: () => { + showToast({ + text: New reference state set!, + duration: toastDuration, + }); + }, + onError: () => { + showToast({ + text: Error setting new reference state!, + duration: toastDuration, + }); + }, + onSettled: () => { + if (isModalOpen) toggleModal(); + }, + }; + + const { mutateAsync: nodesMutation } = + useSetNodeInfoReferenceState(mutationOpts); + const { mutateAsync: wifiMutation } = + useSetWifiLinksInfoReferenceState(mutationOpts); + const { mutateAsync: batmanMutation } = + useSetBatmanLinksInfoReferenceState(mutationOpts); + + const btnText = Set {dataType} reference state; + + const mutate = useCallback(async () => { + switch (dataType) { + case "node_info": + await confirmModal(dataType, async () => { + await nodesMutation(); + }); + break; + case "wifi_links_info": + confirmModal(dataType, async () => { + await wifiMutation(); + }); + break; + case "bat_links_info": + confirmModal(dataType, async () => { + await batmanMutation(); + }); + break; + } + }, [batmanMutation, confirmModal, dataType, nodesMutation, wifiMutation]); + + return { mutate, btnText }; +}; diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx index 16161417f..50e727333 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx @@ -2,8 +2,22 @@ import { Trans } from "@lingui/macro"; import { Button } from "components/buttons/button"; +import { useSetReferenceState } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/SetReferenceStateBtn"; import { Row } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index"; -import { ErrorsDetails } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; +import { + DataTypes, + ErrorsDetails, +} from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; + +const SetDataTypeBtn = ({ dataType }: { dataType: T }) => { + const { mutate, btnText } = useSetReferenceState(dataType); + return ( +
+
{dataType}
+ +
+ ); +}; export const ShowErrorsDetail = ({ errors }: { errors: ErrorsDetails }) => { return ( @@ -49,24 +63,14 @@ export const ShowErrorsDetail = ({ errors }: { errors: ErrorsDetails }) => { null, 2 ); + return ( +
+ {dataType}: {data?.error?.toString()} +
+ ); } return ( -
-
{dataType}
- -
+ ); })}
diff --git a/plugins/lime-plugin-mesh-wide/src/components/configPage/modals.tsx b/plugins/lime-plugin-mesh-wide/src/components/configPage/modals.tsx index 44aec6123..e0f2f40bb 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/configPage/modals.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/configPage/modals.tsx @@ -6,6 +6,8 @@ import { useForm } from "react-hook-form"; import { ModalActions, useModal } from "components/Modal/Modal"; import InputField from "components/inputs/InputField"; +import { DataTypes } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; + const useActionModal = ( title: ComponentChildren, btnText: ComponentChildren, @@ -82,3 +84,26 @@ export const useAddNewSectionModal = () => { ); return { actionModal, toggleModal }; }; + +export const useSetReferenceStateModal = () => { + const { toggleModal, setModalState, isModalOpen } = useModal(); + + const confirmModal = useCallback( + (dataType: DataTypes, cb: () => Promise) => { + setModalState({ + title: Set reference state for {dataType}, + content: ( + + Are you sure you want to set this reference state for{" "} + {dataType} + + ), + successCb: cb, + successBtnText: Continue, + }); + toggleModal(); + }, + [setModalState, toggleModal] + ); + return { confirmModal, toggleModal, isModalOpen }; +}; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx index 7b4509927..abb954a31 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx @@ -4,7 +4,6 @@ import { getSharedStateApiCall } from "plugins/lime-plugin-mesh-wide/src/meshWid import { getMeshWideConfig } from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; import { getFromSharedStateKeys } from "plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys"; import { - DataTypeMap, DataTypes, IBatmanLinks, IMeshWideConfig, @@ -92,12 +91,14 @@ export function useMeshWideNodes(params) { /** * Insert into shared state + * + * Don't use those mutations itself, use it implementing it on the useReferenceState hook in order + * to unify criterias and add a confirmation modal */ -export function useInsertIntoSharedState( - type: T, - data: DataTypeMap[T], - params -) { + +export const useSetNodeInfoReferenceState = (params) => { + const type = "node_info"; + const { data } = useMeshWideNodes({}); const queryKey = getFromSharedStateKeys.insertIntoSharedStateKey( type, data @@ -109,7 +110,43 @@ export function useInsertIntoSharedState( ...params, } ); -} +}; + +export const useSetWifiLinksInfoReferenceState = (params) => { + const type = "wifi_links_info"; + const { data } = useMeshWideLinks({}); + const queryKey = getFromSharedStateKeys.insertIntoSharedStateKey( + type, + data + ); + return useMutation( + queryKey, + () => getSharedStateApiCall(queryKey), + { + ...params, + } + ); +}; + +export const useSetBatmanLinksInfoReferenceState = (params) => { + const type = "bat_links_info"; + const { data } = useMeshWideBatman({}); + const queryKey = getFromSharedStateKeys.insertIntoSharedStateKey( + type, + data + ); + return useMutation( + queryKey, + () => getSharedStateApiCall(queryKey), + { + ...params, + } + ); +}; + +/** + * Set mesh wide config + */ export function useMeshWideConfig(params) { return useQuery( diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys.tsx index 7694f38f5..237afe239 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys.tsx @@ -10,8 +10,8 @@ export const getFromSharedStateMultiWriterKey = [ export const getFromSharedStateAsyncKey = ["shared-state-async", "get"]; export const insertIntoSharedStateKey = [ + "shared-state", "insertIntoSharedStateMultiWriter", - "sync", ]; export const getFromSharedStateKeys = { From 9f72976e8becca669e1140f101143d01f3ce66bc Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 18 Apr 2024 08:38:04 +0200 Subject: [PATCH 112/121] chore(meshwide): refactor function name --- .../lime-plugin-mesh-wide/src/meshWideApi.ts | 2 +- .../src/meshWideQueries.tsx | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideApi.ts b/plugins/lime-plugin-mesh-wide/src/meshWideApi.ts index d43229f05..c8470df9e 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideApi.ts +++ b/plugins/lime-plugin-mesh-wide/src/meshWideApi.ts @@ -8,7 +8,7 @@ import { import api from "utils/uhttpd.service"; -export const getSharedStateApiCall = async ( +export const doSharedStateApiCall = async ( queryKey: QueryKey ) => { const res = (await api.call(...queryKey)) as SharedStateReturnType< diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx index abb954a31..9bae765aa 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx @@ -1,6 +1,6 @@ import { useMutation, useQuery } from "@tanstack/react-query"; -import { getSharedStateApiCall } from "plugins/lime-plugin-mesh-wide/src/meshWideApi"; +import { doSharedStateApiCall } from "plugins/lime-plugin-mesh-wide/src/meshWideApi"; import { getMeshWideConfig } from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; import { getFromSharedStateKeys } from "plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys"; import { @@ -20,7 +20,7 @@ export function useMeshWideLinksReference(params) { getFromSharedStateKeys.getFromSharedStateMultiWriter(dataType); return useQuery( queryKey, - () => getSharedStateApiCall(queryKey), + () => doSharedStateApiCall(queryKey), { ...params, } @@ -32,7 +32,7 @@ export function useMeshWideLinks(params) { const queryKey = getFromSharedStateKeys.getFromSharedStateAsync(dataType); return useQuery( queryKey, - () => getSharedStateApiCall(queryKey), + () => doSharedStateApiCall(queryKey), { ...params, } @@ -45,7 +45,7 @@ export function useMeshWideBatmanReference(params) { getFromSharedStateKeys.getFromSharedStateMultiWriter(dataType); return useQuery( queryKey, - () => getSharedStateApiCall(queryKey), + () => doSharedStateApiCall(queryKey), { ...params, } @@ -57,7 +57,7 @@ export function useMeshWideBatman(params) { const queryKey = getFromSharedStateKeys.getFromSharedStateAsync(dataType); return useQuery( queryKey, - () => getSharedStateApiCall(queryKey), + () => doSharedStateApiCall(queryKey), { ...params, } @@ -70,7 +70,7 @@ export function useMeshWideNodesReference(params) { getFromSharedStateKeys.getFromSharedStateMultiWriter(dataType); return useQuery( queryKey, - () => getSharedStateApiCall(queryKey), + () => doSharedStateApiCall(queryKey), { ...params, } @@ -82,7 +82,7 @@ export function useMeshWideNodes(params) { const queryKey = getFromSharedStateKeys.getFromSharedStateAsync(dataType); return useQuery( queryKey, - () => getSharedStateApiCall(queryKey), + () => doSharedStateApiCall(queryKey), { ...params, } @@ -105,7 +105,7 @@ export const useSetNodeInfoReferenceState = (params) => { ); return useMutation( queryKey, - () => getSharedStateApiCall(queryKey), + () => doSharedStateApiCall(queryKey), { ...params, } @@ -121,7 +121,7 @@ export const useSetWifiLinksInfoReferenceState = (params) => { ); return useMutation( queryKey, - () => getSharedStateApiCall(queryKey), + () => doSharedStateApiCall(queryKey), { ...params, } @@ -137,7 +137,7 @@ export const useSetBatmanLinksInfoReferenceState = (params) => { ); return useMutation( queryKey, - () => getSharedStateApiCall(queryKey), + () => doSharedStateApiCall(queryKey), { ...params, } From afa3e2d80d6b0a6426795e4a2ed27622f32c241c Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 23 Apr 2024 14:39:56 +0200 Subject: [PATCH 113/121] chore(meshwide): implement new nodes visualization --- .../components/FeatureDetail/LinkDetail.tsx | 19 ++++++--- .../components/FeatureDetail/NodeDetail.tsx | 25 ++++++++---- .../src/components/Map/LinkLine.tsx | 24 ++++++++---- .../src/components/Map/NodeMarker.tsx | 19 ++++++--- .../src/components/Map/style.less | 12 ++++++ .../src/containers/MapLayers/LinksLayers.tsx | 34 +++++++++------- .../src/containers/MapLayers/NodesLayer.tsx | 15 +++---- .../src/hooks/useLocatedLinks.tsx | 39 ++++++++++--------- .../src/hooks/useNodes.tsx | 23 +++++++++++ .../src/hooks/useSingleNodeErrors.tsx | 3 +- .../src/lib/nodes/processErrors.ts | 3 ++ 11 files changed, 147 insertions(+), 69 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx index 8868788da..83b497185 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx @@ -170,14 +170,15 @@ const SelectedLink = ({ }; const LinkFeatureDetail = ({ actual, reference }: LinkMapFeature) => { + const linkToShow = reference ?? actual; const [selectedLink, setSelectedLink] = useState(0); const { errors } = usePointToPointErrors({ - id: reference.id, - type: reference.type, + id: linkToShow.id, + type: linkToShow.type, }); - const linkType = reference.type; + const linkType = linkToShow.type; - const tabs = reference.links.map( + const tabs = linkToShow.links.map( (link: MacToMacLink, i) => { return { key: i, @@ -222,15 +223,17 @@ const LinkFeatureDetail = ({ actual, reference }: LinkMapFeature) => { }; export const LinkReferenceStatus = ({ actual, reference }: LinkMapFeature) => { + const isNewNode = !reference; + const { errors } = usePointToPointErrors({ id: reference.id, type: reference.type, }); + // Check if there are errors of global reference state to shown const { reference: fetchDataReference } = getQueryByLinkType( reference.type ); - // Check if there are errors of global reference state to shown const { data: referenceData, isError: isReferenceError } = fetchDataReference({}); let referenceError = false; @@ -246,9 +249,13 @@ export const LinkReferenceStatus = ({ actual, reference }: LinkMapFeature) => { errorMessage = Reference is not set or has errors; } else if (errors?.hasErrors) { errorMessage = This link has errors; + } else if (isNewNode) { + errorMessage = ( + This Link is not registered on the reference state + ); } - const hasError = errors?.hasErrors || referenceError; + const hasError = errors?.hasErrors || referenceError || isNewNode; return ( { - const uptime = reference.uptime; - const firmware = reference.firmware_version; - const ipv6 = reference.ipv6; - const ipv4 = reference.ipv4; - const device = reference.device; - const { errors, isDown } = useSingleNodeErrors({ actual, reference }); + // If node no reference is set, is a new node + const nodeToShow = reference ?? actual; + + const uptime = nodeToShow.uptime; + const firmware = nodeToShow.firmware_version; + const ipv6 = nodeToShow.ipv6; + const ipv4 = nodeToShow.ipv4; + const device = nodeToShow.device; + const { errors, isDown, isNewNode } = useSingleNodeErrors({ + actual, + reference, + }); if (isDown) { return This node seems down; @@ -97,6 +103,7 @@ export const NodeReferenceStatus = ({ actual, reference }: NodeMapFeature) => { errors, hasErrors: hasNodeErrors, isDown, + isNewNode, } = useSingleNodeErrors({ actual, reference, @@ -123,9 +130,13 @@ export const NodeReferenceStatus = ({ actual, reference }: NodeMapFeature) => { errorMessage = Reference is not set or has errors; } else if (isDown) { errorMessage = In the reference state this node is on; + } else if (isNewNode) { + errorMessage = ( + This node is not registered on the reference state + ); } - const hasErrors = hasNodeErrors || referenceError; + const hasErrors = hasNodeErrors || referenceError || isNewNode; return ( { - const type = referenceLink.type; const { data: selectedMapFeature, setData: setSelectedMapFeature } = useSelectedMapFeature(); - const isSelected = selectedMapFeature?.id === referenceLink.id; + + const linkToShow = referenceLink ?? actualLink; + let isNewNode = false; + if (!referenceLink) { + isNewNode = true; + } + + const type = linkToShow.type; + const isSelected = selectedMapFeature?.id === linkToShow.id; + const { linksErrors } = useLocatedLinks({ type }); let hasError = false; let linkUp = true; - if (linksErrors && linksErrors[referenceLink.id]) { + if (!isNewNode && linksErrors && linksErrors[referenceLink.id]) { hasError = linksErrors[referenceLink.id].hasErrors; linkUp = linksErrors[referenceLink.id].linkUp; } const _setSelectedFeature = () => { setSelectedMapFeature({ - id: referenceLink.id, - feature: { reference: referenceLink, actual: actualLink }, + id: linkToShow.id, + feature: { reference: linkToShow, actual: actualLink }, type: "link", }); }; @@ -38,11 +46,11 @@ export const LinkLine = ({ referenceLink, actualLink }: ILinkLineProps) => { color: hasError ? "#eb7575" : "#76bd7d", weight: isSelected ? 7 : 5, opacity: isSelected ? 1 : 0.8, - dashArray: linkUp ? null : "7 10", + dashArray: isNewNode || !linkUp ? "7 10" : null, // Show dash array also when is a new node }; }; - const coordinates = referenceLink.coordinates.map((c) => [c.lat, c.long]); + const coordinates = linkToShow.coordinates.map((c) => [c.lat, c.long]); return ( { const { data: selectedMapFeature, setData: setSelectedMapFeature } = useSelectedMapFeature(); - const { hasErrors, isDown } = useSingleNodeErrors({ actual, reference }); + const { hasErrors, isDown, isNewNode } = useSingleNodeErrors({ + actual, + reference, + }); const markerClasses = `${ selectedMapFeature?.id === name && style.selectedMarker - } ${hasErrors ? style.errorMarker : style.syncedMarker} ${ - isDown && style.notUpMarker - }`; + } + ${hasErrors ? style.errorMarker : style.syncedMarker} + ${isDown && style.notUpMarker} + ${isNewNode && style.newNodeMarker}`; + + // If node no reference is set, is a new node + const nodeToShow = reference ?? actual; return ( { - // If reference is not set or empty, use actual nodes - const linksReference = - !originalLinksReference || isEmpty(originalLinksReference) - ? links - : originalLinksReference; - return (
{linksLoaded && @@ -40,13 +34,21 @@ const LinksLayer = ({ /> ); })} + {newLinks && + Object.entries(newLinks).map(([k, v], i) => { + return ; + })}
); }; export const WifiLinksLayer = () => { - const { locatedLinks, locatedLinksReference, linksLoaded } = - useLocatedLinks({ type: "wifi_links_info" }); + const { + locatedNewLinks: newLinks, + locatedLinks, + locatedLinksReference, + linksLoaded, + } = useLocatedLinks({ type: "wifi_links_info" }); return (
@@ -54,14 +56,19 @@ export const WifiLinksLayer = () => { links={locatedLinks} linksReference={locatedLinksReference} linksLoaded={linksLoaded} + newLinks={newLinks} />
); }; export const BatmanLinksLayer = () => { - const { locatedLinks, locatedLinksReference, linksLoaded } = - useLocatedLinks({ type: "bat_links_info" }); + const { + locatedNewLinks: newLinks, + locatedLinks, + locatedLinksReference, + linksLoaded, + } = useLocatedLinks({ type: "bat_links_info" }); return (
@@ -69,6 +76,7 @@ export const BatmanLinksLayer = () => { links={locatedLinks} linksReference={locatedLinksReference} linksLoaded={linksLoaded} + newLinks={newLinks} />
); diff --git a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx index 10a42406e..0c6250396 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer.tsx @@ -2,22 +2,15 @@ import NodeMarker from "plugins/lime-plugin-mesh-wide/src/components/Map/NodeMar import { useNodes } from "plugins/lime-plugin-mesh-wide/src/hooks/useNodes"; import { INodeInfo } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; -import { isEmpty } from "utils/utils"; - const NodesLayer = () => { const { locatedNodes: { - locatedNodesReference: meshWideNodesReference, + locatedNodesReference: referenceNodes, locatedNodesActual: meshWideNodesActual, + locatedNewNodes, }, } = useNodes(); - // If reference is not set or empty, use actual nodes - const referenceNodes = - !meshWideNodesReference || isEmpty(meshWideNodesReference) - ? meshWideNodesActual - : meshWideNodesReference; - return (
{referenceNodes && @@ -35,6 +28,10 @@ const NodesLayer = () => { /> ); })} + {locatedNewNodes && + Object.entries(locatedNewNodes).map(([k, v], i) => { + return ; + })}
); }; diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx index d769032cf..9f4253ea9 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx @@ -51,6 +51,7 @@ interface IUselocatedLinks { linksErrors: ILinkErrors | undefined; locatedLinks: LocatedLinkData; linksLoaded: boolean; + locatedNewLinks: LocatedLinkData; } export const useLocatedLinks = ({ type, @@ -63,36 +64,24 @@ export const useLocatedLinks = ({ const { data: linksReference } = fetchDataReference({}); const { data: links } = fetchData({}); const { - locatedNodes: { locatedNodesReference, locatedNodesActual }, + locatedNodes: { allLocatedNodes: meshWideNodes }, } = useNodes(); - // If reference is not set or empty, use actual nodes - let meshWideNodesReference = {}; - if (locatedNodesReference && !isEmpty(locatedNodesReference)) { - meshWideNodesReference = locatedNodesReference; - } else if (locatedNodesActual && !isEmpty(locatedNodesActual)) { - meshWideNodesReference = locatedNodesActual; - } - const locatedLinksReference: LocatedLinkData = useMemo(() => { - if (meshWideNodesReference && linksReference) { + if (meshWideNodes && linksReference) { return mergeLinksAndCoordinates( - meshWideNodesReference, + meshWideNodes, linksReference, type ); } - }, [meshWideNodesReference, linksReference, type]); + }, [meshWideNodes, linksReference, type]); const locatedLinks: LocatedLinkData = useMemo(() => { - if (links && meshWideNodesReference) { - return mergeLinksAndCoordinates( - meshWideNodesReference, - links, - type - ); + if (links && meshWideNodes) { + return mergeLinksAndCoordinates(meshWideNodes, links, type); } - }, [links, meshWideNodesReference, type]); + }, [links, meshWideNodes, type]); const linksLoaded = !!locatedLinksReference && !!locatedLinks; @@ -118,11 +107,23 @@ export const useLocatedLinks = ({ } }, [locatedLinksReference, locatedLinks]); + // This links are valid and not exists on the reference state + let locatedNewLinks: LocatedLinkData = {}; + if (locatedLinks) { + locatedNewLinks = Object.keys(locatedLinks).reduce((obj, key) => { + if (!locatedLinksReference || !locatedLinksReference[key]) { + obj[key] = locatedLinks[key]; + } + return obj; + }, {} as LocatedLinkData); + } + return { locatedLinks, locatedLinksReference, linksLoaded, linksErrors, + locatedNewLinks, } as IUselocatedLinks; }; diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx index 31779197e..1a516920c 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx @@ -63,12 +63,33 @@ export const useNodes = () => { Object.keys(invalidNodesReference).length > 0) || (invalidNodesActual && Object.keys(invalidNodesActual).length > 0); + // This nodes are valid and not exists on the reference state + let locatedNewNodes: INodes = {}; + if (locatedNodesActual) { + locatedNewNodes = Object.keys(locatedNodesActual).reduce((obj, key) => { + if (!meshWideNodesReference || !meshWideNodesReference[key]) { + obj[key] = locatedNodesActual[key]; + } + return obj; + }, {} as INodes); + } + + // Used to have on an a single list all the located nodes + // This is used to have an easier way to draw links between nodes + // that are not active, or not on reference or new + const allLocatedNodes = { + ...locatedNodesReference, + ...locatedNodesActual, + ...locatedNewNodes, + }; + return { hasInvalidNodes, allNodes: { meshWideNodesReference, meshWideNodesActual, }, + // Invalid nodes doesn't contain a correct lat long invalidNodes: { invalidNodesReference, invalidNodesActual, @@ -76,6 +97,8 @@ export const useNodes = () => { locatedNodes: { locatedNodesReference, locatedNodesActual, + allLocatedNodes, + locatedNewNodes, // New nodes (not on the ref state) }, }; }; diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useSingleNodeErrors.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useSingleNodeErrors.tsx index 42392db68..6b9b8df6b 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useSingleNodeErrors.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useSingleNodeErrors.tsx @@ -11,9 +11,10 @@ export const useSingleNodeErrors = ({ actual: INodeInfo; reference: INodeInfo; }) => { + const isNewNode = !reference; const errors = processNodeErrors(reference, actual); const isDown = errors.includes(NodeErrorCodes.NODE_DOWN); const hasErrors = errors.length > 0; - return { errors, hasErrors, isDown }; + return { errors, hasErrors, isDown, isNewNode }; }; diff --git a/plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts b/plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts index 63b49e5ab..84dd32e6a 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts @@ -11,6 +11,9 @@ export const processNodeErrors = ( // todo(kon): use community settings and not limeapp defaults // const { data: communitySettings } = useCommunitySettings(); + // If not reference is a new node + if (!reference) return errors; + if (!actual) return [NodeErrorCodes.NODE_DOWN]; // Check mac list are equal From 1bb3c9fc866e99d7aa455edbd102fae86421933e Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 25 Apr 2024 09:19:06 +0200 Subject: [PATCH 114/121] chore(meshwide): Prevent undefined link destination nodes --- .../src/lib/links/getLinksCoordinates.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts index ad2158712..cf62f5918 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts @@ -35,6 +35,10 @@ export const mergeLinksAndCoordinates = ( ); }); + // Is possible that the destination node is not on the list of links, + // just ignore it + if (!dstNodeName) continue; + if ( dstNodeName && dstNodeName !== linkNodeName && @@ -64,6 +68,8 @@ export const mergeLinksAndCoordinates = ( continue; } + console.log("AAAAAA", dstNodeName, links[dstNodeName], links); + // Get the destination link info const destPointData = ( links[dstNodeName] as Array From c224da46f2640c067d3c53f25dfa542dc5f1a30e Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 25 Apr 2024 09:24:48 +0200 Subject: [PATCH 115/121] chore(meshwide): disable power button and floating button To implement on the future --- .../src/components/FeatureDetail/LinkDetail.tsx | 5 ----- .../src/components/FeatureDetail/NodeDetail.tsx | 10 ++++------ plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx | 4 +--- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx index 83b497185..c79adf5a9 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx @@ -1,7 +1,6 @@ import { Trans } from "@lingui/macro"; import { useState } from "preact/hooks"; -import { Button } from "components/buttons/button"; import Tabs from "components/tabs"; import { StatusAndButton } from "plugins/lime-plugin-mesh-wide/src/components/Components"; @@ -11,7 +10,6 @@ import { usePointToPointErrors, } from "plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks"; import ErrorIcon from "plugins/lime-plugin-mesh-wide/src/icons/errorIcon"; -import { PowerIcon } from "plugins/lime-plugin-mesh-wide/src/icons/power"; import { MacToMacLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; import { readableBytes } from "plugins/lime-plugin-mesh-wide/src/lib/utils"; import { @@ -142,9 +140,6 @@ const SelectedLink = ({
)} - {names.map((name, i) => { const node = linkDetail.linkByName(name); diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx index f87d43607..b3f7913a5 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx @@ -1,7 +1,5 @@ import { Trans } from "@lingui/macro"; -import { Button } from "components/buttons/button"; - import { StatusAndButton } from "plugins/lime-plugin-mesh-wide/src/components/Components"; import { useSetReferenceState } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/SetReferenceStateBtn"; import { @@ -9,7 +7,6 @@ import { TitleAndText, } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index"; import { useSingleNodeErrors } from "plugins/lime-plugin-mesh-wide/src/hooks/useSingleNodeErrors"; -import { PowerIcon } from "plugins/lime-plugin-mesh-wide/src/icons/power"; import { getArrayDifference } from "plugins/lime-plugin-mesh-wide/src/lib/utils"; import { useMeshWideNodesReference } from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; import { @@ -42,9 +39,10 @@ const NodeDetails = ({ actual, reference, name }: NodeMapFeature) => {
{name}
- + {/*todo(kon): implement safe_reboot*/} + {/**/}
{!isDown ? ( diff --git a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx index c271398ca..9a1e44e20 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx @@ -1,8 +1,6 @@ import { Trans } from "@lingui/macro"; -import { route } from "preact-router"; import React from "react"; -import FloatingButton from "components/buttons/floatting-button"; import Loading from "components/loading"; import { useLoadLeaflet } from "plugins/lime-plugin-locate/src/locateQueries"; @@ -42,7 +40,7 @@ const MeshWidePage = () => { - route("/meshwide/config")} /> + {/* route("/meshwide/config")} />*/} ); }; From 596d13785b82ee0c121cf8dea394d55fcbaf334b Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 26 Apr 2024 09:14:49 +0200 Subject: [PATCH 116/121] chore(meshwide): fix some todos --- .../components/FeatureDetail/NodeDetail.tsx | 4 +-- .../src/containers/Map.spec.tsx | 27 ++++++++++--------- .../src/lib/links/getLinksCoordinates.ts | 4 +-- .../src/lib/nodes/processErrors.ts | 2 -- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx index b3f7913a5..c91800e61 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx @@ -50,8 +50,8 @@ const NodeDetails = ({ actual, reference, name }: NodeMapFeature) => { {uptime.toString()} ) : ( - Downtime}> - todo + Uptime}> + The node is down )} Firmware version}> diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map.spec.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map.spec.tsx index 226ceaddd..abba9ca14 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/Map.spec.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map.spec.tsx @@ -1,25 +1,26 @@ import "@testing-library/jest-dom"; +import "@testing-library/jest-dom/extend-expect"; +import { screen } from "@testing-library/preact"; -// import "@testing-library/jest-dom/extend-expect"; -// import { -// getMeshWideNodes, -// getMeshWideNodesReference, -// } from "plugins/lime-plugin-mesh-wide/src/meshWideApi"; +import { MeshWideMap } from "plugins/lime-plugin-mesh-wide/src/containers/Map"; +import { doSharedStateApiCall } from "plugins/lime-plugin-mesh-wide/src/meshWideApi"; +import { nodesReferenceState } from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; -jest.mock("plugins/lime-plugin-mesh-wide/src/mesWideApi.ts"); +import { render } from "utils/test_utils"; + +jest.mock("plugins/lime-plugin-mesh-wide/src/meshWideApi.ts"); jest.mock("leaflet"); -// const mockedMeshWideNodes = jest.mocked(getMeshWideNodes); -// const mockedMeshWideNodesReference = jest.mocked(getMeshWideNodesReference); + +const mockedDoSharedStateApiCall = jest.mocked(doSharedStateApiCall); describe("Map component", () => { it("should show nodes alert when a node has not configured properly the coordinates", async () => { - nodesReferenceState["primero"].data.coordinates = { - lon: "FIXME", + nodesReferenceState["primero"].coordinates = { + long: "FIXME", lat: "FIXME", }; - mockedMeshWideNodesReference.mockReturnValue(nodesReferenceState); - mockedMeshWideNodesReference.mockReturnValue(nodesReferenceState); - + // mockedDoSharedStateApiCall.mockResolvedValue(nodesReferenceState); + mockedDoSharedStateApiCall.mockResolvedValue(nodesReferenceState); render( ); diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts index cf62f5918..57f76ec89 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts @@ -25,7 +25,7 @@ export const mergeLinksAndCoordinates = ( // for every node check all links for (const linkNodeName in links) { if (isEmpty(links[linkNodeName])) continue; - for (const linkData of links[linkNodeName]) { + for (const linkData of Object.values(links[linkNodeName])) { if (!linkData.dst_mac) continue; // Get the nodeName of the destination node const dstNodeName = Object.keys(nodes).find((pid) => { @@ -68,8 +68,6 @@ export const mergeLinksAndCoordinates = ( continue; } - console.log("AAAAAA", dstNodeName, links[dstNodeName], links); - // Get the destination link info const destPointData = ( links[dstNodeName] as Array diff --git a/plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts b/plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts index 84dd32e6a..8c562143f 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/nodes/processErrors.ts @@ -8,8 +8,6 @@ export const processNodeErrors = ( actual: INodeInfo | undefined ) => { const errors: NodeErrorCodes[] = []; - // todo(kon): use community settings and not limeapp defaults - // const { data: communitySettings } = useCommunitySettings(); // If not reference is a new node if (!reference) return errors; From 8d1a0fd8132e05d71bdc40305bf90b286fa99b87 Mon Sep 17 00:00:00 2001 From: selankon Date: Sun, 5 May 2024 16:48:28 +0200 Subject: [PATCH 117/121] chore(meshwide): add refetch interval --- plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx index 9bae765aa..62b6887d2 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx @@ -14,6 +14,8 @@ import { import { useSharedData } from "utils/useSharedData"; +const refetchInterval = 5000; + export function useMeshWideLinksReference(params) { const dataType: DataTypes = "wifi_links_info"; const queryKey = @@ -22,6 +24,7 @@ export function useMeshWideLinksReference(params) { queryKey, () => doSharedStateApiCall(queryKey), { + refetchInterval, ...params, } ); @@ -34,6 +37,7 @@ export function useMeshWideLinks(params) { queryKey, () => doSharedStateApiCall(queryKey), { + refetchInterval, ...params, } ); @@ -47,6 +51,7 @@ export function useMeshWideBatmanReference(params) { queryKey, () => doSharedStateApiCall(queryKey), { + refetchInterval, ...params, } ); @@ -59,6 +64,7 @@ export function useMeshWideBatman(params) { queryKey, () => doSharedStateApiCall(queryKey), { + refetchInterval, ...params, } ); @@ -72,6 +78,7 @@ export function useMeshWideNodesReference(params) { queryKey, () => doSharedStateApiCall(queryKey), { + refetchInterval, ...params, } ); @@ -84,6 +91,7 @@ export function useMeshWideNodes(params) { queryKey, () => doSharedStateApiCall(queryKey), { + refetchInterval, ...params, } ); From 884ffc1beb74267ff68b816f2102e6cab3d010fb Mon Sep 17 00:00:00 2001 From: selankon Date: Mon, 6 May 2024 21:13:30 +0200 Subject: [PATCH 118/121] chore(meshwide): implement provider --- .../src/hooks/useNodes.tsx | 80 ++++++++++++++----- .../src/meshWidePage.tsx | 11 ++- 2 files changed, 70 insertions(+), 21 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx index 1a516920c..f1e07659b 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useNodes.tsx @@ -1,4 +1,6 @@ +import { ComponentChildren, createContext } from "preact"; import { useMemo } from "preact/compat"; +import { useContext } from "preact/hooks"; import { isValidCoordinate } from "plugins/lime-plugin-mesh-wide/src/lib/utils"; import { @@ -7,8 +9,31 @@ import { } from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; import { INodes } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; -// todo(kon): this should be inside a provider to don't repeat the calculations -export const useNodes = () => { +interface NodesContextType { + hasInvalidNodes: boolean; + allNodes: { + meshWideNodesReference: INodes; + meshWideNodesActual: INodes; + }; + invalidNodes: { + invalidNodesReference: INodes; + invalidNodesActual: INodes; + }; + locatedNodes: { + locatedNodesReference: INodes; + locatedNodesActual: INodes; + allLocatedNodes: INodes; + locatedNewNodes: INodes; + }; +} + +const NodesContext = createContext(null); + +export const NodesProvider = ({ + children, +}: { + children: ComponentChildren; +}) => { const { data: meshWideNodesReference } = useMeshWideNodesReference({}); const { data: meshWideNodesActual } = useMeshWideNodes({}); @@ -83,22 +108,37 @@ export const useNodes = () => { ...locatedNewNodes, }; - return { - hasInvalidNodes, - allNodes: { - meshWideNodesReference, - meshWideNodesActual, - }, - // Invalid nodes doesn't contain a correct lat long - invalidNodes: { - invalidNodesReference, - invalidNodesActual, - }, - locatedNodes: { - locatedNodesReference, - locatedNodesActual, - allLocatedNodes, - locatedNewNodes, // New nodes (not on the ref state) - }, - }; + return ( + + {children} + + ); +}; + +// Helper hook to use the context +export const useNodes = () => { + const context = useContext(NodesContext); + if (context === null) { + throw new Error("useNodesContext must be used within a NodesProvider"); + } + return context; }; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx index 9a1e44e20..f9d8e9e3d 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx @@ -7,8 +7,9 @@ import { useLoadLeaflet } from "plugins/lime-plugin-locate/src/locateQueries"; import { FloatingAlert } from "plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert"; import { MeshWideMap } from "plugins/lime-plugin-mesh-wide/src/containers/Map"; import { SelectedFeatureBottomSheet } from "plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet"; +import { NodesProvider } from "plugins/lime-plugin-mesh-wide/src/hooks/useNodes"; -const MeshWidePage = () => { +const MeshWide = () => { const { isError: isAssetError, isFetchedAfterMount: assetsLoaded, @@ -45,4 +46,12 @@ const MeshWidePage = () => { ); }; +const MeshWidePage = () => { + return ( + + + + ); +}; + export default MeshWidePage; From 7f43ba63fa8a8a60db725832a63d8df80cb59e12 Mon Sep 17 00:00:00 2001 From: selankon Date: Mon, 6 May 2024 23:26:20 +0200 Subject: [PATCH 119/121] chore(meshwide): implement different providers by link type --- .../src/hooks/useLocatedLinks.tsx | 54 ++++++++++++++++++- .../src/meshWidePage.tsx | 10 +++- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx index 9f4253ea9..d0168821d 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx @@ -1,5 +1,7 @@ import { UseQueryResult } from "@tanstack/react-query"; +import { createContext } from "preact"; import { useMemo } from "preact/compat"; +import { useContext } from "preact/hooks"; import { useNodes } from "plugins/lime-plugin-mesh-wide/src/hooks/useNodes"; import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; @@ -23,7 +25,6 @@ import { import { isEmpty } from "utils/utils"; interface getQueryByLinkTypeReturnType { - // state: (params) => UseQueryResult>; state: (params) => UseQueryResult>; reference: (params) => UseQueryResult>; } @@ -53,7 +54,12 @@ interface IUselocatedLinks { linksLoaded: boolean; locatedNewLinks: LocatedLinkData; } -export const useLocatedLinks = ({ + +/** + * Util hook to get located links and compare them with the reference links + * @param type + */ +const useCalculateLocatedLinks = ({ type, }: { type: LinkType; @@ -137,3 +143,47 @@ export const usePointToPointErrors = ({ const { linksErrors } = useLocatedLinks({ type }); return { errors: linksErrors && linksErrors[id] }; }; + +// Define separate contexts for each type of link +const BatmanLinksContext = createContext(null); +const MeshWideLinksContext = createContext(null); + +// Export a hook that return the proper context based on the type of link +export const useLocatedLinks = ({ type }: { type: LinkType }) => { + let requestedContext = MeshWideLinksContext; + if (type === "bat_links_info") { + requestedContext = BatmanLinksContext; + } + + const context = useContext(requestedContext); + if (context === null) { + throw new Error( + `useLocatedLinks must be used within a provider for ${requestedContext} links` + ); + } + return context; +}; + +export const BatmanLinksProvider = ({ children }) => { + const batmanLinksData = useCalculateLocatedLinks({ + type: "bat_links_info", + }); + + return ( + + {children} + + ); +}; + +export const MeshWideLinksProvider = ({ children }) => { + const meshWideLinksData = useCalculateLocatedLinks({ + type: "wifi_links_info", + }); + + return ( + + {children} + + ); +}; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx index f9d8e9e3d..45f0ab488 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx @@ -7,6 +7,10 @@ import { useLoadLeaflet } from "plugins/lime-plugin-locate/src/locateQueries"; import { FloatingAlert } from "plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert"; import { MeshWideMap } from "plugins/lime-plugin-mesh-wide/src/containers/Map"; import { SelectedFeatureBottomSheet } from "plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet"; +import { + BatmanLinksProvider, + MeshWideLinksProvider, +} from "plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks"; import { NodesProvider } from "plugins/lime-plugin-mesh-wide/src/hooks/useNodes"; const MeshWide = () => { @@ -49,7 +53,11 @@ const MeshWide = () => { const MeshWidePage = () => { return ( - + + + + + ); }; From 1ae958524c6647d3212f7efe45f957886cf04d22 Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 7 May 2024 10:11:29 +0200 Subject: [PATCH 120/121] chore(meshwide): multiple fixes --- .../components/FeatureDetail/LinkDetail.tsx | 40 +++++++------- .../components/FeatureDetail/NodeDetail.tsx | 3 +- .../src/components/FeatureDetail/index.tsx | 2 - .../src/components/Map/FloatingAlert.tsx | 1 + .../components/configPage/ConfigSection.tsx | 28 ++++------ .../src/components/configPage/MeshStatus.tsx | 9 ++-- .../src/components/configPage/OptionForm.tsx | 15 ++---- .../src/containers/MapLayers/LinksLayers.tsx | 4 +- .../src/containers/MapLayers/NodesLayer.tsx | 4 +- .../SelectedFeatureBottomSheet.spec.tsx | 54 +++++++++---------- .../containers/SelectedFeatureBottomSheet.tsx | 6 ++- .../src/hooks/useNodes.tsx | 1 - .../src/meshWideMocks.tsx | 2 - src/components/app.tsx | 5 +- src/components/bottom-sheet/BottomSheet.tsx | 1 - 15 files changed, 78 insertions(+), 97 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx index c79adf5a9..f9c15ef42 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx @@ -193,31 +193,27 @@ const LinkFeatureDetail = ({ actual, reference }: LinkMapFeature) => { ); return ( - <> -
- {tabs?.length > 1 && ( - - )} - {selectedLink !== null && ( - - )} -
- +
+ {tabs?.length > 1 && ( + + )} + {selectedLink !== null && ( + + )} +
); }; -export const LinkReferenceStatus = ({ actual, reference }: LinkMapFeature) => { +export const LinkReferenceStatus = ({ reference }: LinkMapFeature) => { const isNewNode = !reference; const { errors } = usePointToPointErrors({ diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx index c91800e61..25ab29ec3 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx @@ -25,7 +25,7 @@ const NodeDetails = ({ actual, reference, name }: NodeMapFeature) => { const ipv6 = nodeToShow.ipv6; const ipv4 = nodeToShow.ipv4; const device = nodeToShow.device; - const { errors, isDown, isNewNode } = useSingleNodeErrors({ + const { errors, isDown } = useSingleNodeErrors({ actual, reference, }); @@ -98,7 +98,6 @@ const NodeDetails = ({ actual, reference, name }: NodeMapFeature) => { export const NodeReferenceStatus = ({ actual, reference }: NodeMapFeature) => { const { - errors, hasErrors: hasNodeErrors, isDown, isNewNode, diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx index f0ed5c3b4..5171e52ed 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index.tsx @@ -52,8 +52,6 @@ export const FeatureDetail = ({ return ; case "errorsDetails": return ; - default: - return <>; } }; diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx index 0f3748a87..30600437b 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert.tsx @@ -43,6 +43,7 @@ export const FloatingAlert = () => { invalidNodesActual, invalidNodesReference, meshWideDataErrors, + selectedMapFeature, setSelectedFeature, ]); diff --git a/plugins/lime-plugin-mesh-wide/src/components/configPage/ConfigSection.tsx b/plugins/lime-plugin-mesh-wide/src/components/configPage/ConfigSection.tsx index 6c922b13b..666090429 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/configPage/ConfigSection.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/configPage/ConfigSection.tsx @@ -33,7 +33,7 @@ export const SectionEditOrDelete = ({ name }) => { const { toggleModal: toggleEditModal, actionModal: editPropertyModal } = useEditPropModal(); - const { showToast, hideToast } = useToast(); + const { showToast } = useToast(); return ( { toggleEditModal(); showToast({ text: ( - <> - Edited - {name} - {" - "} - {new Date().toDateString()} - + + Edited {name} - {new Date().toDateString()} + ), duration: 5000, onAction: () => { @@ -65,11 +62,9 @@ export const SectionEditOrDelete = ({ name }) => { toggleDeleteModal(); showToast({ text: ( - <> - Deleted {name} - {" - "} - {new Date().toDateString()} - + + Deleted {name} - {new Date().toDateString()} + ), duration: 5000, onAction: () => { @@ -86,7 +81,7 @@ export const AddNewSectionBtn = () => { const { toggleModal: toggleNewSectionModal, actionModal: addSectionModal } = useAddNewSectionModal(); - const { showToast, hideToast } = useToast(); + const { showToast } = useToast(); return (