From 62c2d61e6bedaa2452c84d6df31e42489d7b7f91 Mon Sep 17 00:00:00 2001 From: Arnaud Marant Date: Tue, 30 Jun 2026 10:19:23 +0200 Subject: [PATCH 01/12] Add browser tests and utility functions for network map layers - Implemented tests for ArrowLayer, ForkLineLayer, ParallelPathLayer, ScatterplotLayerExt, and LineLayer. - Added screenshot comparison functionality for visual regression testing. - Created utility functions for rendering layers and setting up test environments. - Introduced network and geo data creation functions for testing purposes. - Added browser setup entrypoint for package-level shared initialization. - Updated App.tsx to utilize large network and geo data for testing. - Added new test cases for arrow, fork, parallel path, and scatterplot layers to handle large network scenarios. - Introduced large network and geo data creation functions in network-fixtures.ts. - Adjusted browser rendering setup to accommodate larger viewport sizes. - Enhanced logging for current view state in network-map.tsx. - Updated Vitest configuration for increased viewport dimensions in tests. - Updated @deck.gl and @luma.gl dependencies to 9.3.0 versions in package.json and network-map-layers/package.json. Signed-off-by: Arnaud Marant --- .gitignore | 1 + README.md | 7 + demo/src/App.tsx | 27 +- eslint.config.js | 4 +- package-lock.json | 1832 +++++++++-------- package.json | 20 +- packages/network-map-layers/package.json | 18 +- .../network-map-layers/src/equipment-types.ts | 7 +- .../line-layer-basic-chromium-linux.png | Bin 0 -> 4537 bytes ...ine-layer-large-network-chromium-linux.png | Bin 0 -> 46917 bytes .../src/network/arrow-direction.ts | 12 + .../src/network/geo-data.ts | 2 +- .../arrow-layer-basic-chromium-linux.png | Bin 0 -> 3323 bytes ...row-layer-large-network-chromium-linux.png | Bin 0 -> 3545 bytes .../fork-line-layer-basic-chromium-linux.png | Bin 0 -> 3469 bytes ...ine-layer-large-network-chromium-linux.png | Bin 0 -> 8026 bytes ...rallel-path-layer-basic-chromium-linux.png | Bin 0 -> 3585 bytes ...ath-layer-large-network-chromium-linux.png | Bin 0 -> 23656 bytes ...terplot-layer-ext-basic-chromium-linux.png | Bin 0 -> 3872 bytes ...layer-ext-large-network-chromium-linux.png | Bin 0 -> 3468 bytes .../layers/arrow-layer.browser.test.ts | 69 + .../src/network/layers/arrow-layer.test.ts | 69 + .../src/network/layers/arrow-layer.ts | 14 +- .../layers/fork-line-layer.browser.test.ts | 102 + .../parallel-path-layer.browser.test.ts | 68 + .../scatterplot-layer-ext.browser.test.ts | 62 + .../src/network/line-layer.browser.test.ts | 74 + .../src/network/line-layer.test.ts | 60 + .../src/network/line-layer.ts | 11 +- .../src/testUtils/browser-render.ts | 89 + .../src/testUtils/network-fixtures.ts | 563 +++++ setupTests.ts | 41 + .../network/network-map.tsx | 1 + vitest.config.ts | 31 +- 34 files changed, 2260 insertions(+), 924 deletions(-) create mode 100644 packages/network-map-layers/src/network/__screenshots__/line-layer.browser.test.ts/line-layer-basic-chromium-linux.png create mode 100644 packages/network-map-layers/src/network/__screenshots__/line-layer.browser.test.ts/line-layer-large-network-chromium-linux.png create mode 100644 packages/network-map-layers/src/network/arrow-direction.ts create mode 100644 packages/network-map-layers/src/network/layers/__screenshots__/arrow-layer.browser.test.ts/arrow-layer-basic-chromium-linux.png create mode 100644 packages/network-map-layers/src/network/layers/__screenshots__/arrow-layer.browser.test.ts/arrow-layer-large-network-chromium-linux.png create mode 100644 packages/network-map-layers/src/network/layers/__screenshots__/fork-line-layer.browser.test.ts/fork-line-layer-basic-chromium-linux.png create mode 100644 packages/network-map-layers/src/network/layers/__screenshots__/fork-line-layer.browser.test.ts/fork-line-layer-large-network-chromium-linux.png create mode 100644 packages/network-map-layers/src/network/layers/__screenshots__/parallel-path-layer.browser.test.ts/parallel-path-layer-basic-chromium-linux.png create mode 100644 packages/network-map-layers/src/network/layers/__screenshots__/parallel-path-layer.browser.test.ts/parallel-path-layer-large-network-chromium-linux.png create mode 100644 packages/network-map-layers/src/network/layers/__screenshots__/scatterplot-layer-ext.browser.test.ts/scatterplot-layer-ext-basic-chromium-linux.png create mode 100644 packages/network-map-layers/src/network/layers/__screenshots__/scatterplot-layer-ext.browser.test.ts/scatterplot-layer-ext-large-network-chromium-linux.png create mode 100644 packages/network-map-layers/src/network/layers/arrow-layer.browser.test.ts create mode 100644 packages/network-map-layers/src/network/layers/arrow-layer.test.ts create mode 100644 packages/network-map-layers/src/network/layers/fork-line-layer.browser.test.ts create mode 100644 packages/network-map-layers/src/network/layers/parallel-path-layer.browser.test.ts create mode 100644 packages/network-map-layers/src/network/layers/scatterplot-layer-ext.browser.test.ts create mode 100644 packages/network-map-layers/src/network/line-layer.browser.test.ts create mode 100644 packages/network-map-layers/src/network/line-layer.test.ts create mode 100644 packages/network-map-layers/src/testUtils/browser-render.ts create mode 100644 packages/network-map-layers/src/testUtils/network-fixtures.ts diff --git a/.gitignore b/.gitignore index 05b8f8bb..b942b36b 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ # Vitest /coverage +.vitest-attachments diff --git a/README.md b/README.md index 0e28b28c..6db41ba1 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,13 @@ To fix this, run this command from the app **after** running "npm install" (Optional) [Test your package from library dependent directory](https://docs.npmjs.com/creating-and-publishing-scoped-public-packages#testing-your-package) +## Testing + +- Full test suite: `npm run test` +- Unit tests (fast): `npm run test:unit` +- Browser visual screenshots (Vitest browser mode): `npm run test:browser` +- Update screenshot baselines: `npm run test:browser -- -u` + According to PowSyBl [branching and release strategy](https://github.com/powsybl/.github/blob/main/BRANCHING_RELEASE_STRATEGY.md), if you want to publish a new release of powsybl-network-viewer in the [NPM package registry](https://www.npmjs.com/package/@powsybl/powsybl-network-viewer), you need to follow the steps below: diff --git a/demo/src/App.tsx b/demo/src/App.tsx index aaf47d3e..02f8a8aa 100644 --- a/demo/src/App.tsx +++ b/demo/src/App.tsx @@ -6,16 +6,19 @@ * SPDX-License-Identifier: MPL-2.0 */ -import { useEffect, useRef } from 'react'; import { createTheme, StyledEngineProvider, ThemeProvider } from '@mui/material/styles'; +import { useEffect, useRef } from 'react'; import { IntlProvider } from 'react-intl'; import { DEFAULT_INTL_CONFIG } from 'react-intl/src/utils'; -import { GeoData, type MapEquipment, MapEquipments, NetworkMap, type NetworkMapRef } from '../../src'; +import { type MapEquipment, NetworkMap, type NetworkMapRef } from '../../src'; + +import { + createLargeGeoData, + createLargeNetwork, +} from '../../packages/network-map-layers/src/testUtils/network-fixtures'; -import sposdata from './map-viewer/data/spos.json'; -import lposdata from './map-viewer/data/lpos.json'; -import smapdata from './map-viewer/data/smap.json'; -import lmapdata from './map-viewer/data/lmap.json'; +const largeNetwork = createLargeNetwork(); +const largeGeoData = createLargeGeoData(); // Called after a click (right mouse click) on some equipment (line or substation) function showEquipmentMenu(equipment: MapEquipment, x: number, y: number, type: string) { @@ -35,13 +38,9 @@ export default function App() { }); //declare data to be displayed: coordinates and network data - const geoData = new GeoData(new Map(), new Map()); - geoData.setSubstationPositions(sposdata); - geoData.setLinePositions(lposdata); + const geoData = largeGeoData; - const mapEquipments = new MapEquipments(); - mapEquipments.updateSubstations(smapdata, true); - mapEquipments.updateLines(lmapdata, true); + const mapEquipments = largeNetwork; useEffect(() => { const handleContextmenu = (e: MouseEvent) => { @@ -54,7 +53,6 @@ export default function App() { }, []); const networkMapRef = useRef(null); - const filteredNominalVoltages = [380.0, 225.0, 110.0]; return (
@@ -99,8 +97,7 @@ export default function App() { ); }} mapLibrary={'cartonolabel'} - mapTheme={'dark'} - filteredNominalVoltages={filteredNominalVoltages} + mapTheme={'light'} onDrawPolygonModeActive={(active) => { console.log('polygon drawing mode active: ', active ? 'active' : 'inactive'); }} diff --git a/eslint.config.js b/eslint.config.js index 6303caa0..4d989654 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -58,7 +58,9 @@ export default defineConfig([ extends: tsEslint.configs.recommendedTypeChecked, languageOptions: { parserOptions: { - projectService: true, + projectService: { + allowDefaultProject: ['./setupBrowserTests.ts'], + }, tsconfigRootDir: import.meta.dirname, }, }, diff --git a/package-lock.json b/package-lock.json index 9a528bb1..4a3b53b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,13 +12,13 @@ "packages/*" ], "dependencies": { - "@deck.gl/core": "~9.2.0", - "@deck.gl/extensions": "~9.2.0", - "@deck.gl/layers": "~9.2.0", - "@deck.gl/mapbox": "~9.2.0", - "@luma.gl/constants": "~9.2.0", - "@luma.gl/core": "~9.2.0", - "@luma.gl/engine": "~9.2.0", + "@deck.gl/core": "~9.3.0", + "@deck.gl/extensions": "~9.3.0", + "@deck.gl/layers": "~9.3.0", + "@deck.gl/mapbox": "~9.3.0", + "@luma.gl/constants": "~9.3.0", + "@luma.gl/core": "~9.3.0", + "@luma.gl/engine": "~9.3.0", "@mapbox/mapbox-gl-draw": "<1.5.0", "@powsybl/network-map-layers": "^3.6.0-dev.0", "@powsybl/network-viewer-core": "^3.6.0-dev.0", @@ -39,8 +39,10 @@ "@types/react": "^19.2.2", "@types/react-dom": "^19.2.1", "@vitejs/plugin-react": "^5.0.4", + "@vitest/browser-playwright": "^4.0.18", "@vitest/coverage-v8": "^4.0.18", "@vitest/eslint-plugin": "^1.6.7", + "@vitest/ui": "^4.0.18", "eslint": "^9.26.0", "eslint-config-prettier": "^10.1.2", "eslint-plugin-prettier": "^5.2.6", @@ -98,7 +100,7 @@ "node": ">=18" } }, - "node_modules/@arethetypeswrong/core": { + "node_modules/@arethetypeswrong/cli/node_modules/@arethetypeswrong/core": { "version": "0.17.4", "dev": true, "license": "MIT", @@ -116,7 +118,12 @@ "node": ">=18" } }, - "node_modules/@arethetypeswrong/core/node_modules/typescript": { + "node_modules/@arethetypeswrong/cli/node_modules/lru-cache": { + "version": "10.4.3", + "dev": true, + "license": "ISC" + }, + "node_modules/@arethetypeswrong/cli/node_modules/typescript": { "version": "5.6.1-rc", "dev": true, "license": "Apache-2.0", @@ -130,8 +137,6 @@ }, "node_modules/@asamuzakjp/css-color": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", - "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==", "dev": true, "license": "MIT", "dependencies": { @@ -142,6 +147,11 @@ "lru-cache": "^10.4.3" } }, + "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { + "version": "10.4.3", + "dev": true, + "license": "ISC" + }, "node_modules/@babel/code-frame": { "version": "7.29.0", "license": "MIT", @@ -408,6 +418,13 @@ "node": ">=6.9.0" } }, + "node_modules/@blazediff/core": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@blazediff/core/-/core-1.9.1.tgz", + "integrity": "sha512-ehg3jIkYKulZh+8om/O25vkvSsXXwC+skXmyA87FFx6A/45eqOkZsBltMw/TVteb0mloiGT8oGRTcjRAz66zaA==", + "dev": true, + "license": "MIT" + }, "node_modules/@braidai/lang": { "version": "1.1.2", "dev": true, @@ -444,8 +461,6 @@ }, "node_modules/@csstools/color-helpers": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", - "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", "dev": true, "funding": [ { @@ -464,8 +479,6 @@ }, "node_modules/@csstools/css-calc": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", - "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", "dev": true, "funding": [ { @@ -488,8 +501,6 @@ }, "node_modules/@csstools/css-color-parser": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", - "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", "dev": true, "funding": [ { @@ -516,8 +527,6 @@ }, "node_modules/@csstools/css-parser-algorithms": { "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", - "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", "dev": true, "funding": [ { @@ -539,8 +548,6 @@ }, "node_modules/@csstools/css-tokenizer": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", - "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", "dev": true, "funding": [ { @@ -558,18 +565,17 @@ } }, "node_modules/@deck.gl/core": { - "version": "9.2.10", - "resolved": "https://registry.npmjs.org/@deck.gl/core/-/core-9.2.10.tgz", - "integrity": "sha512-c3IYKNAeTKSkH0LPUBoAfYef0/aw32Uo7UorcH+FCG9n7iPZT8tg+yaGb7ylWYt5Rdx9Ah/ztnZxOVJ+jUT0Sg==", - "license": "MIT", - "dependencies": { - "@loaders.gl/core": "^4.3.4", - "@loaders.gl/images": "^4.3.4", - "@luma.gl/constants": "^9.2.6", - "@luma.gl/core": "^9.2.6", - "@luma.gl/engine": "^9.2.6", - "@luma.gl/shadertools": "^9.2.6", - "@luma.gl/webgl": "^9.2.6", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@deck.gl/core/-/core-9.3.0.tgz", + "integrity": "sha512-LYa9+I/isYaDD/6ASmyZUCkB/XJjWFKaWYfFTg7NVcrkB+UduHLkmxcM2DXQ3p8ek10fcSB+IWXHfaO8RHTMZg==", + "license": "MIT", + "dependencies": { + "@loaders.gl/core": "^4.4.1", + "@loaders.gl/images": "^4.4.1", + "@luma.gl/core": "^9.3.2", + "@luma.gl/engine": "^9.3.2", + "@luma.gl/shadertools": "^9.3.2", + "@luma.gl/webgl": "^9.3.2", "@math.gl/core": "^4.1.0", "@math.gl/sun": "^4.1.0", "@math.gl/types": "^4.1.0", @@ -582,52 +588,31 @@ "mjolnir.js": "^3.0.0" } }, - "node_modules/@deck.gl/core/node_modules/@probe.gl/env": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@probe.gl/env/-/env-4.1.1.tgz", - "integrity": "sha512-+68seNDMVsEegRB47pFA/Ws1Fjy8agcFYXxzorKToyPcD6zd+gZ5uhwoLd7TzsSw6Ydns//2KEszWn+EnNHTbA==", - "license": "MIT" - }, - "node_modules/@deck.gl/core/node_modules/@probe.gl/log": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@probe.gl/log/-/log-4.1.1.tgz", - "integrity": "sha512-kcZs9BT44pL7hS1OkRGKYRXI/SN9KejUlPD+BY40DguRLzdC5tLG/28WGMyfKdn/51GT4a0p+0P8xvDn1Ez+Kg==", - "license": "MIT", - "dependencies": { - "@probe.gl/env": "4.1.1" - } - }, - "node_modules/@deck.gl/core/node_modules/@probe.gl/stats": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@probe.gl/stats/-/stats-4.1.1.tgz", - "integrity": "sha512-4VpAyMHOqydSvPlEyHwXaE+AkIdR03nX+Qhlxsk2D/IW4OVmDZgIsvJB1cDzyEEtcfKcnaEbfXeiPgejBceT6g==", - "license": "MIT" - }, "node_modules/@deck.gl/extensions": { - "version": "9.2.10", - "resolved": "https://registry.npmjs.org/@deck.gl/extensions/-/extensions-9.2.10.tgz", - "integrity": "sha512-GMKmps67kX2d4nMbEZYDxGDZWmHDQJkFa9YbL/kSbTyt8OpFe9H5zTuqNog3l75F9Fyop/nq7bQYD2pKOUGPBg==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@deck.gl/extensions/-/extensions-9.3.0.tgz", + "integrity": "sha512-QhOPTQOq/OhMQ4wjElP8mLW5Lt2OjOajOXpThGLgk67tqCsd9yOOmXnlRO9jVV6r2/UBZ4j64m3MLxKYCFJgSw==", "license": "MIT", "dependencies": { - "@luma.gl/constants": "^9.2.6", - "@luma.gl/shadertools": "^9.2.6", + "@luma.gl/shadertools": "^9.3.2", + "@luma.gl/webgl": "^9.3.2", "@math.gl/core": "^4.1.0" }, "peerDependencies": { - "@deck.gl/core": "~9.2.0", - "@luma.gl/core": "~9.2.6", - "@luma.gl/engine": "~9.2.6" + "@deck.gl/core": "~9.3.0", + "@luma.gl/core": "~9.3.2", + "@luma.gl/engine": "~9.3.2" } }, "node_modules/@deck.gl/layers": { - "version": "9.2.10", - "resolved": "https://registry.npmjs.org/@deck.gl/layers/-/layers-9.2.10.tgz", - "integrity": "sha512-1emc+0Z+w6Vrmyp39Q+3R/HNbPcABH6kYXe6zTOOZYJX5M3pUssukFLW+Ds96/X9emF53vUC1Rnq9Aj/YY2lWg==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@deck.gl/layers/-/layers-9.3.0.tgz", + "integrity": "sha512-71F2zAB3zerL/q6if+RtzJGHj39wpakDR/ud56fmuAVPEAHsVrYlsjMthdLsvIPZKE1SPUhY0163/a61PYlhew==", "license": "MIT", "dependencies": { - "@loaders.gl/images": "^4.3.4", - "@loaders.gl/schema": "^4.3.4", - "@luma.gl/shadertools": "^9.2.6", + "@loaders.gl/images": "^4.4.1", + "@loaders.gl/schema": "^4.4.1", + "@luma.gl/shadertools": "^9.3.2", "@mapbox/tiny-sdf": "^2.0.5", "@math.gl/core": "^4.1.0", "@math.gl/polygon": "^4.1.0", @@ -635,28 +620,49 @@ "earcut": "^2.2.4" }, "peerDependencies": { - "@deck.gl/core": "~9.2.0", - "@loaders.gl/core": "^4.3.4", - "@luma.gl/core": "~9.2.6", - "@luma.gl/engine": "~9.2.6" + "@deck.gl/core": "~9.3.0", + "@loaders.gl/core": "^4.4.1", + "@luma.gl/core": "~9.3.2", + "@luma.gl/engine": "~9.3.2" } }, "node_modules/@deck.gl/mapbox": { - "version": "9.2.10", - "resolved": "https://registry.npmjs.org/@deck.gl/mapbox/-/mapbox-9.2.10.tgz", - "integrity": "sha512-6xyFv/SBjGyecxCYPmyDQc8XA+Ldj+/BpsT3Szk1QFNekgbvHA/4W62PzomMmoMAf4iwG80mWIqaq8wSzSlR0Q==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@deck.gl/mapbox/-/mapbox-9.3.0.tgz", + "integrity": "sha512-Kzf2mrxsr014UY3ozwt7HJziLe4kxeGaS051h53XnzOzbIAPpuXhh0w8MuMVUdVYOdvOCAqU/eHwZU+wVS9AYQ==", "license": "MIT", "dependencies": { - "@luma.gl/constants": "^9.2.6", "@math.gl/web-mercator": "^4.1.0" }, "peerDependencies": { - "@deck.gl/core": "~9.2.0", - "@luma.gl/constants": "~9.2.6", - "@luma.gl/core": "~9.2.6", + "@deck.gl/core": "~9.3.0", + "@luma.gl/core": "~9.3.2", "@math.gl/web-mercator": "^4.1.0" } }, + "node_modules/@deck.gl/test-utils": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@deck.gl/test-utils/-/test-utils-9.3.0.tgz", + "integrity": "sha512-Ex/wdf3oKBfRBaG0b7PY16cbNlmYoNhywaO4XA/bXZyZU25YjilNIEacc1NMSOlxrUBZkprYeMFB3i17FVm82g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@luma.gl/test-utils": "^9.3.2", + "@luma.gl/webgl": "^9.3.2" + }, + "peerDependencies": { + "@deck.gl/core": "~9.3.0", + "@luma.gl/core": "~9.3.2", + "@luma.gl/engine": "~9.3.2", + "@probe.gl/test-utils": "^4.1.1", + "vitest": "^4.0.18" + }, + "peerDependenciesMeta": { + "vitest": { + "optional": true + } + } + }, "node_modules/@emotion/babel-plugin": { "version": "11.13.5", "license": "MIT", @@ -677,8 +683,6 @@ }, "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "license": "MIT", "peer": true }, @@ -696,8 +700,6 @@ }, "node_modules/@emotion/hash": { "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", - "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", "license": "MIT", "peer": true }, @@ -711,8 +713,6 @@ }, "node_modules/@emotion/memoize": { "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", - "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", "license": "MIT", "peer": true }, @@ -753,8 +753,6 @@ }, "node_modules/@emotion/sheet": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", - "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", "license": "MIT", "peer": true }, @@ -782,8 +780,6 @@ }, "node_modules/@emotion/unitless": { "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", - "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", "license": "MIT", "peer": true }, @@ -797,22 +793,18 @@ }, "node_modules/@emotion/utils": { "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", - "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", "license": "MIT", "peer": true }, "node_modules/@emotion/weak-memoize": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", - "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", "license": "MIT", "peer": true }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", - "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", "cpu": [ "ppc64" ], @@ -827,9 +819,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", - "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", "cpu": [ "arm" ], @@ -844,9 +836,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", - "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", "cpu": [ "arm64" ], @@ -861,9 +853,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", - "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", "cpu": [ "x64" ], @@ -878,9 +870,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", - "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", "cpu": [ "arm64" ], @@ -895,9 +887,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", - "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", "cpu": [ "x64" ], @@ -912,9 +904,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", - "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", "cpu": [ "arm64" ], @@ -929,9 +921,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", - "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", "cpu": [ "x64" ], @@ -946,9 +938,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", - "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", "cpu": [ "arm" ], @@ -963,9 +955,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", - "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", "cpu": [ "arm64" ], @@ -980,9 +972,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", - "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", "cpu": [ "ia32" ], @@ -997,9 +989,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", - "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", "cpu": [ "loong64" ], @@ -1014,9 +1006,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", - "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", "cpu": [ "mips64el" ], @@ -1031,9 +1023,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", - "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", "cpu": [ "ppc64" ], @@ -1048,9 +1040,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", - "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", "cpu": [ "riscv64" ], @@ -1065,9 +1057,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", - "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", "cpu": [ "s390x" ], @@ -1082,9 +1074,7 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", - "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", + "version": "0.27.7", "cpu": [ "x64" ], @@ -1099,9 +1089,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", - "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", "cpu": [ "arm64" ], @@ -1116,9 +1106,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", - "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", "cpu": [ "x64" ], @@ -1133,9 +1123,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", - "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", "cpu": [ "arm64" ], @@ -1150,9 +1140,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", - "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", "cpu": [ "x64" ], @@ -1167,9 +1157,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", - "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", "cpu": [ "arm64" ], @@ -1184,9 +1174,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", - "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", "cpu": [ "x64" ], @@ -1201,9 +1191,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", - "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", "cpu": [ "arm64" ], @@ -1218,9 +1208,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", - "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", "cpu": [ "ia32" ], @@ -1235,9 +1225,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", - "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", "cpu": [ "x64" ], @@ -1288,13 +1278,13 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.21.1", + "version": "0.21.2", "dev": true, "license": "Apache-2.0", "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", - "minimatch": "^3.1.2" + "minimatch": "^3.1.5" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1302,8 +1292,6 @@ }, "node_modules/@eslint/config-array/node_modules/minimatch": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -1336,18 +1324,18 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.3.3", + "version": "3.3.5", "dev": true, "license": "MIT", "dependencies": { - "ajv": "^6.12.4", + "ajv": "^6.14.0", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.1", - "minimatch": "^3.1.2", + "minimatch": "^3.1.5", "strip-json-comments": "^3.1.1" }, "engines": { @@ -1370,8 +1358,6 @@ }, "node_modules/@eslint/eslintrc/node_modules/minimatch": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -1382,7 +1368,7 @@ } }, "node_modules/@eslint/js": { - "version": "9.39.2", + "version": "9.39.4", "dev": true, "license": "MIT", "engines": { @@ -1567,116 +1553,168 @@ } }, "node_modules/@loaders.gl/core": { - "version": "4.3.4", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@loaders.gl/core/-/core-4.4.1.tgz", + "integrity": "sha512-/s4IuvCCQUepvhjLnmePwQppGko2d1pxRS+sp7lyExU0uiqo5dVsAKaCZ2VnddBkFWgDVb/wvcZUBmv/dWcj0Q==", "license": "MIT", "dependencies": { - "@loaders.gl/loader-utils": "4.3.4", - "@loaders.gl/schema": "4.3.4", - "@loaders.gl/worker-utils": "4.3.4", - "@probe.gl/log": "^4.0.2" + "@loaders.gl/loader-utils": "4.4.1", + "@loaders.gl/schema": "4.4.1", + "@loaders.gl/schema-utils": "4.4.1", + "@loaders.gl/worker-utils": "4.4.1", + "@probe.gl/log": "^4.1.1" } }, "node_modules/@loaders.gl/images": { - "version": "4.3.4", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@loaders.gl/images/-/images-4.4.1.tgz", + "integrity": "sha512-v9A4BliEKGxhLuEbh0Ke8ElUlp04KxpKIknUtXXWoEaszAMTSrHI3YhaL/JdRlHraC1VUF/sjzbSBFkKh7nxJg==", "license": "MIT", "dependencies": { - "@loaders.gl/loader-utils": "4.3.4" + "@loaders.gl/loader-utils": "4.4.1" }, "peerDependencies": { - "@loaders.gl/core": "^4.3.0" + "@loaders.gl/core": "~4.4.0" } }, "node_modules/@loaders.gl/loader-utils": { - "version": "4.3.4", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@loaders.gl/loader-utils/-/loader-utils-4.4.1.tgz", + "integrity": "sha512-waosL7VtVRfXsNOXtAM3rOjZyNQD0lQBlhuB5/oY+E+lNzYNFlzgiGXiDOwBpcs7dK7kW2Vv8+KcxyIGIyXOtg==", "license": "MIT", "dependencies": { - "@loaders.gl/schema": "4.3.4", - "@loaders.gl/worker-utils": "4.3.4", - "@probe.gl/log": "^4.0.2", - "@probe.gl/stats": "^4.0.2" - }, - "peerDependencies": { - "@loaders.gl/core": "^4.3.0" + "@loaders.gl/schema": "4.4.1", + "@loaders.gl/worker-utils": "4.4.1", + "@probe.gl/log": "^4.1.1", + "@probe.gl/stats": "^4.1.1" } }, "node_modules/@loaders.gl/schema": { - "version": "4.3.4", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@loaders.gl/schema/-/schema-4.4.1.tgz", + "integrity": "sha512-s7NjEnyK6jZvJJSWj/mHq+S9mHRHVzIYtFP+C7sMf1gVCQbdkt6OSAMUWRzwPr9+whQNVWjZ9pbLsI/IPW3zvw==", + "license": "MIT", + "dependencies": { + "@types/geojson": "^7946.0.7", + "apache-arrow": ">= 17.0.0" + } + }, + "node_modules/@loaders.gl/schema-utils": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@loaders.gl/schema-utils/-/schema-utils-4.4.1.tgz", + "integrity": "sha512-4upip2O6MFaWzk68/lnna7P2uRj9NQ8MIk/ff3CLbciP5/9lKl1qyuzObz5JrJRYzfGB6I81vpOn6FSVQ6m6KQ==", "license": "MIT", "dependencies": { - "@types/geojson": "^7946.0.7" + "@loaders.gl/schema": "4.4.1", + "@types/geojson": "^7946.0.7", + "apache-arrow": ">= 17.0.0" }, "peerDependencies": { - "@loaders.gl/core": "^4.3.0" + "@loaders.gl/core": "~4.4.0" } }, "node_modules/@loaders.gl/worker-utils": { - "version": "4.3.4", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@loaders.gl/worker-utils/-/worker-utils-4.4.1.tgz", + "integrity": "sha512-ovMyIyj9dlChuHuD64Bel7Mir2UYlmLqlZ9MMzVxzTTLvaudJoNAXi6Disp0ooxwF62ZqjNXXutaSbS6UDeuIg==", "license": "MIT", "peerDependencies": { - "@loaders.gl/core": "^4.3.0" + "@loaders.gl/core": "~4.4.0" } }, "node_modules/@luma.gl/constants": { - "version": "9.2.6", - "resolved": "https://registry.npmjs.org/@luma.gl/constants/-/constants-9.2.6.tgz", - "integrity": "sha512-rvFFrJuSm5JIWbDHFuR4Q2s4eudO3Ggsv0TsGKn9eqvO7bBiPm/ANugHredvh3KviEyYuMZZxtfJvBdr3kzldg==", + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/@luma.gl/constants/-/constants-9.3.2.tgz", + "integrity": "sha512-NvO1xqIbuXS9BVQ+huxDvxb8HxC3AQAQz7GxldsCLL5LoicsUHEoM5amvLFVG1tXuXJuA0irSOAQBz/aYWhvPg==", "license": "MIT" }, "node_modules/@luma.gl/core": { - "version": "9.2.6", - "resolved": "https://registry.npmjs.org/@luma.gl/core/-/core-9.2.6.tgz", - "integrity": "sha512-d8KcH8ZZcjDAodSN/G2nueA9YE2X8kMz7Q0OxDGpCww6to1MZXM3Ydate/Jqsb5DDKVgUF6yD6RL8P5jOki9Yw==", + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/@luma.gl/core/-/core-9.3.2.tgz", + "integrity": "sha512-MIsOXnzoGGlbACTC9PVFxsEba6zJEj7Y5tghK/ivpIEqyzLF5bL/DlrVxG3SzJOeBqBMBgF6n5sXK7gIJ3lXvw==", "license": "MIT", "dependencies": { "@math.gl/types": "^4.1.0", - "@probe.gl/env": "^4.0.8", - "@probe.gl/log": "^4.0.8", - "@probe.gl/stats": "^4.0.8", - "@types/offscreencanvas": "^2019.6.4" + "@probe.gl/env": "^4.1.1", + "@probe.gl/log": "^4.1.1", + "@probe.gl/stats": "^4.1.1", + "@types/offscreencanvas": "^2019.7.3" } }, "node_modules/@luma.gl/engine": { - "version": "9.2.6", - "resolved": "https://registry.npmjs.org/@luma.gl/engine/-/engine-9.2.6.tgz", - "integrity": "sha512-1AEDs2AUqOWh7Wl4onOhXmQF+Rz1zNdPXF+Kxm4aWl92RQ42Sh2CmTvRt2BJku83VQ91KFIEm/v3qd3Urzf+Uw==", + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/@luma.gl/engine/-/engine-9.3.2.tgz", + "integrity": "sha512-Qo7JcmXgDFq/8hu1uR4sC1qnUVXW3jx//Mki4T3jCPig1BtcfrLSsmNDu2/u295ls/Mym2a9fvTnXRFejJMKig==", "license": "MIT", "dependencies": { "@math.gl/core": "^4.1.0", "@math.gl/types": "^4.1.0", - "@probe.gl/log": "^4.0.8", - "@probe.gl/stats": "^4.0.8" + "@probe.gl/log": "^4.1.1", + "@probe.gl/stats": "^4.1.1" }, "peerDependencies": { - "@luma.gl/core": "~9.2.0", - "@luma.gl/shadertools": "~9.2.0" + "@luma.gl/core": "~9.3.0", + "@luma.gl/shadertools": "~9.3.0" } }, "node_modules/@luma.gl/shadertools": { - "version": "9.2.6", - "resolved": "https://registry.npmjs.org/@luma.gl/shadertools/-/shadertools-9.2.6.tgz", - "integrity": "sha512-4+uUbynqPUra9d/z1nQChyHmhLgmKfSMjS7kOwLB6exSnhKnpHL3+Hu9fv55qyaX50nGH3oHawhGtJ6RRvu65w==", + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/@luma.gl/shadertools/-/shadertools-9.3.2.tgz", + "integrity": "sha512-gVydhOflR3w7H+F775ubNNWWO9C7BOg3sCGf+R9MdiT4S7iitkzmI3xYkb/ngDjJmzqCx72oBj4RgQV/hV7A8A==", "license": "MIT", "dependencies": { "@math.gl/core": "^4.1.0", - "@math.gl/types": "^4.1.0", - "wgsl_reflect": "^1.2.0" + "@math.gl/types": "^4.1.0" + }, + "peerDependencies": { + "@luma.gl/core": "~9.3.0" + } + }, + "node_modules/@luma.gl/test-utils": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/@luma.gl/test-utils/-/test-utils-9.3.2.tgz", + "integrity": "sha512-hLal4m8TgqvanhQ/zx35HZE6RQCc2aLxzO0Gsh9WXOMqfEv/L+BqokNc5LJxr19O5JToWiPKViL5zystKQ0JKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@probe.gl/env": "^4.1.1", + "@probe.gl/stats": "^4.1.1" }, "peerDependencies": { - "@luma.gl/core": "~9.2.0" + "@luma.gl/core": "~9.3.0", + "@luma.gl/engine": "~9.3.0", + "@luma.gl/shadertools": "~9.3.0", + "@luma.gl/webgl": "~9.3.0", + "@luma.gl/webgpu": "~9.3.0" } }, "node_modules/@luma.gl/webgl": { - "version": "9.2.6", - "resolved": "https://registry.npmjs.org/@luma.gl/webgl/-/webgl-9.2.6.tgz", - "integrity": "sha512-NGBTdxJMk7j8Ygr1zuTyAvr1Tw+EpupMIQo7RelFjEsZXg6pujFqiDMM+rgxex8voCeuhWBJc7Rs+MoSqd46UQ==", + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/@luma.gl/webgl/-/webgl-9.3.2.tgz", + "integrity": "sha512-vYHbTR5UC8O3yMPkOw8peRwmwwX0DMp9CHNLYckfxoSIOQA35eNUQG5hyZWZzma5fmJpfDMTwuJkoA99hhEkew==", "license": "MIT", "dependencies": { - "@luma.gl/constants": "9.2.6", "@math.gl/types": "^4.1.0", - "@probe.gl/env": "^4.0.8" + "@probe.gl/env": "^4.1.1" + }, + "peerDependencies": { + "@luma.gl/core": "~9.3.0" + } + }, + "node_modules/@luma.gl/webgpu": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/@luma.gl/webgpu/-/webgpu-9.3.2.tgz", + "integrity": "sha512-Ahn46qq6o9cMqR1GvwyLKl86MTAwClATN2dBBUOUfx0pR5wiQhSVOJfYzV+eFACKdahq5bt6PfUT013Jv1MUgQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@probe.gl/env": "^4.1.1", + "@webgpu/types": "^0.1.69", + "wgsl_reflect": "^1.2.3" }, "peerDependencies": { - "@luma.gl/core": "~9.2.0" + "@luma.gl/core": "~9.3.0" } }, "node_modules/@mapbox/extent": { @@ -1841,8 +1879,6 @@ }, "node_modules/@microsoft/api-extractor": { "version": "7.58.1", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.58.1.tgz", - "integrity": "sha512-kF3GFME4lN22O5zbnXk2RP4y/4PDQdps0xKiYTipMYprkwCmmpsWLZt/N2Fkbil540cSLfJX0BW7LkHzgMVUYg==", "dev": true, "license": "MIT", "dependencies": { @@ -1867,8 +1903,6 @@ }, "node_modules/@microsoft/api-extractor-model": { "version": "7.33.5", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.33.5.tgz", - "integrity": "sha512-Xh4dXuusndVQqVz4nEN9xOp0DyzsKxeD2FFJkSPg4arAjDSKPcy6cAc7CaeBPA7kF2wV1fuDlo2p/bNMpVr8yg==", "dev": true, "license": "MIT", "dependencies": { @@ -1879,8 +1913,6 @@ }, "node_modules/@microsoft/api-extractor/node_modules/balanced-match": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, "license": "MIT", "engines": { @@ -1889,8 +1921,6 @@ }, "node_modules/@microsoft/api-extractor/node_modules/brace-expansion": { "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1921,8 +1951,6 @@ }, "node_modules/@microsoft/api-extractor/node_modules/minimatch": { "version": "10.2.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.3.tgz", - "integrity": "sha512-Rwi3pnapEqirPSbWbrZaa6N3nmqq4Xer/2XooiOKyV3q12ML06f7MOuc5DVH8ONZIFhwIYQ3yzPH4nt7iWHaTg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -1964,15 +1992,11 @@ }, "node_modules/@microsoft/tsdoc": { "version": "0.16.0", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.16.0.tgz", - "integrity": "sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==", "dev": true, "license": "MIT" }, "node_modules/@microsoft/tsdoc-config": { "version": "0.18.1", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.18.1.tgz", - "integrity": "sha512-9brPoVdfN9k9g0dcWkFeA7IH9bbcttzDJlXvkf8b2OBzd5MueR1V2wkKBL0abn0otvmkHJC6aapBOTJDDeMCZg==", "dev": true, "license": "MIT", "dependencies": { @@ -1984,8 +2008,6 @@ }, "node_modules/@microsoft/tsdoc-config/node_modules/ajv": { "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, "license": "MIT", "dependencies": { @@ -2001,8 +2023,6 @@ }, "node_modules/@microsoft/tsdoc-config/node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, "license": "MIT" }, @@ -2255,6 +2275,11 @@ "url": "https://opencollective.com/pkgr" } }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "dev": true, + "license": "MIT" + }, "node_modules/@popperjs/core": { "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", @@ -2275,24 +2300,47 @@ "link": true }, "node_modules/@probe.gl/env": { - "version": "4.1.0", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@probe.gl/env/-/env-4.1.1.tgz", + "integrity": "sha512-+68seNDMVsEegRB47pFA/Ws1Fjy8agcFYXxzorKToyPcD6zd+gZ5uhwoLd7TzsSw6Ydns//2KEszWn+EnNHTbA==", "license": "MIT" }, "node_modules/@probe.gl/log": { - "version": "4.1.0", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@probe.gl/log/-/log-4.1.1.tgz", + "integrity": "sha512-kcZs9BT44pL7hS1OkRGKYRXI/SN9KejUlPD+BY40DguRLzdC5tLG/28WGMyfKdn/51GT4a0p+0P8xvDn1Ez+Kg==", "license": "MIT", "dependencies": { - "@probe.gl/env": "4.1.0" + "@probe.gl/env": "4.1.1" } }, "node_modules/@probe.gl/stats": { - "version": "4.1.0", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@probe.gl/stats/-/stats-4.1.1.tgz", + "integrity": "sha512-4VpAyMHOqydSvPlEyHwXaE+AkIdR03nX+Qhlxsk2D/IW4OVmDZgIsvJB1cDzyEEtcfKcnaEbfXeiPgejBceT6g==", "license": "MIT" }, + "node_modules/@probe.gl/test-utils": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@probe.gl/log": "4.1.1", + "@types/pngjs": "^6.0.1", + "pixelmatch": "^4.0.2" + }, + "peerDependencies": { + "puppeteer": ">=19" + }, + "peerDependenciesMeta": { + "puppeteer": { + "optional": true + } + } + }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz", - "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==", "dev": true, "license": "MIT" }, @@ -2318,9 +2366,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", - "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.1.tgz", + "integrity": "sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA==", "cpu": [ "arm" ], @@ -2332,9 +2380,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", - "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.1.tgz", + "integrity": "sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA==", "cpu": [ "arm64" ], @@ -2346,9 +2394,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", - "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.1.tgz", + "integrity": "sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw==", "cpu": [ "arm64" ], @@ -2360,9 +2408,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", - "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.1.tgz", + "integrity": "sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew==", "cpu": [ "x64" ], @@ -2374,9 +2422,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", - "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.1.tgz", + "integrity": "sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w==", "cpu": [ "arm64" ], @@ -2388,9 +2436,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", - "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.1.tgz", + "integrity": "sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g==", "cpu": [ "x64" ], @@ -2402,9 +2450,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", - "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.1.tgz", + "integrity": "sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g==", "cpu": [ "arm" ], @@ -2419,9 +2467,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", - "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.1.tgz", + "integrity": "sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg==", "cpu": [ "arm" ], @@ -2436,9 +2484,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", - "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.1.tgz", + "integrity": "sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ==", "cpu": [ "arm64" ], @@ -2453,9 +2501,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", - "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.1.tgz", + "integrity": "sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA==", "cpu": [ "arm64" ], @@ -2470,9 +2518,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", - "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.1.tgz", + "integrity": "sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ==", "cpu": [ "loong64" ], @@ -2487,9 +2535,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", - "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.1.tgz", + "integrity": "sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw==", "cpu": [ "loong64" ], @@ -2504,9 +2552,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", - "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.1.tgz", + "integrity": "sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw==", "cpu": [ "ppc64" ], @@ -2521,9 +2569,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", - "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.1.tgz", + "integrity": "sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg==", "cpu": [ "ppc64" ], @@ -2538,9 +2586,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", - "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.1.tgz", + "integrity": "sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg==", "cpu": [ "riscv64" ], @@ -2555,9 +2603,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", - "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.1.tgz", + "integrity": "sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg==", "cpu": [ "riscv64" ], @@ -2572,9 +2620,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", - "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.1.tgz", + "integrity": "sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ==", "cpu": [ "s390x" ], @@ -2589,11 +2637,14 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.59.0", + "version": "4.60.1", "cpu": [ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2601,11 +2652,16 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.59.0", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.1.tgz", + "integrity": "sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -2613,9 +2669,9 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", - "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.1.tgz", + "integrity": "sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw==", "cpu": [ "x64" ], @@ -2627,9 +2683,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", - "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.1.tgz", + "integrity": "sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA==", "cpu": [ "arm64" ], @@ -2641,9 +2697,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", - "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.1.tgz", + "integrity": "sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g==", "cpu": [ "arm64" ], @@ -2655,9 +2711,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", - "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.1.tgz", + "integrity": "sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg==", "cpu": [ "ia32" ], @@ -2669,9 +2725,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", - "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.1.tgz", + "integrity": "sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg==", "cpu": [ "x64" ], @@ -2683,9 +2739,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", - "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.1.tgz", + "integrity": "sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ==", "cpu": [ "x64" ], @@ -2698,8 +2754,6 @@ }, "node_modules/@rushstack/node-core-library": { "version": "5.21.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.21.0.tgz", - "integrity": "sha512-LFzN+1lyWROit/P8Md6yxAth7lLYKn37oCKJHirEE2TQB25NDUM7bALf0ar+JAtwFfRCH+D+DGOA7DAzIi2r+g==", "dev": true, "license": "MIT", "dependencies": { @@ -2723,8 +2777,6 @@ }, "node_modules/@rushstack/node-core-library/node_modules/ajv": { "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, "license": "MIT", "dependencies": { @@ -2740,8 +2792,6 @@ }, "node_modules/@rushstack/node-core-library/node_modules/ajv-draft-04": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", - "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", "dev": true, "license": "MIT", "peerDependencies": { @@ -2755,15 +2805,11 @@ }, "node_modules/@rushstack/node-core-library/node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, "license": "MIT" }, "node_modules/@rushstack/node-core-library/node_modules/lru-cache": { "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, "license": "ISC", "dependencies": { @@ -2775,8 +2821,6 @@ }, "node_modules/@rushstack/node-core-library/node_modules/semver": { "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "license": "ISC", "dependencies": { @@ -2791,15 +2835,11 @@ }, "node_modules/@rushstack/node-core-library/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, "license": "ISC" }, "node_modules/@rushstack/problem-matcher": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@rushstack/problem-matcher/-/problem-matcher-0.2.1.tgz", - "integrity": "sha512-gulfhBs6n+I5b7DvjKRfhMGyUejtSgOHTclF/eONr8hcgF1APEDjhxIsfdUYYMzC3rvLwGluqLjbwCFZ8nxrog==", "dev": true, "license": "MIT", "peerDependencies": { @@ -2813,8 +2853,6 @@ }, "node_modules/@rushstack/rig-package": { "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.7.2.tgz", - "integrity": "sha512-9XbFWuqMYcHUso4mnETfhGVUSaADBRj6HUAAEYk50nMPn8WRICmBuCphycQGNB3duIR6EEZX3Xj3SYc2XiP+9A==", "dev": true, "license": "MIT", "dependencies": { @@ -2824,8 +2862,6 @@ }, "node_modules/@rushstack/terminal": { "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.22.4.tgz", - "integrity": "sha512-fhtLjnXCc/4WleVbVl6aoc7jcWnU6yqjS1S8WoaNREG3ycu/viZ9R/9QM7Y/b4CDvcXoiDyMNIay7JMwBptM3g==", "dev": true, "license": "MIT", "dependencies": { @@ -2844,8 +2880,6 @@ }, "node_modules/@rushstack/terminal/node_modules/supports-color": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "license": "MIT", "dependencies": { @@ -2860,8 +2894,6 @@ }, "node_modules/@rushstack/ts-command-line": { "version": "5.3.4", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-5.3.4.tgz", - "integrity": "sha512-MLkVKVEN6/2clKTrjN2B2KqKCuPxRwnNsWY7a+FCAq2EMdkj10cM8YgiBSMeGFfzM0mDMzargpHNnNzaBi9Whg==", "dev": true, "license": "MIT", "dependencies": { @@ -2884,8 +2916,6 @@ }, "node_modules/@standard-schema/spec": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", - "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", "dev": true, "license": "MIT" }, @@ -3152,6 +3182,15 @@ "@svgr/core": "*" } }, + "node_modules/@swc/helpers": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.21.tgz", + "integrity": "sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.12", "dev": true, @@ -3211,8 +3250,6 @@ }, "node_modules/@types/argparse": { "version": "1.0.38", - "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", - "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", "dev": true, "license": "MIT" }, @@ -3255,8 +3292,6 @@ }, "node_modules/@types/chai": { "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", - "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", "dev": true, "license": "MIT", "dependencies": { @@ -3264,10 +3299,20 @@ "assertion-error": "^2.0.1" } }, + "node_modules/@types/command-line-args": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/command-line-args/-/command-line-args-5.2.3.tgz", + "integrity": "sha512-uv0aG6R0Y8WHZLTamZwtfsDLVRnOa+n+n5rEvFWL5Na5gZ8V2Teab/duDPFzIIIhs9qizDpcavCusCLJZu62Kw==", + "license": "MIT" + }, + "node_modules/@types/command-line-usage": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/command-line-usage/-/command-line-usage-5.0.4.tgz", + "integrity": "sha512-BwR5KP3Es/CSht0xqBcUXS3qCAUVXwpRKsV2+arxeb65atasuXG9LykC9Ab10Cw3s2raH92ZqOeILaQbsB2ACg==", + "license": "MIT" + }, "node_modules/@types/deep-eql": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", - "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", "dev": true, "license": "MIT" }, @@ -3344,7 +3389,7 @@ } }, "node_modules/@types/node": { - "version": "22.19.10", + "version": "22.19.17", "dev": true, "license": "MIT", "dependencies": { @@ -3357,8 +3402,6 @@ }, "node_modules/@types/parse-json": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", "license": "MIT", "peer": true }, @@ -3366,15 +3409,22 @@ "version": "3.0.5", "license": "MIT" }, + "node_modules/@types/pngjs": { + "version": "6.0.5", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/prop-types": { "version": "15.7.15", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", - "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", "license": "MIT", "peer": true }, "node_modules/@types/react": { - "version": "19.2.13", + "version": "19.2.14", "license": "MIT", "dependencies": { "csstype": "^3.2.2" @@ -3406,18 +3456,18 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.54.0", + "version": "8.58.2", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.54.0", - "@typescript-eslint/type-utils": "8.54.0", - "@typescript-eslint/utils": "8.54.0", - "@typescript-eslint/visitor-keys": "8.54.0", + "@typescript-eslint/scope-manager": "8.58.2", + "@typescript-eslint/type-utils": "8.58.2", + "@typescript-eslint/utils": "8.58.2", + "@typescript-eslint/visitor-keys": "8.58.2", "ignore": "^7.0.5", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.4.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3427,9 +3477,9 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.54.0", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "@typescript-eslint/parser": "^8.58.2", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { @@ -3441,14 +3491,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.54.0", + "version": "8.58.2", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.54.0", - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/typescript-estree": "8.54.0", - "@typescript-eslint/visitor-keys": "8.54.0", + "@typescript-eslint/scope-manager": "8.58.2", + "@typescript-eslint/types": "8.58.2", + "@typescript-eslint/typescript-estree": "8.58.2", + "@typescript-eslint/visitor-keys": "8.58.2", "debug": "^4.4.3" }, "engines": { @@ -3459,17 +3509,17 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.54.0", + "version": "8.58.2", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.54.0", - "@typescript-eslint/types": "^8.54.0", + "@typescript-eslint/tsconfig-utils": "^8.58.2", + "@typescript-eslint/types": "^8.58.2", "debug": "^4.4.3" }, "engines": { @@ -3480,16 +3530,16 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.54.0", + "version": "8.58.2", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/visitor-keys": "8.54.0" + "@typescript-eslint/types": "8.58.2", + "@typescript-eslint/visitor-keys": "8.58.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3500,7 +3550,7 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.54.0", + "version": "8.58.2", "dev": true, "license": "MIT", "engines": { @@ -3511,19 +3561,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.54.0", + "version": "8.58.2", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/typescript-estree": "8.54.0", - "@typescript-eslint/utils": "8.54.0", + "@typescript-eslint/types": "8.58.2", + "@typescript-eslint/typescript-estree": "8.58.2", + "@typescript-eslint/utils": "8.58.2", "debug": "^4.4.3", - "ts-api-utils": "^2.4.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3533,12 +3583,12 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.54.0", + "version": "8.58.2", "dev": true, "license": "MIT", "engines": { @@ -3550,19 +3600,19 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.54.0", + "version": "8.58.2", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.54.0", - "@typescript-eslint/tsconfig-utils": "8.54.0", - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/visitor-keys": "8.54.0", + "@typescript-eslint/project-service": "8.58.2", + "@typescript-eslint/tsconfig-utils": "8.58.2", + "@typescript-eslint/types": "8.58.2", + "@typescript-eslint/visitor-keys": "8.58.2", "debug": "^4.4.3", - "minimatch": "^9.0.5", + "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.4.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3572,44 +3622,18 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", - "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.2" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/utils": { - "version": "8.54.0", + "version": "8.58.2", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.54.0", - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/typescript-estree": "8.54.0" + "@typescript-eslint/scope-manager": "8.58.2", + "@typescript-eslint/types": "8.58.2", + "@typescript-eslint/typescript-estree": "8.58.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3619,17 +3643,17 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.54.0", + "version": "8.58.2", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.54.0", - "eslint-visitor-keys": "^4.2.1" + "@typescript-eslint/types": "8.58.2", + "eslint-visitor-keys": "^5.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3639,8 +3663,19 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@vis.gl/react-mapbox": { - "version": "8.1.0", + "version": "8.1.1", "license": "MIT", "peerDependencies": { "mapbox-gl": ">=3.5.0", @@ -3654,7 +3689,7 @@ } }, "node_modules/@vis.gl/react-maplibre": { - "version": "8.1.0", + "version": "8.1.1", "license": "MIT", "dependencies": { "@maplibre/maplibre-gl-style-spec": "^19.2.1" @@ -3696,9 +3731,7 @@ "license": "BSD-3-Clause" }, "node_modules/@vitejs/plugin-react": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.4.tgz", - "integrity": "sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA==", + "version": "5.2.0", "dev": true, "license": "MIT", "dependencies": { @@ -3713,7 +3746,54 @@ "node": "^20.19.0 || >=22.12.0" }, "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@vitest/browser": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-4.1.8.tgz", + "integrity": "sha512-u21VzX07HzlJYpFgkxmjEXar/tG2UqWGgyGG/46SrrPc7rSdCTPw5vuowopO9CIqF8UCUQzDFdbVnNpw6N0BfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@blazediff/core": "1.9.1", + "@vitest/mocker": "4.1.8", + "@vitest/utils": "4.1.8", + "magic-string": "^0.30.21", + "pngjs": "^7.0.0", + "sirv": "^3.0.2", + "tinyrainbow": "^3.1.0", + "ws": "^8.19.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "vitest": "4.1.8" + } + }, + "node_modules/@vitest/browser-playwright": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@vitest/browser-playwright/-/browser-playwright-4.1.8.tgz", + "integrity": "sha512-SR7FqgegaexEg73xvf3ArtygXegagMdXnL0EZMpxrWvvhQxvicD/E8p0ib0J91riPRtQUViyh67Xjw3NqvyhVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/browser": "4.1.8", + "@vitest/mocker": "4.1.8", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "playwright": "*", + "vitest": "4.1.8" + }, + "peerDependenciesMeta": { + "playwright": { + "optional": false + } } }, "node_modules/@vitest/coverage-v8": { @@ -3749,8 +3829,6 @@ }, "node_modules/@vitest/coverage-v8/node_modules/@bcoe/v8-coverage": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", - "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", "dev": true, "license": "MIT", "engines": { @@ -3758,24 +3836,26 @@ } }, "node_modules/@vitest/eslint-plugin": { - "version": "1.6.9", - "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.6.9.tgz", - "integrity": "sha512-9WfPx1OwJ19QLCSRLkqVO7//1WcWnK3fE/3fJhKMAmDe8+9G4rB47xCNIIeCq3FdEzkIoLTfDlwDlPBaUTMhow==", + "version": "1.6.15", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "^8.55.0", - "@typescript-eslint/utils": "^8.55.0" + "@typescript-eslint/scope-manager": "^8.58.0", + "@typescript-eslint/utils": "^8.58.0" }, "engines": { "node": ">=18" }, "peerDependencies": { + "@typescript-eslint/eslint-plugin": "*", "eslint": ">=8.57.0", "typescript": ">=5.0.0", "vitest": "*" }, "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, "typescript": { "optional": true }, @@ -3784,157 +3864,6 @@ } } }, - "node_modules/@vitest/eslint-plugin/node_modules/@typescript-eslint/project-service": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.1.tgz", - "integrity": "sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.56.1", - "@typescript-eslint/types": "^8.56.1", - "debug": "^4.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@vitest/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.1.tgz", - "integrity": "sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/visitor-keys": "8.56.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@vitest/eslint-plugin/node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.1.tgz", - "integrity": "sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@vitest/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.1.tgz", - "integrity": "sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@vitest/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.1.tgz", - "integrity": "sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/project-service": "8.56.1", - "@typescript-eslint/tsconfig-utils": "8.56.1", - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/visitor-keys": "8.56.1", - "debug": "^4.4.3", - "minimatch": "^10.2.2", - "semver": "^7.7.3", - "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.4.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@vitest/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.1.tgz", - "integrity": "sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.56.1", - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/typescript-estree": "8.56.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@vitest/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.1.tgz", - "integrity": "sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.56.1", - "eslint-visitor-keys": "^5.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@vitest/eslint-plugin/node_modules/eslint-visitor-keys": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", - "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/@vitest/expect": { "version": "4.1.8", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.8.tgz", @@ -3982,8 +3911,6 @@ }, "node_modules/@vitest/mocker/node_modules/estree-walker": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, "license": "MIT", "dependencies": { @@ -4043,6 +3970,28 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/@vitest/ui": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-4.1.8.tgz", + "integrity": "sha512-RUS2ZU2TsduVrI+9c12uTNaKrNUTsm6yFt3fueEUB9iKvyC2UP83F+sqIz00HQIah4UOL1TMoDAki8K0NjGvsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.1.8", + "fflate": "^0.8.2", + "flatted": "^3.4.2", + "pathe": "^2.0.3", + "sirv": "^3.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "vitest": "4.1.8" + } + }, "node_modules/@vitest/utils": { "version": "4.1.8", "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.8.tgz", @@ -4147,8 +4096,6 @@ }, "node_modules/@vue/language-core/node_modules/brace-expansion": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", - "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", "dev": true, "license": "MIT", "dependencies": { @@ -4157,8 +4104,6 @@ }, "node_modules/@vue/language-core/node_modules/minimatch": { "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "license": "ISC", "dependencies": { @@ -4176,6 +4121,14 @@ "dev": true, "license": "MIT" }, + "node_modules/@webgpu/types": { + "version": "0.1.69", + "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.69.tgz", + "integrity": "sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true + }, "node_modules/abbrev": { "version": "1.1.1", "dev": true, @@ -4213,8 +4166,6 @@ }, "node_modules/agent-base": { "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "dev": true, "license": "MIT", "engines": { @@ -4223,8 +4174,6 @@ }, "node_modules/ajv": { "version": "6.14.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", "dependencies": { @@ -4240,8 +4189,6 @@ }, "node_modules/ajv-formats": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4258,8 +4205,6 @@ }, "node_modules/ajv-formats/node_modules/ajv": { "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, "license": "MIT", "dependencies": { @@ -4275,8 +4220,6 @@ }, "node_modules/ajv-formats/node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, "license": "MIT" }, @@ -4298,7 +4241,6 @@ }, "node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -4315,6 +4257,41 @@ "dev": true, "license": "MIT" }, + "node_modules/apache-arrow": { + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/apache-arrow/-/apache-arrow-21.1.0.tgz", + "integrity": "sha512-kQrYLxhC+NTVVZ4CCzGF6L/uPVOzJmD1T3XgbiUnP7oTeVFOFgEUu6IKNwCDkpFoBVqDKQivlX4RUFqqnWFlEA==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.11", + "@types/command-line-args": "^5.2.3", + "@types/command-line-usage": "^5.0.4", + "@types/node": "^24.0.3", + "command-line-args": "^6.0.1", + "command-line-usage": "^7.0.1", + "flatbuffers": "^25.1.24", + "json-bignum": "^0.0.3", + "tslib": "^2.6.2" + }, + "bin": { + "arrow2csv": "bin/arrow2csv.js" + } + }, + "node_modules/apache-arrow/node_modules/@types/node": { + "version": "24.12.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.2.tgz", + "integrity": "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/apache-arrow/node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT" + }, "node_modules/arg": { "version": "4.1.3", "dev": true, @@ -4322,8 +4299,6 @@ }, "node_modules/argparse": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "license": "MIT", "dependencies": { @@ -4337,6 +4312,15 @@ "node": ">=0.10.0" } }, + "node_modules/array-back": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.3.tgz", + "integrity": "sha512-SGDvmg6QTYiTxCBkYVmThcoa67uLl35pyzRHdpCGBOcqFy6BtwnphoFPk7LhJshD+Yk1Kt35WGWeZPTgwR4Fhw==", + "license": "MIT", + "engines": { + "node": ">=12.17" + } + }, "node_modules/array-buffer-byte-length": { "version": "1.0.2", "license": "MIT", @@ -4474,8 +4458,6 @@ }, "node_modules/assertion-error": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, "license": "MIT", "engines": { @@ -4572,8 +4554,6 @@ }, "node_modules/brace-expansion": { "version": "1.1.14", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", - "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "dev": true, "license": "MIT", "dependencies": { @@ -4697,8 +4677,6 @@ }, "node_modules/chai": { "version": "6.2.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", - "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", "dev": true, "license": "MIT", "engines": { @@ -4707,7 +4685,6 @@ }, "node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -4720,6 +4697,21 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chalk-template": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz", + "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/chalk-template?sponsor=1" + } + }, "node_modules/char-regex": { "version": "1.0.2", "dev": true, @@ -4837,7 +4829,6 @@ }, "node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -4848,9 +4839,46 @@ }, "node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, + "node_modules/command-line-args": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-6.0.2.tgz", + "integrity": "sha512-AIjYVxrV9X752LmPDLbVYv8aMCuHPSLZJXEo2qo/xJfv+NYhaZ4sMSF01rM+gHPaMgvPM0l5D/F+Qx+i2WfSmQ==", + "license": "MIT", + "dependencies": { + "array-back": "^6.2.3", + "find-replace": "^5.0.2", + "lodash.camelcase": "^4.3.0", + "typical": "^7.3.0" + }, + "engines": { + "node": ">=12.20" + }, + "peerDependencies": { + "@75lb/nature": "latest" + }, + "peerDependenciesMeta": { + "@75lb/nature": { + "optional": true + } + } + }, + "node_modules/command-line-usage": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-7.0.4.tgz", + "integrity": "sha512-85UdvzTNx/+s5CkSgBm/0hzP80RFHAa7PsfeADE5ezZF3uHz3/Tqj9gIKGT9PTtpycc3Ua64T0oVulGfKxzfqg==", + "license": "MIT", + "dependencies": { + "array-back": "^6.2.2", + "chalk-template": "^0.4.0", + "table-layout": "^4.1.1", + "typical": "^7.3.0" + }, + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/commander": { "version": "10.0.1", "dev": true, @@ -4896,8 +4924,6 @@ }, "node_modules/cosmiconfig/node_modules/yaml": { "version": "1.10.3", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz", - "integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==", "license": "ISC", "peer": true, "engines": { @@ -4996,8 +5022,6 @@ }, "node_modules/cssstyle": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", - "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==", "dev": true, "license": "MIT", "dependencies": { @@ -5014,8 +5038,6 @@ }, "node_modules/data-urls": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", - "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", "dev": true, "license": "MIT", "dependencies": { @@ -5476,9 +5498,7 @@ } }, "node_modules/esbuild": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", - "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", + "version": "0.27.7", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -5489,32 +5509,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.3", - "@esbuild/android-arm": "0.27.3", - "@esbuild/android-arm64": "0.27.3", - "@esbuild/android-x64": "0.27.3", - "@esbuild/darwin-arm64": "0.27.3", - "@esbuild/darwin-x64": "0.27.3", - "@esbuild/freebsd-arm64": "0.27.3", - "@esbuild/freebsd-x64": "0.27.3", - "@esbuild/linux-arm": "0.27.3", - "@esbuild/linux-arm64": "0.27.3", - "@esbuild/linux-ia32": "0.27.3", - "@esbuild/linux-loong64": "0.27.3", - "@esbuild/linux-mips64el": "0.27.3", - "@esbuild/linux-ppc64": "0.27.3", - "@esbuild/linux-riscv64": "0.27.3", - "@esbuild/linux-s390x": "0.27.3", - "@esbuild/linux-x64": "0.27.3", - "@esbuild/netbsd-arm64": "0.27.3", - "@esbuild/netbsd-x64": "0.27.3", - "@esbuild/openbsd-arm64": "0.27.3", - "@esbuild/openbsd-x64": "0.27.3", - "@esbuild/openharmony-arm64": "0.27.3", - "@esbuild/sunos-x64": "0.27.3", - "@esbuild/win32-arm64": "0.27.3", - "@esbuild/win32-ia32": "0.27.3", - "@esbuild/win32-x64": "0.27.3" + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" } }, "node_modules/escalade": { @@ -5536,23 +5556,23 @@ } }, "node_modules/eslint": { - "version": "9.39.2", + "version": "9.39.4", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.1", + "@eslint/config-array": "^0.21.2", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.39.2", + "@eslint/eslintrc": "^3.3.5", + "@eslint/js": "9.39.4", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", - "ajv": "^6.12.4", + "ajv": "^6.14.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", @@ -5571,7 +5591,7 @@ "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", + "minimatch": "^3.1.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, @@ -5688,8 +5708,6 @@ }, "node_modules/eslint-plugin-react/node_modules/minimatch": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -5724,18 +5742,18 @@ } }, "node_modules/eslint-plugin-testing-library": { - "version": "7.15.4", + "version": "7.16.2", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "^8.51.0", - "@typescript-eslint/utils": "^8.51.0" + "@typescript-eslint/scope-manager": "^8.56.0", + "@typescript-eslint/utils": "^8.56.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0" } }, "node_modules/eslint-scope": { @@ -5795,8 +5813,6 @@ }, "node_modules/eslint/node_modules/minimatch": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -5881,8 +5897,6 @@ }, "node_modules/expect-type": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", - "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -5941,6 +5955,22 @@ ], "license": "BSD-3-Clause" }, + "node_modules/fdir": { + "version": "6.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, "node_modules/fflate": { "version": "0.8.2", "dev": true, @@ -5957,10 +5987,25 @@ "node": ">=16.0.0" } }, + "node_modules/find-replace": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-5.0.2.tgz", + "integrity": "sha512-Y45BAiE3mz2QsrN2fb5QEtO4qb44NcS7en/0y9PEVsg351HsLeVclP8QPMH79Le9sH3rs5RSwJu99W0WPZO43Q==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@75lb/nature": "latest" + }, + "peerDependenciesMeta": { + "@75lb/nature": { + "optional": true + } + } + }, "node_modules/find-root": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", "license": "MIT", "peer": true }, @@ -5976,10 +6021,14 @@ "node": ">=16" } }, + "node_modules/flatbuffers": { + "version": "25.9.23", + "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-25.9.23.tgz", + "integrity": "sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ==", + "license": "Apache-2.0" + }, "node_modules/flatted": { "version": "3.4.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", - "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "dev": true, "license": "ISC" }, @@ -5998,8 +6047,6 @@ }, "node_modules/fs-extra": { "version": "11.3.4", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", - "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", "dev": true, "license": "MIT", "dependencies": { @@ -6017,9 +6064,9 @@ "license": "ISC" }, "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "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, "license": "MIT", @@ -6199,8 +6246,6 @@ }, "node_modules/glob/node_modules/minimatch": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -6298,7 +6343,6 @@ }, "node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -6390,8 +6434,6 @@ }, "node_modules/hoist-non-react-statics/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==", "license": "MIT", "peer": true }, @@ -6402,8 +6444,6 @@ }, "node_modules/html-encoding-sniffer": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", - "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6420,8 +6460,6 @@ }, "node_modules/http-proxy-agent": { "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, "license": "MIT", "dependencies": { @@ -6434,8 +6472,6 @@ }, "node_modules/https-proxy-agent": { "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "dev": true, "license": "MIT", "dependencies": { @@ -6448,8 +6484,6 @@ }, "node_modules/iconv-lite": { "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, "license": "MIT", "dependencies": { @@ -6508,8 +6542,6 @@ }, "node_modules/import-lazy": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", - "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", "dev": true, "license": "MIT", "engines": { @@ -6981,8 +7013,6 @@ }, "node_modules/jju": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", - "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", "dev": true, "license": "MIT" }, @@ -7022,8 +7052,6 @@ }, "node_modules/jsdom": { "version": "26.1.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz", - "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", "dev": true, "license": "MIT", "dependencies": { @@ -7070,6 +7098,14 @@ "node": ">=6" } }, + "node_modules/json-bignum": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/json-bignum/-/json-bignum-0.0.3.tgz", + "integrity": "sha512-2WHyXj3OfHSgNyuzDbSxI1w2jgw5gkWSWhS7Qg4bWXx1nLk3jnbwfUeS0PSba3IzpTUWdHxBieELUzXRjQB2zg==", + "engines": { + "node": ">=0.8" + } + }, "node_modules/json-buffer": { "version": "3.0.1", "dev": true, @@ -7106,8 +7142,6 @@ }, "node_modules/jsonfile": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", "dev": true, "license": "MIT", "dependencies": { @@ -7289,11 +7323,15 @@ }, "node_modules/lodash": { "version": "4.18.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", - "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "dev": true, "license": "MIT" }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "license": "MIT" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "license": "MIT" @@ -7326,9 +7364,12 @@ } }, "node_modules/lru-cache": { - "version": "10.4.3", + "version": "11.3.5", "dev": true, - "license": "ISC" + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } }, "node_modules/magic-string": { "version": "0.30.21", @@ -7340,8 +7381,6 @@ }, "node_modules/magicast": { "version": "0.5.2", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.2.tgz", - "integrity": "sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==", "dev": true, "license": "MIT", "dependencies": { @@ -7554,13 +7593,11 @@ "license": "CC0-1.0" }, "node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "version": "10.2.5", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" @@ -7579,8 +7616,6 @@ }, "node_modules/minimatch/node_modules/brace-expansion": { "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, "license": "MIT", "dependencies": { @@ -7607,8 +7642,6 @@ }, "node_modules/mjolnir.js": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mjolnir.js/-/mjolnir.js-3.0.0.tgz", - "integrity": "sha512-siX3YCG7N2HnmN1xMH3cK4JkUZJhbkhRFJL+G5N1vH0mh1t5088rJknIoqDFWDIU6NPGvRRgLnYW3ZHjSMEBLA==", "license": "MIT" }, "node_modules/mkdirp": { @@ -7648,6 +7681,14 @@ "pathe": "^2.0.1" } }, + "node_modules/mrmime": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/ms": { "version": "2.1.3", "license": "MIT" @@ -7865,8 +7906,6 @@ }, "node_modules/obug": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", - "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", "dev": true, "funding": [ "https://github.com/sponsors/sxzz", @@ -8055,14 +8094,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "11.2.5", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, "node_modules/path-type": { "version": "4.0.0", "license": "MIT", @@ -8091,8 +8122,6 @@ }, "node_modules/picomatch": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { @@ -8102,6 +8131,27 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pixelmatch": { + "version": "4.0.2", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "pngjs": "^3.0.0" + }, + "bin": { + "pixelmatch": "bin/pixelmatch" + } + }, + "node_modules/pixelmatch/node_modules/pngjs": { + "version": "3.4.0", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/pkg-types": { "version": "2.3.0", "dev": true, @@ -8112,6 +8162,46 @@ "pathe": "^2.0.3" } }, + "node_modules/playwright": { + "version": "1.59.1", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "playwright-core": "1.59.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.59.1", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/pngjs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz", + "integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.19.0" + } + }, "node_modules/point-in-polygon-hao": { "version": "1.2.4", "license": "MIT", @@ -8172,7 +8262,7 @@ } }, "node_modules/prettier": { - "version": "3.8.1", + "version": "3.8.2", "dev": true, "license": "MIT", "bin": { @@ -8304,11 +8394,11 @@ "peer": true }, "node_modules/react-map-gl": { - "version": "8.1.0", + "version": "8.1.1", "license": "MIT", "dependencies": { - "@vis.gl/react-mapbox": "8.1.0", - "@vis.gl/react-maplibre": "8.1.0" + "@vis.gl/react-mapbox": "8.1.1", + "@vis.gl/react-maplibre": "8.1.1" }, "peerDependencies": { "mapbox-gl": ">=1.13.0", @@ -8327,8 +8417,6 @@ }, "node_modules/react-refresh": { "version": "0.18.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", - "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", "dev": true, "license": "MIT", "engines": { @@ -8458,8 +8546,6 @@ }, "node_modules/require-from-string": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, "license": "MIT", "engines": { @@ -8530,7 +8616,7 @@ "license": "Unlicense" }, "node_modules/rollup": { - "version": "4.59.0", + "version": "4.60.1", "dev": true, "license": "MIT", "dependencies": { @@ -8544,38 +8630,36 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.59.0", - "@rollup/rollup-android-arm64": "4.59.0", - "@rollup/rollup-darwin-arm64": "4.59.0", - "@rollup/rollup-darwin-x64": "4.59.0", - "@rollup/rollup-freebsd-arm64": "4.59.0", - "@rollup/rollup-freebsd-x64": "4.59.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", - "@rollup/rollup-linux-arm-musleabihf": "4.59.0", - "@rollup/rollup-linux-arm64-gnu": "4.59.0", - "@rollup/rollup-linux-arm64-musl": "4.59.0", - "@rollup/rollup-linux-loong64-gnu": "4.59.0", - "@rollup/rollup-linux-loong64-musl": "4.59.0", - "@rollup/rollup-linux-ppc64-gnu": "4.59.0", - "@rollup/rollup-linux-ppc64-musl": "4.59.0", - "@rollup/rollup-linux-riscv64-gnu": "4.59.0", - "@rollup/rollup-linux-riscv64-musl": "4.59.0", - "@rollup/rollup-linux-s390x-gnu": "4.59.0", - "@rollup/rollup-linux-x64-gnu": "4.59.0", - "@rollup/rollup-linux-x64-musl": "4.59.0", - "@rollup/rollup-openbsd-x64": "4.59.0", - "@rollup/rollup-openharmony-arm64": "4.59.0", - "@rollup/rollup-win32-arm64-msvc": "4.59.0", - "@rollup/rollup-win32-ia32-msvc": "4.59.0", - "@rollup/rollup-win32-x64-gnu": "4.59.0", - "@rollup/rollup-win32-x64-msvc": "4.59.0", + "@rollup/rollup-android-arm-eabi": "4.60.1", + "@rollup/rollup-android-arm64": "4.60.1", + "@rollup/rollup-darwin-arm64": "4.60.1", + "@rollup/rollup-darwin-x64": "4.60.1", + "@rollup/rollup-freebsd-arm64": "4.60.1", + "@rollup/rollup-freebsd-x64": "4.60.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.60.1", + "@rollup/rollup-linux-arm-musleabihf": "4.60.1", + "@rollup/rollup-linux-arm64-gnu": "4.60.1", + "@rollup/rollup-linux-arm64-musl": "4.60.1", + "@rollup/rollup-linux-loong64-gnu": "4.60.1", + "@rollup/rollup-linux-loong64-musl": "4.60.1", + "@rollup/rollup-linux-ppc64-gnu": "4.60.1", + "@rollup/rollup-linux-ppc64-musl": "4.60.1", + "@rollup/rollup-linux-riscv64-gnu": "4.60.1", + "@rollup/rollup-linux-riscv64-musl": "4.60.1", + "@rollup/rollup-linux-s390x-gnu": "4.60.1", + "@rollup/rollup-linux-x64-gnu": "4.60.1", + "@rollup/rollup-linux-x64-musl": "4.60.1", + "@rollup/rollup-openbsd-x64": "4.60.1", + "@rollup/rollup-openharmony-arm64": "4.60.1", + "@rollup/rollup-win32-arm64-msvc": "4.60.1", + "@rollup/rollup-win32-ia32-msvc": "4.60.1", + "@rollup/rollup-win32-x64-gnu": "4.60.1", + "@rollup/rollup-win32-x64-msvc": "4.60.1", "fsevents": "~2.3.2" } }, "node_modules/rrweb-cssom": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", - "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", "dev": true, "license": "MIT" }, @@ -8630,15 +8714,11 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true, "license": "MIT" }, "node_modules/sax": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz", - "integrity": "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -8810,11 +8890,22 @@ }, "node_modules/siginfo": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true, "license": "ISC" }, + "node_modules/sirv": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/skin-tone": { "version": "2.0.0", "dev": true, @@ -8978,15 +9069,11 @@ }, "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, "license": "BSD-3-Clause" }, "node_modules/stackback": { "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true, "license": "MIT" }, @@ -9010,8 +9097,6 @@ }, "node_modules/string-argv": { "version": "0.3.2", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", - "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true, "license": "MIT", "engines": { @@ -9160,7 +9245,6 @@ }, "node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -9201,8 +9285,6 @@ }, "node_modules/svgo": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.3.tgz", - "integrity": "sha512-+wn7I4p7YgJhHs38k2TNjy1vCfPIfLIJWR5MnCStsN8WuuTcBnRKcMHQLMM2ijxGZmDoZwNv8ipl5aTTen62ng==", "dev": true, "license": "MIT", "dependencies": { @@ -9252,10 +9334,21 @@ "url": "https://opencollective.com/synckit" } }, + "node_modules/table-layout": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-4.1.1.tgz", + "integrity": "sha512-iK5/YhZxq5GO5z8wb0bY1317uDF3Zjpha0QFFLA8/trAoiLbQD0HUbMesEaxyzUgDxi2QlcbM8IvqOlEjgoXBA==", + "license": "MIT", + "dependencies": { + "array-back": "^6.2.2", + "wordwrapjs": "^5.1.0" + }, + "engines": { + "node": ">=12.17" + } + }, "node_modules/tagged-tag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", - "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", "license": "MIT", "engines": { "node": ">=20" @@ -9290,15 +9383,11 @@ }, "node_modules/tinybench": { "version": "2.9.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", - "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", "dev": true, "license": "MIT" }, "node_modules/tinyexec": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", - "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "version": "1.1.1", "dev": true, "license": "MIT", "engines": { @@ -9306,12 +9395,12 @@ } }, "node_modules/tinyglobby": { - "version": "0.2.15", + "version": "0.2.16", "dev": true, "license": "MIT", "dependencies": { "fdir": "^6.5.0", - "picomatch": "^4.0.3" + "picomatch": "^4.0.4" }, "engines": { "node": ">=12.0.0" @@ -9320,22 +9409,6 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tinyglobby/node_modules/fdir": { - "version": "6.5.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, "node_modules/tinyqueue": { "version": "3.0.0", "license": "ISC" @@ -9352,8 +9425,6 @@ }, "node_modules/tldts": { "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", - "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", "dev": true, "license": "MIT", "dependencies": { @@ -9365,15 +9436,19 @@ }, "node_modules/tldts-core": { "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", - "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==", "dev": true, "license": "MIT" }, + "node_modules/totalist": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/tough-cookie": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", - "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -9385,8 +9460,6 @@ }, "node_modules/tr46": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", - "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", "dev": true, "license": "MIT", "dependencies": { @@ -9420,7 +9493,7 @@ } }, "node_modules/ts-api-utils": { - "version": "2.4.0", + "version": "2.5.0", "dev": true, "license": "MIT", "engines": { @@ -9489,8 +9562,6 @@ }, "node_modules/type-fest": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.5.0.tgz", - "integrity": "sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g==", "license": "(MIT OR CC0-1.0)", "dependencies": { "tagged-tag": "^1.0.0" @@ -9601,14 +9672,14 @@ } }, "node_modules/typescript-eslint": { - "version": "8.54.0", + "version": "8.58.2", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.54.0", - "@typescript-eslint/parser": "8.54.0", - "@typescript-eslint/typescript-estree": "8.54.0", - "@typescript-eslint/utils": "8.54.0" + "@typescript-eslint/eslint-plugin": "8.58.2", + "@typescript-eslint/parser": "8.58.2", + "@typescript-eslint/typescript-estree": "8.58.2", + "@typescript-eslint/utils": "8.58.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -9618,8 +9689,8 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/typewise": { @@ -9633,6 +9704,15 @@ "version": "1.2.0", "license": "MIT" }, + "node_modules/typical": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-7.3.0.tgz", + "integrity": "sha512-ya4mg/30vm+DOWfBg4YK3j2WD6TWtRkCbasOJr40CseYENzCUby/7rIvXA99JGsQHeNxLbnXdyLLxKSv3tauFw==", + "license": "MIT", + "engines": { + "node": ">=12.17" + } + }, "node_modules/ufo": { "version": "1.6.3", "dev": true, @@ -9693,8 +9773,6 @@ }, "node_modules/universalify": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "license": "MIT", "engines": { @@ -9767,8 +9845,6 @@ }, "node_modules/vite": { "version": "7.3.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz", - "integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==", "dev": true, "license": "MIT", "dependencies": { @@ -9842,8 +9918,6 @@ }, "node_modules/vite-plugin-checker": { "version": "0.12.0", - "resolved": "https://registry.npmjs.org/vite-plugin-checker/-/vite-plugin-checker-0.12.0.tgz", - "integrity": "sha512-CmdZdDOGss7kdQwv73UyVgLPv0FVYe5czAgnmRX2oKljgEvSrODGuClaV3PDR2+3ou7N/OKGauDDBjy2MB07Rg==", "dev": true, "license": "MIT", "dependencies": { @@ -9969,20 +10043,19 @@ "vite": ">=2.6.0" } }, - "node_modules/vite/node_modules/fdir": { - "version": "6.5.0", + "node_modules/vite/node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, + "hasInstallScript": true, "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/vitest": { @@ -10109,8 +10182,6 @@ }, "node_modules/w3c-xmlserializer": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", - "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", "dev": true, "license": "MIT", "dependencies": { @@ -10122,8 +10193,6 @@ }, "node_modules/webidl-conversions": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -10138,13 +10207,12 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/wgsl_reflect/-/wgsl_reflect-1.2.3.tgz", "integrity": "sha512-BQWBIsOn411M+ffBxmA6QRLvAOVbuz3Uk4NusxnqC1H7aeQcVLhdA3k2k/EFFFtqVjhz3z7JOOZF1a9hj2tv4Q==", - "license": "MIT" + "dev": true, + "license": "MIT", + "peer": true }, "node_modules/whatwg-encoding": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", - "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", "dev": true, "license": "MIT", "dependencies": { @@ -10156,8 +10224,6 @@ }, "node_modules/whatwg-mimetype": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", "dev": true, "license": "MIT", "engines": { @@ -10166,8 +10232,6 @@ }, "node_modules/whatwg-url": { "version": "14.2.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", - "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", "dev": true, "license": "MIT", "dependencies": { @@ -10271,8 +10335,6 @@ }, "node_modules/why-is-node-running": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", - "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dev": true, "license": "MIT", "dependencies": { @@ -10294,6 +10356,15 @@ "node": ">=0.10.0" } }, + "node_modules/wordwrapjs": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-5.1.1.tgz", + "integrity": "sha512-0yweIbkINJodk27gX9LBGMzyQdBDan3s/dEAiwBOj+Mf0PPyWL6/rikalkv8EeD0E8jm4o5RXEOrFTP3NXbhJg==", + "license": "MIT", + "engines": { + "node": ">=12.17" + } + }, "node_modules/wrap-ansi": { "version": "7.0.0", "dev": true, @@ -10316,7 +10387,7 @@ "license": "ISC" }, "node_modules/ws": { - "version": "8.19.0", + "version": "8.20.0", "dev": true, "license": "MIT", "engines": { @@ -10337,8 +10408,6 @@ }, "node_modules/xml-name-validator": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", - "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", "dev": true, "license": "Apache-2.0", "engines": { @@ -10400,6 +10469,8 @@ }, "devDependencies": { "@arethetypeswrong/cli": "^0.17.4", + "@deck.gl/test-utils": "~9.3.0", + "@luma.gl/test-utils": "~9.3.0", "typescript": "^5.8.3", "typescript-eslint": "^8.31.0", "vite": "^7.2.4", @@ -10408,13 +10479,26 @@ "vite-plugin-svgr": "^4.3.0" }, "peerDependencies": { - "@deck.gl/core": "~9.2.0", - "@deck.gl/extensions": "~9.2.0", - "@deck.gl/layers": "~9.2.0", - "@luma.gl/constants": "~9.2.0", - "@luma.gl/core": "~9.2.0", - "@luma.gl/engine": "~9.2.0", - "@luma.gl/shadertools": "~9.2.0" + "@deck.gl/core": "~9.3.0", + "@deck.gl/extensions": "~9.3.0", + "@deck.gl/layers": "~9.3.0", + "@luma.gl/constants": "~9.3.0", + "@luma.gl/core": "~9.3.0", + "@luma.gl/engine": "~9.3.0", + "@luma.gl/shadertools": "~9.3.0" + } + }, + "packages/network-map-layers/node_modules/type-fest": { + "version": "5.4.4", + "license": "(MIT OR CC0-1.0)", + "dependencies": { + "tagged-tag": "^1.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "packages/network-viewer-core": { diff --git a/package.json b/package.json index 1f0d03a4..231599d5 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,8 @@ "build:all": "npm run build --workspaces && npm run build", "prepublishOnly": "$npm_execpath run build", "test": "vitest run", + "test:unit": "vitest run --project unit-tests", + "test:browser": "vitest run --project browser-tests", "test:coverage": "vitest run --coverage", "start": "vite demo/ --config demo/vite.config.ts", "start:open": "vite demo/ --config demo/vite.config.ts --open", @@ -57,13 +59,13 @@ } }, "dependencies": { - "@deck.gl/core": "~9.2.0", - "@deck.gl/extensions": "~9.2.0", - "@deck.gl/layers": "~9.2.0", - "@deck.gl/mapbox": "~9.2.0", - "@luma.gl/constants": "~9.2.0", - "@luma.gl/core": "~9.2.0", - "@luma.gl/engine": "~9.2.0", + "@deck.gl/core": "~9.3.0", + "@deck.gl/extensions": "~9.3.0", + "@deck.gl/layers": "~9.3.0", + "@deck.gl/mapbox": "~9.3.0", + "@luma.gl/constants": "~9.3.0", + "@luma.gl/core": "~9.3.0", + "@luma.gl/engine": "~9.3.0", "@mapbox/mapbox-gl-draw": "<1.5.0", "@powsybl/network-map-layers": "^3.6.0-dev.0", "@powsybl/network-viewer-core": "^3.6.0-dev.0", @@ -92,8 +94,10 @@ "@types/react": "^19.2.2", "@types/react-dom": "^19.2.1", "@vitejs/plugin-react": "^5.0.4", + "@vitest/browser-playwright": "^4.0.18", "@vitest/coverage-v8": "^4.0.18", "@vitest/eslint-plugin": "^1.6.7", + "@vitest/ui": "^4.0.18", "eslint": "^9.26.0", "eslint-config-prettier": "^10.1.2", "eslint-plugin-prettier": "^5.2.6", @@ -119,4 +123,4 @@ "vitest": "^4.0.18" }, "packageManager": "npm@11.11.0+sha512.f36811c4aae1fde639527368ae44c571d050006a608d67a191f195a801a52637a312d259186254aa3a3799b05335b7390539cf28656d18f0591a1125ba35f973" -} +} \ No newline at end of file diff --git a/packages/network-map-layers/package.json b/packages/network-map-layers/package.json index f51d1432..65f89d9c 100644 --- a/packages/network-map-layers/package.json +++ b/packages/network-map-layers/package.json @@ -44,15 +44,17 @@ "type-fest": "^5.5.0" }, "peerDependencies": { - "@deck.gl/core": "~9.2.0", - "@deck.gl/extensions": "~9.2.0", - "@deck.gl/layers": "~9.2.0", - "@luma.gl/constants": "~9.2.0", - "@luma.gl/core": "~9.2.0", - "@luma.gl/engine": "~9.2.0", - "@luma.gl/shadertools": "~9.2.0" + "@deck.gl/core": "~9.3.0", + "@deck.gl/extensions": "~9.3.0", + "@deck.gl/layers": "~9.3.0", + "@luma.gl/constants": "~9.3.0", + "@luma.gl/core": "~9.3.0", + "@luma.gl/engine": "~9.3.0", + "@luma.gl/shadertools": "~9.3.0" }, "devDependencies": { + "@luma.gl/test-utils": "~9.3.0", + "@deck.gl/test-utils": "~9.3.0", "@arethetypeswrong/cli": "^0.17.4", "typescript": "^5.8.3", "typescript-eslint": "^8.31.0", @@ -61,4 +63,4 @@ "vite-plugin-dts": "^4.5.4", "vite-plugin-svgr": "^4.3.0" } -} +} \ No newline at end of file diff --git a/packages/network-map-layers/src/equipment-types.ts b/packages/network-map-layers/src/equipment-types.ts index 1f4bd215..d26bf313 100644 --- a/packages/network-map-layers/src/equipment-types.ts +++ b/packages/network-map-layers/src/equipment-types.ts @@ -129,8 +129,9 @@ export type MapEquipment = MapVoltageLevel | MapSubstation | MapAnyLine; export type MapLineWithType = MapLine & { equipmentType: EQUIPMENT_TYPES.LINE }; export type MapTieLineWithType = MapTieLine & { equipmentType: EQUIPMENT_TYPES.TIE_LINE }; export type MapHvdcLineWithType = MapHvdcLine & { equipmentType: EQUIPMENT_TYPES.HVDC_LINE }; -export type MapAnyLineWithType = (MapLineWithType | MapTieLineWithType | MapHvdcLineWithType) & { - // additional properties from line-layer + +// additional properties from line-layer +export type MapAdditionalProperties = { origin?: LonLat; end?: LonLat; substationIndexStart?: number; @@ -144,3 +145,5 @@ export type MapAnyLineWithType = (MapLineWithType | MapTieLineWithType | MapHvdc cumulativeDistances?: number[]; positions?: LonLat[]; }; + +export type MapAnyLineWithType = (MapLineWithType | MapTieLineWithType | MapHvdcLineWithType) & MapAdditionalProperties; diff --git a/packages/network-map-layers/src/network/__screenshots__/line-layer.browser.test.ts/line-layer-basic-chromium-linux.png b/packages/network-map-layers/src/network/__screenshots__/line-layer.browser.test.ts/line-layer-basic-chromium-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..15e3938dcab31ecca56e09ea1b6438c65b7b3568 GIT binary patch literal 4537 zcmeHLT}+c_6h5VhLlRCadyQm+Z4%)7PYiM+l&#m z5J5pjrL;4|5QESQW3Wt0FX_{c)vKtk6<^$_M?~dDZ(}dee(0&FOj1&vTyV zI9+OXO3|h3g*-C&VirqW59Vn)a{e7@*+3#1^Kelw} z6B7PfQqEk`w6-n~4%fD`nFkjCw0G~-<@5Yh;lTAnr&?y{vEQ`bsy2pdFisr?yR;d= zaDxW$OFY1a0szH9I>5tZfWw36ax>x*!6ib5h)5!v;bW{r-IG;W(xo6!#waoe%NHj4 zJn}G$8=U$UiZ>>Mbr(;~c{J@dPj=MR)q(fNO`tm`v~@Lhh&>}!jIIaws*>o2swd#R zFPWRl7rwlGZclxN^KK&d6JQuugKnRSEvXF$TwKahpC?-mf*Y8pckD%bQ8*OjYekWY~N7QA@K%hhC`^5S5>5KB9JC9~}9tEb~Xf%o(_s_i4 zNxsOFQ9tM8w7tYf@b=3iXeOOBzo# zEY8l(-ooJ|0K>Ezl{XN)XQw4&aPXV0+2iZ;6}zXunOB5`24)>Kl+9Y^w}4l)GRmM8 ziA1%CC%bHJQ*Il-XVPUVav2-J+s%wtkZ-IlSy_*`p^2K5gvvl*(zJ!e>U)QD-vAtM z3(UDS)JQ|2uP04C{7*$(euIe{W_!Bkg-}c-W4SJq+SQ#Zf9UM1pL|uBIzn32N~e!m zrS4Yn`Zj}d1veZhTE#9tOHSgil)k#U+BcA!hiGYNc0LpHXWB~ZcpPd?4CA?9RyRN&!JJvBcK}!MkgHI+7phiLzGEAGS+TO z08J%2KSdrEA##3e2?KPTWDu~#9_ypd62E9{=vKxwu2N;kN#)9e>Yy!LJ5HoaOO94pLU0fIbi{+Xk@W)jgG zelyS_aW#sg4DMERy(0@sRb07BA8;}-su`oc)XTa0&|E>+?7vk?r7~J!&Z8UBCj!)D zsox@|?B$8R(7b1%V)81@o+w5Q6zYRtc6WDEubXP33>2!avIEN(TJBsRgGx(FquB#T zVRn0#bn5d=;mZd|0;S(3=Yo=f^Q$DRA{a7Ld}e(JX~0G6)2x!2b=-h=`?$5Up)xUb z1Q$RFFx3e(`!&KlgxB}>`AtGY$<*t8$P*DW1+$+-+1|s2Awsn%RjLs(vr>4b!CYHEVxoXwzHO62+hoAD0M2+1%ynqOU0LpM+Z;N4#u4*E&) zoLPH$U_9uznNVHG#!tbhiNTWIzFpT|Xfu*!HT`CQa754IaE!MK%)VxBa4jg28jNRk zX*{yI_;*gOCBhH8`+3}WaOKhsanraohe!LHDQpNQ6lG|*MzdFFOZ-A2x%Aw&;p4a+ zGLg4&C#2FVL}3Wtdnz;_7b|X~YYvY$Ic?5!4G*sY-DSkJ;x_6&kcuMYqA EA35R22LJ#7 literal 0 HcmV?d00001 diff --git a/packages/network-map-layers/src/network/__screenshots__/line-layer.browser.test.ts/line-layer-large-network-chromium-linux.png b/packages/network-map-layers/src/network/__screenshots__/line-layer.browser.test.ts/line-layer-large-network-chromium-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..e9c953004e76160ff58195349ca8114087ab4fa0 GIT binary patch literal 46917 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 z z*tKPKX%Q7&zD%d~DPO{CkTcHRiiqKA}B;aXtb&-@s`)~du4QW*WqT=Xr}y-b~nS3#VCopec{_=hKDF61-G9BzaVIr0E#C08)A{!yS}Wcu8#By zt)(UkC0ge-b94HXR8-(KI3^}0!%{8K)tOgSMOtk1NlvEp`QU9ju31Q~V?uVG8lCEeNW|Sc7N5uv0>)r%LFb#GEp3CwEQ^;}W*V35WnaomDFoW- z^H>QmxD8S6?_WJ12aYM=6XQTZCWw*Vp2Fkb@(vS6-cX0Mc0EM7Kj(L43*Jh2XJ=CWc;v)6z1es>bm;`bFH>*{ir@evcyThB-3@_wha$H=7JL0cSO)=j_cj8>&Z z!XR7lo$Yl`_%GwtfW(H12_ySlOj3omoGM1nUG+z;XR*c&!@IfsC^Jh z{odkbNon29qmhj2(ijK+pKVli6a7gXa~zR=g}whR(xs*F6B#@F*)cj7iRL!+5zjAt zfRMyE*qjj;Z1m-%PQx9wlJOCtaqN70d~#r_PO=!%I^cQ4{rzz^=vhBF48i?)<@1JC zJkmKmyPn$MQ=TzZ)L!!I@uz7a_#ck>q=-Ksx?(jMJ?DFZ!5}`HaV)$7Ti>6lTA!G% zNRBAug7%~ak#|~IGYFE|2m}$_SxNV!;Z@O^df&J?Q4$wn5*s$%Qnr5^hFHAOwqP-s ztBUF+B&=cMz)dJPQ~*7~{R?E(>(XQ1VEn2Q195-0Nwx$2v`us3qZ!r{|kG-9o>er%8`koE_J++NNIT`%ZT4 zp4BPn*{lw&w_Ql63hm*sh`p7@;3=UtN7r08=>MRKU31evJ?Z8_RjtxYQ*JJ+O585| z$% zWe-XodNq=V1PF;+8{-xEZejLk_FGO?;}a4=jBCzg&h7%YH*BPoa@vDCRfkm(V~Dpr z{HQVW(jc9mAG{Q=<*5Y_rFsA2Qyy)>mf@Sn#L+StVl+JTe(LHnxjpT4%*sqXR;yb6 z-;37|P|+u-sIWQ7T#Nm?pYi3X9ynoGS<(5=9*MZmX11MMdgj-CAXu6SE0J|@Z5<_M zCO!lv%liGvVrQ5jAr)co<~w`)Zv_S6G2)k@o=0nO2?>Eh*x(JyUQX%IMdQ~y%=)ap z_obi8J298?`?I|~N+vXmXtQ)Q9#W(pho^sPBqAL^smFD+a%s2J9-ir|cH3Dx?NcmL zP+rRi+3qZ$_kPx4zyseyy|TCt~R=u^6OnYiq;6$G14%_ya&g zHW#r^0H6x=r*A0t=zOxN{tr!G9TsKReXVp1Fi3Yv2#9opGJv48q=2-9B7)K>-Jyum zDczt_N=r8nB@IeTh;;bd+#BYiVC}1jT%dS)6ZLS{hoS6){KP z;QkZm(0;z{JnCfT%dxeu>8aPdn1}aubjUmFEl(Lz<5u*Jms9vm~*0SfFSJqg~8P}V;`OLyak&sH1{kKk=a5kIThxzBoM;~75sH!5wW}V484eOn6 zpu)12e>=U8r%CG8H$CHyRJvttK8`}Eve3u&{}pA8X`| z=}`#Ei0n)*g3_<0-UbIO&xIT1Ts%a4o-m14M;qnMqv{OR4WH2FWGiJAar3>8EGXbo zkC?`EIe>^BA8CeSv@lx_BRkCb{el}>hKB`O_O?%#7w74-J)2V2{keQoQ@bWrN)l5E zSnhG7!WIkp8{GVNwO{Tu(3u$-NZHBduaU%zwuc~k%8#Th;!AsZhbG3XM+ zWwo6pea0HZZ_dslX~L1Kp!=W#{g{nWzo;q=$NiN15;LBO;XMl09|jgC{7ywg`|o;r zNZmX$#3RE0wz|K#e*#(`z)sZfKWF-K#FB_el)&E-ZEqeW%_yAuwW1$NTv=Hkt>{S~ z>s=kQ#fbZUFpAyz_5B_UOqTX8Qfs2+H>oOJ;oXZMVNk#pG541hHAS`P|%G?2N(CZYx$%QA+eW6B5(ES|24{vVW*u z7gE(BXzW0x*A_8rWuy0<_g%DU$mr4sQ&{@dG&e>Ne{w~%t_|nxd44s1*)L*cV`C|p z#Glen9nzw!|0oy`j5xLFtSVZ{fq+D=_M}|4nBrePUEiq&u*DSOq-XEc+~DFy;q8&= zwe_ra_{Nw#zjga!H$O^)dN4TW7Fyr)Yr3Y|^_L+$?nR%qkdu=WyukK{nnr|>b~ml?^@r8_CG~nwtZ+fTM!5VA4W22+0;-R4}RL zimm`+%e>yEjY*kP*?<3tUp}D%xOzs}CWxUkHzmP4L{V!ke^YYFbgGJDbi(n9$_$sf zp%ERND;;ta;%&q`f@IHRxRbIVM7O1d(ojjo7;((EwtonRd+_1tYDm53q}LU`M8dj< zVbw}X^!kS`909VL!k7B+GAFQS53YWhy-NIL$$aBNG-ksAPxBxz^wKJS_1dfb#TBeG)1v_?;gq zX^{gP60AT})1_$yUiI{{+#~{=qAcW5NwG<1NHP(5J5?Ob>w8WX0^u?t!rmH|EnC*yaH39*sX#e4I@vf)#OX5kN}PTZNc_121rJ^+3T|rA zc&g3QSyWQ;Afo8>mYe{_fWQ3`qzY=>YPEZub)887j_7Z07WKOSdm zdxt}-o68yvm+hw;2iJo*_;0;rjD7T*8upmP&%JXZoxNRGQ_!d-}khImpo{UA;GN6i$ zf%VhTWxstpqojnl{mS%bA|OhKkyU0{W1giPjeeiLe;YfvyF32GVv#DmLXn^APo4RJ z($E}!ZO@sQk&qLdOr>9sA#YP?Ih*N;1U zhS;qYxC4Z4KBiq?TsI)%5p4^}=0ea;yS9CP#P5gGuHgSIO1uWD@f1zx-XN z;J>%trpn?HHriU7CPjF>M1(wAGI`TgrS(H1;WB*<-+Qgmo=7H`ap#$0}@qEP=QY9@ZkKgfOIx42H`Xt@=A~)fSdY zc{_#E*;79f)I?HGcYf^2vKIO()~{+^>8tzqmZV%W*P_WK@{wDjEJ4%;?Ck771OT@j z32r1FNb2yhFz9o+2!I>UYxFq^#AfZB)f_*U9K@UNO@AU>>6eeP_ewdeg2gl1_#8+2 zS}vRIHGqLa+BR<%l$)Oz(EL|K(w2M>mw~Br3r9^J!6<1lG~$xRuJUeZYN{JTA!zoz zQ%SSUf?l!TUmaET8@k)Xmg4j06PCmueUf#m6!9Xb;@BRsFW38rSqhK>dTn^vv)Rl+ z;!ad1?ko`V{~R2kvpX##qu%O4Srtf7lq6c|KTb_MT1x><_70*VkE5&WP82;90p;_N zw-%Py-{e1hRGC~mBu*J?(x*Xrft6xz*|mF;Rfr8+{X~damQvt&EljT8p$2%!GMj{*z}muCo^3>-s*dgTB?7tB z)DON2U?K*s(qGnXAw+0~g|MjT3!Tea?-gVIP@*!T$)abxJ%&MJ6|9#@q>LJaE!Wf| z=1IoJD$K5098W`SlkhBo-iaZrb6P&5CYHudsP^-&A(Z$CiC<~E+qh-|Z2?JUH7q!s z3<68*qQR5llJKN4zYnk_^mNig8rZ^$$2DeYnc#tih5CH|8_-H0U{2HZ6^=)_e+I1N zk&zJ{T$Ru`J1s1VDBDDf$!~dY6Sn7f?7N;!qhXvz$@O9@MQfJJSP4lYQ*d7Rwi#@O zbY>8cmT9{1_{=zW-$Pr1u!>TX+Ef`L9&t5h{;)Hf)$nfHl_$~R5pV|Q45_wpC9i*_ygCsn6gbYY^q?uR_k|gF(Z578gVTGnV*#(>Q^y^ zlsA2*bn}_dv$y{xI2QauLa)a7%}e}@-V1s_^0EtQ?MtS*9$VgGiVPH^Y`gSH2iDO(6SFCMcA6Rxh{d%_fjdlYr4ZO?wYH*G1~W9!>H5p*kJHB$8}jeUjRsmvf`4@W zv=k``Bm1-65SJW5J<~(mi-vWfZvjd7$HR|;a1TMTucoSuXfu4t11aeBj+XajcMxil zD8z#SRU#XXzpVAjY{H7)W*I+Z)DX_3UDc6aEYKBm&ap+l`H)SEysg$rTYBwvF-!Z@ z(u+DT+`So0)+!_8w9EhhMv~-9R#YlJmWTO{o zr-@|#Qq*GC!(*Zs-FWnWhpDQb-j`S)V65#(^!l?h>$BI8j#R81wat&q^WzC|%Bfzr zSQ{a=2pjGrIK;yC!sr|lANOdgTwX_vJp7seI6tG~8k3At07SYDtu$QBk6VXXNffC` z+z~i=ND7s=0Z7c2pD%{z=F}}LSV49X#dJHJEP*n;gJkt0?!D`mc1$Me<^!@aPS{gw z!_*SwOoB~1Cdm%_ZBpI9dBA@ck<7GgP0>Y zOn{AJl9ZQd&eF9^D_m!nw$_Jc)vO_+3@jlx;^kSmO*y$uSIG)9Z5K8PA2jqRH8Wke zkGlI?Ixy$(q9ytXmq88%N?W(joB;i*)q|#g0r~>c3Y3WnBWG{6QLV$dOG$}AH``Mt zbFFdKmDuFiV{#&*p$S}k{IKdls@=VTMmMgfylo{Zm9%It z^BHUMFDJ=d8M6$L+{$gT02#R~(;<>*BOisBv7u)KDEg}rK0Nn=G86bS=w7(eyc4% z7MMzgxr1wr#CvqfnpcUlQz)FJ3|MvAyEKiBRYA^%$udVe*fjXp4UN1VmDb170eSNc zTlk{turqmEK+|Aw3qE+v@YP;%TJg9r=}GDJ$ohkg>d#V`&Yt@7NevIGw4t%+(;icN z1xZcqYnmu|WE-5-rMGt0!F%%`M+Qe}K4jzzbya#AVf|haS#iU80=x1qk3lwh zRg+cg>pYhB@cO4K|8m%6IwqUNg5W;&jOb&gr{m2NO)=utQ7KYSoNqJ3 zMRfRgxNSV+aBP=Tp4Bht9g_LdiO}f9YM*Ol#wckFnULq-t`wxssM9IYoe+ ztTyu%A0Ph51QrVi9%r_{o;^M}{W*!Cql&6~#j{_ga2|W-il^sdVDy?RT}IQdO?q3~ zOt4@jBoaDk(d`XxN9W{Kmpj=_s*>rHQeie*lioR zFo~&udHr!$ID|}bOp{1R&W$9a@G~XQY%z;VDx=uS*tYB^?=@|58V^DU2(xsT)~q5+ zHZ;Fa+O8n*ZKredAiIb=#GE;ViGc-@#3YJrLYJ7_0s`IVUMCCVCW7VsU0>&-Zs^E` z#lAG4pAkHuB>u#()aiF7a9esO^t$9Vn%5f}Aj%VPOy~1R)^}^_N$}8r@oe!ETy&b` z*n0wWpXK=R_HADE-@mOkIwVXa;Jprr5=Fec`O;CT>bdNHC4Z{+aKDNx75?y>4L~y4 z6yW5rDxtyMli>{}bX))Zib+JeC(lFSZFB8e4&SC*?c$C3e{K`Ys~iYoxCB*oa-j-a8Z!8_o) zr-43(-95))@36?bQPKcK%MJd}6xVAvNC@idQj-@L1e4Uy|ucP?5;DIXT`PWC@9PbHvDci$ep3S&pnlR2Ei%Z3B{di5t$kIa@ zd`u3OUal=(Oej4`Rc?hSWB4u>PW!hV=lSxEHMq9344J-ZB#MCr7(^^9kNcMUZ+-2C zx*(n*t$z$#Ur1;Do#sq5u0&bWIkxY`Q}=VHcAMgzqWr94|9q8nj^Wo`eIJv&pRUv( zI~O-XZc1ei61_LQ5`%2-%3}+nuIe-A-W%1m$hYO8S z*}E?c1g-m{#EF}jMC}8SbgJA~DHJS#!^x)?-SD1iUH!G?*WDIT+z`&KQ`z~{%C9?! zS_1CZ8BK4@B+{grzn2%hbWKqK#~2~N5Sw$yeDmfwv_FOPZ&6uwOd64t$JZ?vh~R^2 z@eZtF98`NW-m;Um4EK8%MuOw0Ly=0b`$E`fv*TW-C8cimecU-3{mj{1`DIq_l*ScX z;7fmZqC7m|;4`n7SYn@c=srW6KFB(=npiKSC1Z9J7|}*Y7DJ zOwqpuHlFn7MS;en?IQ!<;TIto+E&-Tx_F%^)Dzbemw&+^k-oCr!IBB*_=xyRCt>cb z-S%7!&9|CC;`q9sc6&_C7kRn*6vH&K;eEZPY@$YK$iJFfxzdpCm{Wk1Qe^vuL1uAW z|G4KSn$)@TWuHMd__?pPRh9%(OSzD1-qeuEO*0=9;JTn=&h!L>g;*9XQ)+j_H06ahp1 zy>_aEzQxhaia1?upsHNw5PWdqGH-e^J3hac5N^7d9PpHX(;B)WOV>ZTwSHHNOGo4g zf$Qy(J8S{Abn6F0s%DcEF%ezkQx_?+_un7A{-W7=t?UiI5hO;LPY5h*Ra`mthn7O! z*8)RppC9#sgYH=tAOKIyFn7B zy>Qr^Of)ov^`7??KQ1a2kAWrV80#HZF#deywOt%L-aXh2ceKMZew;|!hM6x-S2yYio;T z!=>64i2edD_yTd_G0m`)Y%($IfUBB1mlMg)|CmK;b^Q&&ewi3RojlMh9$VP0U3W4l zrVU*b-4lHQD;>SoF@2#KmwKtX{ZgrWvC5o0f{{D@myCeZi7QGSwQj_kbz3N_DWKVr z&_7hxI^o2wNm?%>tlF0PI=RGBKg8@(>2EEEV2Q{!6Pr5e|Jh`IqSWi**dJ(Yu(r3n|*34E@4fdfVOZ=jvlIxR&51m#$kv@GZ(Mt^6JcO~P`VL&%l za);x{>Mu*5e$VvTQ{H`{RUt@zP1AQDx7!t!1s)h>F;m^mWkoY-fR|)7NsdSfU=Q$H za%qWp`Y5VyyqPwaR7gu+$lqFzTA;q(e9X{&Uzdv-x4TPe+nhPrlsP*)JMQ<3jZROifKeAvBUAeCg3}rtA7TLk0jTes7K5p-0VWeJ zxM_{1kUYQinb{j>Kwm~*qC5bDS&b-4+4JxOj%T7OM+||h^Focm5K*8nm^t{?mkE)7 zI{3WTF(+2=q&T~G_FMV8bAoDzyQv&CxN|3TTm-ydsez{9x--ubgtU2O9q=&{;Yo`D zmFLjMF{Ne7+fLffccb{I=u0}rYH^>rVLws9eQO_5B{*4y{n_51GyPR4Q%D{Mn2y|6 z$@)SM&Bcu;1?Bk}O}W@I+!2M^`Bjg5DNjFv@z(hGT}ar`P@F?ewa30SI4k!Q=@x^j zE;E4K@sEYtDzbZ_l*io+YnQ(b1`ZFquxj*HxqnY>s zi-Qb>z(OCCK-DY)JE}xHoR(2i=7pabwNEf7mvzab7a#Z24!I6rFXB?&H{wy>>{T|BrF2GwY59eb~k+PeC)qF zH(m-A)%j|=%$AzQ>c;*+PEHPH^_1%E$Zsfs7V^1UDO*ZM9UebAkZe5tuJ2(sj2RWq z*fvE8MCgc!Y)P}Mk00Lx;-yz=sCaR>M9XL?;@TkPzItYz~HIA98bHw+GG+ zj$cOA4@eI5O2;M@3RNcA17uBoW%GV!HUXbB32Pgv1vB~}J9rhO`>dJ4>h=+qN^@!_s5Q7x61kHm7L;d(crXEs@`g7|05uEF@O^kn^Un(f~ zVD&u_@A>bSk>Vm-VsnZNBJjMJ*I5FiHo6P4x+* zpWn*298~(xP-x1)5PgWi*~`1IFr1{V4gb46ga`p>7m_PxRaLzSC*#cClnm^q^O|3P zdSv+Lx`pwUc%$YYY(X|bQcT-rFi?kZRuNPk@vMRe#;1T`Ph5e8-W>S-|o3pg*;m_cK5;V z8F&#Eai`MIF(jCjk}(E~)O4?H^ZsO!5|gjV0DdP5Sfau1374g%rLOMota>1LlvDLt zbKEixd!2-T;|9Ma4zIzL=U=fWOi5T+;?jw&g$jUSGlYQr;hy95-To%u`150Li!FiF zdkpN)hkn=CXr4-TM|`eolzF?fWO11A{^jN8XCHm{A_4e@_6`J3Kt2~=)NyfhgUDk* zq-L-m0)z2MYl0P+T-mn@Qa--PI{Z4UY$NRI$Smfq%V0kPY24N{*d2ENc87qngpkNT zo^!WSFW>E(4HtievG96Fs6XCUS==>;kVhW8ETDMZj7cOsuZJS&M_=aSo#~HmI~`Qd zI@b`HzsiE%x#D5*^IET%y0bvjHZBech!_CtY!L9k*0H|69z4xb{Vq=cj*17fx^Anb z41>}NTT)(QJa+co(A&+QpCK8DDl1dNj)&Z>KlCr0jI7$NJz*B%rKonW&cwcuHKs_h zBl*787RAH;ez^L!5?~BU5Q%H3^tDLiIn;pd0_fNJ`Z~+ao6+s<3gn85#_MaF3%`EX zJaloSV9W@G67ffblRnacND0B5L2{_q?9Z(n7Tm3vS%~M9_y1Rd#x;12HSM@iGOL^R zQ2gL;H7?WcLn_y$&f86UCDIz{TVFX@kSJ#R>-GxYv`Tf24oYk)Kl!-KT$FE?KPdm| zIdSMY;WR$3CuPqt`9O|0yUHpsDhS!d9Juv$zi)nia``fq;^Don5gtA< z$H9OUbj4UCC6l3PeT|F^cocU=h07A&N1Ci~dik|}Y4<2mHf@<{ue%<4oh_tgx*;o% zm|z9<0>hRY6@|Wks4;co1K3O!+w3n5NSsuhfhcCLMc|LmU370Td2QW4o|8o=zSlfP zd5Qj|g5XM+6~@bVqxJhWI*or~u~uha9h@4g({r(#YY>&DG0;mmy;Zg0m#TTj3AUu* zf@o-DS9Cr0t$8q(qe`pTiM`LTY*lkVI({c!Y8Sw?y_&VJL= zaJJY4u8EtdBDkj<0_S&R zUd`|36mjeS$O>H;H(ES)n*50G>9x4sz`_$5`ylSY9eXq0K_;*C4-3~B6Hl(Rm6aeK zJg6O?4%JV}# z^f;xaX)A<<m6c{dWKcIrYEMaBNn$i8|RlN`83v=s7Zz$h|P+JrA?~ZUJ-X_z#B^UPep3xB_ z^y}z1OGUU&lOoH6eCxT-|A?JcVim552D9iIBftUQTSC4tI~%Qng&XlO6X_XWwyfa7 z(`#u=&fp!I*oAlQw0C~kEX#Ou*2J0HiTzV|XbM~AE7A-*KD?Kbk=XCZEwgBM(^TF= z!hjb^gCEfvnv@~Vq&DV$+B}N&FtFn67xcc+(5s3HA+*EcNd4T9tW0Yz3AWY4C8tE$ z-6%2XSLSx$UUBZVGm$!=l^WdoQJEWC$?Aihbu}x@TzDaXELZa((Zh9qAzYR+5%e)w zO)ca;0UXX~$0n0PU0Uc)o9r#2rYDxl7wZ}o_B8T0rKM9B7R72r(Ek3p0x{xs2a- zV`*u@0$t~5J!-_Y8MtG{jD_`Ts_%rA;dM!m!8bxbU;hpNC)QT|3%i$X5D%9e#cPc* zMHCa;mISbs+6L0%USAClM^I(VE2-HK-J)o0k3BpO>wX=7vKW2)IuC2)9TjGaL=Wkq z@vGB^%}aH0DMa-#$eiF9BnppQH_M@h%I!VV^H@|nBKnwJ((_d-`wgDJbVg+rOL4p8 zj`Nd!E!_k;78Vwuv{1J3Yrd5dn7MGKpSg3^c(Aa)(Dx`<#z(aMuADu&@TWT}QmNwD zX|qU5jH#prXUA?hIQi)TGF}UX`OTZbW5tW(MkkpMhpP)Td5(wEnHG0`FCU%NJ$dwK z!I9rsT{z85eh;S=qcxFKDv3o*0z>a%nXu^l!b);S66wc?yrpwfbZ z;+!n9{yHzYA8J<}A9uu7e|o`l^lhe7SHc+&JbR1BzEAWdeHKcMr+VKh_SqY=e7?8- z=VryasI#t8RA&6+-BZz8JDMM>0eP(Lwjcg&GnTph4T5Av7FPXE#+(;1#iN<$6k=tf z)VBMU_zyJI2zEBt{h#~MH6Gk_l%ydd*Hv^2LZw)Pq^Vy16A;C@} zhG&KzfBKb9_U4$X8*OD8xZNsU2Mp1%nzBEjs343~kpBv2Z)VB0m4R0!!kQF8)TJL? zcI4m+QTpw5r$$bH`N}s9FS{Fmw3?<>jQ#O__vtisqhkH&q0sMKmP6Af9t-n_a$XZ& zzT5Y@(A{wGLDQuX;=haz%8Y1hmtEOn><8Ca*l19JEsR%Wd>nVF$kncZBC6g7jN(A zsPg;k>n-za@)_mjd1&+>3M#S}%h5q0z=ejrWNe|C^k~#>?Zm>J^mSqC^;q@sZ?&7DD(EoG- zk>0GgkV*ObkPsZ$24HmGY*7jHg?px^Ou%ERo{GxmN-ej{47{0ZbljIA+XmtHN8^{X zg6)!(49W|#ZkFya(jSL+w0Y=du0DMyZ+Oj?78Qm4z5a+9q>9;KR3_!NZFPBmGAYkX zFZm+wk>3enjgpekX0hqx-g-e#6*ELu4=Ri|dqDf~qny5&&RFY|r>*_fNSbqB{*)8bcYMLvgl3(@?(6IY zWg#FaTXZT>HNB^0NjlB_`88$o-AwklmpZ!N0KWhc!s+QLSJxoN^=5_f%lNIA;uRsG zz%x_=>_$XHgq(tc6p3sGn|h$rqDyv|iUbbCFuE#rUAnE9z5GSNA=3P+xwqSxTX#fP zYqn7sNdzaSB(6Zf>8bgAgXZ*=ed~a>7^G$R=WQ7XT(w-_5)S-D^o%KBuRwyA%)>JU zMfUzqZD4EJuSsnmRa5Ek(;D(3-)pUJHH>IVb*d?hmUJ*ierpLwpWePCR5Q9H)OI8v zpS8W`fgY8LTwCx93WZ`1I2P16-kU~4<98RnVB~%K zVKLt4ZN5y^6+Xbi!5<?Kcrb+E=DWnr$t6ig`q z_6a~zFnq6|pa5iNmZ{PnZ@>W4Wag3;mzH=pMXhOZj{T@g*z$&UPTq?~E+ujcECxy9 z=_9#I;Y3jy40}9*aof$gKv2j=zNjN zq=ll>M9O#fnEJpQ*-5?E=~fzr?@XF6Zwod%mSw1+#d?J8nr%@wh>To zAaja#c9t8yA+C){Xd{o}Er7~F5%N_QzVP{-&VLlt-4k!n&RZHbrT-}ROI!PZu25kA z0hbGilNE-gse`n6BPL6^FRD}G?$PF53GVaaon$4yOZe2D<6g!E#r9{z(_+H)V(}X7n$BDa?!js6b2i}x~%3|QY(*bK=_Eb6(&Hv$%RY6qk{C!k%Mq5%*YILulT6ImO#$SRXw{QByYoP#XFREuG5+fwzU) z;SmvNVryfgEF5j%UM8K>Am|%v) zO9&Icw569DEnf}vynnR#%Rbv@p64UexlsB$+CREV1BrW9R!6F=ijlR*C zKiPQ=>XDI5la;YCRYKy<3_eq+^Xiq+{qQr#kRZ#6o6iULbt(+vnSy)w!07-ebQ!1r z<%9hWK;laH>JxbCp^4a%t5SP}RPW3Zy1b(o5Ycjg7z1g{zdN22JR5h=urzvp^Aw5BS>xcErpU{PHpG8vd7EpLR5e*~mCh(H?zfxiQeH_)*f0AQ3K~^y6O6`FPq@%_ z*1yurIwj6CTry-WW_dgOT%801-WaCa15{1Nimh#J9-E~#VKFf)aJoP!LM;cG{u%Qm zrkR{9DvI;p!AQ!p`%+$ruQtjok+gp!A|TJsxbVXm$0=Rbj~c%3>c`!+y{fy}e6Bll z{b=wRJ`1>xXv@;%M7B5lm{-FkQkUJ1MrViBpN^3@_I(MyLNrr4rVt{zc5AMAD#me! z;!HW>R6P0So6|;a)>J2h`~j<;xvw)?4nI@;PBdb~=vUtt{|(G;@(RefSZESI>-s9} zB38L@ij59a5>HvaGpV&yVPM?!x1X&~fWakb^#ge8mX?-^r>W!M;2_zoCa$in1z}e= z)8N&IAeY0@ueR5cy26Rg`*ai`VpA0&M3cROwZOp7^*1M_I$IcO4MWIDS3U}{jV~ekg;abM1exsxgyD9O$Oo)${hDX_`IwbJ#B{OGCld9h7 zh4Vqe@SB2{A9j!2RekgLjC)>&g!{*<6Ms2l^EL4c3C=jbUe4&3aCvd@;Z$4TtZ&Ap z_mT8oJK5W}Z_R3^(MC+>=H@W=6b7wy0pMQ%vrskRHtJc{uq{bzL|6I2K>6Oitn%_$_~_*1v7 z=h~14)~$#(aOr>&+Jc(mJ<1%vuP4|;2x%cb`tRX!aGHOG9J}8|0oJXhr3L+)p`~K$ z6ET9YF&D|+i!U!8i7k%mzWdwLVhc2GA?v<{)YH$NqKvc3dr!YjqU=>;5>+3{)6|zO zCvKTJUEZHN2&r~Fm`yy~S=Fxbj(8-}a9s1~@7EKW)fyiE-KFCS1^hnBcZr=Wn&t@H)n5j+MPL(K6I0Y(J^mf-Y=vKFn0myWdj51kV%GzhYO2{n2V;s zPXK%9AqeMyp%YT_Hm^Igh8Vo$+47;vZZ%hDM5&VhJK=*V&s*a)1Rp@W=y`hs!T{u! zx0nrodME43Rddn1XEW(bSP@*t&-oy(Q6c^_}YXO(ZI}YaN02Lk|53l*jr#A@+ zihz8;&`cS~!Q{{n$&Y|wi(q*VByb=W5UfBEj#9n;|1#H{g9HBw!m}fAA}x8;tE^2P z9I55v$WeTK-i*UHJbdG(Lw(PM!r+)h=c=HlOK=uwd(tq|K#ywD^nRZHf+*I(=dIU^ z9do^NUV9F@_dTOehkQB~{t)uDz7V$d?MD?YciL~AW3mjyZ#}_he)d3gZ*TA4{blq0 zqaASgLV=RMw7gttzzc(g$*QONB*5$;By9fGp}M#u))x~4L8h&%nOt}RuhF$}ZEYFf z@ghl9JuRb0P-XMA?6@NeIwqZyWL&ozf1!u$*8cdqs}U}B^~XOKO<%~b5N(ytMGo%n z%`gm-{tR1s;f{+S@Y~4#)YVy{RElL|>v%4HSB=Q@Wc|qYcwbV_=V!`Vy}G(OF$@<` z)Z$N4wN1XOr$-6<23WvmqA8?pKa@$|ruzrfA<4p#WYD32tS>Sqgz5YWId+~p_Itv2 zH!XSZgUJoxL;XtLU-n}!u9uA@?Zt{hiueBM^8*uKrv)l$w_}OMx*sVsNiR8zvVUtq zcV_CN9T{{ALCWCp^+2!4L{Mv6QlamWsC_u$Rief{qPL+;cSYzD19CuUf_R`y@n}LK zkk4T~_EKwnPiG(F277kiZ50JDy2DuN(mk3l<|Gr5WyCtdI*rMPU znXzBjfZ)r^%J<*dIhAE>3WbzbU52`*xAz;QDr6KCXyQ#2f!7KGe-t;GzSA3b;`G(e?@+&vA1qt1=+)SU9 zmOfEYB}%#b(^{AzF#U)=xdy0Xa;^PGsadT@hy^>AQ5?r929&v-*+=M4lwS~l=Vagx}+zMUo* zc1aUC;>&4j%Fs8tVKw)|1B^_vHYG1EE`-x06^F9q3ub4{Dw*#lP7~qApcIK_DzIAR zNm1uF(XWB(sGV%L3yi`!8c?U5{f@W=^{tuHa|G>MI-1U1mmh=k+`hj3y2bHRkHO|m z$NWg0$Yb_Z$kInACqaNr5D12aZR?}?5|@2KynefKZ+9JWTo^qVjJ!ox!mhXDi5ufN z3B+X(>Jg&CNb=EnZVq^&ZO`uRX9#HlXK{bZQg>juG_H0;p%2AyZX5>zkPHX{@+2}r zMMa4EoyN1Zi~i?{X|LsmIB$0|129m&LH#Zf(atZ3;NlC;;WXPuDBlB(`!JATP~IQ2 zSq&N}_l8xk61?wu^2y?pp+x7>fkk0)px-Iykno(%@vyzRvlpI4qRvFiB@AOjh?T#( zgA1qg--T#?aZ&M{$@_9Y%-pJ`Z8`R(Y|}(^LoV$%D@BAr6O*CTLNr5MJhq265@q~v z7gLQ-;U^@ZSNC210dMkDi1jD75KVnCdTAWl+cQ3dlbG;-GX7g=Jp;T*N;yY<3#%m5 za+tvZo&{drjHWX!N3NU!-ed_BLKzVdCJ4{gHK4(vN#4#6vT67y+qJr%Ww5n2;Mk7b zbvN5FcVE<1Rtq|&u6Rg_GNwU)HdEPWN>vU#5+y|Z{3WIAp}>IK=^r$Q6+LB1NGKju zckQ}dGMJAO;;3=mX09Aw2}0^CfyGICsMp4g<50gVp_l@QIS*V`RW4tj4I7-W$62LIn5YoK@U{ENEGYz$UbWLxHE%Eo;L_Z6Cf)jfA` zQ^-3@o6oMx%<7Mr{?%bo$;>Bjgi9|=e0b$}!$xitWK0Yc@YsIE6-ev;fRDoPQ%~)V z+c}x}V)lXg0`oC2AA8{sG%x}lHov1}9P&<7+=(_%!~bDjrX7&b-l5}ZlkP)&7?NiG zyPeFN`q6}wfttIF`pks`3LM%}`omQC7XlugWql>oyA^_d!HZd}u=}1fNa4UAz0S3x z^^njmV61rX=#d)q(US96__Axs4;e#hscStXuq5Fbfz}E30n?2>n#PFr^|04&j~sB) z#uXKK&&WCA@tsJOG@4_496O_tRMAL_V{}M8o>xx~qTsosg_JL-CethXVL@N$(O&9{ z^$#@)BeZ?ue^aV?HT0G&o)d_J?}ngX_+J=(XX1&!{gq0f9X)&buWvgNisXE5W-+=v z8=$8>1Qj65Wz%O-JOow)gFp}t&O#R{7uOwQxJFE72{?Nf>Zd@`o*aU-u=@8DJT-Kp z4nZ!PNcpX9&P7Y6z+-p5JeRX_QYMJ^mGKpSxvcV9BZBc*%KrBnbd3n5T<=)0THt-% z!?B+y7Mtt(_9smO^?d4TJMNYQqBDX;jIL^=*$VRAU+CNQxOiO8pc)4Q1F4@6#`=(Y zLX#TG*7oP~1G#JBwf@a^y`+DCsS*JWo>W+2ONywTp-DU+ixu* zfCBRJ9}jAic?5#lGjXv5vRs^7%1uM^C==sxE45&4snBn4cPVmrY7k}5yR-qx6>KHg z?l>nSBemqo{r5C4X*o*fWVuR%wjB(Fao><3QBmsXwO(**3JhgL8Ox}RI(kaiN=Z4* z`bt51Y)mjqdcS=HH>tvPE3it4|0V5*>j5B7qE3U@W04KcL4B$qNYU3gI7#&0Aphz% z8*HQt_4{382>!VVjwRG9{jb`^gOE9(K|!fH?=%wf=rMga~D&@&;aBp}?`;Bt z0@`ImFHQi=g+zA4Q<(i|QDK!zaJD(B-dqcd3VL;={nM!5XFP3X-XaH!nT>7#=;tVB zEb>0=NE(**$q(>y$P#+7H^*Bpj@Uw)$4eLXo!IMRnu0~l36|eX6DhLq9y-)|z}$8$ zN+I}Y71#tEMf#>ceP9qn@kdMC^S#)GJxBI>4g0ot{0UB-%fa%US;e?3tMV0O@CEtk zFVOXnfDU&UONHxApePxX8i(JD{TfWUU}Y@v5a;g!U0B2`4f=+~G z@-$H}`_Omdj5=IrU{4?CqMv%0>GDdo4O`jG=Nfd;DSzVyO7p2)8Lre&tqfdw1nkzv zbvO?S+6H(60^rD9c2nO{Vr9snqr^uka|^+11W6h!6%K6TMB8+CjCAj7P82473>cW^ zi>R`Y#r@3hsZkQq{hGRjW1k#*@8dZ$2PKN@z&2#Hdlr1@tE?h#91Ma-+4SO{4uu`` z>0OBrOt8xxu)VI#c#xsPn<_8lKmxD7oN&ze-Cp7bc+{*${)M1^@9cwUnP-%i0nli=B(s4?i=_wX4b-|BoTFskL*7my>5BOLEO5{}Bn$a+bE2ZdihtwN=QcX27W;sc z6L@Zrmjoqp%{XZ4hD9qHXTcyY-#x;x80*%_N)pdgvqfG!VmN32PR(R3sf7izIJHx7 zy7!x`5&cKXcPxl=-prHqKhxC1pOvXNm#i>^Fe!(AQ(E>jcoGs}!&!$%rk%5Ty#+e% z1fREF9aGoZNf_LO1(iVmC{l6?IVD^epnf-W?#*nX{4%vJ0MXNoc!a@c4zRgpqag08 zVnL&s?!&jj!9#`Zl{L^wN-hjYk?NbR zsvqC}8=Cc>*Ao(!>gSJj);2@MTv3|Lyy>{aQqcO)LcfDAJU4^8<69h*jPpWpxNe0$ ztfuA;nUAe$pqQm;5&5}?Qlb0u63N<@X~rkM1yB900RH2yuM2)bVZHzThgCC+6G7uLsxelYc)DXeN$FvthkMW7rvg zrBfxpIj&0|;#|GqfoQl&^`(yRvWnqdU+9e_SPV@xHFdA+X8@IH5HRAMXk51-NBO-^ z!?)c*pvoeEC=THecO-|Dpv&>!_Q(PvH*)#)G?A7Tk~X4N!9k2(hQRc%WLs{7JFfo} zHdj$c1=y*qk-ybz?W0$Y0zDr`#^Dh*pjTk61>2fB7DlMUTtpoTr*PSmdj(}UYL;9yAuSRDZqiVW|Eu8< z_~j(YMvKu5j>`|i!eOU}#G}6ofH5Q`j@ZnrT0}C=jT;Dx*iLyRa77alfhjnnv$N5I zt8Gs{0YCOWz%iATl~`C5Tc#m;JhUO%wL z<={AUkj3JHtpQA>d%p%#^KSXzkBm?ggqS=2S<{+xUnZLK+`KuEDj^TP20k(}$3&R$ z*x)wHsgeGpJ)8_piUWZ!l9IB6-Kk;GktMY>^xHl&gySIUd;fOa+qW>5+scNGuSHu! z?#`9=P9bst34!DYCL57zDWY1SjRH&;boN2CX_IW%)((qwbaXWJ^g6)jBHEl9dXsP9 z@%ycp*%IE$KPI}~-r8vcA$B4Fy{McN6rdMcx(2*&GL1VvGV-}F7#0(k7(L1u(AF53 zl?=@`bT#B0?=AB+#mEaGM=`ao|ohn4Y_ z3SA?GJyk?6P&^r@SwC&N;<0yy9a)L#pytNb7J9V-GDJeL(v!eb_v`a?*Wh5j&8Ue* z^>4hxLZDCr=mz#FwBTHW9vycto&$zlh7=W@-@5s%!iB0`u`S0GyzPjV`Rsu=^C8=IRsA3g*Dvo0Vo@Zm>W(wD0P?A+W0v!jvLgzf9jZve~&bTSd1 z9eR~--oUP*?bQ;1teGh$P-bxH*fCtKW~-VVJ>56b6-=c$8-zo!%4KkOucitWp(ex##sNC+=uwd?=_rXl2vjrfU^fIk|=t&j*pGE z4y5hwwuMCkuM5hOko)rTK=a))1AaR>CFRI}|0#HRNd?|lQStaQtTe2PtrJaxZukIJ z2>|bb5^+`O=ZGMEvWMW6!=qOMLvE>x$I!8w%&bJ&A)o8+{ds&I z-+$rj7eCzRe%;q=U*mZ_FRT9`!VrA})(^OIB+;Ad^-oY;+Y-RUVp?C!PI^S`@j`lQ34q<9!;b1d4p#oMrB(^MWY?~(M~jFK!X8#sR0JtdM|q9UcQPufMb;w~5ucX| zst0^WX-B`d-PZl=ep$XUm6?V(;ok3zhAsfn1KVHw(gwPI?x9Qb+RJ+Kfv2j5baQ9G z?#4j9Z|Ho=$EZoS53?S9P%q8Q?3A{zE6)ICzPrrA=*z_TlTU}Z*&?U9rXOl;#3*0voGp`H>raomeJb@7W z=kf8*ED6W;fV$QXA5xN&!=WSR(LOW!csCYbhCS z^ffWEr3nYegd-%5T}jXIy1jUXW&Hc-z~$J16_mY6Jgd)#4NO}g6*K}e7<)lfOMHD} zQm$%EsWmq44iMCEi6tiw_V+hW)dl*CItWY>9^MpG)YG+Rfmnj=uemlLfTV#ia=FvM z*|TS%`pt1T3lmViu#}%a{BjZJISR1=@5%}<3pIg?Ro8>7NAkK<(#bMDj6k9R0UN65vJInq4cb{7|3@Lo;uxl0KlF9 z+qxe`LQnK6CCKPsq`WzD3|*~l9@Q&>j>@Y-FT4XLz|U^SY#CQ@7Eb6-pFa6*k2?DA zEo1=XjT&w`l-?S`B*6a#I6vr{>%aMt@gZlW0-oH5ORqoJ{<4p|V^_GlQ`hcq7dq-otBYR_=<=g8@R>R-|xDE&jL7V!A>nJ6qed)i;uSYbmoE|C- zA5?DpR;}r)onPUqPeCno0C6zvRjtSHJ!8UJ=a| za4BY8_&hnKGn8uriCsh_BuH{{(_C8uUQZ9m>f2AE3Q+f_PP-j9(`ve3>{hWNA+(EK zcBX7XF?}>R{Y68c%E5sJl1IJT5MzO2j#x1d9X7Jz*xYQa@rk3I*#ciM z4Fgq5e-$g?y@m2Lj<(07km8^M83+Kz09_7-xz+$3=5L!$9iJjPaJ;n$-C2G+(?dH# zY`dxscSa{mT8xMct>zF)k_WmhDDSY7zy90F#uXL71vT~7UqVAm&6rWWEcBQ!M^v>0 zr()JQBab6x+K@RSIMA+MzYYm6&?9!#H*jO?&-eAMmlCsVisV~c;G@SRRNhwCW5l-K zI{#Gv5gL7h{6Hrb_`Nl_{aSAf4wHVkA3oU=wdmV&bl3no44^;@L0@ZO#OcSh%9KUT zZp^LRIMxE#eoz6xSq<1NQCD$Yov%7u z>8nN8z5`By1GVc>>rXOZ@f3J$GuMCCP}Ki1ikWy+sbbGsi1j$n^7p`9<_%-PGgLAI za2K}T@LHxRwWfT~9_3gejtT?>b4tYhNEJ){UpLEp45lZ&;1ar{0r#rb$;#8Yq3mDE zG%=Am`&<%$bF4NO8qeif{F>-M9uN95FCDsEF4kI;kw?Ul@d{R+Ryy*JN$sQ*ag9nP z!r`ytb`_#}>VUC6^9FiQN%9L4X@>V*;w{avAxXKzHK2TKe=0g_fK%vBK3&Bk2l{37 z`qN73&gN2L_s%)-T_iLdTpL_(uaRQg)SbD(ek;pGhlz1=60Untsq7AaI08UjH@C~^ z`)Z_+JSQK8;Yn2kX7Z_AsXx8BsFVVzltR!IUEa96SDOQ7iJ?+>OzTujQWj*uW1jpm zslWHWf(4{}_HQ^vF;E~q^gx@pe098OcBaJd$R^O^xb-zVPUqduN6Hj9PKrxBN4tZZK^9*t0_cA%JjlRc3aG%vtC2Ho* z=1jP8Rg8vHgYz_YseyXS$WKvgb*Ck-g$FoS_#ZC;rz=x3t~njR#L;y=ERAWl0zsoak-9MCat^ zouSMx`z`vShLW47ju;tyNQ^U707ChyUHb<)Z1OWuNbdCXO!?3k)z9Y3qm(tbpX6VC zIG(m`5}K3B$$)q6IgTwZ7P2C@ssV26ZXH*l2`}oPwZNo|4^Dxbr!+yv|jAptU&3W=Xxx*fem zqaV9bc$}20jL^$k5+>hpH)6@c2f^-dkDibwVS_m}kOw+~B#8>gmH*Io8~RFZu6FW2 zFNq;e$k*ob?kdV3`VpKk(dn*=Y=(mb0%>UwNC^Iu7f>Qga?U#TLV(InnPg0S<*-Lj zv^v_J3bg0M@BM>J$h@!g=0t~6pf7=US8N2u4UG0XK^~mDYQPjR4pE}v#9v(a^&#Iv znoRw{J@wd``hAE9=;4jd3tEx~3&)h@K&D^2hu>t-n}B-&)Fa0ClcEDvYI#C2u)nk` zli+d@979D{@wDEnWK6#KVhj2Wk;aoGT=+j6FaY!b9@WdqbJTwjeKun05tMRdmcAeG zT$UuU7oFj}Gf3f6CXiuP`7a@ad9Qyx+?j|1JJXvghSdV(y0x4I z%3Uc`8~I9}MZs|HX!boh19*y&?S@@1b4w2~q>!2dZQGHWo<1+dw4Ov*Fsv-+2Ko7Y zUz*$$^??23SUd+TynC+WQp;cNUAOy4XIhgQFj~p+*N4$tj)PpTA6pQIjNbN~+B!<) z6e7g;$427}9meWTM;sd~=la}gF9yZep1pX%!QH}`*K>^?VrCO zEsa)_c6F@cFHsvQf@W``3JSR2LEHs2>^lW<2M0j`Ti@Ek2neg@ z;?FG)zvKYi>Lp_m>1mADqKdNs2Y?_Jt8`;~e|v3leYQn6Q#AZ;EPI5_ z!EthOnc{xJSKbVkVnj8*YDg-x8n##rvaL>?>MNqYGY2sqw9Xoe$-CB>ervvimV}yJ z7c2{YQ2ZgyO9-k|crNHbH4Ibmc0eMD_xCUN%0iEJ%5RP$DFTYe8vZIyh|<>ha;CNy!}Ktj}%@+o0@2<*wuDP}TZ(vW|}3XYs0#)XVgGqh7_7tRvhaBQyPw}96c>n?GuM50=y(_Z`kayMd$c2tip9+kg8*hFePUOG* z)MMbH^ylKsd;lv(JB1pTXVTci{9iV{3h#Rn=6A`&C+bjSs@H!wm>S>D2TMA}`#`4a z;R(>tqqy$O17jXa0BL514+&9HkHK(BOJ|5;_EO5rCFQ)A8`DgzKNgKuE_vWjxYzCR zqBaF=SjE8EVkX;NmE~0Z+GqTuRH``VMOipC%;K=;3)9Z!yO=DG!oma!z2r06=n97l z31D-gI+=~jWX*ZS!0keYOF2k$Q%kHY7^0ze?)-vQ#12|2!+NbLXN@n6(@G>^hxDPj z)EYU{cNnFOQ*;LOni>X>kqJrMpKE+v^mrlaTz)b8Spqj~qqsKvgVAvD-9yW&>yq9p zxLT*tCy;`=sf}DwhJ}4;`$zaEo#nwh8U}zlzj%?-fF89P=rtdD9PHi#)T=HHQBa{s zNb*>hu3lUL;HAk01O#x(9&zPQp4%SamdEb+rP390<4YP~DV#+kJ}VcJvhds^4WY_V zKkh5ca#3mNU4X7%0`lAwE?-J#@5}$>go5LVbPNoyWihaEpwWuib|zZdR#AnuJ&tw{SPs#-=2wg_38;Mehc=TqlLdLn1>U= z(s!;xv3b;loqT^AV5)kccNRU?fA6*TC66{}wM|wq$WfkHei}`e027{0q@c!J;N6Rv z%fmsZ@%_aok_+Fu4)87yQONmXlTlon*ODHLdle9fo|3#lqe|l;U_Q*c^eNJ)_A^(; zVEo|~H}l@@)p1$BbY0o5lMpl&5M@rs5F*b(+q2=$1toAFe}0_$OZDmKn7PhVZPBhWa#r_?JUJW zDGHM^EMI!F33WmnAA3scR3!@3Lr$KY#H8WhE`= zn@LaDU$0ntG?#o{6ZHyf7*snjWbH9=;pKt}5bviUf4z3URDwE%n0?#m^&0&px2V6b zpd8{#JKovZ0Z?#x`D_i3tDT18y=(Z9H0Nlim_8+L?+HBWtk+He9t0Lyj!!P$R zM*(@6uYxTCHkX@*Ol-Pg2IFq~7-^5l@9T}-+apH`B~HQ;v|lk~mPHDs9H|ukVoybC zHI8(in%v#T!P07tp#IAHj;rdrfo`o4bx9!Iw#s;(p zKgF1Xh`Ta%-q%`|RYAFXKx{K4Fo`U}nSa%>(qXiJSh!G7=FGe7iVyCcmi7eK6c+CY3qkKgr$|fx6H$M0{C7l2bR8;Q zpBh_4Zh)KO#^@U!CnqPks!^XC`g09L&*&nh!l5J(S`ZO@3FWs_ zUstHJf5;G?^{)NZe)?fwfhJVq?7wl-fS$JX{^hNoByhUG++|TD7hc}l9;ZoAovz2G z)YdA9>J(nGH#Y>pxq za>XWrsby;yAjMuRVTIcyUfx=V_DI&ES1 zLjxELJ;#!C4SPRoA>P|?rv`UDqW1Ui%O}L=7aW&zja;&h5j&F?Y=Om>Bp$>6!9o&S zVkky>TG!CDistVk1!QOit!Q<0^JcM5teAHEUy+p)@2%89D9C+@0c(n^dKnIc;KjguM* ze3#^}Dq<*M!G(8bCO|fCLCF2jHV=Q$nvLxbjj9Ebj!vFaY(c9A=2nudc*B+xNrj0U z&uy9(GE&y3M#vwRg*Rl8KugBjQneZh8-d(-XBpVm;yaV1hx;wnOGw|ldP?`3(IS&% z)uY(AV8^gQE9B718-EFi=|LB;rF$E*+0)?*F1GWRprfM|b-#_Vc*=7s$X|2%ritqH zype)qnTiZ>Is%tFe-8`ddU4KocY$Re~0l;@f zG?2fQkV>{@ohg$Xb>$WYhN~fm%3oHJl&$QD04Z!g$%zm3+&l~QoAnh`)yArbb*LJb zo~m0@A=vX#H26PYSm!(HFOMWgy}2z?Tgj1L7Lol_<=^8}^s)a2WWnRlZY;Hc6ceZv z^9!7KLvoOu`oD!|L%l4~Kow;ddG$Y}B0n zZsnuKq2cBi19`5(@aY&Dym=K(40UWXy!~yhiCN1;Tg=OL%Rwy z-7sLRIF5+k{R~q*1bK?1aL)B1+Y%k!(bjcwF5~Z-N=auPd=#A(z~Y^C2#^Ow2;FWA z$ISa_o-zi8ChE1Qb1x(Kzb3<*(KzQ^CNX}Hm+8l9KNr;KJ>DQ0jx!SYa*O;NXR$BuX!tlQ-~6e%o)TLE`A+#wCm#}Q=jY6UyFSG)$R`#+H{0AW8uE0 zJZ(E7I@i-K2?xVX{ z{6|g=!{7ch1h@;4&1w&H;hy|Kkm*OMdnys0ajO`5j@F$9Sj_HK;;GOQ!kf?|2M<|Rb80y33O;1T2^bl$*-Sl+jBuvjvydp!TPO{M}n zJb>w$|225oV>UV|`@-Y#O6pJd8^_n0TMeMOQs_WzUEnOZ>ie-QlVcU@y~xmu8!pbFK zM+n15-!<&ZGm9OE>r>L5LA_h7s+1b`tuz-xHyqCZ72zlR&fK%#xIR)x?dh4n)<#1F zADn>M)vc(2l+K`?_i&{~o)eBa@}s#w+}wD93j@1JmOME%Q|H3o<8x(sO|a3r0%rl# zko-ss6gfc^!?`;1He_dpjr$g6Hu`ESWs$Z@@iFrlDY>Sh} zlWQIW7-l6JJVHc(&|UDCg&ef?nMld1?(tbuAxj@w1UyC{?gax{kQH1Tk^I6j{o=Tb zk>MHKc;v5kSYa!;3ovXtk^BM?Yey8RY!Md%IN^yQjOlA{ej)NJ zT1eq7C6Lly#*^r0?aBJz3@ojS-5$e}FszO1;W*U0z{xMxl|ym)sY-|vrTye}W@TEf z5EeZ62ndil8-LlGV?==8G-FC=D)H%iLZQn{>Es0OrBEc(n}8++ut_W!d?)Q+Gk=JW zj}xv611-kTUhF=*q7J=gx${sw#K-i;$0{zJRCN}>R1x8k&5y^iZTCzC+y88RM{Cu~ za>aA|u8y@?9c}7QG&oW(tTpt)BeM!;hUdmF3Z6ZSI~y+}G+x;fsz`1?bQq}4jP}Yb ztgtE>LDaw?D=sTrM3D_&x*y`lw^ytGynV#O#}^BFAD|la+}wmuOWn+S_b&bNyI}c) zC3m}KBIbUMh+}v#7om?@pqGL-=D~wcCqCb2o3G#FeG*9`7Px&AjKYyhcQhCXj&x6; zJ_f6{o!_jQ?q?uP``zesF(8KC#kfLVBQvv)`RcJipUo#Cl6WNKx?-rL=*klORDbES zHpdfSD&r)BtSaaxC_vzvNC6!U^t(6LyIH`hVg{!ITW$!|)5&8kBIucDBa{0UKXWdj@RmCwX~c5CHzYu>pO53bZDWlb8rryxt;Y5>MRv zz~;R+l>=#|i`}{El0E_$wlFMS4z#QXR}vV7ZhS5v<^$^*GD8;@7Fc)3hHW=*gzUAR zgs5qZT}#a8cdiz~b(@B$Z$psrap=+CD7%i2sTmn>!TaUubKSosDM)y;1uY8)S{qity(=q}anAn_p8vL(?$=h7Y9Ktnm z5^uctvhaa>?M zCc!e%(joy-!PJQ7$d+z_aNEk0hsiveq5&8Thc5Wzz+I#PUt{A!=F~4zf@5(aL_UhE zh=(z?S&6h@*f$Q=ZW<90>SI={HZ?(G|t6nD;8_GODQ^1ZD=X zVL0NT4O5tY7gw5M zeA63K`9ZXjr_Rog0zy2FQx^&czceTPMGw=$b_VWZr-Nl}kH33Kk9zq=-?^U7vZzF=Jr!RB zY+ZM^)2@ND>VaBVVSD8@3NY^B$Q}G3o0c}eIzl{r(eC1P6?*h@PiZ-eZvk%RV9#UN zYH+xSnr&gi;IT~qdwDR=%H1a6bQ+WdwW{omIDjF=9G+$HoaS7gMQ2Ais-r_OhXW;d@@ilI^q}!W~LB0 z&$5EG)3_c&XOu>CH?2zHasXwPO5U$P)Q3^)U-k40Ev%=u8I!lIV*!|Pl_=hp`* zJXA@UrH=Khq4L18@F*#<{mi|)6S|}>ATUeanQuXWISm_M2Sb3c^h6MYF|)bSVk2Wt z@ODYv_*~Twv?Ft5NrR##B{PtsF6O{Vw)-|-$8W{x>@wLI5>;~+7^Pbq!s+(vwR_I+GhX18Ma)h-<5ediLotE3wc^D)gB)I~w%5 z@tH2y?ASjk|E#Gf?(j9;T}#^I1Zcsxp7nU zi2Hq85GOG7gbrNqaXNANgQ_(c4*Yw>I5{u>Y8Wrn^8-JqgP;o-q?K?3f#VLs3b0hC z;7tTOWC8Pq6b4Wv!M`i+aJu4=Z$ke+y>vvaG_F7(ZD~Px4F2$%dKzVFwh{jWU0lm= literal 0 HcmV?d00001 diff --git a/packages/network-map-layers/src/network/arrow-direction.ts b/packages/network-map-layers/src/network/arrow-direction.ts new file mode 100644 index 00000000..a99691ee --- /dev/null +++ b/packages/network-map-layers/src/network/arrow-direction.ts @@ -0,0 +1,12 @@ +/** + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +export enum ArrowDirection { + NONE = 'none', + FROM_SIDE_1_TO_SIDE_2 = 'fromSide1ToSide2', + FROM_SIDE_2_TO_SIDE_1 = 'fromSide2ToSide1', +} diff --git a/packages/network-map-layers/src/network/geo-data.ts b/packages/network-map-layers/src/network/geo-data.ts index 56558cdf..5ed6fb1c 100644 --- a/packages/network-map-layers/src/network/geo-data.ts +++ b/packages/network-map-layers/src/network/geo-data.ts @@ -9,7 +9,7 @@ import CheapRuler from 'cheap-ruler'; import { computeDestinationPoint, getGreatCircleBearing, getRhumbLineBearing } from 'geolib'; import { type LonLat, type MapAnyLine } from '../equipment-types'; import { type Coordinate, Country } from '../powsybl'; -import { ArrowDirection } from './layers/arrow-layer'; +import { ArrowDirection } from './arrow-direction'; import { type MapEquipments } from './map-equipments'; export type GeoDataEquipment = { id: string }; diff --git a/packages/network-map-layers/src/network/layers/__screenshots__/arrow-layer.browser.test.ts/arrow-layer-basic-chromium-linux.png b/packages/network-map-layers/src/network/layers/__screenshots__/arrow-layer.browser.test.ts/arrow-layer-basic-chromium-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..a1673c9c38ae0195a0d615a1c316bcc59dfe9ebf GIT binary patch literal 3323 zcmeAS@N?(olHy`uVBq!ia0y~yV7dUp9Be?5o#F0t7#MgCdAc};R4~3hxG+#AfPwYE zbaNgt!Q#{h>-eG;@{9Ba9EudlRhaNYWir>i$K7}TetkY4sCP2ZfElI?3JrPM}PV<<$vCGhJs~m4fDVMn|CMgUi4b4o<|o&xPwuaq{^jJ8 zo#nvPbq6T);NSI=@%Mc8{WaP7`}>ny`aofj$_E9yJOBNDa!&l@TmH$wM0)?P=FUGw z3=Dmj6$_@tRM}O2d;4VO_DS#m%P=%NzIGt8_{x(*PoKE!voSo_F>^pjJoPhM;V zD*hwox4-_6+0Fvhou9IbUf+Fk?l~jFgA|!VFTa0TKWYA+i88T1eR?YGtD&OhFRK_B qek6{TbR#BZjn-+SbsBP=_NKmQs)ylC;|_74D1)b~pUXO@geCwO&PF5v literal 0 HcmV?d00001 diff --git a/packages/network-map-layers/src/network/layers/__screenshots__/fork-line-layer.browser.test.ts/fork-line-layer-basic-chromium-linux.png b/packages/network-map-layers/src/network/layers/__screenshots__/fork-line-layer.browser.test.ts/fork-line-layer-basic-chromium-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..3042c3d9274022ed19e906c841224957dc9e27f7 GIT binary patch literal 3469 zcmeAS@N?(olHy`uVBq!ia0y~yV7dUp9Be?5o#F0tfZ`#ZE{-7;jBgKG_ldGFuwHmQ z^&%tdlpl)M>K1h_4GDX9=59pvPR3|%Q?allg^dm_t%B@qC7k9DL-n7}nLh8oJ_Eyn zC5#LVX}k;!2H6Y@4UxVm7!s}l?br;oXoe|J$(m6mqv0}|7)CS6Xvr{I91gB( zq9Sqs{eM>b>%OPXv)L!k&=<{ofV;Y`a9+LKpE>E`>5LC{m@@3y@cMo2#Lt^|SN{4@ z$6%4i%b@?}$rrbEcmLSb-}$M=AhVsVq1j^RpS*vyCFT&`j+(#CbMF3E?En8yl|g1b zNPh3HIzPSpXBPjy&))F(Dno&Q`ttmzPs7(ed-JcK@j-L@ICu-tG)8ulf-lKcR3l3uVj3Xux?+iw*UG6r}p#b1C6@EP+*|G+`Q=N zS^rPZ^Y1^qd9;$j!j6}Lz4YtcXv_K%^OLR+{?}i(=d14Yn8)6rT%yS!b7iWz-8uL8 w8c~M6;L+M?w00V;oknY?(b|df+UY-IhfQGriXfd0z%CGjr>mdKI;Vst0N;fXxc~qF literal 0 HcmV?d00001 diff --git a/packages/network-map-layers/src/network/layers/__screenshots__/fork-line-layer.browser.test.ts/fork-line-layer-large-network-chromium-linux.png b/packages/network-map-layers/src/network/layers/__screenshots__/fork-line-layer.browser.test.ts/fork-line-layer-large-network-chromium-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..febc6283cb52171b0826b9cde7fcc1dd04c77c1c GIT binary patch literal 8026 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 literal 0 HcmV?d00001 diff --git a/packages/network-map-layers/src/network/layers/__screenshots__/parallel-path-layer.browser.test.ts/parallel-path-layer-basic-chromium-linux.png b/packages/network-map-layers/src/network/layers/__screenshots__/parallel-path-layer.browser.test.ts/parallel-path-layer-basic-chromium-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..f6cc9ebdf16db01e1f5345e8a6ee33e24cc2eb40 GIT binary patch literal 3585 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 X^Sm!Nzrn>fi2F&!X`9=VKRo<@9FS4# literal 0 HcmV?d00001 diff --git a/packages/network-map-layers/src/network/layers/__screenshots__/scatterplot-layer-ext.browser.test.ts/scatterplot-layer-ext-basic-chromium-linux.png b/packages/network-map-layers/src/network/layers/__screenshots__/scatterplot-layer-ext.browser.test.ts/scatterplot-layer-ext-basic-chromium-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..ef7ff046011b352a03db714c01844b09d41ee500 GIT binary patch literal 3872 zcmeH~{ZCqF6vq!`v0Z)3vL!l4Ve5!(rmJhW4y7nzWpShlY^^CX)8cBPKe&ozRlot) z%ows52lmCbkz$&(dr2y~xJJP$Y|F+J6O6XLWGb{1$OaQD34uUZUM*&NyMTG4P)&WZc^!Kea|sr}qSJlEOnLlQk1qpysld2QL3-|8AUKu! zzkeTCZ79-}!52IFA)g^X=RBI|x~D@6pSiI9*BE|M%5+KWt?RPD{w!l~VU+3mj^V#0 zc;SSAFa6Fv#=CrC0an{ozN1Xu&)+TSuLp(N?TJ46|n-rD*_dIk% z?701Wcocg)OqTQ!SF=Nr;0Y}r_FdtX#ys|rrUWduS{NC;svN&8(-G}hxCklqp|=r) zZz|gs8}Lw>nN3~)DW;i&^iB7H-ns&F%K7gjreSCa)X{5PF z9^afVdljT|Dq?GzrTVjgDx-wr>P*N<`1RR=__DBv{Kp*J2+Pu*g_^4Lg)%{MWl8N# zVOEct)L1p!rP}SI%5?ZXoC}8{O~tDlJi&FIGa--n4~10doR&SJdRtzkpcHGlU^r-G z#T^CnC}m6+$)RCJ!;FU6^Me_^A<&!Ce_j`f^oKtU{*fV`<5Q#s$%j(0?Sq=H{{^Ed B6a@eP literal 0 HcmV?d00001 diff --git a/packages/network-map-layers/src/network/layers/__screenshots__/scatterplot-layer-ext.browser.test.ts/scatterplot-layer-ext-large-network-chromium-linux.png b/packages/network-map-layers/src/network/layers/__screenshots__/scatterplot-layer-ext.browser.test.ts/scatterplot-layer-ext-large-network-chromium-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..d712773118c13257de777c124058f716495b4926 GIT binary patch literal 3468 zcmeAS@N?(olHy`uVBq!ia0y~yV7dUp9Be?5o#F0tfa1ZPE{-7;jBgKaJSE1$zT+NHRfy%xJ@ZD(t? zuDN{N^7)nf|A7`6WHK-`L^3lloRMN+NVo>HXEV^U8Kw*j2i7n$Fr@JUm1K`984Z`w z#4wskMoWg#;t->nc%#A~bLKC5{nPGf`RB9e=RI3leE#X(aJy4aKkKtLJT4Ss;CpoZ z{=U=c@%1z2zrT0RdHG zI(j}!!{dt#1p@c~l^FMb`W;{X>Gu3`rUQi;3>F>ga`yB8f4=e3nDK#y34_d$t={=h z1LJmlC^|RKMiOG&p1PM+_bUF)onvV^y}fEx<;O?amH)5yGavY9!O6g0`0$N!<@;B? zF}uH%{i`X^w=K1rem?%>QT2Je496dXJT&w2^P;CO&4KE(Mr*&(+HbV>8?F6DYro-H c`~7DBJKu&$>cT<=U^&O&>FVdQ&MBb@06a?-OaK4? literal 0 HcmV?d00001 diff --git a/packages/network-map-layers/src/network/layers/arrow-layer.browser.test.ts b/packages/network-map-layers/src/network/layers/arrow-layer.browser.test.ts new file mode 100644 index 00000000..3b2cbf4f --- /dev/null +++ b/packages/network-map-layers/src/network/layers/arrow-layer.browser.test.ts @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +import { afterEach, test } from 'vitest'; +import { type MapAnyLineWithType } from '../../equipment-types'; +import { expectElement, SCREENSHOT_OPTIONS, setupBrowserLayerRenderer } from '../../testUtils/browser-render'; +import { createLargeMapLinesWithType, createMapLineWithType } from '../../testUtils/network-fixtures'; +import { LineStatus } from '../line-layer'; +import ArrowLayer, { ArrowDirection } from './arrow-layer'; + +const { renderLayers, cleanup } = setupBrowserLayerRenderer(); + +afterEach(cleanup); + +test('arrow-layer-basic', async () => { + const line = createMapLineWithType(); + + const canvas = await renderLayers([ + new ArrowLayer({ + id: 'arrows', + data: [{ line, distance: 1.5 }], + sizeMinPixels: 3, + sizeMaxPixels: 7, + getDistance: (value: { line: MapAnyLineWithType; distance: number }) => value.distance, + getLine: (value: { line: MapAnyLineWithType; distance: number }) => value.line as never, + getLinePositions: (value: MapAnyLineWithType) => value.positions, + getDirection: () => ArrowDirection.FROM_SIDE_1_TO_SIDE_2, + getColor: [255, 0, 0, 255], + animated: false, + } as never), + ]); + + await expectElement(canvas).toMatchScreenshot('arrow-layer-basic', SCREENSHOT_OPTIONS); +}); + +test('arrow-layer-large-network', async () => { + const lines = createLargeMapLinesWithType(); + + const canvas = await renderLayers([ + new ArrowLayer({ + id: 'arrows-large-network', + data: lines.map((line, index) => ({ line, distance: 0.2 + (index % 4) * 0.2 })), + sizeMinPixels: 3, + sizeMaxPixels: 7, + getDistance: (value: { line: MapAnyLineWithType; distance: number }) => value.distance, + getLine: (value: { line: MapAnyLineWithType; distance: number }) => value.line as never, + getLinePositions: (value: MapAnyLineWithType) => value.positions, + getDirection: (value: { line: MapAnyLineWithType; distance: number }) => + value.line.p1 !== undefined && value.line.p1 < 0 + ? ArrowDirection.FROM_SIDE_2_TO_SIDE_1 + : ArrowDirection.FROM_SIDE_1_TO_SIDE_2, + getLineParallelIndex: (value: { line: MapAnyLineWithType; distance: number }) => value.line.parallelIndex, + getLineAngles: (value: { line: MapAnyLineWithType; distance: number }) => [ + value.line.angleStart ?? 0, + value.line.angle ?? 0, + value.line.angleEnd ?? 0, + ], + getColor: (value: { line: MapAnyLineWithType; distance: number }) => + value.line.operatingStatus === LineStatus.FORCED_OUTAGE ? [255, 0, 0, 255] : [255, 200, 0, 255], + animated: false, + } as never), + ]); + + await expectElement(canvas).toMatchScreenshot('arrow-layer-large-network', SCREENSHOT_OPTIONS); +}); diff --git a/packages/network-map-layers/src/network/layers/arrow-layer.test.ts b/packages/network-map-layers/src/network/layers/arrow-layer.test.ts new file mode 100644 index 00000000..94f6966b --- /dev/null +++ b/packages/network-map-layers/src/network/layers/arrow-layer.test.ts @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +import { testLayer } from '@deck.gl/test-utils/vitest'; +import { expect, test } from 'vitest'; +import { type MapAnyLineWithType } from '../../equipment-types'; +import { createMapLineWithType } from '../../testUtils/network-fixtures'; +import ArrowLayer, { type Arrow, ArrowDirection } from './arrow-layer'; + +function createProps() { + const line = createMapLineWithType({ + id: 'line-1', + voltageLevelId1: 'vl-1', + voltageLevelId2: 'vl-2', + p1: 10, + p2: -10, + cumulativeDistances: [0, 1500], + positions: [ + [2.0, 48.0], + [2.02, 48.02], + ], + }); + const arrows: Arrow[] = [{ line, distance: 0.4 }]; + + return { + id: 'arrow-layer-under-test', + data: arrows, + animated: false, + getDistance: (arrow: Arrow) => arrow.distance, + getLine: (arrow: Arrow) => arrow.line, + getLinePositions: (currentLine: MapAnyLineWithType) => currentLine.positions ?? [], + getDirection: () => ArrowDirection.NONE, + }; +} + +test('ArrowLayer lifecycle updates textures and animation state', () => { + testLayer({ + Layer: ArrowLayer, + testCases: [ + { + title: 'initializes textures and model', + props: createProps(), + onAfterUpdate: ({ layer }: { layer: ArrowLayer }) => { + expect(layer.state.lineAttributes?.size).toBe(1); + expect(layer.state.model).toBeDefined(); + expect(layer.state.stop).toBe(true); + const attributes = layer.getArrowLineAttributes(layer.props.data[0]); + expect(attributes.pointCount).toBe(2); + }, + }, + { + title: 'updates animation state', + updateProps: { + animated: true, + getDirection: () => ArrowDirection.FROM_SIDE_2_TO_SIDE_1, + }, + onAfterUpdate: ({ layer }: { layer: ArrowLayer }) => { + expect(layer.state.stop).toBe(false); + expect(layer.state.linePositionsTexture).toBeDefined(); + expect(layer.state.lineDistancesTexture).toBeDefined(); + }, + }, + ], + }); +}); diff --git a/packages/network-map-layers/src/network/layers/arrow-layer.ts b/packages/network-map-layers/src/network/layers/arrow-layer.ts index 7033aace..2a973a77 100644 --- a/packages/network-map-layers/src/network/layers/arrow-layer.ts +++ b/packages/network-map-layers/src/network/layers/arrow-layer.ts @@ -23,10 +23,13 @@ import { } from '@deck.gl/core'; import { ShaderModule } from '@luma.gl/shadertools'; import { type MapAnyLineWithType } from '../../equipment-types'; +import { ArrowDirection } from '../arrow-direction'; import fs from './arrow-layer-fragment.frag?raw'; import vs from './arrow-layer-vertex.vert?raw'; +export { ArrowDirection } from '../arrow-direction'; + const arrowUniformBlock = `\ uniform arrowUniforms { float sizeMinPixels; @@ -69,12 +72,6 @@ const DEFAULT_COLOR = [0, 0, 0, 255] satisfies Color; // this value has to be consistent with the one in vertex shader const MAX_LINE_POINT_COUNT = 2 ** 15; -export enum ArrowDirection { - NONE = 'none', - FROM_SIDE_1_TO_SIDE_2 = 'fromSide1ToSide2', - FROM_SIDE_2_TO_SIDE_1 = 'fromSide2ToSide1', -} - type LineAttributes = { distance: number; positionsTextureOffset: number; @@ -105,7 +102,8 @@ type _ArrowLayerProps = { getLineAngles?: Accessor; /** distance in meters between line when no pixel clamping is applied */ getDistanceBetweenLines?: Accessor; - // TODO missing getProximityFactors?: Accessor; + /** accessor for proximity factors */ + getProximityFactors?: Accessor; /** max pixel distance */ maxParallelOffset?: number; /** min pixel distance */ @@ -126,6 +124,8 @@ const defaultProps: DefaultProps = { getDirection: { type: 'accessor', value: ArrowDirection.NONE }, animated: { type: 'boolean', value: true }, getLineParallelIndex: { type: 'accessor', value: 0 }, + getDistanceBetweenLines: { type: 'accessor', value: 1000 }, + getProximityFactors: { type: 'accessor', value: [0, 0] }, getLineAngles: { type: 'accessor', value: [0, 0, 0] }, maxParallelOffset: { type: 'number', value: 100 }, minParallelOffset: { type: 'number', value: 3 }, diff --git a/packages/network-map-layers/src/network/layers/fork-line-layer.browser.test.ts b/packages/network-map-layers/src/network/layers/fork-line-layer.browser.test.ts new file mode 100644 index 00000000..bd0ee3b6 --- /dev/null +++ b/packages/network-map-layers/src/network/layers/fork-line-layer.browser.test.ts @@ -0,0 +1,102 @@ +/** + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +import { afterEach, test } from 'vitest'; +import { expectElement, SCREENSHOT_OPTIONS, setupBrowserLayerRenderer } from '../../testUtils/browser-render'; +import { createLargeMapLinesWithType } from '../../testUtils/network-fixtures'; +import ForkLineLayer from './fork-line-layer'; + +const { renderLayers, cleanup } = setupBrowserLayerRenderer(); + +afterEach(cleanup); + +test('fork-line-layer-basic', async () => { + const forkLines = [ + { + id: 'fork-1', + source: [2.35, 48.85] as [number, number], + target: [2.37, 48.87] as [number, number], + lineParallelIndex: 0.5, + lineAngle: 0.7, + substationOffset: 1, + proximityFactor: 0.35, + }, + ]; + + const canvas = await renderLayers([ + new ForkLineLayer({ + id: 'fork-line-layer', + data: forkLines, + getSourcePosition: (lineData) => lineData.source, + getTargetPosition: (lineData) => lineData.target, + getColor: [210, 179, 63], + getWidth: 2, + widthUnits: 'pixels', + getLineParallelIndex: (lineData) => lineData.lineParallelIndex, + getLineAngle: (lineData) => lineData.lineAngle, + getSubstationOffset: (lineData) => lineData.substationOffset, + getProximityFactor: (lineData) => lineData.proximityFactor, + getDistanceBetweenLines: 1000, + getMaxParallelOffset: 100, + getMinParallelOffset: 3, + getSubstationRadius: 500, + getSubstationMaxPixel: 5, + getMinSubstationRadiusPixel: 1, + distanceBetweenLines: 1000, + maxParallelOffset: 100, + minParallelOffset: 3, + substationRadius: 500, + substationMaxPixel: 5, + minSubstationRadiusPixel: 1, + }), + ]); + + await expectElement(canvas).toMatchScreenshot('fork-line-layer-basic', SCREENSHOT_OPTIONS); +}); + +test('fork-line-layer-large-network', async () => { + const lines = createLargeMapLinesWithType(); + const forkLines = lines.map((line) => ({ + id: `fork-${line.id}`, + source: line.positions![0], + target: line.positions![1] ?? line.positions![line.positions!.length - 1], + lineParallelIndex: line.parallelIndex ?? 0, + lineAngle: line.angle ?? 0, + substationOffset: 1, + proximityFactor: line.proximityFactorStart ?? 1, + })); + + const canvas = await renderLayers([ + new ForkLineLayer({ + id: 'fork-line-layer-large-network', + data: forkLines, + getSourcePosition: (lineData) => lineData.source, + getTargetPosition: (lineData) => lineData.target, + getColor: [210, 179, 63], + getWidth: 2, + widthUnits: 'pixels', + getLineParallelIndex: (lineData) => lineData.lineParallelIndex, + getLineAngle: (lineData) => lineData.lineAngle, + getSubstationOffset: (lineData) => lineData.substationOffset, + getProximityFactor: (lineData) => lineData.proximityFactor, + getDistanceBetweenLines: 1000, + getMaxParallelOffset: 100, + getMinParallelOffset: 3, + getSubstationRadius: 500, + getSubstationMaxPixel: 5, + getMinSubstationRadiusPixel: 1, + distanceBetweenLines: 1000, + maxParallelOffset: 100, + minParallelOffset: 3, + substationRadius: 500, + substationMaxPixel: 5, + minSubstationRadiusPixel: 1, + }), + ]); + + await expectElement(canvas).toMatchScreenshot('fork-line-layer-large-network', SCREENSHOT_OPTIONS); +}); diff --git a/packages/network-map-layers/src/network/layers/parallel-path-layer.browser.test.ts b/packages/network-map-layers/src/network/layers/parallel-path-layer.browser.test.ts new file mode 100644 index 00000000..28057640 --- /dev/null +++ b/packages/network-map-layers/src/network/layers/parallel-path-layer.browser.test.ts @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +import { afterEach, test } from 'vitest'; +import { type MapAnyLineWithType } from '../../equipment-types'; +import { expectElement, SCREENSHOT_OPTIONS, setupBrowserLayerRenderer } from '../../testUtils/browser-render'; +import { createLargeMapLinesWithType, createMapLineWithType } from '../../testUtils/network-fixtures'; +import ParallelPathLayer from './parallel-path-layer'; + +const { renderLayers, cleanup } = setupBrowserLayerRenderer(); + +afterEach(cleanup); + +test('parallel-path-layer-basic', async () => { + const line = createMapLineWithType(); + + const canvas = await renderLayers([ + new ParallelPathLayer({ + id: 'parallel-lines', + data: [line], + getPath: (value: MapAnyLineWithType) => value.positions, + getColor: [40, 120, 220], + getWidth: 2, + getLineParallelIndex: (value: MapAnyLineWithType) => value.parallelIndex, + getExtraAttributes: (value: MapAnyLineWithType) => [ + value.angleStart, + value.angle, + value.angleEnd, + value.parallelIndex! * 2 + 31, + ], + distanceBetweenLines: 1000, + maxParallelOffset: 100, + minParallelOffset: 3, + } as never), + ]); + + await expectElement(canvas).toMatchScreenshot('parallel-path-layer-basic', SCREENSHOT_OPTIONS); +}); + +test('parallel-path-layer-large-network', async () => { + const lines = createLargeMapLinesWithType(); + + const canvas = await renderLayers([ + new ParallelPathLayer({ + id: 'parallel-lines-large-network', + data: lines, + getPath: (value: MapAnyLineWithType) => value.positions, + getColor: [40, 120, 220], + getWidth: 2, + getLineParallelIndex: (value: MapAnyLineWithType) => value.parallelIndex, + getExtraAttributes: (value: MapAnyLineWithType) => [ + value.angleStart, + value.angle, + value.angleEnd, + value.parallelIndex! * 2 + 31, + ], + distanceBetweenLines: 1000, + maxParallelOffset: 100, + minParallelOffset: 3, + } as never), + ]); + + await expectElement(canvas).toMatchScreenshot('parallel-path-layer-large-network', SCREENSHOT_OPTIONS); +}); diff --git a/packages/network-map-layers/src/network/layers/scatterplot-layer-ext.browser.test.ts b/packages/network-map-layers/src/network/layers/scatterplot-layer-ext.browser.test.ts new file mode 100644 index 00000000..f5e12fc9 --- /dev/null +++ b/packages/network-map-layers/src/network/layers/scatterplot-layer-ext.browser.test.ts @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +import { afterEach, test } from 'vitest'; +import { expectElement, SCREENSHOT_OPTIONS, setupBrowserLayerRenderer } from '../../testUtils/browser-render'; +import { createLargeGeoData } from '../../testUtils/network-fixtures'; +import ScatterplotLayerExt from './scatterplot-layer-ext'; + +const { renderLayers, cleanup } = setupBrowserLayerRenderer(); + +afterEach(cleanup); + +test('scatterplot-layer-ext-basic', async () => { + const points = [ + { id: 's1', position: [2.35, 48.85] as [number, number], radius: 1, maxPixels: 5 }, + { id: 's2', position: [2.37, 48.87] as [number, number], radius: 2, maxPixels: 9 }, + ]; + + const canvas = await renderLayers([ + new ScatterplotLayerExt({ + id: 'scatterplot-layer-ext', + data: points, + radiusMinPixels: 1, + getRadiusMaxPixels: (point: (typeof points)[number]) => point.maxPixels, + getPosition: (point: (typeof points)[number]) => point.position, + getFillColor: [107, 178, 40], + getRadius: (point: (typeof points)[number]) => 500 * point.radius, + stroked: false, + } as never), + ]); + + await expectElement(canvas).toMatchScreenshot('scatterplot-layer-ext-basic', SCREENSHOT_OPTIONS); +}); + +test('scatterplot-layer-ext-large-network', async () => { + const geoData = createLargeGeoData(); + const points = Array.from(geoData.substationPositionsById.entries()).map(([id, coordinate], index) => ({ + id, + position: [coordinate.lon, coordinate.lat] as [number, number], + radius: 1 + (index % 3), + maxPixels: 5 + (index % 3) * 2, + })); + + const canvas = await renderLayers([ + new ScatterplotLayerExt({ + id: 'scatterplot-layer-ext-large-network', + data: points, + radiusMinPixels: 1, + getRadiusMaxPixels: (point: (typeof points)[number]) => point.maxPixels, + getPosition: (point: (typeof points)[number]) => point.position, + getFillColor: [107, 178, 40], + getRadius: (point: (typeof points)[number]) => 500 * point.radius, + stroked: false, + } as never), + ]); + + await expectElement(canvas).toMatchScreenshot('scatterplot-layer-ext-large-network', SCREENSHOT_OPTIONS); +}); diff --git a/packages/network-map-layers/src/network/line-layer.browser.test.ts b/packages/network-map-layers/src/network/line-layer.browser.test.ts new file mode 100644 index 00000000..9cbb120f --- /dev/null +++ b/packages/network-map-layers/src/network/line-layer.browser.test.ts @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +import { afterEach, test } from 'vitest'; +import { expectElement, SCREENSHOT_OPTIONS, setupBrowserLayerRenderer } from '../testUtils/browser-render'; +import { + createGeoData, + createLargeGeoData, + createLargeMapLinesWithType, + createLargeNetwork, + createLineForLineLayer, + createNetwork, +} from '../testUtils/network-fixtures'; +import { getNominalVoltageColor } from '../utils/colors'; +import { LineLayer } from './line-layer'; + +const { renderLayers, cleanup } = setupBrowserLayerRenderer(); + +afterEach(cleanup); + +test('line-layer-basic', async () => { + const line = createLineForLineLayer(); + const network = createNetwork(line); + const geoData = createGeoData(line); + + const canvas = await renderLayers([ + new LineLayer({ + id: 'line-layer', + data: [line], + network, + geoData, + updatedLines: [], + areFlowsValid: true, + labelsVisible: true, + labelColor: [255, 255, 255], + getNominalVoltageColor: () => [200, 200, 200] as [number, number, number], + }), + ]); + + await expectElement(canvas).toMatchScreenshot('line-layer-basic', SCREENSHOT_OPTIONS); +}); + +test('line-layer-large-network', async () => { + const data = createLargeMapLinesWithType(); + const network = createLargeNetwork(); + const geoData = createLargeGeoData(); + + const canvas = await renderLayers( + [ + new LineLayer({ + id: 'line-layer-large-network', + data, + network, + geoData, + updatedLines: [], + areFlowsValid: true, + labelsVisible: true, + labelColor: [0, 0, 0], + getNominalVoltageColor: getNominalVoltageColor, + }), + ], + { + zoom: 7, + longitude: 1.8305, + latitude: 49.0434, + } + ); + + await expectElement(canvas).toMatchScreenshot('line-layer-large-network', SCREENSHOT_OPTIONS); +}); diff --git a/packages/network-map-layers/src/network/line-layer.test.ts b/packages/network-map-layers/src/network/line-layer.test.ts new file mode 100644 index 00000000..a0a6073b --- /dev/null +++ b/packages/network-map-layers/src/network/line-layer.test.ts @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +import { testLayer } from '@deck.gl/test-utils/vitest'; +import { expect, test } from 'vitest'; +import { createGeoData, createLineForLineLayer, createNetwork } from '../testUtils/network-fixtures'; +import { LineFlowMode, LineLayer } from './line-layer'; + +test('LineLayer lifecycle renders expected sublayers and applies updates', () => { + const line = createLineForLineLayer(); + const network = createNetwork(line); + const geoData = createGeoData(line); + + testLayer({ + Layer: LineLayer, + testCases: [ + { + title: 'initializes and renders map sublayers', + props: { + id: 'line-layer-under-test', + data: [line], + network, + geoData, + updatedLines: [], + areFlowsValid: true, + labelsVisible: true, + labelColor: [255, 255, 255], + getNominalVoltageColor: () => [200, 200, 200] as [number, number, number], + }, + onAfterUpdate: ({ layer, subLayers }: { layer: LineLayer; subLayers: Array<{ id: string }> }) => { + expect(layer.state.compositeData).toHaveLength(1); + expect(layer.state.compositeData[0].arrows).toHaveLength(2); + expect(subLayers).toHaveLength(6); + expect(subLayers.some((subLayer) => subLayer.id.includes('ArrowNominalVoltage400'))).toBe(true); + expect(subLayers.some((subLayer) => subLayer.id.includes('LineNominalVoltage400'))).toBe(true); + }, + }, + { + title: 'updates flow mode and cached line connectivity', + updateProps: { + lineFlowMode: LineFlowMode.ANIMATED_ARROWS, + updatedLines: [ + { + ...line, + terminal1Connected: false, + }, + ], + }, + onAfterUpdate: ({ layer }: { layer: LineLayer }) => { + expect(layer.state.compositeData[0].arrows.length).toBeGreaterThanOrEqual(1); + expect(layer.state.linesConnection.get(line.id)?.terminal1Connected).toBe(false); + }, + }, + ], + }); +}); diff --git a/packages/network-map-layers/src/network/line-layer.ts b/packages/network-map-layers/src/network/line-layer.ts index c2d70fe9..f7ed40b6 100644 --- a/packages/network-map-layers/src/network/line-layer.ts +++ b/packages/network-map-layers/src/network/line-layer.ts @@ -5,7 +5,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { PathStyleExtension } from '@deck.gl/extensions'; import { type Color, CompositeLayer, @@ -18,19 +17,21 @@ import { type Position, type UpdateParameters, } from '@deck.gl/core'; +import { PathStyleExtension } from '@deck.gl/extensions'; +import { IconLayer, type IconLayerProps, TextLayer, type TextLayerProps } from '@deck.gl/layers'; import { getDistance } from 'geolib'; import type { LiteralUnion } from 'type-fest'; import { type LonLat, type MapAnyLine, type MapAnyLineWithType } from '../equipment-types'; import BoltIcon from '../images/bolt_black_24dp.svg?url'; import PadlockIcon from '../images/lock_black_24dp.svg?url'; import { INVALID_FLOW_OPACITY } from '../utils/colors'; +import { ArrowDirection } from './arrow-direction'; import { SUBSTATION_RADIUS, SUBSTATION_RADIUS_MAX_PIXEL, SUBSTATION_RADIUS_MIN_PIXEL } from './constants'; import { type GeoData } from './geo-data'; -import ArrowLayer, { type Arrow, ArrowDirection, type ArrowLayerProps } from './layers/arrow-layer'; +import ArrowLayer, { type Arrow, type ArrowLayerProps } from './layers/arrow-layer'; import ForkLineLayer, { type ForkLineLayerProps } from './layers/fork-line-layer'; import ParallelPathLayer, { type ParallelPathLayerProps } from './layers/parallel-path-layer'; import { MapEquipments } from './map-equipments'; -import { IconLayer, type IconLayerProps, TextLayer, type TextLayerProps } from '@deck.gl/layers'; // isn't exported in @deck.gl/layers lib type UnpackedIcon = Exclude>, string>; @@ -868,8 +869,8 @@ export class LineLayer extends CompositeLayer> { // @ts-expect-error TODO: manage undefined case getLineAngles: (arrow) => [arrow.line.angleStart, arrow.line.angle, arrow.line.angleEnd], getProximityFactors: (arrow: Arrow) => [ - arrow.line.proximityFactorStart, - arrow.line.proximityFactorEnd, + arrow.line.proximityFactorStart!, + arrow.line.proximityFactorEnd!, ], getDistanceBetweenLines: this.props.distanceBetweenLines, maxParallelOffset: this.props.maxParallelOffset, diff --git a/packages/network-map-layers/src/testUtils/browser-render.ts b/packages/network-map-layers/src/testUtils/browser-render.ts new file mode 100644 index 00000000..f6c80d68 --- /dev/null +++ b/packages/network-map-layers/src/testUtils/browser-render.ts @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +import { Deck, MapViewState, type LayersList } from '@deck.gl/core'; +import { expect } from 'vitest'; + +export const VIEW_STATE = { + longitude: 2.36, + latitude: 48.86, + zoom: 11, + pitch: 0, + bearing: 0, +}; + +export const SCREENSHOT_OPTIONS = { + comparatorName: 'pixelmatch' as const, + comparatorOptions: { + allowedMismatchedPixelRatio: 0.0, + }, +}; + +type BrowserExpect = { + element: (element: Element) => { + toMatchScreenshot: (name?: string, options?: typeof SCREENSHOT_OPTIONS) => Promise; + }; +}; + +export function expectElement(element: Element) { + return (expect as unknown as BrowserExpect).element(element); +} + +export function setupBrowserLayerRenderer() { + let currentDeck: Deck | null = null; + let currentContainer: HTMLDivElement | null = null; + + function createContainer(): HTMLDivElement { + const container = document.createElement('div'); + container.style.width = '1000px'; + container.style.height = '1000px'; + container.style.position = 'fixed'; + container.style.top = '0'; + container.style.left = '0'; + document.body.append(container); + return container; + } + + async function renderLayers( + layers: LayersList, + initialViewState: MapViewState = VIEW_STATE + ): Promise { + currentContainer = createContainer(); + + currentDeck = new Deck({ + parent: currentContainer, + width: 1000, + height: 1000, + useDevicePixels: false, + initialViewState, + controller: false, + layers, + }); + + currentDeck.redraw(); + await new Promise((resolve) => setTimeout(resolve, 250)); + + const canvas = currentContainer.querySelector('canvas'); + if (!(canvas instanceof HTMLCanvasElement)) { + throw new Error('Unable to find deck.gl canvas for screenshot assertion'); + } + + return canvas; + } + + function cleanup(): void { + currentDeck?.finalize(); + currentDeck = null; + currentContainer?.remove(); + currentContainer = null; + } + + return { + renderLayers, + cleanup, + }; +} diff --git a/packages/network-map-layers/src/testUtils/network-fixtures.ts b/packages/network-map-layers/src/testUtils/network-fixtures.ts new file mode 100644 index 00000000..c05ca394 --- /dev/null +++ b/packages/network-map-layers/src/testUtils/network-fixtures.ts @@ -0,0 +1,563 @@ +/** + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +import { EQUIPMENT_TYPES, MapAdditionalProperties, MapLine, type MapLineWithType } from '../equipment-types'; +import { GeoData } from '../network/geo-data'; +import { LineStatus } from '../network/line-layer'; +import { MapEquipments } from '../network/map-equipments'; + +type Coordinate = { lat: number; lon: number }; + +type LargeLineRoute = { + lineId: string; + fromSubstationId: string; + toSubstationId: string; + bend: number; +}; + +const SUBSTATION_1 = { + id: 's1', + name: 'S1', + voltageLevels: [{ id: 'vl1', nominalV: 400, substationId: 's1' }], +}; + +const SUBSTATION_2 = { + id: 's2', + name: 'S2', + voltageLevels: [{ id: 'vl2', nominalV: 400, substationId: 's2' }], +}; + +const SUBSTATION_COORDINATES: Coordinate[] = [ + { lat: 48.85, lon: 2.35 }, + { lat: 48.87, lon: 2.37 }, +]; + +const LINE_COORDINATES: Coordinate[] = [ + { lat: 48.85, lon: 2.35 }, + { lat: 48.86, lon: 2.36 }, + { lat: 48.87, lon: 2.37 }, +]; + +const LARGE_SUBSTATIONS = [ + { + id: 's-paris', + name: 'Paris', + voltageLevels: [ + { id: 'vl-paris-400', nominalV: 400, substationId: 's-paris' }, + { id: 'vl-paris-225', nominalV: 225, substationId: 's-paris' }, + { id: 'vl-paris-90', nominalV: 90, substationId: 's-paris' }, + { id: 'vl-paris-63', nominalV: 63, substationId: 's-paris' }, + { id: 'vl-paris-45', nominalV: 45, substationId: 's-paris' }, + ], + }, + { + id: 's-mantes', + name: 'Mantes', + voltageLevels: [ + { id: 'vl-mantes-400', nominalV: 400, substationId: 's-mantes' }, + { id: 'vl-mantes-90', nominalV: 90, substationId: 's-mantes' }, + { id: 'vl-mantes-45', nominalV: 45, substationId: 's-mantes' }, + ], + }, + { + id: 's-tours', + name: 'Tours', + voltageLevels: [ + { id: 'vl-tours-400', nominalV: 400, substationId: 's-tours' }, + { id: 'vl-tours-45', nominalV: 45, substationId: 's-tours' }, + ], + }, + { + id: 's-lille', + name: 'Lille', + voltageLevels: [ + { id: 'vl-lille-400', nominalV: 400, substationId: 's-lille' }, + { id: 'vl-lille-150', nominalV: 150, substationId: 's-lille' }, + ], + }, + { + id: 's-versailles', + name: 'Versailles', + voltageLevels: [ + { id: 'vl-versailles-225', nominalV: 225, substationId: 's-versailles' }, + { id: 'vl-versailles-63', nominalV: 63, substationId: 's-versailles' }, + ], + }, + { + id: 's-rouen', + name: 'Rouen', + voltageLevels: [ + { id: 'vl-rouen-225', nominalV: 225, substationId: 's-rouen' }, + { id: 'vl-rouen-150', nominalV: 150, substationId: 's-rouen' }, + ], + }, + { + id: 's-reims', + name: 'Reims', + voltageLevels: [ + { id: 'vl-reims-225', nominalV: 225, substationId: 's-reims' }, + { id: 'vl-reims-45', nominalV: 45, substationId: 's-reims' }, + ], + }, + { + id: 's-caen', + name: 'Caen', + voltageLevels: [ + { id: 'vl-caen-150', nominalV: 150, substationId: 's-caen' }, + { id: 'vl-caen-63', nominalV: 63, substationId: 's-caen' }, + ], + }, + { + id: 's-amiens', + name: 'Amiens', + voltageLevels: [ + { id: 'vl-amiens-90', nominalV: 90, substationId: 's-amiens' }, + { id: 'vl-amiens-63', nominalV: 63, substationId: 's-amiens' }, + ], + }, + { + id: 's-orleans', + name: 'Orleans', + voltageLevels: [ + { id: 'vl-orleans-90', nominalV: 90, substationId: 's-orleans' }, + { id: 'vl-orleans-20', nominalV: 20, substationId: 's-orleans' }, + ], + }, +]; + +const LARGE_SUBSTATION_COORDINATES: Record = { + 's-paris': { lat: 48.8566, lon: 2.3522 }, + 's-mantes': { lat: 48.9905, lon: 1.7172 }, + 's-tours': { lat: 47.3941, lon: 0.6848 }, + 's-lille': { lat: 50.6292, lon: 3.0573 }, + 's-versailles': { lat: 48.8049, lon: 2.1204 }, + 's-rouen': { lat: 49.4432, lon: 1.0993 }, + 's-reims': { lat: 49.2583, lon: 4.0317 }, + 's-caen': { lat: 49.1829, lon: -0.3707 }, + 's-amiens': { lat: 49.8941, lon: 2.2958 }, + 's-orleans': { lat: 47.9029, lon: 1.9093 }, +}; + +const LARGE_NETWORK_LINES: MapLineWithType[] = [ + { + id: 'line-paris-mantes-400', + equipmentType: EQUIPMENT_TYPES.LINE, + voltageLevelId1: 'vl-paris-400', + voltageLevelId2: 'vl-mantes-400', + terminal1Connected: true, + terminal2Connected: true, + p1: 280, + p2: -280, + i1: 65, + i2: 64, + operatingStatus: LineStatus.IN_OPERATION, + currentLimits1: { permanentLimit: 800 }, + currentLimits2: { permanentLimit: 800 }, + }, + { + id: 'line-paris-lille-400', + equipmentType: EQUIPMENT_TYPES.LINE, + voltageLevelId1: 'vl-paris-400', + voltageLevelId2: 'vl-lille-400', + terminal1Connected: true, + terminal2Connected: true, + p1: 360, + p2: -360, + i1: 82, + i2: 80, + operatingStatus: LineStatus.IN_OPERATION, + currentLimits1: { permanentLimit: 900 }, + currentLimits2: { permanentLimit: 900 }, + }, + { + id: 'line-paris-tours-400', + equipmentType: EQUIPMENT_TYPES.LINE, + voltageLevelId1: 'vl-paris-400', + voltageLevelId2: 'vl-tours-400', + terminal1Connected: true, + terminal2Connected: false, + p1: 0, + p2: 0, + i1: 0, + i2: 0, + operatingStatus: LineStatus.PLANNED_OUTAGE, + currentLimits1: { permanentLimit: 750 }, + currentLimits2: { permanentLimit: 750 }, + }, + { + id: 'line-mantes-tours-400', + equipmentType: EQUIPMENT_TYPES.LINE, + voltageLevelId1: 'vl-mantes-400', + voltageLevelId2: 'vl-tours-400', + terminal1Connected: true, + terminal2Connected: true, + p1: 150, + p2: -150, + i1: 36, + i2: 35, + operatingStatus: LineStatus.IN_OPERATION, + currentLimits1: { permanentLimit: 700 }, + currentLimits2: { permanentLimit: 700 }, + }, + { + id: 'line-paris-versailles-225', + equipmentType: EQUIPMENT_TYPES.LINE, + voltageLevelId1: 'vl-paris-225', + voltageLevelId2: 'vl-versailles-225', + terminal1Connected: true, + terminal2Connected: true, + p1: 110, + p2: -110, + i1: 40, + i2: 39, + operatingStatus: LineStatus.IN_OPERATION, + currentLimits1: { permanentLimit: 400 }, + currentLimits2: { permanentLimit: 400 }, + }, + { + id: 'line-paris-reims-225', + equipmentType: EQUIPMENT_TYPES.LINE, + voltageLevelId1: 'vl-paris-225', + voltageLevelId2: 'vl-reims-225', + terminal1Connected: true, + terminal2Connected: true, + p1: 140, + p2: -140, + i1: 48, + i2: 47, + operatingStatus: LineStatus.IN_OPERATION, + currentLimits1: { permanentLimit: 430 }, + currentLimits2: { permanentLimit: 430 }, + }, + { + id: 'line-paris-rouen-225', + equipmentType: EQUIPMENT_TYPES.LINE, + voltageLevelId1: 'vl-paris-225', + voltageLevelId2: 'vl-rouen-225', + terminal1Connected: true, + terminal2Connected: true, + p1: 0, + p2: 0, + i1: 0, + i2: 0, + operatingStatus: LineStatus.FORCED_OUTAGE, + currentLimits1: { permanentLimit: 420 }, + currentLimits2: { permanentLimit: 420 }, + }, + { + id: 'line-rouen-caen-150', + equipmentType: EQUIPMENT_TYPES.LINE, + voltageLevelId1: 'vl-rouen-150', + voltageLevelId2: 'vl-caen-150', + terminal1Connected: true, + terminal2Connected: true, + p1: 95, + p2: -95, + i1: 37, + i2: 36, + operatingStatus: LineStatus.IN_OPERATION, + currentLimits1: { permanentLimit: 320 }, + currentLimits2: { permanentLimit: 320 }, + }, + { + id: 'line-caen-lille-150', + equipmentType: EQUIPMENT_TYPES.LINE, + voltageLevelId1: 'vl-caen-150', + voltageLevelId2: 'vl-lille-150', + terminal1Connected: true, + terminal2Connected: true, + p1: 0, + p2: 0, + i1: 0, + i2: 0, + operatingStatus: LineStatus.PLANNED_OUTAGE, + currentLimits1: { permanentLimit: 340 }, + currentLimits2: { permanentLimit: 340 }, + }, + { + id: 'line-paris-versailles-63', + equipmentType: EQUIPMENT_TYPES.LINE, + voltageLevelId1: 'vl-paris-63', + voltageLevelId2: 'vl-versailles-63', + terminal1Connected: true, + terminal2Connected: true, + p1: 70, + p2: -70, + i1: 42, + i2: 41, + operatingStatus: LineStatus.IN_OPERATION, + currentLimits1: { permanentLimit: 240 }, + currentLimits2: { permanentLimit: 240 }, + }, + { + id: 'line-paris-mantes-90', + equipmentType: EQUIPMENT_TYPES.LINE, + voltageLevelId1: 'vl-paris-90', + voltageLevelId2: 'vl-mantes-90', + terminal1Connected: true, + terminal2Connected: true, + p1: 70, + p2: -70, + i1: 42, + i2: 41, + operatingStatus: LineStatus.IN_OPERATION, + currentLimits1: { permanentLimit: 240 }, + currentLimits2: { permanentLimit: 240 }, + }, + { + id: 'line-paris-mantes-45', + equipmentType: EQUIPMENT_TYPES.LINE, + voltageLevelId1: 'vl-paris-45', + voltageLevelId2: 'vl-mantes-45', + terminal1Connected: true, + terminal2Connected: true, + p1: 70, + p2: -70, + i1: 42, + i2: 41, + operatingStatus: LineStatus.IN_OPERATION, + currentLimits1: { permanentLimit: 240 }, + currentLimits2: { permanentLimit: 240 }, + }, + { + id: 'line-paris-amiens-90', + equipmentType: EQUIPMENT_TYPES.LINE, + voltageLevelId1: 'vl-paris-90', + voltageLevelId2: 'vl-amiens-90', + terminal1Connected: true, + terminal2Connected: true, + p1: 85, + p2: -85, + i1: 44, + i2: 43, + operatingStatus: LineStatus.IN_OPERATION, + currentLimits1: { permanentLimit: 250 }, + currentLimits2: { permanentLimit: 250 }, + }, + { + id: 'line-paris-orleans-90', + equipmentType: EQUIPMENT_TYPES.LINE, + voltageLevelId1: 'vl-paris-90', + voltageLevelId2: 'vl-orleans-90', + terminal1Connected: false, + terminal2Connected: true, + p1: 0, + p2: 0, + i1: 0, + i2: 0, + operatingStatus: LineStatus.FORCED_OUTAGE, + currentLimits1: { permanentLimit: 220 }, + currentLimits2: { permanentLimit: 220 }, + }, + { + id: 'line-versailles-caen-63', + equipmentType: EQUIPMENT_TYPES.LINE, + voltageLevelId1: 'vl-versailles-63', + voltageLevelId2: 'vl-caen-63', + terminal1Connected: true, + terminal2Connected: false, + p1: 0, + p2: 0, + i1: 0, + i2: 0, + operatingStatus: LineStatus.IN_OPERATION, + currentLimits1: { permanentLimit: 180 }, + currentLimits2: { permanentLimit: 180 }, + }, + { + id: 'line-caen-amiens-63', + equipmentType: EQUIPMENT_TYPES.LINE, + voltageLevelId1: 'vl-caen-63', + voltageLevelId2: 'vl-amiens-63', + terminal1Connected: true, + terminal2Connected: true, + p1: 55, + p2: -55, + i1: 33, + i2: 32, + operatingStatus: LineStatus.IN_OPERATION, + currentLimits1: { permanentLimit: 170 }, + currentLimits2: { permanentLimit: 170 }, + }, + { + id: 'line-tours-reims-45', + equipmentType: EQUIPMENT_TYPES.LINE, + voltageLevelId1: 'vl-tours-45', + voltageLevelId2: 'vl-reims-45', + terminal1Connected: true, + terminal2Connected: true, + p1: 0, + p2: 0, + i1: 0, + i2: 0, + operatingStatus: LineStatus.PLANNED_OUTAGE, + currentLimits1: { permanentLimit: 150 }, + currentLimits2: { permanentLimit: 150 }, + }, +]; + +const LARGE_LINE_ROUTES: LargeLineRoute[] = [ + { lineId: 'line-paris-mantes-400', fromSubstationId: 's-paris', toSubstationId: 's-mantes', bend: 0.05 }, + { lineId: 'line-paris-lille-400', fromSubstationId: 's-paris', toSubstationId: 's-lille', bend: 0.08 }, + { lineId: 'line-paris-tours-400', fromSubstationId: 's-paris', toSubstationId: 's-tours', bend: -0.1 }, + { lineId: 'line-mantes-tours-400', fromSubstationId: 's-mantes', toSubstationId: 's-tours', bend: -0.06 }, + { + lineId: 'line-paris-versailles-225', + fromSubstationId: 's-paris', + toSubstationId: 's-versailles', + bend: 0.02, + }, + { lineId: 'line-paris-reims-225', fromSubstationId: 's-paris', toSubstationId: 's-reims', bend: 0.04 }, + { lineId: 'line-paris-rouen-225', fromSubstationId: 's-paris', toSubstationId: 's-rouen', bend: 0.03 }, + { lineId: 'line-rouen-caen-150', fromSubstationId: 's-rouen', toSubstationId: 's-caen', bend: 0.06 }, + { lineId: 'line-caen-lille-150', fromSubstationId: 's-caen', toSubstationId: 's-lille', bend: 0.07 }, + { lineId: 'line-paris-versailles-63', fromSubstationId: 's-paris', toSubstationId: 's-versailles', bend: -0.02 }, + { lineId: 'line-paris-mantes-90', fromSubstationId: 's-paris', toSubstationId: 's-mantes', bend: -0.04 }, + { lineId: 'line-paris-mantes-45', fromSubstationId: 's-paris', toSubstationId: 's-mantes', bend: -0.01 }, + { lineId: 'line-paris-amiens-90', fromSubstationId: 's-paris', toSubstationId: 's-amiens', bend: 0.02 }, + { lineId: 'line-paris-orleans-90', fromSubstationId: 's-paris', toSubstationId: 's-orleans', bend: -0.05 }, + { + lineId: 'line-versailles-caen-63', + fromSubstationId: 's-versailles', + toSubstationId: 's-caen', + bend: 0.09, + }, + { lineId: 'line-caen-amiens-63', fromSubstationId: 's-caen', toSubstationId: 's-amiens', bend: -0.04 }, + { lineId: 'line-tours-reims-45', fromSubstationId: 's-tours', toSubstationId: 's-reims', bend: 0.11 }, +]; + +function createPolylineCoordinates(start: Coordinate, end: Coordinate, bend: number): Coordinate[] { + const middle = { + lat: (start.lat + end.lat) / 2 + bend, + lon: (start.lon + end.lon) / 2 - bend, + }; + + return [start, middle, end]; +} + +export function createLineForLineLayer(overrides: Partial = {}): MapLineWithType { + return { + id: 'line-1', + equipmentType: EQUIPMENT_TYPES.LINE, + voltageLevelId1: 'vl1', + voltageLevelId2: 'vl2', + terminal1Connected: true, + terminal2Connected: true, + p1: 120, + p2: -120, + i1: 20, + i2: 20, + operatingStatus: LineStatus.IN_OPERATION, + currentLimits1: { permanentLimit: 100 }, + currentLimits2: { permanentLimit: 100 }, + ...overrides, + }; +} + +export function createMapLineWithType(overrides: Partial = {}): MapAdditionalProperties & MapLineWithType { + return { + id: 'line-visual-1', + equipmentType: EQUIPMENT_TYPES.LINE, + voltageLevelId1: 'vl1', + voltageLevelId2: 'vl2', + terminal1Connected: true, + terminal2Connected: true, + p1: 90, + p2: -90, + positions: [ + [2.35, 48.85], + [2.36, 48.86], + [2.37, 48.865], + ], + cumulativeDistances: [0, 1200, 2200], + parallelIndex: 0, + angleStart: 0, + angle: 0, + angleEnd: 0, + proximityFactorStart: 1, + proximityFactorEnd: 1, + ...overrides, + }; +} + +export function createNetwork(lineData: MapLineWithType): MapEquipments { + const network = new MapEquipments(); + network.updateSubstations([SUBSTATION_1, SUBSTATION_2], true); + network.updateLines([lineData], true); + return network; +} + +export function createGeoData(lineData: MapLineWithType): GeoData { + const geoData = new GeoData(new Map(), new Map()); + geoData.setSubstationPositions([ + { id: SUBSTATION_1.id, coordinate: SUBSTATION_COORDINATES[0] }, + { id: SUBSTATION_2.id, coordinate: SUBSTATION_COORDINATES[1] }, + ]); + geoData.setLinePositions([ + { + id: lineData.id, + coordinates: LINE_COORDINATES, + }, + ]); + return geoData; +} + +export function createLargeNetwork(): MapEquipments { + const network = new MapEquipments(); + network.updateSubstations(LARGE_SUBSTATIONS, true); + network.updateLines(LARGE_NETWORK_LINES, true); + return network; +} + +export function createLargeGeoData(): GeoData { + const geoData = new GeoData(new Map(), new Map()); + + geoData.setSubstationPositions( + LARGE_SUBSTATIONS.map((substation) => ({ + id: substation.id, + coordinate: LARGE_SUBSTATION_COORDINATES[substation.id], + })) + ); + + geoData.setLinePositions( + LARGE_LINE_ROUTES.map((route) => ({ + id: route.lineId, + coordinates: createPolylineCoordinates( + LARGE_SUBSTATION_COORDINATES[route.fromSubstationId], + LARGE_SUBSTATION_COORDINATES[route.toSubstationId], + route.bend + ), + })) + ); + + return geoData; +} + +export function createLargeMapLinesWithType(): (MapAdditionalProperties & MapLineWithType)[] { + const network = createLargeNetwork(); + const geoData = createLargeGeoData(); + + return LARGE_NETWORK_LINES.map((line, index) => { + const positions = geoData.getLinePositions(network, line, true); + const cumulativeDistances = geoData.getLineDistances(positions) ?? []; + const start = positions[0]; + const end = positions[positions.length - 1]; + const angle = Math.atan2(end[1] - start[1], end[0] - start[0]); + + return { + ...line, + positions, + cumulativeDistances, + parallelIndex: (index % 5) - 2, + angleStart: angle, + angle, + angleEnd: angle, + proximityFactorStart: 1, + proximityFactorEnd: 1, + }; + }); +} diff --git a/setupTests.ts b/setupTests.ts index 4c4cb044..e5218252 100644 --- a/setupTests.ts +++ b/setupTests.ts @@ -11,3 +11,44 @@ declare var SVG: any; global.SVG = () => {}; global.SVG.extend = () => {}; /* eslint-enable */ + +const canvas2DContextStub = { + font: '', + clearRect: () => {}, + fillRect: () => {}, + fillText: () => {}, + strokeText: () => {}, + measureText: (text: string) => { + const width = text.length * 8; + return { + width, + actualBoundingBoxLeft: 0, + actualBoundingBoxRight: width, + actualBoundingBoxAscent: 8, + actualBoundingBoxDescent: 2, + fontBoundingBoxAscent: 8, + fontBoundingBoxDescent: 2, + }; + }, + getImageData: (sx: number, sy: number, sw: number, sh: number) => ({ + data: new Uint8ClampedArray(sw * sh * 4), + width: sw, + height: sh, + }), + putImageData: () => {}, + drawImage: () => {}, + createImageData: (sw: number, sh: number) => ({ + data: new Uint8ClampedArray(sw * sh * 4), + width: sw, + height: sh, + }), +}; + +if (typeof HTMLCanvasElement !== 'undefined') { + HTMLCanvasElement.prototype.getContext = function (contextId: '2d' | 'bitmaprenderer' | 'webgl' | 'webgl2') { + if (contextId === '2d') { + return canvas2DContextStub as unknown as CanvasRenderingContext2D; + } + return null; + } as unknown as typeof HTMLCanvasElement.prototype.getContext; +} diff --git a/src/components/network-map-viewer/network/network-map.tsx b/src/components/network-map-viewer/network/network-map.tsx index e2ee7345..cdf9f9a6 100644 --- a/src/components/network-map-viewer/network/network-map.tsx +++ b/src/components/network-map-viewer/network/network-map.tsx @@ -750,6 +750,7 @@ const NetworkMap = forwardRef((rawProps, ref) => if (!map) { return null; } + return { zoom: map.getZoom(), center: map.getCenter(), diff --git a/vitest.config.ts b/vitest.config.ts index fdfc2201..3afc36df 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -5,13 +5,38 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +import react from '@vitejs/plugin-react'; +import { playwright } from '@vitest/browser-playwright'; import { coverageConfigDefaults, defineConfig } from 'vitest/config'; export default defineConfig({ + plugins: [react()], test: { - globals: true, - environment: 'jsdom', - setupFiles: ['./setupTests.ts'], + projects: [ + { + test: { + name: 'unit-tests', + include: ['**/*.test.{ts,tsx}', '!**/*.browser.test.{ts,tsx}'], + globals: true, + environment: 'jsdom', + setupFiles: ['./setupTests.ts'], + }, + }, + { + test: { + name: 'browser-tests', + include: ['**/*.browser.test.{ts,tsx}'], + globals: true, + browser: { + enabled: true, + provider: playwright(), + headless: true, + // at least one instance is required + instances: [{ browser: 'chromium', viewport: { width: 1000, height: 1000 } }], + }, + }, + }, + ], coverage: { provider: 'v8', reporter: ['text', 'lcov'], From 82f3f1ebd6f3b8ec9de9d3b92d812f04f759917e Mon Sep 17 00:00:00 2001 From: Arnaud Marant Date: Tue, 30 Jun 2026 10:19:25 +0200 Subject: [PATCH 02/12] Add Playwright installation step to CI build process Signed-off-by: Arnaud Marant --- .github/workflows/build.yml | 22 ++++++++++++++----- packages/network-map-layers/package.json | 2 +- .../src/testUtils/network-fixtures.ts | 4 +++- vitest.config.ts | 1 + 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3c32414a..1d656964 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -39,13 +39,23 @@ jobs: with: node-version: 24 + - name: Install dependencies + run: npm ci + + - name: Install Playwright Browsers + run: npx playwright install --with-deps chromium + + - name: Lint + run: npm run lint + + - name: Run tests + run: npm run test:coverage + + - name: Licenses check + run: npm run licenses-check + - name: Build - run: | - npm ci - npm run build:all - npm run licenses-check - npm run lint - npm run test:coverage + run: npm run build:all - name: SonarCloud Scan uses: SonarSource/sonarqube-scan-action@1a6d90ebcb0e6a6b1d87e37ba693fe453195ae25 #v5.3.1 diff --git a/packages/network-map-layers/package.json b/packages/network-map-layers/package.json index 65f89d9c..438fe033 100644 --- a/packages/network-map-layers/package.json +++ b/packages/network-map-layers/package.json @@ -63,4 +63,4 @@ "vite-plugin-dts": "^4.5.4", "vite-plugin-svgr": "^4.3.0" } -} \ No newline at end of file +} diff --git a/packages/network-map-layers/src/testUtils/network-fixtures.ts b/packages/network-map-layers/src/testUtils/network-fixtures.ts index c05ca394..7cf92257 100644 --- a/packages/network-map-layers/src/testUtils/network-fixtures.ts +++ b/packages/network-map-layers/src/testUtils/network-fixtures.ts @@ -458,7 +458,9 @@ export function createLineForLineLayer(overrides: Partial = {}) }; } -export function createMapLineWithType(overrides: Partial = {}): MapAdditionalProperties & MapLineWithType { +export function createMapLineWithType( + overrides: Partial = {} +): MapAdditionalProperties & MapLineWithType { return { id: 'line-visual-1', equipmentType: EQUIPMENT_TYPES.LINE, diff --git a/vitest.config.ts b/vitest.config.ts index 3afc36df..5aaa6792 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -27,6 +27,7 @@ export default defineConfig({ name: 'browser-tests', include: ['**/*.browser.test.{ts,tsx}'], globals: true, + testTimeout: 30000, browser: { enabled: true, provider: playwright(), From bbc9b3bb6e70bed124943402dc39b9a1c991acbe Mon Sep 17 00:00:00 2001 From: Arnaud Marant Date: Tue, 30 Jun 2026 10:19:25 +0200 Subject: [PATCH 03/12] Add upload step for browser failure screenshots in CI workflows add image approximate comparison in tests sonar ignore test fixtures Signed-off-by: Arnaud Marant --- .github/workflows/build.yml | 10 ++++++++++ .github/workflows/fork-build-tests.yml | 10 ++++++++++ .../network-map-layers/src/testUtils/browser-render.ts | 2 +- sonar-project.properties | 2 +- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1d656964..aca2f2fb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -51,6 +51,16 @@ jobs: - name: Run tests run: npm run test:coverage + - name: Upload browser failure screenshots + if: failure() && !cancelled() + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: browser-failure-screenshots-${{ github.run_id }} + retention-days: 7 + if-no-files-found: ignore + path: | + packages/**/__screenshots__/**/*.png + - name: Licenses check run: npm run licenses-check diff --git a/.github/workflows/fork-build-tests.yml b/.github/workflows/fork-build-tests.yml index b405275a..e2e6efcc 100644 --- a/.github/workflows/fork-build-tests.yml +++ b/.github/workflows/fork-build-tests.yml @@ -27,6 +27,16 @@ jobs: npm run test:coverage npm run build:all + - name: Upload browser failure screenshots + if: failure() && !cancelled() + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: browser-failure-screenshots-${{ github.event.pull_request.number }} + retention-days: 7 + if-no-files-found: ignore + path: | + packages/**/__screenshots__/**/*.png + - name: Save build artifacts and coverage report uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: diff --git a/packages/network-map-layers/src/testUtils/browser-render.ts b/packages/network-map-layers/src/testUtils/browser-render.ts index f6c80d68..4e0f42d9 100644 --- a/packages/network-map-layers/src/testUtils/browser-render.ts +++ b/packages/network-map-layers/src/testUtils/browser-render.ts @@ -19,7 +19,7 @@ export const VIEW_STATE = { export const SCREENSHOT_OPTIONS = { comparatorName: 'pixelmatch' as const, comparatorOptions: { - allowedMismatchedPixelRatio: 0.0, + allowedMismatchedPixelRatio: 0.001, // Allow up to 0.1% of pixels to be different }, }; diff --git a/sonar-project.properties b/sonar-project.properties index e2b5f6b0..7b75d741 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -3,5 +3,5 @@ sonar.organization=powsybl-ci-github sonar.javascript.lcov.reportPaths=./coverage/lcov.info sonar.sources=src/,packages/network-map-layers/src/,packages/network-viewer-core/src/ sonar.tests=src/,packages/network-map-layers/src/,packages/network-viewer-core/src/ -sonar.exclusions=**/*.test.ts,**/node_modules/**,**/dist/** +sonar.exclusions=**/*.test.ts,**/node_modules/**,**/dist/**,packages/network-map-layers/src/testUtils/** sonar.test.inclusions=**/*.test.ts From d30d2522b86427442208933000e6df3085437825 Mon Sep 17 00:00:00 2001 From: Arnaud Marant Date: Tue, 30 Jun 2026 10:19:25 +0200 Subject: [PATCH 04/12] Refactor LineLayer coordinate system checks to use string literals Signed-off-by: Arnaud Marant --- .github/workflows/build.yml | 2 +- packages/network-map-layers/src/network/line-layer.ts | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index aca2f2fb..5b8f895f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,7 +2,7 @@ name: CI on: push: branches: - - "main" + - 'main' pull_request: permissions: {} diff --git a/packages/network-map-layers/src/network/line-layer.ts b/packages/network-map-layers/src/network/line-layer.ts index f7ed40b6..9dbd7e1c 100644 --- a/packages/network-map-layers/src/network/line-layer.ts +++ b/packages/network-map-layers/src/network/line-layer.ts @@ -9,7 +9,6 @@ import { type Color, CompositeLayer, type CompositeLayerProps, - COORDINATE_SYSTEM, type DefaultProps, type Layer, type LayerContext, @@ -751,7 +750,7 @@ export class LineLayer extends CompositeLayer> { getProximityFactor(firstPosition: LonLat, secondPosition: LonLat) { let dist; - if (this.props.coordinateSystem === COORDINATE_SYSTEM.CARTESIAN) { + if (this.props.coordinateSystem === 'cartesian') { dist = Math.hypot(secondPosition[0] - firstPosition[0], secondPosition[1] - firstPosition[1]); } else { dist = getDistance(firstPosition, secondPosition); @@ -764,7 +763,7 @@ export class LineLayer extends CompositeLayer> { } computeAngle(props: this['props'], position1: LonLat, position2: LonLat) { - if (props.coordinateSystem === COORDINATE_SYSTEM.CARTESIAN) { + if (props.coordinateSystem === 'cartesian') { const [x1, y1] = position1; const [x2, y2] = position2; return (3 * Math.PI) / 2 - Math.atan2(y2 - y1, x2 - x1); From d247bd67aaac7586120fb9b0c6baef80a1f88720 Mon Sep 17 00:00:00 2001 From: Arnaud Marant Date: Tue, 30 Jun 2026 10:19:25 +0200 Subject: [PATCH 05/12] Reorganize CI workflow steps for better clarity and execution order Signed-off-by: Arnaud Marant --- .github/workflows/fork-build-tests.yml | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/.github/workflows/fork-build-tests.yml b/.github/workflows/fork-build-tests.yml index e2e6efcc..f7d492ff 100644 --- a/.github/workflows/fork-build-tests.yml +++ b/.github/workflows/fork-build-tests.yml @@ -19,13 +19,17 @@ jobs: with: node-version: 24 - - name: Build - run: | - npm ci - npm run licenses-check - npm run lint - npm run test:coverage - npm run build:all + - name: Install dependencies + run: npm ci + + - name: Install Playwright Browsers + run: npx playwright install --with-deps chromium + + - name: Lint + run: npm run lint + + - name: Run tests + run: npm run test:coverage - name: Upload browser failure screenshots if: failure() && !cancelled() @@ -37,6 +41,12 @@ jobs: path: | packages/**/__screenshots__/**/*.png + - name: Licenses check + run: npm run licenses-check + + - name: Build + run: npm run build:all + - name: Save build artifacts and coverage report uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: From 8c9b02ff53c3ff37f893cd1648b03b7f78a8e9e7 Mon Sep 17 00:00:00 2001 From: Arnaud Marant Date: Tue, 30 Jun 2026 10:19:25 +0200 Subject: [PATCH 06/12] update packages Signed-off-by: Arnaud Marant --- package-lock.json | 325 ++++++++++++++++++++++++++-------------------- package.json | 22 ++-- 2 files changed, 197 insertions(+), 150 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4a3b53b4..cea113dd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,13 +12,13 @@ "packages/*" ], "dependencies": { - "@deck.gl/core": "~9.3.0", - "@deck.gl/extensions": "~9.3.0", - "@deck.gl/layers": "~9.3.0", - "@deck.gl/mapbox": "~9.3.0", - "@luma.gl/constants": "~9.3.0", - "@luma.gl/core": "~9.3.0", - "@luma.gl/engine": "~9.3.0", + "@deck.gl/core": "~9.3.4", + "@deck.gl/extensions": "~9.3.4", + "@deck.gl/layers": "~9.3.4", + "@deck.gl/mapbox": "~9.3.4", + "@luma.gl/constants": "~9.3.4", + "@luma.gl/core": "~9.3.4", + "@luma.gl/engine": "~9.3.4", "@mapbox/mapbox-gl-draw": "<1.5.0", "@powsybl/network-map-layers": "^3.6.0-dev.0", "@powsybl/network-viewer-core": "^3.6.0-dev.0", @@ -39,10 +39,10 @@ "@types/react": "^19.2.2", "@types/react-dom": "^19.2.1", "@vitejs/plugin-react": "^5.0.4", - "@vitest/browser-playwright": "^4.0.18", - "@vitest/coverage-v8": "^4.0.18", + "@vitest/browser-playwright": "^4.1.9", + "@vitest/coverage-v8": "^4.1.9", "@vitest/eslint-plugin": "^1.6.7", - "@vitest/ui": "^4.0.18", + "@vitest/ui": "^4.1.9", "eslint": "^9.26.0", "eslint-config-prettier": "^10.1.2", "eslint-plugin-prettier": "^5.2.6", @@ -65,7 +65,7 @@ "vite-plugin-checker": "^0.12.0", "vite-plugin-dts": "^4.5.4", "vite-plugin-svgr": "^4.3.0", - "vitest": "^4.0.18" + "vitest": "^4.1.9" }, "peerDependencies": { "@emotion/styled": "^11.14.0", @@ -297,14 +297,18 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -331,10 +335,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.29.0", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", "license": "MIT", "dependencies": { - "@babel/types": "^7.29.0" + "@babel/types": "^7.29.7" }, "bin": { "parser": "bin/babel-parser.js" @@ -408,16 +414,28 @@ } }, "node_modules/@babel/types": { - "version": "7.29.0", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@bcoe/v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", + "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/@blazediff/core": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@blazediff/core/-/core-1.9.1.tgz", @@ -565,17 +583,17 @@ } }, "node_modules/@deck.gl/core": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@deck.gl/core/-/core-9.3.0.tgz", - "integrity": "sha512-LYa9+I/isYaDD/6ASmyZUCkB/XJjWFKaWYfFTg7NVcrkB+UduHLkmxcM2DXQ3p8ek10fcSB+IWXHfaO8RHTMZg==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/@deck.gl/core/-/core-9.3.4.tgz", + "integrity": "sha512-2zQykey/qiToLYsWvKvnT9/+LCe7gNX6/npu39huFxT1zEa8AndF5OZHI0gQuV4btKX6BR5A165FPG8jJJwWrQ==", "license": "MIT", "dependencies": { "@loaders.gl/core": "^4.4.1", "@loaders.gl/images": "^4.4.1", - "@luma.gl/core": "^9.3.2", - "@luma.gl/engine": "^9.3.2", - "@luma.gl/shadertools": "^9.3.2", - "@luma.gl/webgl": "^9.3.2", + "@luma.gl/core": "^9.3.3", + "@luma.gl/engine": "^9.3.3", + "@luma.gl/shadertools": "^9.3.3", + "@luma.gl/webgl": "^9.3.3", "@math.gl/core": "^4.1.0", "@math.gl/sun": "^4.1.0", "@math.gl/types": "^4.1.0", @@ -589,30 +607,30 @@ } }, "node_modules/@deck.gl/extensions": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@deck.gl/extensions/-/extensions-9.3.0.tgz", - "integrity": "sha512-QhOPTQOq/OhMQ4wjElP8mLW5Lt2OjOajOXpThGLgk67tqCsd9yOOmXnlRO9jVV6r2/UBZ4j64m3MLxKYCFJgSw==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/@deck.gl/extensions/-/extensions-9.3.4.tgz", + "integrity": "sha512-pzqPJMnzCLJpPWTS9QE3g4DX5usXwJMpYXvbqh9/DYQSCYw+gN+VpbVbvfGNLzUtXFhnp1RbRS+7Y0KDFEy8Dw==", "license": "MIT", "dependencies": { - "@luma.gl/shadertools": "^9.3.2", - "@luma.gl/webgl": "^9.3.2", + "@luma.gl/shadertools": "^9.3.3", + "@luma.gl/webgl": "^9.3.3", "@math.gl/core": "^4.1.0" }, "peerDependencies": { "@deck.gl/core": "~9.3.0", - "@luma.gl/core": "~9.3.2", - "@luma.gl/engine": "~9.3.2" + "@luma.gl/core": "~9.3.3", + "@luma.gl/engine": "~9.3.3" } }, "node_modules/@deck.gl/layers": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@deck.gl/layers/-/layers-9.3.0.tgz", - "integrity": "sha512-71F2zAB3zerL/q6if+RtzJGHj39wpakDR/ud56fmuAVPEAHsVrYlsjMthdLsvIPZKE1SPUhY0163/a61PYlhew==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/@deck.gl/layers/-/layers-9.3.4.tgz", + "integrity": "sha512-9DnFuWiul3rwE9uuum/AdGt7M/z0gybp6rL0ewlaLFojuaonCkxSQZo/gtEBsJwpw3RrNuhGdBej5axKNvkTgw==", "license": "MIT", "dependencies": { "@loaders.gl/images": "^4.4.1", "@loaders.gl/schema": "^4.4.1", - "@luma.gl/shadertools": "^9.3.2", + "@luma.gl/shadertools": "^9.3.3", "@mapbox/tiny-sdf": "^2.0.5", "@math.gl/core": "^4.1.0", "@math.gl/polygon": "^4.1.0", @@ -622,21 +640,21 @@ "peerDependencies": { "@deck.gl/core": "~9.3.0", "@loaders.gl/core": "^4.4.1", - "@luma.gl/core": "~9.3.2", - "@luma.gl/engine": "~9.3.2" + "@luma.gl/core": "~9.3.3", + "@luma.gl/engine": "~9.3.3" } }, "node_modules/@deck.gl/mapbox": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@deck.gl/mapbox/-/mapbox-9.3.0.tgz", - "integrity": "sha512-Kzf2mrxsr014UY3ozwt7HJziLe4kxeGaS051h53XnzOzbIAPpuXhh0w8MuMVUdVYOdvOCAqU/eHwZU+wVS9AYQ==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/@deck.gl/mapbox/-/mapbox-9.3.4.tgz", + "integrity": "sha512-chAEyVc8qD5I/tvy+VO2b/W01LP19LJTQLamR0gVCMkCm58hnKh83nQtj/XGqrHk61LOpnN/ASfksXa7XNc0hA==", "license": "MIT", "dependencies": { "@math.gl/web-mercator": "^4.1.0" }, "peerDependencies": { "@deck.gl/core": "~9.3.0", - "@luma.gl/core": "~9.3.2", + "@luma.gl/core": "~9.3.3", "@math.gl/web-mercator": "^4.1.0" } }, @@ -1623,15 +1641,15 @@ } }, "node_modules/@luma.gl/constants": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/@luma.gl/constants/-/constants-9.3.2.tgz", - "integrity": "sha512-NvO1xqIbuXS9BVQ+huxDvxb8HxC3AQAQz7GxldsCLL5LoicsUHEoM5amvLFVG1tXuXJuA0irSOAQBz/aYWhvPg==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/@luma.gl/constants/-/constants-9.3.4.tgz", + "integrity": "sha512-1H3TX4uBrotndfiZcgUImxxT4xGK6p2kyoaAay4brPdaMt6LHNUjoEJ7NwRPIWya3pJCygfkN1j6IDaSBWkLeQ==", "license": "MIT" }, "node_modules/@luma.gl/core": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/@luma.gl/core/-/core-9.3.2.tgz", - "integrity": "sha512-MIsOXnzoGGlbACTC9PVFxsEba6zJEj7Y5tghK/ivpIEqyzLF5bL/DlrVxG3SzJOeBqBMBgF6n5sXK7gIJ3lXvw==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/@luma.gl/core/-/core-9.3.4.tgz", + "integrity": "sha512-NJ6u+HXs1aXf9JrjnN6/RMwt43iyDCqvlbZPKcgdyKWZwNFQ9HWoEHSfUFrhb3ZaEyyNd0HYVKrdfq8xsE3fdQ==", "license": "MIT", "dependencies": { "@math.gl/types": "^4.1.0", @@ -1642,9 +1660,9 @@ } }, "node_modules/@luma.gl/engine": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/@luma.gl/engine/-/engine-9.3.2.tgz", - "integrity": "sha512-Qo7JcmXgDFq/8hu1uR4sC1qnUVXW3jx//Mki4T3jCPig1BtcfrLSsmNDu2/u295ls/Mym2a9fvTnXRFejJMKig==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/@luma.gl/engine/-/engine-9.3.4.tgz", + "integrity": "sha512-DT93o+2q12QtaJmVUdQaAZc7VwJ3PJxYXiVV6UHDtSlkN+l2K46t8393PzPfdVYUjYcrJI7+WOnmvwGh+SbrNw==", "license": "MIT", "dependencies": { "@math.gl/core": "^4.1.0", @@ -1658,9 +1676,9 @@ } }, "node_modules/@luma.gl/shadertools": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/@luma.gl/shadertools/-/shadertools-9.3.2.tgz", - "integrity": "sha512-gVydhOflR3w7H+F775ubNNWWO9C7BOg3sCGf+R9MdiT4S7iitkzmI3xYkb/ngDjJmzqCx72oBj4RgQV/hV7A8A==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/@luma.gl/shadertools/-/shadertools-9.3.4.tgz", + "integrity": "sha512-6JszXZ1uBpwkfvgqe9l64fuxjduJSNndzDb9IitqTNLapF5ioM3ISDpWF4qRluCaLd9lvNgGPgpc48xrO27KZw==", "license": "MIT", "dependencies": { "@math.gl/core": "^4.1.0", @@ -1689,9 +1707,9 @@ } }, "node_modules/@luma.gl/webgl": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/@luma.gl/webgl/-/webgl-9.3.2.tgz", - "integrity": "sha512-vYHbTR5UC8O3yMPkOw8peRwmwwX0DMp9CHNLYckfxoSIOQA35eNUQG5hyZWZzma5fmJpfDMTwuJkoA99hhEkew==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/@luma.gl/webgl/-/webgl-9.3.4.tgz", + "integrity": "sha512-qZoNyQO1UpQBxUftgvg5hSPSoAs3e0l27a3mZjb1W8LnFH5upplT7ok4pMmt1C+bIILCvho700/8F8jUgmeaiw==", "license": "MIT", "dependencies": { "@math.gl/types": "^4.1.0", @@ -2277,6 +2295,8 @@ }, "node_modules/@polka/url": { "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", "dev": true, "license": "MIT" }, @@ -2916,6 +2936,8 @@ }, "node_modules/@standard-schema/spec": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", "dev": true, "license": "MIT" }, @@ -3292,6 +3314,8 @@ }, "node_modules/@types/chai": { "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", "dev": true, "license": "MIT", "dependencies": { @@ -3313,6 +3337,8 @@ }, "node_modules/@types/deep-eql": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", "dev": true, "license": "MIT" }, @@ -3750,15 +3776,15 @@ } }, "node_modules/@vitest/browser": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-4.1.8.tgz", - "integrity": "sha512-u21VzX07HzlJYpFgkxmjEXar/tG2UqWGgyGG/46SrrPc7rSdCTPw5vuowopO9CIqF8UCUQzDFdbVnNpw6N0BfQ==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-4.1.9.tgz", + "integrity": "sha512-j1BKtWmPcqpMhmx/L9EPLgAJpCb0zKfwoWLmqBbxaogCXHjOwHFSEoHCBfnGtx93xKQwilZ26m+UOsHqHMkRNg==", "dev": true, "license": "MIT", "dependencies": { "@blazediff/core": "1.9.1", - "@vitest/mocker": "4.1.8", - "@vitest/utils": "4.1.8", + "@vitest/mocker": "4.1.9", + "@vitest/utils": "4.1.9", "magic-string": "^0.30.21", "pngjs": "^7.0.0", "sirv": "^3.0.2", @@ -3769,18 +3795,18 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "vitest": "4.1.8" + "vitest": "4.1.9" } }, "node_modules/@vitest/browser-playwright": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/browser-playwright/-/browser-playwright-4.1.8.tgz", - "integrity": "sha512-SR7FqgegaexEg73xvf3ArtygXegagMdXnL0EZMpxrWvvhQxvicD/E8p0ib0J91riPRtQUViyh67Xjw3NqvyhVg==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/browser-playwright/-/browser-playwright-4.1.9.tgz", + "integrity": "sha512-Bq1rOGf9waevzG3EOkO/dene6bvKTUsZMVg8S1i+WH3JcMjuXEjiahP9rAqZRELUqjBySOJsvvSWqK/B3wjKQw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/browser": "4.1.8", - "@vitest/mocker": "4.1.8", + "@vitest/browser": "4.1.9", + "@vitest/mocker": "4.1.9", "tinyrainbow": "^3.1.0" }, "funding": { @@ -3788,7 +3814,7 @@ }, "peerDependencies": { "playwright": "*", - "vitest": "4.1.8" + "vitest": "4.1.9" }, "peerDependenciesMeta": { "playwright": { @@ -3797,14 +3823,14 @@ } }, "node_modules/@vitest/coverage-v8": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.8.tgz", - "integrity": "sha512-lt3kovsyHwYe00wq4D1ti0Z974fWj4NLp6siqiyEufUpyFwK9Yhi7rBhac9JL5aA0zoMrJqc4vYPZRUnI7l7nw==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.9.tgz", + "integrity": "sha512-G9/lgqibheLVBDRuya45EbsEXTYcWoSG+TLg7i2axuzx0Eq62eXn+aWXyaVdV5vKvFSWd6ywcX8hA7la9Pvu8g==", "dev": true, "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^1.0.2", - "@vitest/utils": "4.1.8", + "@vitest/utils": "4.1.9", "ast-v8-to-istanbul": "^1.0.0", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", @@ -3818,8 +3844,8 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser": "4.1.8", - "vitest": "4.1.8" + "@vitest/browser": "4.1.9", + "vitest": "4.1.9" }, "peerDependenciesMeta": { "@vitest/browser": { @@ -3827,14 +3853,6 @@ } } }, - "node_modules/@vitest/coverage-v8/node_modules/@bcoe/v8-coverage": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, "node_modules/@vitest/eslint-plugin": { "version": "1.6.15", "dev": true, @@ -3865,16 +3883,16 @@ } }, "node_modules/@vitest/expect": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.8.tgz", - "integrity": "sha512-h3nDO677RDLEGlBxyQ5CW8RlMThSKSRLUePLOx09gNIWRL40edgA1GCZSZgf1W55MFAG6/Sw14KeaAnqv0NKdQ==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.9.tgz", + "integrity": "sha512-vl/rYsUKcBr3SnQn166+XR5ZQcgMx3DQhFWdfli/cWpLnLUmbxZvyrJZotLFUryib+LtArYMSTJ5RbQ57ZqrlA==", "dev": true, "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.8", - "@vitest/utils": "4.1.8", + "@vitest/spy": "4.1.9", + "@vitest/utils": "4.1.9", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" }, @@ -3883,13 +3901,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.8.tgz", - "integrity": "sha512-LEiN/xe4OSIbKe9HQIp5OC24agGD9J5CnmMgsLohVVoOPWL9a2sBoR6VBx43jQZb7Kr1l4RCuyCJzcAa0+dojw==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.9.tgz", + "integrity": "sha512-EVkXzBjrPGM+cK8/ANWgBrkUCfJfb38/EfTSO8h7pWvKkyPkpWxvR7BkD2MyItMF62C97zAEoqdpUixwR/e+Rw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "4.1.8", + "@vitest/spy": "4.1.9", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, @@ -3911,6 +3929,8 @@ }, "node_modules/@vitest/mocker/node_modules/estree-walker": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, "license": "MIT", "dependencies": { @@ -3918,9 +3938,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.8.tgz", - "integrity": "sha512-9GasEBxpZ1VYIpqHf/0+YGg121uSNwCKOJqIrTwWP/TB7DmFCiaBpNl3aPZzoLWfWkuqhbH8vJIVobZkvdo2cA==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.9.tgz", + "integrity": "sha512-s0iufns3iIFitdgm+YR7g1whCAaGtXz459VS9/PqyKDEEFgYIhsHOQmXgIgDuYCt7DeQmiZT0Qe2OA2p4ZPu5A==", "dev": true, "license": "MIT", "dependencies": { @@ -3931,13 +3951,13 @@ } }, "node_modules/@vitest/runner": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.8.tgz", - "integrity": "sha512-EmVxeBAfMJvycdjd6Hm+RbFBbA9fKvo0Kx37hNpBYoYeavH3RNsBXWDooR1mgD52dCrxIIuP7UotpfiwOikvcg==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.9.tgz", + "integrity": "sha512-KXLMDtc7oe70+3mJfGrPUWPesswH+3sTxAMAMl8DG7I8IUQT4XW718dY5ID3vPUcmlu27CcKfY4P3h3I29SLJg==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "4.1.8", + "@vitest/utils": "4.1.9", "pathe": "^2.0.3" }, "funding": { @@ -3945,14 +3965,14 @@ } }, "node_modules/@vitest/snapshot": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.8.tgz", - "integrity": "sha512-acfZboRmAIf05DEKcBQy33VXojFJjtUdLyo7oOmV9kebb2xdU01UknNiPuPZoJZQyO7DF0gZdTGTpeAzET9QPQ==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.9.tgz", + "integrity": "sha512-Jc7RKGNBo8Z28WYIm0Niej4xdSPByRf6mU58VpHQkd6Zh05rlnA+twjbK5HyeIGHxrzsc3mJgS43uM0CZKzaIA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.8", - "@vitest/utils": "4.1.8", + "@vitest/pretty-format": "4.1.9", + "@vitest/utils": "4.1.9", "magic-string": "^0.30.21", "pathe": "^2.0.3" }, @@ -3961,9 +3981,9 @@ } }, "node_modules/@vitest/spy": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.8.tgz", - "integrity": "sha512-6EevtBp6OZOPF7bmz36HrGMeP3txgVSrgebWxHOafDXGkhIzfXK14f8KF6MuFfgXXUeHxmpD3BQxkV00/3s5mA==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.9.tgz", + "integrity": "sha512-fHpsS6mIi+PiEW+vcRVOMkX1oSaPKne3VOclSFICPcGOmfKgXPU5iAah+wcNcj2xPrCCmfq99IDGf+EojhhvhA==", "dev": true, "license": "MIT", "funding": { @@ -3971,13 +3991,13 @@ } }, "node_modules/@vitest/ui": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-4.1.8.tgz", - "integrity": "sha512-RUS2ZU2TsduVrI+9c12uTNaKrNUTsm6yFt3fueEUB9iKvyC2UP83F+sqIz00HQIah4UOL1TMoDAki8K0NjGvsA==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-4.1.9.tgz", + "integrity": "sha512-U/cRvtqfEPj27FI1n9cyUvi4vXXdcLhjJiI+InYKdk8hP4VrS6RXOjGL7rfFaeBc37iRKANsR6eEzIoC7lmgBQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "4.1.8", + "@vitest/utils": "4.1.9", "fflate": "^0.8.2", "flatted": "^3.4.2", "pathe": "^2.0.3", @@ -3989,17 +4009,17 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "vitest": "4.1.8" + "vitest": "4.1.9" } }, "node_modules/@vitest/utils": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.8.tgz", - "integrity": "sha512-uOJamYALNhfJ6iolExyQM40yIQwDqYnkKtQ5VCiSe17E33H0aQ/u+1GlRuz4LZBk6Mm3sg90G9hEbmEt37C1Zg==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.9.tgz", + "integrity": "sha512-A51o8ymO5PpqlWNnBP9ZHPXDIpuMtTLlGSjN7la4US+LJzoUMyhwjA5QXlm39JexgwHKW4Xjs8Z2d3dLCXOeuA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.8", + "@vitest/pretty-format": "4.1.9", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" }, @@ -4458,6 +4478,8 @@ }, "node_modules/assertion-error": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, "license": "MIT", "engines": { @@ -4472,9 +4494,9 @@ } }, "node_modules/ast-v8-to-istanbul": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.3.tgz", - "integrity": "sha512-jCMQ6ZylLPudp0CDfBmQBZUsrh1/8psbmu9ibeVWKuHWD0YrH9YABwlKu5kVEFoT0GCQQW9Z/SxfuEbbkGQCRg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.4.tgz", + "integrity": "sha512-0bC0/4bTSrnwdhU3IsZDwEdojvuPrSg59OYZfKsLRtJZ0u8VBx9DebfqqG8bRdCC0I7vjgxmPi41P0lpkhJHtA==", "dev": true, "license": "MIT", "dependencies": { @@ -4677,6 +4699,8 @@ }, "node_modules/chai": { "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", "dev": true, "license": "MIT", "engines": { @@ -6455,6 +6479,8 @@ }, "node_modules/html-escaper": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true, "license": "MIT" }, @@ -6964,6 +6990,8 @@ }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -6972,6 +7000,8 @@ }, "node_modules/istanbul-lib-report": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -6985,6 +7015,8 @@ }, "node_modules/istanbul-reports": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -7380,17 +7412,21 @@ } }, "node_modules/magicast": { - "version": "0.5.2", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.3.tgz", + "integrity": "sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.29.0", + "@babel/parser": "^7.29.3", "@babel/types": "^7.29.0", "source-map-js": "^1.2.1" } }, "node_modules/make-dir": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "license": "MIT", "dependencies": { @@ -7683,6 +7719,8 @@ }, "node_modules/mrmime": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", "dev": true, "license": "MIT", "engines": { @@ -7905,13 +7943,18 @@ } }, "node_modules/obug": { - "version": "2.1.1", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.3.tgz", + "integrity": "sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==", "dev": true, "funding": [ "https://github.com/sponsors/sxzz", "https://opencollective.com/debug" ], - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } }, "node_modules/once": { "version": "1.4.0", @@ -8895,6 +8938,8 @@ }, "node_modules/sirv": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", + "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", "dev": true, "license": "MIT", "dependencies": { @@ -9441,6 +9486,8 @@ }, "node_modules/totalist": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true, "license": "MIT", "engines": { @@ -10059,19 +10106,19 @@ } }, "node_modules/vitest": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.8.tgz", - "integrity": "sha512-flY6ScbCIt9HThs+C5HS7jvGOB560DJtk/Z15IQROTA6zEy49Nh8T/dofWTQL+n3vswqn87sbJNiuqw1SDp5Ig==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.9.tgz", + "integrity": "sha512-nE3/LEyc0z87uHYLZebqCUOaJr2hdtuPp7BQ4BosVFnfltxgAvMG08NyrSGlPpOUWvR27c5flSmYFTNr78L9GQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/expect": "4.1.8", - "@vitest/mocker": "4.1.8", - "@vitest/pretty-format": "4.1.8", - "@vitest/runner": "4.1.8", - "@vitest/snapshot": "4.1.8", - "@vitest/spy": "4.1.8", - "@vitest/utils": "4.1.8", + "@vitest/expect": "4.1.9", + "@vitest/mocker": "4.1.9", + "@vitest/pretty-format": "4.1.9", + "@vitest/runner": "4.1.9", + "@vitest/snapshot": "4.1.9", + "@vitest/spy": "4.1.9", + "@vitest/utils": "4.1.9", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", @@ -10099,12 +10146,12 @@ "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.1.8", - "@vitest/browser-preview": "4.1.8", - "@vitest/browser-webdriverio": "4.1.8", - "@vitest/coverage-istanbul": "4.1.8", - "@vitest/coverage-v8": "4.1.8", - "@vitest/ui": "4.1.8", + "@vitest/browser-playwright": "4.1.9", + "@vitest/browser-preview": "4.1.9", + "@vitest/browser-webdriverio": "4.1.9", + "@vitest/coverage-istanbul": "4.1.9", + "@vitest/coverage-v8": "4.1.9", + "@vitest/ui": "4.1.9", "happy-dom": "*", "jsdom": "*", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" diff --git a/package.json b/package.json index 231599d5..17298ae9 100644 --- a/package.json +++ b/package.json @@ -59,13 +59,13 @@ } }, "dependencies": { - "@deck.gl/core": "~9.3.0", - "@deck.gl/extensions": "~9.3.0", - "@deck.gl/layers": "~9.3.0", - "@deck.gl/mapbox": "~9.3.0", - "@luma.gl/constants": "~9.3.0", - "@luma.gl/core": "~9.3.0", - "@luma.gl/engine": "~9.3.0", + "@deck.gl/core": "~9.3.4", + "@deck.gl/extensions": "~9.3.4", + "@deck.gl/layers": "~9.3.4", + "@deck.gl/mapbox": "~9.3.4", + "@luma.gl/constants": "~9.3.4", + "@luma.gl/core": "~9.3.4", + "@luma.gl/engine": "~9.3.4", "@mapbox/mapbox-gl-draw": "<1.5.0", "@powsybl/network-map-layers": "^3.6.0-dev.0", "@powsybl/network-viewer-core": "^3.6.0-dev.0", @@ -94,10 +94,10 @@ "@types/react": "^19.2.2", "@types/react-dom": "^19.2.1", "@vitejs/plugin-react": "^5.0.4", - "@vitest/browser-playwright": "^4.0.18", - "@vitest/coverage-v8": "^4.0.18", + "@vitest/browser-playwright": "^4.1.9", + "@vitest/coverage-v8": "^4.1.9", "@vitest/eslint-plugin": "^1.6.7", - "@vitest/ui": "^4.0.18", + "@vitest/ui": "^4.1.9", "eslint": "^9.26.0", "eslint-config-prettier": "^10.1.2", "eslint-plugin-prettier": "^5.2.6", @@ -120,7 +120,7 @@ "vite-plugin-checker": "^0.12.0", "vite-plugin-dts": "^4.5.4", "vite-plugin-svgr": "^4.3.0", - "vitest": "^4.0.18" + "vitest": "^4.1.9" }, "packageManager": "npm@11.11.0+sha512.f36811c4aae1fde639527368ae44c571d050006a608d67a191f195a801a52637a312d259186254aa3a3799b05335b7390539cf28656d18f0591a1125ba35f973" } \ No newline at end of file From 3a4a14cca692bdf17e9b54165fbb0a4b7f68c3d9 Mon Sep 17 00:00:00 2001 From: Arnaud Marant Date: Tue, 30 Jun 2026 10:19:25 +0200 Subject: [PATCH 07/12] Fix CI configuration: standardize branch name quotes and remove Playwright browser installation step Signed-off-by: Arnaud Marant --- .github/workflows/build.yml | 17 +++++++++++++---- .github/workflows/fork-build-tests.yml | 6 +++--- package-lock.json | 13 ++++++++----- package.json | 1 + 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5b8f895f..a7298510 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,7 +2,7 @@ name: CI on: push: branches: - - 'main' + - "main" pull_request: permissions: {} @@ -29,6 +29,9 @@ jobs: build: runs-on: ubuntu-latest if: github.event.pull_request.head.repo.fork == false + container: + image: mcr.microsoft.com/playwright:v1.61.0-noble + options: --user 1001 steps: - name: Checkout sources uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 @@ -42,9 +45,6 @@ jobs: - name: Install dependencies run: npm ci - - name: Install Playwright Browsers - run: npx playwright install --with-deps chromium - - name: Lint run: npm run lint @@ -67,6 +67,15 @@ jobs: - name: Build run: npm run build:all + sonar: + name: SonarCloud Scan + runs-on: ubuntu-latest + if: github.event.pull_request.head.repo.fork == false + steps: + - name: Checkout sources + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - name: SonarCloud Scan uses: SonarSource/sonarqube-scan-action@1a6d90ebcb0e6a6b1d87e37ba693fe453195ae25 #v5.3.1 env: diff --git a/.github/workflows/fork-build-tests.yml b/.github/workflows/fork-build-tests.yml index f7d492ff..3f64ec9d 100644 --- a/.github/workflows/fork-build-tests.yml +++ b/.github/workflows/fork-build-tests.yml @@ -9,6 +9,9 @@ jobs: build: runs-on: ubuntu-latest if: github.event.pull_request.head.repo.fork == true + container: + image: mcr.microsoft.com/playwright:v1.61.0-noble + options: --user 1001 steps: - name: Checkout sources uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 @@ -22,9 +25,6 @@ jobs: - name: Install dependencies run: npm ci - - name: Install Playwright Browsers - run: npx playwright install --with-deps chromium - - name: Lint run: npm run lint diff --git a/package-lock.json b/package-lock.json index cea113dd..6cb83c34 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54,6 +54,7 @@ "jsdom": "^26.0.0", "license-checker": "^25.0.1", "minimatch": "^10.0.1", + "playwright": "^1.61.0", "prettier": "^3.5.3", "prettier-plugin-properties": "^0.3.0", "rimraf": "^6.0.1", @@ -8206,12 +8207,13 @@ } }, "node_modules/playwright": { - "version": "1.59.1", + "version": "1.61.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.61.0.tgz", + "integrity": "sha512-Z+7BeeqQPRRzklHsVFP4KTGIyMxKUmfeRA4WisM6G3/XW6nwGeX6fX9qYaDa+CiUqpOkb2f6X3nar05R3kSuJQ==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { - "playwright-core": "1.59.1" + "playwright-core": "1.61.0" }, "bin": { "playwright": "cli.js" @@ -8224,10 +8226,11 @@ } }, "node_modules/playwright-core": { - "version": "1.59.1", + "version": "1.61.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.61.0.tgz", + "integrity": "sha512-caX7TrY3Ml6egyDX0WUcTHDxodl/b51y5wJOdCEA36QviK/s2g081hvmGs8eaE3DWb6NYZQ6BjO/QkNRPenoPA==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "playwright-core": "cli.js" }, diff --git a/package.json b/package.json index 17298ae9..21f4b501 100644 --- a/package.json +++ b/package.json @@ -109,6 +109,7 @@ "jsdom": "^26.0.0", "license-checker": "^25.0.1", "minimatch": "^10.0.1", + "playwright": "^1.61.0", "prettier": "^3.5.3", "prettier-plugin-properties": "^0.3.0", "rimraf": "^6.0.1", From 15211e8003a9eeb8792fec64f07430a1fb35630d Mon Sep 17 00:00:00 2001 From: Arnaud Marant Date: Mon, 6 Jul 2026 12:58:20 +0200 Subject: [PATCH 08/12] Refactor test utility imports and update sonar exclusions for test utility files Signed-off-by: Arnaud Marant --- .github/workflows/build.yml | 2 +- demo/src/App.tsx | 4 +++- demo/tsconfig.json | 1 + .../src/network/layers/arrow-layer.browser.test.ts | 11 ++++++++--- .../src/network/layers/arrow-layer.test.ts | 5 +++-- .../src/network/layers/arrow-layer.ts | 2 -- .../network/layers/fork-line-layer.browser.test.ts | 8 ++++++-- .../layers/parallel-path-layer.browser.test.ts | 8 ++++++-- .../layers/scatterplot-layer-ext.browser.test.ts | 8 ++++++-- .../src/network/line-layer.browser.test.ts | 4 ++-- .../network-map-layers/src/network/line-layer.test.ts | 2 +- ...browser-render.ts => browser-render.test.utils.ts} | 0 ...ork-fixtures.ts => network-fixtures.test.utils.ts} | 0 sonar-project.properties | 2 +- 14 files changed, 38 insertions(+), 19 deletions(-) rename packages/network-map-layers/src/testUtils/{browser-render.ts => browser-render.test.utils.ts} (100%) rename packages/network-map-layers/src/testUtils/{network-fixtures.ts => network-fixtures.test.utils.ts} (100%) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a7298510..a0673b9a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,7 +2,7 @@ name: CI on: push: branches: - - "main" + - 'main' pull_request: permissions: {} diff --git a/demo/src/App.tsx b/demo/src/App.tsx index 02f8a8aa..d54c2cc7 100644 --- a/demo/src/App.tsx +++ b/demo/src/App.tsx @@ -15,7 +15,7 @@ import { type MapEquipment, NetworkMap, type NetworkMapRef } from '../../src'; import { createLargeGeoData, createLargeNetwork, -} from '../../packages/network-map-layers/src/testUtils/network-fixtures'; +} from '../../packages/network-map-layers/src/testUtils/network-fixtures.test.utils'; const largeNetwork = createLargeNetwork(); const largeGeoData = createLargeGeoData(); @@ -53,6 +53,7 @@ export default function App() { }, []); const networkMapRef = useRef(null); + const filteredNominalVoltages = [400.0, 380.0, 225.0, 150.0, 110.0, 90.0, 45.0]; return (
@@ -98,6 +99,7 @@ export default function App() { }} mapLibrary={'cartonolabel'} mapTheme={'light'} + filteredNominalVoltages={filteredNominalVoltages} onDrawPolygonModeActive={(active) => { console.log('polygon drawing mode active: ', active ? 'active' : 'inactive'); }} diff --git a/demo/tsconfig.json b/demo/tsconfig.json index 5fe141a2..1aeee918 100644 --- a/demo/tsconfig.json +++ b/demo/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "../tsconfig.base.json", "compilerOptions": { + "rootDir": "..", "outDir": "./dist", "jsx": "react-jsx", "paths": { diff --git a/packages/network-map-layers/src/network/layers/arrow-layer.browser.test.ts b/packages/network-map-layers/src/network/layers/arrow-layer.browser.test.ts index 3b2cbf4f..c9f408b2 100644 --- a/packages/network-map-layers/src/network/layers/arrow-layer.browser.test.ts +++ b/packages/network-map-layers/src/network/layers/arrow-layer.browser.test.ts @@ -7,10 +7,15 @@ import { afterEach, test } from 'vitest'; import { type MapAnyLineWithType } from '../../equipment-types'; -import { expectElement, SCREENSHOT_OPTIONS, setupBrowserLayerRenderer } from '../../testUtils/browser-render'; -import { createLargeMapLinesWithType, createMapLineWithType } from '../../testUtils/network-fixtures'; +import { + expectElement, + SCREENSHOT_OPTIONS, + setupBrowserLayerRenderer, +} from '../../testUtils/browser-render.test.utils'; +import { createLargeMapLinesWithType, createMapLineWithType } from '../../testUtils/network-fixtures.test.utils'; import { LineStatus } from '../line-layer'; -import ArrowLayer, { ArrowDirection } from './arrow-layer'; +import ArrowLayer from './arrow-layer'; +import { ArrowDirection } from '../arrow-direction'; const { renderLayers, cleanup } = setupBrowserLayerRenderer(); diff --git a/packages/network-map-layers/src/network/layers/arrow-layer.test.ts b/packages/network-map-layers/src/network/layers/arrow-layer.test.ts index 94f6966b..4e87b0bb 100644 --- a/packages/network-map-layers/src/network/layers/arrow-layer.test.ts +++ b/packages/network-map-layers/src/network/layers/arrow-layer.test.ts @@ -8,8 +8,9 @@ import { testLayer } from '@deck.gl/test-utils/vitest'; import { expect, test } from 'vitest'; import { type MapAnyLineWithType } from '../../equipment-types'; -import { createMapLineWithType } from '../../testUtils/network-fixtures'; -import ArrowLayer, { type Arrow, ArrowDirection } from './arrow-layer'; +import { createMapLineWithType } from '../../testUtils/network-fixtures.test.utils'; +import ArrowLayer, { type Arrow } from './arrow-layer'; +import { ArrowDirection } from '../arrow-direction'; function createProps() { const line = createMapLineWithType({ diff --git a/packages/network-map-layers/src/network/layers/arrow-layer.ts b/packages/network-map-layers/src/network/layers/arrow-layer.ts index 2a973a77..daa7d8fd 100644 --- a/packages/network-map-layers/src/network/layers/arrow-layer.ts +++ b/packages/network-map-layers/src/network/layers/arrow-layer.ts @@ -28,8 +28,6 @@ import { ArrowDirection } from '../arrow-direction'; import fs from './arrow-layer-fragment.frag?raw'; import vs from './arrow-layer-vertex.vert?raw'; -export { ArrowDirection } from '../arrow-direction'; - const arrowUniformBlock = `\ uniform arrowUniforms { float sizeMinPixels; diff --git a/packages/network-map-layers/src/network/layers/fork-line-layer.browser.test.ts b/packages/network-map-layers/src/network/layers/fork-line-layer.browser.test.ts index bd0ee3b6..3a57f21e 100644 --- a/packages/network-map-layers/src/network/layers/fork-line-layer.browser.test.ts +++ b/packages/network-map-layers/src/network/layers/fork-line-layer.browser.test.ts @@ -6,8 +6,12 @@ */ import { afterEach, test } from 'vitest'; -import { expectElement, SCREENSHOT_OPTIONS, setupBrowserLayerRenderer } from '../../testUtils/browser-render'; -import { createLargeMapLinesWithType } from '../../testUtils/network-fixtures'; +import { + expectElement, + SCREENSHOT_OPTIONS, + setupBrowserLayerRenderer, +} from '../../testUtils/browser-render.test.utils'; +import { createLargeMapLinesWithType } from '../../testUtils/network-fixtures.test.utils'; import ForkLineLayer from './fork-line-layer'; const { renderLayers, cleanup } = setupBrowserLayerRenderer(); diff --git a/packages/network-map-layers/src/network/layers/parallel-path-layer.browser.test.ts b/packages/network-map-layers/src/network/layers/parallel-path-layer.browser.test.ts index 28057640..5fa067b4 100644 --- a/packages/network-map-layers/src/network/layers/parallel-path-layer.browser.test.ts +++ b/packages/network-map-layers/src/network/layers/parallel-path-layer.browser.test.ts @@ -7,8 +7,12 @@ import { afterEach, test } from 'vitest'; import { type MapAnyLineWithType } from '../../equipment-types'; -import { expectElement, SCREENSHOT_OPTIONS, setupBrowserLayerRenderer } from '../../testUtils/browser-render'; -import { createLargeMapLinesWithType, createMapLineWithType } from '../../testUtils/network-fixtures'; +import { + expectElement, + SCREENSHOT_OPTIONS, + setupBrowserLayerRenderer, +} from '../../testUtils/browser-render.test.utils'; +import { createLargeMapLinesWithType, createMapLineWithType } from '../../testUtils/network-fixtures.test.utils'; import ParallelPathLayer from './parallel-path-layer'; const { renderLayers, cleanup } = setupBrowserLayerRenderer(); diff --git a/packages/network-map-layers/src/network/layers/scatterplot-layer-ext.browser.test.ts b/packages/network-map-layers/src/network/layers/scatterplot-layer-ext.browser.test.ts index f5e12fc9..633352f2 100644 --- a/packages/network-map-layers/src/network/layers/scatterplot-layer-ext.browser.test.ts +++ b/packages/network-map-layers/src/network/layers/scatterplot-layer-ext.browser.test.ts @@ -6,8 +6,12 @@ */ import { afterEach, test } from 'vitest'; -import { expectElement, SCREENSHOT_OPTIONS, setupBrowserLayerRenderer } from '../../testUtils/browser-render'; -import { createLargeGeoData } from '../../testUtils/network-fixtures'; +import { + expectElement, + SCREENSHOT_OPTIONS, + setupBrowserLayerRenderer, +} from '../../testUtils/browser-render.test.utils'; +import { createLargeGeoData } from '../../testUtils/network-fixtures.test.utils'; import ScatterplotLayerExt from './scatterplot-layer-ext'; const { renderLayers, cleanup } = setupBrowserLayerRenderer(); diff --git a/packages/network-map-layers/src/network/line-layer.browser.test.ts b/packages/network-map-layers/src/network/line-layer.browser.test.ts index 9cbb120f..d0c88dab 100644 --- a/packages/network-map-layers/src/network/line-layer.browser.test.ts +++ b/packages/network-map-layers/src/network/line-layer.browser.test.ts @@ -6,7 +6,7 @@ */ import { afterEach, test } from 'vitest'; -import { expectElement, SCREENSHOT_OPTIONS, setupBrowserLayerRenderer } from '../testUtils/browser-render'; +import { expectElement, SCREENSHOT_OPTIONS, setupBrowserLayerRenderer } from '../testUtils/browser-render.test.utils'; import { createGeoData, createLargeGeoData, @@ -14,7 +14,7 @@ import { createLargeNetwork, createLineForLineLayer, createNetwork, -} from '../testUtils/network-fixtures'; +} from '../testUtils/network-fixtures.test.utils'; import { getNominalVoltageColor } from '../utils/colors'; import { LineLayer } from './line-layer'; diff --git a/packages/network-map-layers/src/network/line-layer.test.ts b/packages/network-map-layers/src/network/line-layer.test.ts index a0a6073b..91e00d83 100644 --- a/packages/network-map-layers/src/network/line-layer.test.ts +++ b/packages/network-map-layers/src/network/line-layer.test.ts @@ -7,7 +7,7 @@ import { testLayer } from '@deck.gl/test-utils/vitest'; import { expect, test } from 'vitest'; -import { createGeoData, createLineForLineLayer, createNetwork } from '../testUtils/network-fixtures'; +import { createGeoData, createLineForLineLayer, createNetwork } from '../testUtils/network-fixtures.test.utils'; import { LineFlowMode, LineLayer } from './line-layer'; test('LineLayer lifecycle renders expected sublayers and applies updates', () => { diff --git a/packages/network-map-layers/src/testUtils/browser-render.ts b/packages/network-map-layers/src/testUtils/browser-render.test.utils.ts similarity index 100% rename from packages/network-map-layers/src/testUtils/browser-render.ts rename to packages/network-map-layers/src/testUtils/browser-render.test.utils.ts diff --git a/packages/network-map-layers/src/testUtils/network-fixtures.ts b/packages/network-map-layers/src/testUtils/network-fixtures.test.utils.ts similarity index 100% rename from packages/network-map-layers/src/testUtils/network-fixtures.ts rename to packages/network-map-layers/src/testUtils/network-fixtures.test.utils.ts diff --git a/sonar-project.properties b/sonar-project.properties index 7b75d741..628babed 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -3,5 +3,5 @@ sonar.organization=powsybl-ci-github sonar.javascript.lcov.reportPaths=./coverage/lcov.info sonar.sources=src/,packages/network-map-layers/src/,packages/network-viewer-core/src/ sonar.tests=src/,packages/network-map-layers/src/,packages/network-viewer-core/src/ -sonar.exclusions=**/*.test.ts,**/node_modules/**,**/dist/**,packages/network-map-layers/src/testUtils/** +sonar.exclusions=**/*.test.ts,**/node_modules/**,**/dist/**,**/*.test.utils.ts sonar.test.inclusions=**/*.test.ts From bc349fa2f108f3ba479edc9f04e64f60547b5edc Mon Sep 17 00:00:00 2001 From: Arnaud Marant Date: Mon, 6 Jul 2026 16:33:23 +0200 Subject: [PATCH 09/12] Refactor vitest configuration: streamline test includes and excludes, and add missing configDefaults import Signed-off-by: Arnaud Marant --- vitest.config.ts | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/vitest.config.ts b/vitest.config.ts index 5aaa6792..3ba2d273 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -7,22 +7,25 @@ import react from '@vitejs/plugin-react'; import { playwright } from '@vitest/browser-playwright'; -import { coverageConfigDefaults, defineConfig } from 'vitest/config'; +import { configDefaults, coverageConfigDefaults, defineConfig } from 'vitest/config'; export default defineConfig({ plugins: [react()], test: { projects: [ { + extends: true, test: { name: 'unit-tests', - include: ['**/*.test.{ts,tsx}', '!**/*.browser.test.{ts,tsx}'], + include: ['**/*.test.{ts,tsx}'], + exclude: [...configDefaults.exclude, '**/*.browser.test.{ts,tsx}'], globals: true, environment: 'jsdom', setupFiles: ['./setupTests.ts'], }, }, { + extends: true, test: { name: 'browser-tests', include: ['**/*.browser.test.{ts,tsx}'], @@ -42,7 +45,15 @@ export default defineConfig({ provider: 'v8', reporter: ['text', 'lcov'], reportsDirectory: './coverage', - exclude: [...coverageConfigDefaults.exclude, '**/*.svg'], + include: ['src/**/*.{ts,tsx}', 'packages/*/src/**/*.{ts,tsx}'], + exclude: [ + ...coverageConfigDefaults.exclude, + '**/*.svg', + '**/*.test.{ts,tsx}', + '**/*.browser.test.{ts,tsx}', + '**/*.test.utils.ts', + '**/__screenshots__/**', + ], }, }, }); From 34069fe8cb6e20ceaa227d149715785c1cc8b17f Mon Sep 17 00:00:00 2001 From: Arnaud Marant Date: Fri, 10 Jul 2026 14:39:09 +0200 Subject: [PATCH 10/12] Remove unused JSON data files and sync deck.gl dependencies to version 9.3.0 Signed-off-by: Arnaud Marant --- demo/src/map-viewer/data/lmap.json | 26 -------------------- demo/src/map-viewer/data/lpos.json | 32 ------------------------ demo/src/map-viewer/data/smap.json | 39 ------------------------------ demo/src/map-viewer/data/spos.json | 16 ------------ package-lock.json | 14 +++++------ package.json | 14 +++++------ 6 files changed, 14 insertions(+), 127 deletions(-) delete mode 100644 demo/src/map-viewer/data/lmap.json delete mode 100644 demo/src/map-viewer/data/lpos.json delete mode 100644 demo/src/map-viewer/data/smap.json delete mode 100644 demo/src/map-viewer/data/spos.json diff --git a/demo/src/map-viewer/data/lmap.json b/demo/src/map-viewer/data/lmap.json deleted file mode 100644 index 2fd94a9e..00000000 --- a/demo/src/map-viewer/data/lmap.json +++ /dev/null @@ -1,26 +0,0 @@ -[ - { - "id": "L1", - "voltageLevelId1": "VL2_3", - "voltageLevelId2": "VL1_1", - "name": "Line1", - "terminal1Connected": true, - "terminal2Connected": true, - "p1": -115.0, - "p2": 115.0, - "i1": 290.0, - "i2": 310.0 - }, - { - "id": "L2", - "voltageLevelId1": "VL2_3", - "voltageLevelId2": "VL1_1", - "name": "Line2", - "terminal1Connected": true, - "terminal2Connected": true, - "p1": -55.0, - "p2": 55.0, - "i1": 140.0, - "i2": 155.0 - } -] diff --git a/demo/src/map-viewer/data/lpos.json b/demo/src/map-viewer/data/lpos.json deleted file mode 100644 index 6f0f7ed2..00000000 --- a/demo/src/map-viewer/data/lpos.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "id": "L1", - "coordinates": [ - { - "lat": 45.18608, - "lon": 9.15484 - }, - { - "lat": 45.249375, - "lon": 9.35453 - }, - { - "lat": 45.31267, - "lon": 9.49322 - } - ] - }, - { - "id": "L2", - "coordinates": [ - { - "lat": 45.18608, - "lon": 9.15484 - }, - { - "lat": 45.31267, - "lon": 9.49322 - } - ] - } -] diff --git a/demo/src/map-viewer/data/smap.json b/demo/src/map-viewer/data/smap.json deleted file mode 100644 index 6dba3543..00000000 --- a/demo/src/map-viewer/data/smap.json +++ /dev/null @@ -1,39 +0,0 @@ -[ - { - "id": "SUB1", - "name": "Substation1", - "voltageLevels": [ - { - "id": "VL1_1", - "substationId": "SUB1", - "nominalV": 225.0 - }, - { - "id": "VL1_2", - "substationId": "SUB1", - "nominalV": 110.0 - } - ] - }, - { - "id": "SUB2", - "name": "Substation2", - "voltageLevels": [ - { - "id": "VL2_1", - "substationId": "SUB2", - "nominalV": 110.0 - }, - { - "id": "VL2_2", - "substationId": "SUB2", - "nominalV": 380.0 - }, - { - "id": "VL2_3", - "substationId": "SUB2", - "nominalV": 225.0 - } - ] - } -] diff --git a/demo/src/map-viewer/data/spos.json b/demo/src/map-viewer/data/spos.json deleted file mode 100644 index 13a97c4d..00000000 --- a/demo/src/map-viewer/data/spos.json +++ /dev/null @@ -1,16 +0,0 @@ -[ - { - "id": "SUB1", - "coordinate": { - "lat": 45.31267, - "lon": 9.49322 - } - }, - { - "id": "SUB2", - "coordinate": { - "lat": 45.18608, - "lon": 9.15484 - } - } -] diff --git a/package-lock.json b/package-lock.json index 6cb83c34..3d39a150 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,13 +12,13 @@ "packages/*" ], "dependencies": { - "@deck.gl/core": "~9.3.4", - "@deck.gl/extensions": "~9.3.4", - "@deck.gl/layers": "~9.3.4", - "@deck.gl/mapbox": "~9.3.4", - "@luma.gl/constants": "~9.3.4", - "@luma.gl/core": "~9.3.4", - "@luma.gl/engine": "~9.3.4", + "@deck.gl/core": "~9.3.0", + "@deck.gl/extensions": "~9.3.0", + "@deck.gl/layers": "~9.3.0", + "@deck.gl/mapbox": "~9.3.0", + "@luma.gl/constants": "~9.3.0", + "@luma.gl/core": "~9.3.0", + "@luma.gl/engine": "~9.3.0", "@mapbox/mapbox-gl-draw": "<1.5.0", "@powsybl/network-map-layers": "^3.6.0-dev.0", "@powsybl/network-viewer-core": "^3.6.0-dev.0", diff --git a/package.json b/package.json index 21f4b501..0c4c8477 100644 --- a/package.json +++ b/package.json @@ -59,13 +59,13 @@ } }, "dependencies": { - "@deck.gl/core": "~9.3.4", - "@deck.gl/extensions": "~9.3.4", - "@deck.gl/layers": "~9.3.4", - "@deck.gl/mapbox": "~9.3.4", - "@luma.gl/constants": "~9.3.4", - "@luma.gl/core": "~9.3.4", - "@luma.gl/engine": "~9.3.4", + "@deck.gl/core": "~9.3.0", + "@deck.gl/extensions": "~9.3.0", + "@deck.gl/layers": "~9.3.0", + "@deck.gl/mapbox": "~9.3.0", + "@luma.gl/constants": "~9.3.0", + "@luma.gl/core": "~9.3.0", + "@luma.gl/engine": "~9.3.0", "@mapbox/mapbox-gl-draw": "<1.5.0", "@powsybl/network-map-layers": "^3.6.0-dev.0", "@powsybl/network-viewer-core": "^3.6.0-dev.0", From 2831727c19813b0a20b19036ceaf75cc96d8e5dd Mon Sep 17 00:00:00 2001 From: Arnaud Marant Date: Fri, 10 Jul 2026 15:33:00 +0200 Subject: [PATCH 11/12] Refactor tooltip and event handling: use optional chaining for safer access to properties Signed-off-by: Arnaud Marant --- .../network-map-viewer/network/network-map.tsx | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/components/network-map-viewer/network/network-map.tsx b/src/components/network-map-viewer/network/network-map.tsx index cdf9f9a6..c236984e 100644 --- a/src/components/network-map-viewer/network/network-map.tsx +++ b/src/components/network-map-viewer/network/network-map.tsx @@ -415,8 +415,7 @@ const NetworkMap = forwardRef((rawProps, ref) => function renderTooltip() { return ( - tooltip && - tooltip.visible && + tooltip?.visible && !shouldDisableToolTip && //As of now only LINE tooltip is implemented, the following condition is to be removed or tweaked once other types of line tooltip are implemented tooltip.equipmentType === EQUIPMENT_TYPES.LINE && ( @@ -456,8 +455,7 @@ const NetworkMap = forwardRef((rawProps, ref) => const leftButton = event.originalEvent.button === MOUSE_EVENT_BUTTON_LEFT; const rightButton = event.originalEvent.button === MOUSE_EVENT_BUTTON_RIGHT; if ( - info.layer && - info.layer.id.startsWith(SUBSTATION_LAYER_PREFIX) && + info?.layer?.id.startsWith(SUBSTATION_LAYER_PREFIX) && info.object && (info.object.substationId || info.object.voltageLevels) // is a voltage level marker, or a substation text ) { @@ -505,8 +503,7 @@ const NetworkMap = forwardRef((rawProps, ref) => } if ( rightButton && - info.layer && - info.layer.id.startsWith(LINE_LAYER_PREFIX) && + info?.layer?.id.startsWith(LINE_LAYER_PREFIX) && info.object?.id && info.object.voltageLevelId1 && info.object.voltageLevelId2 From 0eaaaebe4891073788da039df88f936e4493af4f Mon Sep 17 00:00:00 2001 From: Arnaud Marant Date: Fri, 10 Jul 2026 15:53:17 +0200 Subject: [PATCH 12/12] Refactor ESLint configuration: simplify projectService setting for parserOptions Signed-off-by: Arnaud Marant --- eslint.config.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index 4d989654..6303caa0 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -58,9 +58,7 @@ export default defineConfig([ extends: tsEslint.configs.recommendedTypeChecked, languageOptions: { parserOptions: { - projectService: { - allowDefaultProject: ['./setupBrowserTests.ts'], - }, + projectService: true, tsconfigRootDir: import.meta.dirname, }, },