diff --git a/.nvmrc b/.nvmrc index bdae6e9f4..3f430af82 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v18.18 +v18 diff --git a/adr/2021_03_16_url_param_structure.md b/adr/2021_03_16_url_param_structure.md index fcf88c2ce..703b9838f 100644 --- a/adr/2021_03_16_url_param_structure.md +++ b/adr/2021_03_16_url_param_structure.md @@ -4,7 +4,7 @@ > Date: 16.03.2021 -> Updated: 17.11.2023 +> Updated: 10.04.2024 ## Context @@ -95,17 +95,19 @@ The layer ID of the external Layers are in the following format (note that only - an external WMS: `WMS|GET_CAP_BASE_URL|LAYER_ID` - The WMS version is taken from the Get Capabilities +- an external group of WMS layer : `WMS|GET_CAP_BASE_URL|LAYER_ID` + - We don't differentiate between group of layers and regular WMS layer in the URL. This differentiation was neither done in the legacy viewer. - an external WMTS: `WMTS|GET_CAP_BASE_URL|LAYER_ID` - The WMTS version is taken from the Get Capabilities -- an external KML: `KML|URL|TITLE` - - TITLE is optional and used as display in the active layers, if omitted then it will be displayed as `KML` -- a geoadmin KML: `KML|URL|TITLE` - - TITLE is set to `Drawing` upon drawing creation and in the current language at that time -- a geoadmin KML with adminId: `KML|URL|TITLE@adminId=ADMIN_ID` -- an external GPX: `GPX|GPX|TITLE` - - TITLE is optional and used as display in the active layers, if omitted then it will be displayed as `GPX` -- an external KMZ: `KMZ|KMZ|TITLE` (needs to pass by proxy to be unzipped) - - TITLE is optional and used as display in the active layers, if omitted then it will be displayed as `KMZ` +- an external KML: `KML|URL` + - The title is read from the metadata +- a geoadmin KML: `KML|URL` + - The title is read from the metadata +- a geoadmin KML with adminId: `KML|URL@adminId=ADMIN_ID` + - The title is read from the metadata +- an external GPX: `GPX|URL` + - The title is read from the metadata +- an external KMZ: `KMZ|URL` (needs to pass by proxy to be unzipped) ## Consequences diff --git a/package-lock.json b/package-lock.json index fa5ddc6a5..04b9a6371 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,13 +6,13 @@ "": { "name": "web-mapviewer", "dependencies": { - "@fortawesome/fontawesome-svg-core": "^6.5.1", - "@fortawesome/free-brands-svg-icons": "^6.5.1", - "@fortawesome/free-regular-svg-icons": "^6.5.1", - "@fortawesome/free-solid-svg-icons": "^6.5.1", + "@fortawesome/fontawesome-svg-core": "^6.5.2", + "@fortawesome/free-brands-svg-icons": "^6.5.2", + "@fortawesome/free-regular-svg-icons": "^6.5.2", + "@fortawesome/free-solid-svg-icons": "^6.5.2", "@fortawesome/vue-fontawesome": "^3.0.6", "@geoblocks/cesium-compass": "^0.5.0", - "@geoblocks/mapfishprint": "github:geoblocks/mapfishprint#4c47539f391af3c641f9455efe0d31ebdc145cfe", + "@geoblocks/mapfishprint": "^0.2.11", "@geoblocks/ol-maplibre-layer": "^0.1.3", "@ivanv/vue-collapse-transition": "^1.0.2", "@mapbox/togeojson": "^0.16.2", @@ -29,31 +29,31 @@ "@turf/nearest-point": "^6.5.0", "@turf/point-to-line-distance": "^6.5.0", "animate.css": "^4.1.1", - "axios": "^1.6.7", + "axios": "^1.6.8", "bootstrap": "^5.3.3", - "cesium": "^1.115.0", + "cesium": "^1.116.0", "chart.js": "^4.4.2", "chartjs-plugin-zoom": "^2.0.1", - "dompurify": "^3.0.9", + "dompurify": "^3.0.11", "file-saver": "^2.0.5", "form-data": "^4.0.0", "geographiclib-geodesic": "^2.0.0", "hammerjs": "^2.0.8", "jquery": "^3.7.1", "liang-barsky": "^1.0.5", - "maplibre-gl": "^4.1.0", - "ol": "^9.0.0", + "maplibre-gl": "^4.1.2", + "ol": "^9.1.0", "pako": "^2.1.0", "print-js": "^1.6.0", - "proj4": "^2.10.0", + "proj4": "^2.11.0", "reproject": "^1.2.7", "sortablejs": "^1.15.2", "tippy.js": "^6.3.7", "vue": "^3.4.21", "vue-chartjs": "^5.3.0", - "vue-i18n": "^9.10.1", + "vue-i18n": "^9.11.0", "vue-router": "^4.3.0", - "vue-social-sharing": "next", + "vue-social-sharing": "^4.0.0-alpha4", "vuex": "^4.1.0" }, "devDependencies": { @@ -61,30 +61,30 @@ "@cypress/vite-dev-server": "^5.0.7", "@cypress/vue": "^6.0.0", "@nuintun/qrcode": "^3.4.0", - "@prettier/plugin-xml": "^3.3.1", - "@rushstack/eslint-patch": "^1.7.2", + "@prettier/plugin-xml": "^3.4.1", + "@rushstack/eslint-patch": "^1.10.1", "@types/jsdom": "^21.1.6", - "@types/node": "^18.19.21", + "@types/node": "^18.19.29", "@vitejs/plugin-vue": "^5.0.4", "@vue/eslint-config-prettier": "^9.0.0", "@vue/eslint-config-typescript": "^12.0.0", "@vue/tsconfig": "^0.5.1", - "axios-retry": "^4.0.0", + "axios-retry": "^4.1.0", "chai": "^5.1.0", - "cypress": "^13.6.6", + "cypress": "^13.7.2", "cypress-browser-permissions": "^1.1.0", "cypress-real-events": "^1.12.0", - "cypress-recurse": "^1.35.2", + "cypress-recurse": "^1.35.3", "cypress-vite": "^1.5.0", "cypress-wait-until": "^3.0.1", "dotenv": "^16.4.5", "eslint": "^8.57.0", "eslint-plugin-cypress": "^2.15.1", "eslint-plugin-markdownlint": "^0.5.0", - "eslint-plugin-mocha": "^10.3.0", + "eslint-plugin-mocha": "^10.4.1", "eslint-plugin-prettier-vue": "^5.0.0", "eslint-plugin-simple-import-sort": "^12.0.0", - "eslint-plugin-vue": "^9.22.0", + "eslint-plugin-vue": "^9.24.0", "git-describe": "^4.1.1", "googleapis": "^133.0.0", "jsdom": "^24.0.0", @@ -93,12 +93,12 @@ "prettier": "^3.2.5", "prettier-plugin-jsdoc": "^1.3.0", "rimraf": "^5.0.5", - "sass": "^1.71.1", + "sass": "^1.74.1", "start-server-and-test": "^2.0.3", - "typescript": "^5.3.3", - "vite": "^5.2.2", + "typescript": "^5.4.4", + "vite": "^5.2.8", "vite-node": "^1.4.0", - "vite-plugin-static-copy": "^1.0.1", + "vite-plugin-static-copy": "^1.0.2", "vitest": "^1.4.0", "vue-tsc": "^1.8.27", "write-yaml-file": "^5.0.0", @@ -106,7 +106,7 @@ }, "engines": { "node": ">=18", - "npm": "9.*.*" + "npm": "10.*.*" } }, "node_modules/@4tw/cypress-drag-drop": { @@ -128,9 +128,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz", - "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==", + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz", + "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==", "bin": { "parser": "bin/babel-parser.js" }, @@ -139,9 +139,9 @@ } }, "node_modules/@cesium/engine": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@cesium/engine/-/engine-8.0.0.tgz", - "integrity": "sha512-0HvvpoKPrb1Go6MnKsTk0Vn2HV4wv+UAlZGbzG3sD/QjEm4FOYj/sLFrwQqmCn6nFN1aRbhAH1xXJnA9bF+1Wg==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@cesium/engine/-/engine-9.0.0.tgz", + "integrity": "sha512-GIeBitHo1t6OwgWnxAsCoHuCcJEfdki2G0hbKfaP87r2EapbnDLBmfxZziscl1ksv7kQiQ6x2FOOSPuV9QFvhA==", "dependencies": { "@tweenjs/tween.js": "^23.1.1", "@zip.js/zip.js": "^2.7.34", @@ -153,7 +153,7 @@ "grapheme-splitter": "^1.0.4", "jsep": "^1.3.8", "kdbush": "^4.0.1", - "ktx-parse": "^0.6.0", + "ktx-parse": "^0.7.0", "lerc": "^2.0.0", "mersenne-twister": "^1.1.0", "meshoptimizer": "^0.20.0", @@ -168,11 +168,11 @@ } }, "node_modules/@cesium/widgets": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@cesium/widgets/-/widgets-5.0.0.tgz", - "integrity": "sha512-004x7F5F8CHFnhWkuRbOrgduOug8q36/fqegs4UMdzgxOG9zNXfJoZInD6jwytCZJHH7aVcZvIoTKAdsS8bNKQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@cesium/widgets/-/widgets-6.0.0.tgz", + "integrity": "sha512-zq0UqHji4PgPWTVdUB2hNb/FXe60eNDB11oW35/Z3REQfE4LBOkeR/RGck7hBOfYaubMiqwuwOw2lbl54OXzIA==", "dependencies": { - "@cesium/engine": "^8.0.0", + "@cesium/engine": "^9.0.0", "nosleep.js": "^0.12.0" }, "engines": { @@ -729,57 +729,57 @@ } }, "node_modules/@fortawesome/fontawesome-common-types": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.1.tgz", - "integrity": "sha512-GkWzv+L6d2bI5f/Vk6ikJ9xtl7dfXtoRu3YGE6nq0p/FFqA1ebMOAWg3XgRyb0I6LYyYkiAo+3/KrwuBp8xG7A==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.2.tgz", + "integrity": "sha512-gBxPg3aVO6J0kpfHNILc+NMhXnqHumFxOmjYCFfOiLZfwhnnfhtsdA2hfJlDnj+8PjAs6kKQPenOTKj3Rf7zHw==", "hasInstallScript": true, "engines": { "node": ">=6" } }, "node_modules/@fortawesome/fontawesome-svg-core": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.1.tgz", - "integrity": "sha512-MfRCYlQPXoLlpem+egxjfkEuP9UQswTrlCOsknus/NcMoblTH2g0jPrapbcIb04KGA7E2GZxbAccGZfWoYgsrQ==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.2.tgz", + "integrity": "sha512-5CdaCBGl8Rh9ohNdxeeTMxIj8oc3KNBgIeLMvJosBMdslK/UnEB8rzyDRrbKdL1kDweqBPo4GT9wvnakHWucZw==", "hasInstallScript": true, "dependencies": { - "@fortawesome/fontawesome-common-types": "6.5.1" + "@fortawesome/fontawesome-common-types": "6.5.2" }, "engines": { "node": ">=6" } }, "node_modules/@fortawesome/free-brands-svg-icons": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.5.1.tgz", - "integrity": "sha512-093l7DAkx0aEtBq66Sf19MgoZewv1zeY9/4C7vSKPO4qMwEsW/2VYTUTpBtLwfb9T2R73tXaRDPmE4UqLCYHfg==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.5.2.tgz", + "integrity": "sha512-zi5FNYdmKLnEc0jc0uuHH17kz/hfYTg4Uei0wMGzcoCL/4d3WM3u1VMc0iGGa31HuhV5i7ZK8ZlTCQrHqRHSGQ==", "hasInstallScript": true, "dependencies": { - "@fortawesome/fontawesome-common-types": "6.5.1" + "@fortawesome/fontawesome-common-types": "6.5.2" }, "engines": { "node": ">=6" } }, "node_modules/@fortawesome/free-regular-svg-icons": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.5.1.tgz", - "integrity": "sha512-m6ShXn+wvqEU69wSP84coxLbNl7sGVZb+Ca+XZq6k30SzuP3X4TfPqtycgUh9ASwlNh5OfQCd8pDIWxl+O+LlQ==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.5.2.tgz", + "integrity": "sha512-iabw/f5f8Uy2nTRtJ13XZTS1O5+t+anvlamJ3zJGLEVE2pKsAWhPv2lq01uQlfgCX7VaveT3EVs515cCN9jRbw==", "hasInstallScript": true, "dependencies": { - "@fortawesome/fontawesome-common-types": "6.5.1" + "@fortawesome/fontawesome-common-types": "6.5.2" }, "engines": { "node": ">=6" } }, "node_modules/@fortawesome/free-solid-svg-icons": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.1.tgz", - "integrity": "sha512-S1PPfU3mIJa59biTtXJz1oI0+KAXW6bkAb31XKhxdxtuXDiUIFsih4JR1v5BbxY7hVHsD1RKq+jRkVRaf773NQ==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.2.tgz", + "integrity": "sha512-QWFZYXFE7O1Gr1dTIp+D6UcFUF0qElOnZptpi7PBUMylJh+vFmIedVe1Ir6RM1t2tEQLLSV1k7bR4o92M+uqlw==", "hasInstallScript": true, "dependencies": { - "@fortawesome/fontawesome-common-types": "6.5.1" + "@fortawesome/fontawesome-common-types": "6.5.2" }, "engines": { "node": ">=6" @@ -806,10 +806,9 @@ } }, "node_modules/@geoblocks/mapfishprint": { - "version": "0.2.10", - "resolved": "git+ssh://git@github.com/geoblocks/mapfishprint.git#4c47539f391af3c641f9455efe0d31ebdc145cfe", - "integrity": "sha512-1T6jA/Uz07CtLO9vXq4EwnD1LhWUBuRz3FnzCv1hPKQa5VNLOD8Ye1GaNG+/YDuWgR/DY2U9RcZBMpZS7gwRIg==", - "license": "BSD-3-Clause", + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@geoblocks/mapfishprint/-/mapfishprint-0.2.11.tgz", + "integrity": "sha512-wcmoUHJ/O5iUYWHI6Rf665OaRpzE1j2pSxxveXmolhh6/2OiiLYZC8TSztIma/RW/u47fcvaq6cBR+2QZea55Q==", "optionalDependencies": { "@geoblocks/print": "0.7.8" }, @@ -900,18 +899,18 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "dev": true }, "node_modules/@intlify/core-base": { - "version": "9.10.1", - "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.10.1.tgz", - "integrity": "sha512-0+Wtjj04GIyglh5KKiNjRwgjpHrhqqGZhaKY/QVjjogWKZq5WHROrTi84pNVsRN18QynyPmjtsVUWqFKPQ45xQ==", + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.11.0.tgz", + "integrity": "sha512-cveOqAstjLZIiyatcP/HrzrQ87cZI8ScPQna3yvoM8zjcjcIRK1MRvmxUNlPdg0rTNJMZw7rixPVM58O5aHVPA==", "dependencies": { - "@intlify/message-compiler": "9.10.1", - "@intlify/shared": "9.10.1" + "@intlify/message-compiler": "9.11.0", + "@intlify/shared": "9.11.0" }, "engines": { "node": ">= 16" @@ -921,11 +920,11 @@ } }, "node_modules/@intlify/message-compiler": { - "version": "9.10.1", - "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.10.1.tgz", - "integrity": "sha512-b68UTmRhgZfswJZI7VAgW6BXZK5JOpoi5swMLGr4j6ss2XbFY13kiw+Hu+xYAfulMPSapcHzdWHnq21VGnMCnA==", + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.11.0.tgz", + "integrity": "sha512-x31Gl7cscnoI4UUY1yaIy8e7vVMVW1VVlTXZz4SIHKqoSEUkfmgqK8NAx1e7RcoHEbICR7uyCbud0ZL1s4OGXQ==", "dependencies": { - "@intlify/shared": "9.10.1", + "@intlify/shared": "9.11.0", "source-map-js": "^1.0.2" }, "engines": { @@ -936,9 +935,9 @@ } }, "node_modules/@intlify/shared": { - "version": "9.10.1", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.10.1.tgz", - "integrity": "sha512-liyH3UMoglHBUn70iCYcy9CQlInx/lp50W2aeSxqqrvmG+LDj/Jj7tBJhBoQL4fECkldGhbmW0g2ommHfL6Wmw==", + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.11.0.tgz", + "integrity": "sha512-KHSNgi7sRjmSm7aD8QH8WFt9VfKaekJuJ473opbJlkGY3EDnDUU8ikIhG8PbasQbgNvbY3m3tWNGqk2omIdwMA==", "engines": { "node": ">= 16" }, @@ -1070,9 +1069,9 @@ "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==" }, "node_modules/@lit-labs/ssr-dom-shim": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.1.2.tgz", - "integrity": "sha512-jnOD+/+dSrfTWYfSXBXlo5l5f0q1UuJo3tkbMDCYA2lKUYq79jaxqtGEvnRoh049nt1vdo1+45RinipU6FGY2g==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.0.tgz", + "integrity": "sha512-yWJKmpGE6lUURKAaIltoPIE/wrbY3TEkqQt+X0m+7fQNnAv0keydnYvbiJFP1PnMhizmIWRWOG5KLhYyc/xl+g==" }, "node_modules/@lit/reactive-element": { "version": "1.6.3", @@ -1220,9 +1219,9 @@ } }, "node_modules/@petamoriken/float16": { - "version": "3.8.4", - "resolved": "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.8.4.tgz", - "integrity": "sha512-kB+NJ5Br56ZhElKsf0pM7/PQfrDdDVMRz8f0JM6eVOGE+L89z9hwcst9QvWBBnazzuqGTGtPsJNZoQ1JdNiGSQ==" + "version": "3.8.6", + "resolved": "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.8.6.tgz", + "integrity": "sha512-GNJhABTtcmt9al/nqdJPycwFD46ww2+q2zwZzTjY0dFFwUAFRw9zszvEr9osyJRd9krRGy6hUDopWUg9fX7VVw==" }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", @@ -1235,9 +1234,9 @@ } }, "node_modules/@pkgr/core": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.0.tgz", - "integrity": "sha512-Zwq5OCzuwJC2jwqmpEQt7Ds1DTi6BWSwoGkbb1n9pO3hzb35BoJELx7c0T23iDkBGkh2e7tvOtjF3tr3OaQHDQ==", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", "dev": true, "engines": { "node": "^12.20.0 || ^14.18.0 || >=16.0.0" @@ -1256,9 +1255,9 @@ } }, "node_modules/@prettier/plugin-xml": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@prettier/plugin-xml/-/plugin-xml-3.3.1.tgz", - "integrity": "sha512-kllNJk6n2pXJjGWdj+HAr1GhOoOTrlmeWkDYCGBzkyZS2l0K6h2gsUQcVif2cNqAE1MNC+nUrzN6QwEsCukPnQ==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@prettier/plugin-xml/-/plugin-xml-3.4.1.tgz", + "integrity": "sha512-Uf/6/+9ez6z/IvZErgobZ2G9n1ybxF5BhCd7eMcKqfoWuOzzNUxBipNo3QAP8kRC1VD18TIo84no7LhqtyDcTg==", "dev": true, "dependencies": { "@xml-tools/parser": "^1.0.11" @@ -1322,9 +1321,9 @@ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.0.tgz", - "integrity": "sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.0.tgz", + "integrity": "sha512-jwXtxYbRt1V+CdQSy6Z+uZti7JF5irRKF8hlKfEnF/xJpcNGuuiZMBvuoYM+x9sr9iWGnzrlM0+9hvQ1kgkf1w==", "cpu": [ "arm" ], @@ -1335,9 +1334,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.0.tgz", - "integrity": "sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.0.tgz", + "integrity": "sha512-fI9nduZhCccjzlsA/OuAwtFGWocxA4gqXGTLvOyiF8d+8o0fZUeSztixkYjcGq1fGZY3Tkq4yRvHPFxU+jdZ9Q==", "cpu": [ "arm64" ], @@ -1348,9 +1347,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.0.tgz", - "integrity": "sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.0.tgz", + "integrity": "sha512-BcnSPRM76/cD2gQC+rQNGBN6GStBs2pl/FpweW8JYuz5J/IEa0Fr4AtrPv766DB/6b2MZ/AfSIOSGw3nEIP8SA==", "cpu": [ "arm64" ], @@ -1361,9 +1360,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.0.tgz", - "integrity": "sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.0.tgz", + "integrity": "sha512-LDyFB9GRolGN7XI6955aFeI3wCdCUszFWumWU0deHA8VpR3nWRrjG6GtGjBrQxQKFevnUTHKCfPR4IvrW3kCgQ==", "cpu": [ "x64" ], @@ -1374,9 +1373,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.0.tgz", - "integrity": "sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.0.tgz", + "integrity": "sha512-ygrGVhQP47mRh0AAD0zl6QqCbNsf0eTo+vgwkY6LunBcg0f2Jv365GXlDUECIyoXp1kKwL5WW6rsO429DBY/bA==", "cpu": [ "arm" ], @@ -1387,9 +1386,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.0.tgz", - "integrity": "sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.0.tgz", + "integrity": "sha512-x+uJ6MAYRlHGe9wi4HQjxpaKHPM3d3JjqqCkeC5gpnnI6OWovLdXTpfa8trjxPLnWKyBsSi5kne+146GAxFt4A==", "cpu": [ "arm64" ], @@ -1400,9 +1399,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.0.tgz", - "integrity": "sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.0.tgz", + "integrity": "sha512-nrRw8ZTQKg6+Lttwqo6a2VxR9tOroa2m91XbdQ2sUUzHoedXlsyvY1fN4xWdqz8PKmf4orDwejxXHjh7YBGUCA==", "cpu": [ "arm64" ], @@ -1412,10 +1411,23 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.0.tgz", + "integrity": "sha512-xV0d5jDb4aFu84XKr+lcUJ9y3qpIWhttO3Qev97z8DKLXR62LC3cXT/bMZXrjLF9X+P5oSmJTzAhqwUbY96PnA==", + "cpu": [ + "ppc64le" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.0.tgz", - "integrity": "sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.0.tgz", + "integrity": "sha512-SDDhBQwZX6LPRoPYjAZWyL27LbcBo7WdBFWJi5PI9RPCzU8ijzkQn7tt8NXiXRiFMJCVpkuMkBf4OxSxVMizAw==", "cpu": [ "riscv64" ], @@ -1425,10 +1437,23 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.0.tgz", + "integrity": "sha512-RxB/qez8zIDshNJDufYlTT0ZTVut5eCpAZ3bdXDU9yTxBzui3KhbGjROK2OYTTor7alM7XBhssgoO3CZ0XD3qA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.0.tgz", - "integrity": "sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.0.tgz", + "integrity": "sha512-C6y6z2eCNCfhZxT9u+jAM2Fup89ZjiG5pIzZIDycs1IwESviLxwkQcFRGLjnDrP+PT+v5i4YFvlcfAs+LnreXg==", "cpu": [ "x64" ], @@ -1439,9 +1464,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.0.tgz", - "integrity": "sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.0.tgz", + "integrity": "sha512-i0QwbHYfnOMYsBEyjxcwGu5SMIi9sImDVjDg087hpzXqhBSosxkE7gyIYFHgfFl4mr7RrXksIBZ4DoLoP4FhJg==", "cpu": [ "x64" ], @@ -1452,9 +1477,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.0.tgz", - "integrity": "sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.0.tgz", + "integrity": "sha512-Fq52EYb0riNHLBTAcL0cun+rRwyZ10S9vKzhGKKgeD+XbwunszSY0rVMco5KbOsTlwovP2rTOkiII/fQ4ih/zQ==", "cpu": [ "arm64" ], @@ -1465,9 +1490,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.0.tgz", - "integrity": "sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.0.tgz", + "integrity": "sha512-e/PBHxPdJ00O9p5Ui43+vixSgVf4NlLsmV6QneGERJ3lnjIua/kim6PRFe3iDueT1rQcgSkYP8ZBBXa/h4iPvw==", "cpu": [ "ia32" ], @@ -1478,9 +1503,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.0.tgz", - "integrity": "sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.0.tgz", + "integrity": "sha512-aGg7iToJjdklmxlUlJh/PaPNa4PmqHfyRMLunbL3eaMO0gp656+q1zOKkpJ/CVe9CryJv6tAN1HDoR8cNGzkag==", "cpu": [ "x64" ], @@ -1491,15 +1516,15 @@ ] }, "node_modules/@rushstack/eslint-patch": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.7.2.tgz", - "integrity": "sha512-RbhOOTCNoCrbfkRyoXODZp75MlpiHMgbE5MEBZAnnnLyQNgrigEj4p0lzsMDyc1zVsJDLrivB58tgg3emX0eEA==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.1.tgz", + "integrity": "sha512-S3Kq8e7LqxkA9s7HKLqXGTGck1uwis5vAXan3FnU5yw1Ec5hsSGnq4s/UCaSqABPOnOTg7zASLyst7+ohgWexg==", "dev": true }, "node_modules/@sideway/address": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", - "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", "dev": true, "dependencies": { "@hapi/hoek": "^9.0.0" @@ -1854,9 +1879,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.19.21", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.21.tgz", - "integrity": "sha512-2Q2NeB6BmiTFQi4DHBzncSoq/cJMLDdhPaAoJFnFCyD9a8VPZRf7a1GAwp1Edb7ROaZc5Jz/tnZyL6EsWMRaqw==", + "version": "18.19.29", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.29.tgz", + "integrity": "sha512-5pAX7ggTmWZdhUrhRWLPf+5oM7F80bcKVCBbr0zwEkTNzTJL2CWQjznpFgHYy6GrzkYi2Yjy7DHKoynFxqPV8g==", "dependencies": { "undici-types": "~5.26.4" } @@ -1867,9 +1892,9 @@ "integrity": "sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==" }, "node_modules/@types/semver": { - "version": "7.5.6", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", - "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", "dev": true }, "node_modules/@types/sinonjs__fake-timers": { @@ -1920,16 +1945,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.18.1.tgz", - "integrity": "sha512-nISDRYnnIpk7VCFrGcu1rnZfM1Dh9LRHnfgdkjcbi/l7g16VYRri3TjXi9Ir4lOZSw5N/gnV/3H7jIPQ8Q4daA==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", + "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.18.1", - "@typescript-eslint/type-utils": "6.18.1", - "@typescript-eslint/utils": "6.18.1", - "@typescript-eslint/visitor-keys": "6.18.1", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/type-utils": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -1955,15 +1980,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.18.1.tgz", - "integrity": "sha512-zct/MdJnVaRRNy9e84XnVtRv9Vf91/qqe+hZJtKanjojud4wAVy/7lXxJmMyX6X6J+xc6c//YEWvpeif8cAhWA==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.18.1", - "@typescript-eslint/types": "6.18.1", - "@typescript-eslint/typescript-estree": "6.18.1", - "@typescript-eslint/visitor-keys": "6.18.1", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4" }, "engines": { @@ -1983,13 +2008,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.18.1.tgz", - "integrity": "sha512-BgdBwXPFmZzaZUuw6wKiHKIovms97a7eTImjkXCZE04TGHysG+0hDQPmygyvgtkoB/aOQwSM/nWv3LzrOIQOBw==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.18.1", - "@typescript-eslint/visitor-keys": "6.18.1" + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2000,13 +2025,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.18.1.tgz", - "integrity": "sha512-wyOSKhuzHeU/5pcRDP2G2Ndci+4g653V43gXTpt4nbyoIOAASkGDA9JIAgbQCdCkcr1MvpSYWzxTz0olCn8+/Q==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", + "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.18.1", - "@typescript-eslint/utils": "6.18.1", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/utils": "6.21.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -2027,9 +2052,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.18.1.tgz", - "integrity": "sha512-4TuMAe+tc5oA7wwfqMtB0Y5OrREPF1GeJBAjqwgZh1lEMH5PJQgWgHGfYufVB51LtjD+peZylmeyxUXPfENLCw==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2040,13 +2065,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.18.1.tgz", - "integrity": "sha512-fv9B94UAhywPRhUeeV/v+3SBDvcPiLxRZJw/xZeeGgRLQZ6rLMG+8krrJUyIf6s1ecWTzlsbp0rlw7n9sjufHA==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.18.1", - "@typescript-eslint/visitor-keys": "6.18.1", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2068,17 +2093,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.18.1.tgz", - "integrity": "sha512-zZmTuVZvD1wpoceHvoQpOiewmWu3uP9FuTWo8vqpy2ffsmfCE8mklRPi+vmnIYAIk9t/4kOThri2QCDgor+OpQ==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.18.1", - "@typescript-eslint/types": "6.18.1", - "@typescript-eslint/typescript-estree": "6.18.1", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", "semver": "^7.5.4" }, "engines": { @@ -2093,12 +2118,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.18.1.tgz", - "integrity": "sha512-/kvt0C5lRqGoCfsbmm7/CwMqoSkY3zzHLIjdhHZQW3VFrnz7ATecOHR7nb7V+xn4286MBxfnQfQhAmCI0u+bJA==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.18.1", + "@typescript-eslint/types": "6.21.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -2193,6 +2218,15 @@ "node": ">=6" } }, + "node_modules/@vitest/expect/node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, "node_modules/@vitest/expect/node_modules/pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", @@ -2281,6 +2315,15 @@ "@types/estree": "^1.0.0" } }, + "node_modules/@vitest/utils/node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, "node_modules/@volar/language-core": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.11.1.tgz", @@ -2356,9 +2399,9 @@ } }, "node_modules/@vue/devtools-api": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.1.tgz", - "integrity": "sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==" + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.1.tgz", + "integrity": "sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==" }, "node_modules/@vue/eslint-config-prettier": { "version": "9.0.0", @@ -2491,9 +2534,9 @@ } }, "node_modules/@zip.js/zip.js": { - "version": "2.7.36", - "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.36.tgz", - "integrity": "sha512-u11fkedhUmMYIH1RRiVJM7fVw4CY+VPl0k6BxLBgngsIml70gGvbTHLhbXcN+BMBmQbZWL3DGEVxIo2xXVkLWg==", + "version": "2.7.41", + "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.41.tgz", + "integrity": "sha512-EMxPWXlEqqvsK9jxPmNvEShrIXP2LYTdQnEfsBH6OQCnlZRVo/dJIgtzbKvtK9A8PBTDQdxwxulj+QKplmW2Xg==", "engines": { "bun": ">=0.7.0", "deno": ">=1.0.0", @@ -2531,9 +2574,9 @@ } }, "node_modules/agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, "dependencies": { "debug": "^4.3.4" @@ -2786,19 +2829,19 @@ "dev": true }, "node_modules/axios": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", - "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", + "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", "dependencies": { - "follow-redirects": "^1.15.4", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } }, "node_modules/axios-retry": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-4.0.0.tgz", - "integrity": "sha512-F6P4HVGITD/v4z9Lw2mIA24IabTajvpDZmKa6zq/gGwn57wN5j1P3uWrAV0+diqnW6kTM2fTqmWNfgYWGmMuiA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-4.1.0.tgz", + "integrity": "sha512-svdth4H00yhlsjBbjfLQ/sMLkXqeLxhiFC1nE1JtkN/CIssGxqk0UwTEdrVjwA2gr3yJkAulwvDSIm4z4HyPvg==", "dev": true, "dependencies": { "is-retry-allowed": "^2.2.0" @@ -2852,12 +2895,15 @@ } }, "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/binary-searching": { @@ -3015,14 +3061,19 @@ } }, "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3057,12 +3108,12 @@ "dev": true }, "node_modules/cesium": { - "version": "1.115.0", - "resolved": "https://registry.npmjs.org/cesium/-/cesium-1.115.0.tgz", - "integrity": "sha512-aIC+JWO+0W/WDOAR1KIN+hEAUCZ98qUTQba7cPhW0fvMKiRVblDT1IJmZlb4dGBDtUGc0ZhwMXk2KpfM8BSztQ==", + "version": "1.116.0", + "resolved": "https://registry.npmjs.org/cesium/-/cesium-1.116.0.tgz", + "integrity": "sha512-RZOOMePztCVb74JU/DTCTfuha7xTsJtEm3FRZeMUXyZABeRhbYjT1GwtAtoaPPJ5/IoqNjLvZnTNJdnU3LVE5g==", "dependencies": { - "@cesium/engine": "^8.0.0", - "@cesium/widgets": "^5.0.0" + "@cesium/engine": "^9.0.0", + "@cesium/widgets": "^6.0.0" }, "engines": { "node": ">=14.0.0" @@ -3084,15 +3135,6 @@ "node": ">=12" } }, - "node_modules/chai/node_modules/loupe": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.0.tgz", - "integrity": "sha512-qKl+FrLXUhFuHUoDJG7f8P8gEMHq9NFS0c6ghXG1J0rldmZFQZoNVv/vyirE9qwCIhWZDsvEFd1sbFu3GvRQFg==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.1" - } - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -3190,16 +3232,10 @@ } }, "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -3212,6 +3248,9 @@ "engines": { "node": ">= 8.10.0" }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, "optionalDependencies": { "fsevents": "~2.3.2" } @@ -3253,9 +3292,9 @@ } }, "node_modules/cli-table3": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", - "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.4.tgz", + "integrity": "sha512-Lm3L0p+/npIQWNIiyF/nAn7T5dnOwR3xNTHXYEBFBFVPXzCVNZ5lqEC/1eo/EVfpDsQ1I+TX4ORPQgp+UI0CRw==", "dev": true, "dependencies": { "string-width": "^4.2.0" @@ -3312,14 +3351,23 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/color-parse": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/color-parse/-/color-parse-2.0.0.tgz", - "integrity": "sha512-g2Z+QnWsdHLppAbrpcFWo629kLOnOPtpxYV69GCqm92gqSgyXbzlfyN3MXs0412fPBkFmiuS+rXposgBgBa6Kg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/color-parse/-/color-parse-2.0.2.tgz", + "integrity": "sha512-eCtOz5w5ttWIUcaKLiktF+DxZO1R9KLNY/xhbV6CkhM7sR3GhVghmt6X6yOnzeaM24po+Z9/S1apbXMwA3Iepw==", "dependencies": { - "color-name": "^1.0.0" + "color-name": "^2.0.0" + } + }, + "node_modules/color-parse/node_modules/color-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.0.tgz", + "integrity": "sha512-SbtvAMWvASO5TE2QP07jHBMXKafgdZz8Vrsrn96fiL+O92/FN/PLARzUW5sKt013fjAprK2d2iCn2hk2Xb5oow==", + "engines": { + "node": ">=12.20" } }, "node_modules/color-rgba": { @@ -3493,9 +3541,9 @@ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/cypress": { - "version": "13.6.6", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.6.6.tgz", - "integrity": "sha512-S+2S9S94611hXimH9a3EAYt81QM913ZVA03pUmGDfLTFa5gyp85NJ8dJGSlEAEmyRsYkioS1TtnWtbv/Fzt11A==", + "version": "13.7.2", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.7.2.tgz", + "integrity": "sha512-FF5hFI5wlRIHY8urLZjJjj/YvfCBrRpglbZCLr/cYcL9MdDe0+5usa8kTIrDHthlEc9lwihbkb5dmwqBDNS2yw==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -3571,9 +3619,9 @@ } }, "node_modules/cypress-recurse": { - "version": "1.35.2", - "resolved": "https://registry.npmjs.org/cypress-recurse/-/cypress-recurse-1.35.2.tgz", - "integrity": "sha512-G6HfxP90xa7phw8oeOX4uabxcI9gE1ktkKHShcA3nCByrkMLs56+GIJVn0A+ws1tI0PGRKBz6+V9DHS5WnZX4A==", + "version": "1.35.3", + "resolved": "https://registry.npmjs.org/cypress-recurse/-/cypress-recurse-1.35.3.tgz", + "integrity": "sha512-NbFOpEuZT4tFqAB0jQqel7WtVNDe8pvSHE2TfXvYk4pspf3wq98OC2RhhLn3bMnoCnPtY4IHO7e37c+CZ9HnMA==", "dev": true, "dependencies": { "humanize-duration": "^3.27.3" @@ -3719,17 +3767,20 @@ "dev": true }, "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/delayed-stream": { @@ -3856,9 +3907,9 @@ } }, "node_modules/dompurify": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.9.tgz", - "integrity": "sha512-uyb4NDIvQ3hRn6NiC+SIFaP4mJ/MdXlvtunaqK9Bn6dD3RuB/1S/gasEjDHD8eiaqdSael2vBv+hOs7Y+jhYOQ==" + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.11.tgz", + "integrity": "sha512-Fan4uMuyB26gFV3ovPoEoQbxRRPfTu3CvImyZnhGq5fsIEO+gEFLp45ISFt+kQBWsK5ulDdT0oV28jS1UrwQLg==" }, "node_modules/domutils": { "version": "2.8.0", @@ -3965,6 +4016,27 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/esbuild": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", @@ -4004,9 +4076,9 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true, "engines": { "node": ">=6" @@ -4119,12 +4191,13 @@ } }, "node_modules/eslint-plugin-mocha": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.3.0.tgz", - "integrity": "sha512-IWzbg2K6B1Q7h37Ih4zMyW+nhmw1JvUlHlbCUUUu6PfOOAUGCB0gxmvv7/U+TQQ6e8yHUv+q7KMdIIum4bx+PA==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.4.1.tgz", + "integrity": "sha512-G85ALUgKaLzuEuHhoW3HVRgPTmia6njQC3qCG6CEvA8/Ja9PDZnRZOuzekMki+HaViEQXINuYsmhp5WR5/4MfA==", "dev": true, "dependencies": { "eslint-utils": "^3.0.0", + "globals": "^13.24.0", "rambda": "^7.4.0" }, "engines": { @@ -4190,12 +4263,13 @@ } }, "node_modules/eslint-plugin-vue": { - "version": "9.22.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.22.0.tgz", - "integrity": "sha512-7wCXv5zuVnBtZE/74z4yZ0CM8AjH6bk4MQGm7hZjUC2DBppKU5ioeOk5LGSg/s9a1ZJnIsdPLJpXnu1Rc+cVHg==", + "version": "9.24.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.24.0.tgz", + "integrity": "sha512-9SkJMvF8NGMT9aQCwFc5rj8Wo1XWSMSHk36i7ZwdI614BU7sIOR28ZjuFPKp8YGymZN12BSEbiSwa7qikp+PBw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", + "globals": "^13.24.0", "natural-compare": "^1.4.0", "nth-check": "^2.1.1", "postcss-selector-parser": "^6.0.15", @@ -4587,9 +4661,9 @@ "dev": true }, "node_modules/fastq": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", - "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -4697,6 +4771,48 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/flat-cache/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/flat-cache/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flat-cache/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/flat-cache/node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -4713,9 +4829,9 @@ } }, "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "node_modules/follow-redirects": { @@ -4837,20 +4953,34 @@ } }, "node_modules/gaxios": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.1.1.tgz", - "integrity": "sha512-bw8smrX+XlAoo9o1JAksBwX+hi/RG15J+NTSxmNPIclKC3ZVK6C2afwY8OSdRvOK0+ZLecUJYtj2MmjOt3Dm0w==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.4.0.tgz", + "integrity": "sha512-apAloYrY4dlBGlhauDAYSZveafb5U6+L9titing1wox6BvWM0TSXBp603zTrLpyLMGkrcFgohnUN150dFN/zOA==", "dev": true, "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "is-stream": "^2.0.0", - "node-fetch": "^2.6.9" + "node-fetch": "^2.6.9", + "uuid": "^9.0.1" }, "engines": { "node": ">=14" } }, + "node_modules/gaxios/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/gcp-metadata": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", @@ -4884,9 +5014,9 @@ "integrity": "sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg==" }, "node_modules/geotiff": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/geotiff/-/geotiff-2.1.1.tgz", - "integrity": "sha512-Ss6HQEhrlR2v0FmOGq88l0wa2oCmmGi6rXAMiUxR/T7Xe98evypEmyiji7lvVeVR/AXuxK0xDCWcwfWkSmOrAA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/geotiff/-/geotiff-2.1.3.tgz", + "integrity": "sha512-PT6uoF5a1+kbC3tHmZSUsLHBp2QJlHasxxxxPW47QIY1VBKpFB+FcDvX+MxER6UzgLQZ0xDzJ9s48B9JbOCTqA==", "dependencies": { "@petamoriken/float16": "^3.4.7", "lerc": "^3.0.0", @@ -4925,16 +5055,20 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, "dependencies": { + "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -5012,20 +5146,20 @@ "integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==" }, "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, + "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "minimatch": "^5.0.1", + "once": "^1.3.0" }, "engines": { - "node": "*" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -5043,26 +5177,17 @@ "node": ">= 6" } }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, + "peer": true, "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=10" } }, "node_modules/global-dirs": { @@ -5145,9 +5270,9 @@ } }, "node_modules/google-auth-library": { - "version": "9.4.2", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.4.2.tgz", - "integrity": "sha512-rTLO4gjhqqo3WvYKL5IdtlCvRqeQ4hxUx/p4lObobY2xotFW3bCQC+Qf1N51CYOfiqfMecdMwW9RIo7dFWYjqw==", + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.7.0.tgz", + "integrity": "sha512-I/AvzBiUXDzLOy4iIZ2W+Zq33W4lcukQv1nl7C8WUA6SQwyQwUwu3waNmWNAvzds//FG8SZ+DnKnW/2k6mQS8A==", "dev": true, "dependencies": { "base64-js": "^1.3.0", @@ -5175,14 +5300,14 @@ } }, "node_modules/googleapis-common": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-7.0.1.tgz", - "integrity": "sha512-mgt5zsd7zj5t5QXvDanjWguMdHAcJmmDrF9RkInCecNsyV7S7YtGqm5v2IWONNID88osb7zmx5FtrAP12JfD0w==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-7.1.0.tgz", + "integrity": "sha512-p3KHiWDBBWJEXk6SYauBEvxw5+UmRy7k2scxGtsNv9eHsTbpopJ3/7If4OrNnzJ9XMLg3IlyQXpVp8YPQsStiw==", "dev": true, "dependencies": { "extend": "^3.0.2", "gaxios": "^6.0.3", - "google-auth-library": "^9.0.0", + "google-auth-library": "^9.7.0", "qs": "^6.7.0", "url-template": "^2.0.8", "uuid": "^9.0.0" @@ -5234,9 +5359,9 @@ "dev": true }, "node_modules/gtoken": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.0.1.tgz", - "integrity": "sha512-KcFVtoP1CVFtQu0aSk3AyAt2og66PFhZAlkUOuWKwzMLoulHXG5W5wE5xAnHb+yl3/wEFoqGW7/cDGMU8igDZQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", + "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", "dev": true, "dependencies": { "gaxios": "^6.0.0", @@ -5264,21 +5389,21 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.2" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, "engines": { "node": ">= 0.4" @@ -5300,9 +5425,9 @@ } }, "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, "dependencies": { "function-bind": "^1.1.2" @@ -5333,9 +5458,9 @@ } }, "node_modules/http-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", - "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "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, "dependencies": { "agent-base": "^7.1.0", @@ -5360,9 +5485,9 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", "dev": true, "dependencies": { "agent-base": "^7.0.2", @@ -5382,9 +5507,9 @@ } }, "node_modules/humanize-duration": { - "version": "3.31.0", - "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.31.0.tgz", - "integrity": "sha512-fRrehgBG26NNZysRlTq1S+HPtDpp3u+Jzdc/d5A4cEzOD86YLAkDaJyJg8krSdCi7CJ+s7ht3fwRj8Dl+Btd0w==", + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.32.0.tgz", + "integrity": "sha512-6WsXYTHJr7hXKqoqf5zoWza/lANRAqGlbnZnm0cjDykbXuez1JVXOQGmq0EPB45pXYAJyueRA3S3hfhmMbrMEQ==", "dev": true }, "node_modules/iconv-lite": { @@ -5419,18 +5544,18 @@ ] }, "node_modules/ignore": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", - "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { "node": ">= 4" } }, "node_modules/immutable": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", - "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz", + "integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==", "dev": true }, "node_modules/import-fresh": { @@ -5700,14 +5825,14 @@ } }, "node_modules/joi": { - "version": "17.11.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.11.1.tgz", - "integrity": "sha512-671acnrx+w96PCcQOzvm0VYQVwNL2PVgZmDRaFuSsx8sIUmGzYElPw5lU8F3Cr0jOuPs1oM56p7W2a1cdDOwcw==", + "version": "17.12.3", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.3.tgz", + "integrity": "sha512-2RRziagf555owrm9IRVtdKynOBeITiDpuZqIpgwqXShPncPKNiRQoiGsl/T8SQdq+8ugRzH2LqY67irr2y/d+g==", "dev": true, "dependencies": { "@hapi/hoek": "^9.3.0", "@hapi/topo": "^5.1.0", - "@sideway/address": "^4.1.4", + "@sideway/address": "^4.1.5", "@sideway/formula": "^3.0.1", "@sideway/pinpoint": "^2.0.0" } @@ -5718,9 +5843,9 @@ "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==" }, "node_modules/js-tokens": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.3.tgz", - "integrity": "sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz", + "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==", "dev": true }, "node_modules/js-yaml": { @@ -5843,9 +5968,9 @@ "dev": true }, "node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", + "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", "dev": true }, "node_modules/jsonfile": { @@ -5942,9 +6067,9 @@ } }, "node_modules/ktx-parse": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/ktx-parse/-/ktx-parse-0.6.0.tgz", - "integrity": "sha512-hYOJUI86N9+YPm0M3t8hVzW9t5FnFFibRalZCrqHs/qM2eNziqQzBtAaF0ErgkXm8F+5uE8CjPUYr32vWlXLkQ==" + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/ktx-parse/-/ktx-parse-0.7.0.tgz", + "integrity": "sha512-naezun/2iiWrantwoRI9mw6E4iN41ggYzJSR9XAZzf6+rv+2Tb1yYN8VJhGsA0uptBexE0m4GDh+iiQhYpW+Qw==" }, "node_modules/lazy-ass": { "version": "1.6.0", @@ -6162,9 +6287,9 @@ "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" }, "node_modules/loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.0.tgz", + "integrity": "sha512-qKl+FrLXUhFuHUoDJG7f8P8gEMHq9NFS0c6ghXG1J0rldmZFQZoNVv/vyirE9qwCIhWZDsvEFd1sbFu3GvRQFg==", "dev": true, "dependencies": { "get-func-name": "^2.0.1" @@ -6183,9 +6308,9 @@ } }, "node_modules/magic-string": { - "version": "0.30.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.7.tgz", - "integrity": "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==", + "version": "0.30.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.9.tgz", + "integrity": "sha512-S1+hd+dIrC8EZqKyT9DstTH/0Z+f76kmmvZnkfQVmOpDEF9iVgdYif3Q/pIWHmCoo59bQVGW0kVL3e2nl+9+Sw==", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" }, @@ -6199,9 +6324,9 @@ "integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==" }, "node_modules/maplibre-gl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-4.1.0.tgz", - "integrity": "sha512-4RQFJSroo/JAJml6Rj2FFIZOfnjsqPp0O9kSp8aVXQUY0HGXNupltzPKbBZeucqi7ynRQHFeu+onTM3hY0Makw==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-4.1.2.tgz", + "integrity": "sha512-98T+3BesL4w/N39q/rgs9q6HzHLG6pgbS9UaTqg6fMISfzy2WGKokjK205ENFDDmEljj54/LTfdXgqg2XfYU4A==", "dependencies": { "@mapbox/geojson-rewind": "^0.5.2", "@mapbox/jsonlint-lines-primitives": "^2.0.2", @@ -6549,9 +6674,9 @@ } }, "node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "dev": true, "funding": [ { @@ -6903,9 +7028,9 @@ } }, "node_modules/mlly": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.5.0.tgz", - "integrity": "sha512-NPVQvAY1xr1QoVeG0cy8yUYC7FQcOx6evl/RjT1wL5FvzPnzOysoqB/jmx/DhssT2dYa8nxECLAaFI/+gVLhDQ==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.6.1.tgz", + "integrity": "sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==", "dev": true, "dependencies": { "acorn": "^8.11.3", @@ -6915,9 +7040,9 @@ } }, "node_modules/mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", + "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==", "dev": true, "peer": true, "dependencies": { @@ -6928,13 +7053,12 @@ "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", - "glob": "7.2.0", + "glob": "8.1.0", "he": "1.2.0", "js-yaml": "4.1.0", "log-symbols": "4.1.0", "minimatch": "5.0.1", "ms": "2.1.3", - "nanoid": "3.3.3", "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", @@ -6949,10 +7073,6 @@ }, "engines": { "node": ">= 14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" } }, "node_modules/mocha-junit-reporter": { @@ -6981,6 +7101,34 @@ "node": ">=6" } }, + "node_modules/mocha/node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "peer": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/mocha/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -7138,11 +7286,15 @@ "integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==" }, "node_modules/nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true, - "peer": true, + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -7262,9 +7414,9 @@ } }, "node_modules/ol": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/ol/-/ol-9.0.0.tgz", - "integrity": "sha512-+nYHZYbHrRUTDJ8ryxXPdDoAiaT6Zea02cocmGqsJXs4Oac1fYC9EbTIU2Y7803QcmG3u2MR88RxbksBvK+ZfQ==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/ol/-/ol-9.1.0.tgz", + "integrity": "sha512-nDrkJ2tzZNpo/wzN/PpHV5zdxbnXZaFktoMaD2cFLEc6gCwlgLY21Yd8wnt/4FjaVYwLBnbN9USXSwIBGcyksQ==", "dependencies": { "color-rgba": "^3.0.0", "color-space": "^2.0.1", @@ -7438,12 +7590,12 @@ } }, "node_modules/path-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", + "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", "dev": true, "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", + "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { @@ -7454,9 +7606,9 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", - "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", "dev": true, "engines": { "node": "14 || >=16.14" @@ -7583,9 +7735,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.0.15", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz", - "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==", + "version": "6.0.16", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", + "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", "dev": true, "dependencies": { "cssesc": "^3.0.0", @@ -7595,23 +7747,6 @@ "node": ">=4" } }, - "node_modules/postcss/node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, "node_modules/potpack": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/potpack/-/potpack-2.0.0.tgz", @@ -7723,9 +7858,9 @@ } }, "node_modules/proj4": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/proj4/-/proj4-2.10.0.tgz", - "integrity": "sha512-0eyB8h1PDoWxucnq88/EZqt7UZlvjhcfbXCcINpE7hqRN0iRPWE/4mXINGulNa/FAvK+Ie7F+l2OxH/0uKV36A==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/proj4/-/proj4-2.11.0.tgz", + "integrity": "sha512-SasuTkAx8HnWQHfIyhkdUNJorSJqINHAN3EyMWYiQRVorftz9DHz650YraFgczwgtHOxqnfuDxSNv3C8MUnHeg==", "dependencies": { "mgrs": "1.0.0", "wkt-parser": "^1.3.3" @@ -8044,9 +8179,9 @@ } }, "node_modules/rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", + "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", "dev": true }, "node_modules/rimraf": { @@ -8068,16 +8203,16 @@ } }, "node_modules/rimraf/node_modules/glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "version": "10.3.12", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", + "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", "dev": true, "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", + "jackspeak": "^2.3.6", "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" + "minipass": "^7.0.4", + "path-scurry": "^1.10.2" }, "bin": { "glob": "dist/esm/bin.mjs" @@ -8090,9 +8225,9 @@ } }, "node_modules/rollup": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.0.tgz", - "integrity": "sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.0.tgz", + "integrity": "sha512-Qe7w62TyawbDzB4yt32R0+AbIo6m1/sqO7UPzFS8Z/ksL5mrfhA0v4CavfdmFav3D+ub4QeAgsGEe84DoWe/nQ==", "dev": true, "dependencies": { "@types/estree": "1.0.5" @@ -8105,19 +8240,21 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.13.0", - "@rollup/rollup-android-arm64": "4.13.0", - "@rollup/rollup-darwin-arm64": "4.13.0", - "@rollup/rollup-darwin-x64": "4.13.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.13.0", - "@rollup/rollup-linux-arm64-gnu": "4.13.0", - "@rollup/rollup-linux-arm64-musl": "4.13.0", - "@rollup/rollup-linux-riscv64-gnu": "4.13.0", - "@rollup/rollup-linux-x64-gnu": "4.13.0", - "@rollup/rollup-linux-x64-musl": "4.13.0", - "@rollup/rollup-win32-arm64-msvc": "4.13.0", - "@rollup/rollup-win32-ia32-msvc": "4.13.0", - "@rollup/rollup-win32-x64-msvc": "4.13.0", + "@rollup/rollup-android-arm-eabi": "4.14.0", + "@rollup/rollup-android-arm64": "4.14.0", + "@rollup/rollup-darwin-arm64": "4.14.0", + "@rollup/rollup-darwin-x64": "4.14.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.14.0", + "@rollup/rollup-linux-arm64-gnu": "4.14.0", + "@rollup/rollup-linux-arm64-musl": "4.14.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.14.0", + "@rollup/rollup-linux-riscv64-gnu": "4.14.0", + "@rollup/rollup-linux-s390x-gnu": "4.14.0", + "@rollup/rollup-linux-x64-gnu": "4.14.0", + "@rollup/rollup-linux-x64-musl": "4.14.0", + "@rollup/rollup-win32-arm64-msvc": "4.14.0", + "@rollup/rollup-win32-ia32-msvc": "4.14.0", + "@rollup/rollup-win32-x64-msvc": "4.14.0", "fsevents": "~2.3.2" } }, @@ -8190,9 +8327,9 @@ "dev": true }, "node_modules/sass": { - "version": "1.71.1", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.71.1.tgz", - "integrity": "sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg==", + "version": "1.74.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.74.1.tgz", + "integrity": "sha512-w0Z9p/rWZWelb88ISOLyvqTWGmtmu2QJICqDBGyNnfG4OUnPX9BBjjYIXUpXCMOOg5MQWNpqzt876la1fsTvUA==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -8244,16 +8381,17 @@ } }, "node_modules/set-function-length": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", - "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, "dependencies": { - "define-data-property": "^1.1.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.2", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -8295,14 +8433,18 @@ } }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8631,12 +8773,12 @@ } }, "node_modules/strip-literal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.0.0.tgz", - "integrity": "sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.0.tgz", + "integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==", "dev": true, "dependencies": { - "js-tokens": "^8.0.2" + "js-tokens": "^9.0.0" }, "funding": { "url": "https://github.com/sponsors/antfu" @@ -8708,15 +8850,15 @@ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, "node_modules/tinybench": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.1.tgz", - "integrity": "sha512-65NKvSuAVDP/n4CqH+a9w2kTlLReS9vhsAP06MWx+/89nMinJyB2icyl58RIcqCmIggpojIGeuJGhjU1aGMBSg==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.6.0.tgz", + "integrity": "sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==", "dev": true }, "node_modules/tinypool": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.2.tgz", - "integrity": "sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ==", + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.3.tgz", + "integrity": "sha512-Ud7uepAklqRH1bvwy22ynrliC7Dljz7Tm8M/0RBUW+YRa4YHhZ6e4PpgE+fu1zr/WqB1kbeuVrdfeuyIBpy4tw==", "dev": true, "engines": { "node": ">=14.0.0" @@ -8745,30 +8887,12 @@ } }, "node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", "dev": true, - "dependencies": { - "rimraf": "^3.0.0" - }, "engines": { - "node": ">=8.17.0" - } - }, - "node_modules/tmp/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=14.14" } }, "node_modules/to-regex-range": { @@ -8838,12 +8962,12 @@ } }, "node_modules/ts-api-utils": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", - "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, "engines": { - "node": ">=16.13.0" + "node": ">=16" }, "peerDependencies": { "typescript": ">=4.2.0" @@ -8916,9 +9040,9 @@ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" }, "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz", + "integrity": "sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==", "devOptional": true, "bin": { "tsc": "bin/tsc", @@ -8948,9 +9072,9 @@ "dev": true }, "node_modules/ufo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.3.2.tgz", - "integrity": "sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", + "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", "dev": true }, "node_modules/undici-types": { @@ -9062,13 +9186,13 @@ } }, "node_modules/vite": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.2.tgz", - "integrity": "sha512-FWZbz0oSdLq5snUI0b6sULbz58iXFXdvkZfZWR/F0ZJuKTSPO7v72QPXt6KqYeMFb0yytNp6kZosxJ96Nr/wDQ==", + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.8.tgz", + "integrity": "sha512-OyZR+c1CE8yeHw5V5t59aXsUPPVTHMDjEZz8MgguLL/Q7NblxhZUlTu9xSPqlsUO/y+X7dlU05jdhvyycD55DA==", "dev": true, "dependencies": { "esbuild": "^0.20.1", - "postcss": "^8.4.36", + "postcss": "^8.4.38", "rollup": "^4.13.0" }, "bin": { @@ -9139,9 +9263,9 @@ } }, "node_modules/vite-plugin-static-copy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-1.0.1.tgz", - "integrity": "sha512-3eGL4mdZoPJMDBT68pv/XKIHR4MgVolStIxxv1gIBP4R8TpHn9C9EnaU0hesqlseJ4ycLGUxckFTu/jpuJXQlA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-1.0.2.tgz", + "integrity": "sha512-AfmEF+a/mfjsUsrgjbCkhzUCeIUF4EKQXXt3Ie1cour9MBpy6f6GphbdW2td28oYfOrwCyRzFCksgLkpk58q6Q==", "dev": true, "dependencies": { "chokidar": "^3.5.3", @@ -9342,6 +9466,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/vitest/node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, "node_modules/vitest/node_modules/mimic-fn": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", @@ -9355,9 +9488,9 @@ } }, "node_modules/vitest/node_modules/npm-run-path": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", - "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, "dependencies": { "path-key": "^4.0.0" @@ -9493,12 +9626,12 @@ } }, "node_modules/vue-i18n": { - "version": "9.10.1", - "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.10.1.tgz", - "integrity": "sha512-37HVJQZ/pZaRXGzFmmMomM1u1k7kndv3xCBPYHKEVfv5W3UVK67U/TpBug71ILYLNmjHLHdvTUPRF81pFT5fFg==", + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.11.0.tgz", + "integrity": "sha512-vU4gY6lu8Pdfs9BgKGiDAJmFDf88cceR47KcSB0VW4xJzUrXR/7qwqM7A8dQ2nedhoIDxoOm5Ro4pFd2KvJqbA==", "dependencies": { - "@intlify/core-base": "9.10.1", - "@intlify/shared": "9.10.1", + "@intlify/core-base": "9.11.0", + "@intlify/shared": "9.11.0", "@vue/devtools-api": "^6.5.0" }, "engines": { @@ -9818,9 +9951,9 @@ } }, "node_modules/xml-utils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/xml-utils/-/xml-utils-1.7.0.tgz", - "integrity": "sha512-bWB489+RQQclC7A9OW8e5BzbT8Tu//jtAOvkYwewFr+Q9T9KDGvfzC1lp0pYPEQPEoPQLDkmxkepSC/2gIAZGw==" + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/xml-utils/-/xml-utils-1.8.0.tgz", + "integrity": "sha512-1TY5yLw8DApowZAUsWCniNr8HH6Ebt6O7UQvmIwziGKwUNsQx6e+4NkfOvCfnqmYIcPjCeoI6dh1JenPJ9a1hQ==" }, "node_modules/xmlchars": { "version": "2.2.0", diff --git a/package.json b/package.json index 7b4c2a8c3..3b8a85b0c 100644 --- a/package.json +++ b/package.json @@ -33,13 +33,13 @@ "delete:reports:unit": "rimraf tests/results/unit/ || true" }, "dependencies": { - "@fortawesome/fontawesome-svg-core": "^6.5.1", - "@fortawesome/free-brands-svg-icons": "^6.5.1", - "@fortawesome/free-regular-svg-icons": "^6.5.1", - "@fortawesome/free-solid-svg-icons": "^6.5.1", + "@fortawesome/fontawesome-svg-core": "^6.5.2", + "@fortawesome/free-brands-svg-icons": "^6.5.2", + "@fortawesome/free-regular-svg-icons": "^6.5.2", + "@fortawesome/free-solid-svg-icons": "^6.5.2", "@fortawesome/vue-fontawesome": "^3.0.6", "@geoblocks/cesium-compass": "^0.5.0", - "@geoblocks/mapfishprint": "github:geoblocks/mapfishprint#4c47539f391af3c641f9455efe0d31ebdc145cfe", + "@geoblocks/mapfishprint": "^0.2.11", "@geoblocks/ol-maplibre-layer": "^0.1.3", "@ivanv/vue-collapse-transition": "^1.0.2", "@mapbox/togeojson": "^0.16.2", @@ -56,31 +56,31 @@ "@turf/nearest-point": "^6.5.0", "@turf/point-to-line-distance": "^6.5.0", "animate.css": "^4.1.1", - "axios": "^1.6.7", + "axios": "^1.6.8", "bootstrap": "^5.3.3", - "cesium": "^1.115.0", + "cesium": "^1.116.0", "chart.js": "^4.4.2", "chartjs-plugin-zoom": "^2.0.1", - "dompurify": "^3.0.9", + "dompurify": "^3.0.11", "file-saver": "^2.0.5", "form-data": "^4.0.0", "geographiclib-geodesic": "^2.0.0", "hammerjs": "^2.0.8", "jquery": "^3.7.1", "liang-barsky": "^1.0.5", - "maplibre-gl": "^4.1.0", - "ol": "^9.0.0", + "maplibre-gl": "^4.1.2", + "ol": "^9.1.0", "pako": "^2.1.0", "print-js": "^1.6.0", - "proj4": "^2.10.0", + "proj4": "^2.11.0", "reproject": "^1.2.7", "sortablejs": "^1.15.2", "tippy.js": "^6.3.7", "vue": "^3.4.21", "vue-chartjs": "^5.3.0", - "vue-i18n": "^9.10.1", + "vue-i18n": "^9.11.0", "vue-router": "^4.3.0", - "vue-social-sharing": "next", + "vue-social-sharing": "^4.0.0-alpha4", "vuex": "^4.1.0" }, "devDependencies": { @@ -88,30 +88,30 @@ "@cypress/vite-dev-server": "^5.0.7", "@cypress/vue": "^6.0.0", "@nuintun/qrcode": "^3.4.0", - "@prettier/plugin-xml": "^3.3.1", - "@rushstack/eslint-patch": "^1.7.2", + "@prettier/plugin-xml": "^3.4.1", + "@rushstack/eslint-patch": "^1.10.1", "@types/jsdom": "^21.1.6", - "@types/node": "^18.19.21", + "@types/node": "^18.19.29", "@vitejs/plugin-vue": "^5.0.4", "@vue/eslint-config-prettier": "^9.0.0", "@vue/eslint-config-typescript": "^12.0.0", "@vue/tsconfig": "^0.5.1", - "axios-retry": "^4.0.0", + "axios-retry": "^4.1.0", "chai": "^5.1.0", - "cypress": "^13.6.6", + "cypress": "^13.7.2", "cypress-browser-permissions": "^1.1.0", "cypress-real-events": "^1.12.0", - "cypress-recurse": "^1.35.2", + "cypress-recurse": "^1.35.3", "cypress-vite": "^1.5.0", "cypress-wait-until": "^3.0.1", "dotenv": "^16.4.5", "eslint": "^8.57.0", "eslint-plugin-cypress": "^2.15.1", "eslint-plugin-markdownlint": "^0.5.0", - "eslint-plugin-mocha": "^10.3.0", + "eslint-plugin-mocha": "^10.4.1", "eslint-plugin-prettier-vue": "^5.0.0", "eslint-plugin-simple-import-sort": "^12.0.0", - "eslint-plugin-vue": "^9.22.0", + "eslint-plugin-vue": "^9.24.0", "git-describe": "^4.1.1", "googleapis": "^133.0.0", "jsdom": "^24.0.0", @@ -120,12 +120,12 @@ "prettier": "^3.2.5", "prettier-plugin-jsdoc": "^1.3.0", "rimraf": "^5.0.5", - "sass": "^1.71.1", + "sass": "^1.74.1", "start-server-and-test": "^2.0.3", - "typescript": "^5.3.3", - "vite": "^5.2.2", + "typescript": "^5.4.4", + "vite": "^5.2.8", "vite-node": "^1.4.0", - "vite-plugin-static-copy": "^1.0.1", + "vite-plugin-static-copy": "^1.0.2", "vitest": "^1.4.0", "vue-tsc": "^1.8.27", "write-yaml-file": "^5.0.0", @@ -133,7 +133,7 @@ }, "engines": { "node": ">=18", - "npm": "9.*.*" + "npm": "10.*.*" }, "type": "module", "engineStrict": true diff --git a/src/api/features/LayerFeature.class.js b/src/api/features/LayerFeature.class.js index e30b0c150..371b9aae6 100644 --- a/src/api/features/LayerFeature.class.js +++ b/src/api/features/LayerFeature.class.js @@ -20,10 +20,7 @@ export default class LayerFeature extends SelectableFeature { super({ id, coordinates, - // using the layer name as title (so that user can differentiate the source) - title: layer.name, - // and the name as description (so that we do not lose track of this data) - description: name, + title: name, extent, geometry, isEditable: false, diff --git a/src/api/features/SelectableFeature.class.js b/src/api/features/SelectableFeature.class.js index 038579eda..4f1b1f1ad 100644 --- a/src/api/features/SelectableFeature.class.js +++ b/src/api/features/SelectableFeature.class.js @@ -42,7 +42,9 @@ export default class SelectableFeature extends EventEmitter { } = featureData this.id = id // using the setter for coordinate (see below) - this.coordinates = coordinates + + // if coordinates are not defined, we set them to null + this.coordinates = coordinates ? coordinates : null this.title = title this.description = description this.geometry = geometry diff --git a/src/api/features/features.api.js b/src/api/features/features.api.js index 1fbd8c79f..f36563f79 100644 --- a/src/api/features/features.api.js +++ b/src/api/features/features.api.js @@ -294,13 +294,13 @@ async function identifyOnExternalWmsLayer(config) { SERVICE: 'WMS', VERSION: layer.wmsVersion ?? '1.3.0', REQUEST: 'GetFeatureInfo', - LAYERS: layer.externalLayerId, + LAYERS: layer.id, STYLES: null, CRS: projection.epsg, BBOX: requestExtent.join(','), WIDTH: GET_FEATURE_INFO_FAKE_VIEWPORT_SIZE, HEIGHT: GET_FEATURE_INFO_FAKE_VIEWPORT_SIZE, - QUERY_LAYERS: layer.externalLayerId, + QUERY_LAYERS: layer.id, INFO_FORMAT: outputFormat, FEATURE_COUNT: featureCount, LANG: lang, @@ -369,6 +369,7 @@ async function identifyOnExternalWmsLayer(config) { return new LayerFeature({ layer, id: feature.id, + name: feature.title ?? feature.name ?? feature.id, data: feature.properties, coordinates: getGeoJsonFeatureCoordinates( geometry, @@ -521,7 +522,18 @@ const getFeature = (layer, featureID, outputProjection, lang = 'en') => { if (featureMetadata.bbox) { featureExtent.push(...featureMetadata.bbox) } - const featureName = featureMetadata?.properties?.name + let featureName = featureID + if (featureMetadata.properties) { + const { name = null, title = null } = featureMetadata.properties + const titleInCurrentLang = featureMetadata.properties[`title_${lang}`] + if (name) { + featureName = name + } else if (title) { + featureName = title + } else if (titleInCurrentLang) { + featureName = titleInCurrentLang + } + } if (outputProjection.epsg !== LV95.epsg) { if (featureExtent.length === 4) { diff --git a/src/api/feedback.api.js b/src/api/feedback.api.js index a19acdc37..e584e1608 100644 --- a/src/api/feedback.api.js +++ b/src/api/feedback.api.js @@ -6,20 +6,16 @@ import { API_SERVICES_BASE_URL, APP_VERSION } from '@/config' import log from '@/utils/logging' /** + * @param {String} subject Mandatory * @param {String} text Mandatory - * @param {Number} rating Optional - * @param {Number} maxRating Optional - * @param {String} kmlFileUrl Optional - * @param {String} email Optional + * @param {String | null} [options.kmlFileUrl=null] Default is `null` + * @param {String | null} [options.email=null] Default is `null` + * @param {File | null} [options.attachment=null] Default is `null` * @returns {Promise} True if successful, false otherwise */ -export default async function sendFeedback( - text, - rating = null, - maxRating = null, - kmlFileUrl = null, - email = null -) { +export default async function sendFeedback(subject, text, options) { + const { kmlFileUrl = null, email = null, attachment = null } = options + try { let shortLink = null try { @@ -47,12 +43,6 @@ export default async function sendFeedback( } } - let subject = '[web-mapviewer]' - if (rating && maxRating) { - subject += ` [rating: ${rating}/${maxRating}]` - } - subject += ' User feedback' - const data = { subject, feedback: text, @@ -61,6 +51,7 @@ export default async function sendFeedback( permalink: shortLink, kml, email, + attachment, } log.debug('sending feedback with', data) const response = await axios.post(`${API_SERVICES_BASE_URL}feedback`, data, { diff --git a/src/api/layers/ExternalGroupOfLayers.class.js b/src/api/layers/ExternalGroupOfLayers.class.js index 181711b6c..9378581b9 100644 --- a/src/api/layers/ExternalGroupOfLayers.class.js +++ b/src/api/layers/ExternalGroupOfLayers.class.js @@ -20,14 +20,13 @@ import LayerTypes from '@/api/layers/LayerTypes.enum' */ export default class ExternalGroupOfLayers extends ExternalLayer { /** + * @param {String} externalLayerData.id Layer ID of the group to be found in GetCapabilities * @param {String} externalLayerData.name Name of this layer to be shown to the user * @param {number} [externalLayerData.opacity=1.0] The opacity of this layer, between 0.0 * (transparent) and 1.0 (opaque). Default is `1.0` * @param {boolean} [externalLayerData.visible=true] If the layer should be shown on the map. * Default is `true` * @param {String} externalLayerData.baseUrl GetCapabilities base URL - * @param {String} externalLayerData.externalLayerId Layer ID of the group to be found in - * GetCapabilities * @param {ExternalLayer[]} externalLayerData.layers Description of the layers being part of * this group (they will all be displayed at the same time, in contrast to an aggregate * layer) @@ -53,11 +52,11 @@ export default class ExternalGroupOfLayers extends ExternalLayer { throw new InvalidLayerDataError('Missing external layer data', externalLayerData) } const { + id = null, name = null, opacity = 1.0, visible = true, baseUrl = null, - externalLayerId = null, layers = [], attributions = null, abstract = '', @@ -74,13 +73,9 @@ export default class ExternalGroupOfLayers extends ExternalLayer { ) } super({ + id, name, - // format coming from https://github.com/geoadmin/web-mapviewer/blob/develop/adr/2021_03_16_url_param_structure.md - // NOTE we don't differentiate between group of layers and regular WMS layer. This differentiation was not - // done the legacy parameter and is not required. - id: `WMS|${baseUrl}|${externalLayerId}`, type: LayerTypes.GROUP, - externalLayerId, baseUrl, opacity, visible, diff --git a/src/api/layers/ExternalLayer.class.js b/src/api/layers/ExternalLayer.class.js index 8a3b70b8d..7ae465737 100644 --- a/src/api/layers/ExternalLayer.class.js +++ b/src/api/layers/ExternalLayer.class.js @@ -69,13 +69,9 @@ export class LayerLegend { export default class ExternalLayer extends AbstractLayer { /** * @param {String} externalLayerData.name Name of this layer to be shown to the user - * @param {String} externalLayerData.id The unique ID of this layer that will be used in the URL - * to identify it. It should typically contain the type of external layer we are dealing with, - * with the URL to get the capabilites or data of this layer. + * @param {String} externalLayerData.id Layer ID to use when requesting the tiles on the server * @param {LayerTypes} externalLayerData.type The type of layer in GeoAdmin sense (WMTS, WMS, * GeoJson, etc...) - * @param {String} externalLayerData.externalLayerId Layer ID to use when requesting the tiles - * on the server * @param {String} externalLayerData.baseUrl Base URL to build the request to the data * @param {number} [externalLayerData.opacity=1.0] The opacity of this layer, between 0.0 * (transparent) and 1.0 (opaque). Default is `1.0` @@ -108,7 +104,6 @@ export default class ExternalLayer extends AbstractLayer { name = null, id = null, type = null, - externalLayerId = null, baseUrl = null, opacity = 1.0, visible = true, @@ -141,7 +136,6 @@ export default class ExternalLayer extends AbstractLayer { hasDescription: abstract?.length > 0 || legends?.length > 0, hasLegend: legends?.length > 0, }) - this.externalLayerId = externalLayerId this.abstract = abstract this.extent = extent this.legends = legends diff --git a/src/api/layers/ExternalWMSLayer.class.js b/src/api/layers/ExternalWMSLayer.class.js index 33dadabdc..f1d367c6a 100644 --- a/src/api/layers/ExternalWMSLayer.class.js +++ b/src/api/layers/ExternalWMSLayer.class.js @@ -1,6 +1,5 @@ import ExternalLayer from '@/api/layers/ExternalLayer.class' import { InvalidLayerDataError } from '@/api/layers/InvalidLayerData.error' -import { encodeExternalLayerParam } from '@/api/layers/layers-external.api' import LayerTypes from '@/api/layers/LayerTypes.enum' /** @@ -16,6 +15,7 @@ import LayerTypes from '@/api/layers/LayerTypes.enum' */ export default class ExternalWMSLayer extends ExternalLayer { /** + * @param {String} externalWmsData.id Layer ID to use when requesting the tiles on the server * @param {String} externalWmsData.name Name of this layer to be shown to the user * @param {Number} [externalWmsData.opacity=1.0] The opacity of this layer, between 0.0 * (transparent) and 1.0 (opaque). Default is `1.0` @@ -23,8 +23,6 @@ export default class ExternalWMSLayer extends ExternalLayer { * Default is `true` * @param {String} externalWmsData.baseUrl Base URL to build WMS requests (no endpoint / URL * param defined) - * @param {String} externalWmsData.externalLayerId Layer ID to use when requesting the tiles on - * the server * @param {String} [externalWmsData.wmsVersion='1.3.0'] WMS protocol version to be used when * querying this server. Default is `'1.3.0'` * @param {LayerAttribution[]} [externalWmsData.attributions=null] Description of the data @@ -54,11 +52,11 @@ export default class ExternalWMSLayer extends ExternalLayer { throw new InvalidLayerDataError('Missing external WMS layer data', externalWmsData) } const { + id = null, name = null, opacity = 1.0, visible = true, baseUrl = null, - externalLayerId = null, attributions = null, wmsVersion = '1.3.0', format = 'png', @@ -72,12 +70,8 @@ export default class ExternalWMSLayer extends ExternalLayer { } = externalWmsData super({ name, - // format coming from https://github.com/geoadmin/web-mapviewer/blob/develop/adr/2021_03_16_url_param_structure.md - // base URL and name must be URL encoded (no & signs or other reserved URL chars must pass, or it could break URL param parsing) - // NOTE the pipe character needs to be encoded in order to not break the parsing - id: `WMS|${encodeExternalLayerParam(baseUrl)}|${encodeExternalLayerParam(externalLayerId)}`, + id, type: LayerTypes.WMS, - externalLayerId, baseUrl, opacity, visible, diff --git a/src/api/layers/ExternalWMTSLayer.class.js b/src/api/layers/ExternalWMTSLayer.class.js index fb35bd8ef..e1ff75171 100644 --- a/src/api/layers/ExternalWMTSLayer.class.js +++ b/src/api/layers/ExternalWMTSLayer.class.js @@ -1,6 +1,5 @@ import ExternalLayer from '@/api/layers/ExternalLayer.class' import { InvalidLayerDataError } from '@/api/layers/InvalidLayerData.error' -import { encodeExternalLayerParam } from '@/api/layers/layers-external.api' import LayerTypes from '@/api/layers/LayerTypes.enum' /** @@ -17,6 +16,7 @@ import LayerTypes from '@/api/layers/LayerTypes.enum' */ export default class ExternalWMTSLayer extends ExternalLayer { /** + * @param {String} externalWmtsData.id Layer ID to use when requesting the tiles on the server * @param {String} externalWmtsData.name Name of this layer to be shown to the user * @param {number} [externalWmtsData.opacity=1.0] The opacity of this layer, between 0.0 * (transparent) and 1.0 (opaque). Default is `1.0` @@ -24,8 +24,6 @@ export default class ExternalWMTSLayer extends ExternalLayer { * be hidden. Default is `true` * @param {String} externalWmtsData.baseUrl To the getCapabilities.xml endpoint of the server * for this layer - * @param {String} externalWmtsData.externalLayerId Layer ID to use when requesting the tiles on - * the server * @param {LayerAttribution[]} [externalWmtsData.attributions=null] Description of the data * owner(s) for this layer. When `null` is given it uses the default attribution which is * based on the hostname of the GetCapabilities server. Default is `null` @@ -46,11 +44,11 @@ export default class ExternalWMTSLayer extends ExternalLayer { throw new InvalidLayerDataError('Missing external WMTS layer data', externalWmtsData) } const { + id = null, name = null, opacity = 1.0, visible = true, baseUrl = null, - externalLayerId = null, attributions = null, abstract = '', extent = null, @@ -61,11 +59,8 @@ export default class ExternalWMTSLayer extends ExternalLayer { } = externalWmtsData super({ name, - // format coming from https://github.com/geoadmin/web-mapviewer/blob/develop/adr/2021_03_16_url_param_structure.md - // NOTE the pipe character needs to be encoded in order to not break the parsing - id: `WMTS|${encodeExternalLayerParam(baseUrl)}|${encodeExternalLayerParam(externalLayerId)}`, + id, type: LayerTypes.WMTS, - externalLayerId, baseUrl, ensureTrailingSlashInBaseUrl: true, opacity, diff --git a/src/api/layers/GPXLayer.class.js b/src/api/layers/GPXLayer.class.js index 18935234c..f3217f01a 100644 --- a/src/api/layers/GPXLayer.class.js +++ b/src/api/layers/GPXLayer.class.js @@ -46,7 +46,7 @@ export default class GPXLayer extends AbstractLayer { hasDescription: false, hasLegend: false, isExternal: true, - isLoading: !!gpxData && !!gpxMetadata, + isLoading: !gpxData, }) this.gpxFileUrl = gpxFileUrl this.gpxData = gpxData diff --git a/src/api/layers/KMLLayer.class.js b/src/api/layers/KMLLayer.class.js index 562157ca2..c62953a71 100644 --- a/src/api/layers/KMLLayer.class.js +++ b/src/api/layers/KMLLayer.class.js @@ -1,6 +1,5 @@ import AbstractLayer, { LayerAttribution } from '@/api/layers/AbstractLayer.class' import { InvalidLayerDataError } from '@/api/layers/InvalidLayerData.error' -import { encodeExternalLayerParam } from '@/api/layers/layers-external.api' import LayerTypes from '@/api/layers/LayerTypes.enum' import { API_SERVICE_KML_BASE_URL } from '@/config' import { parseKmlName } from '@/utils/kmlUtils' @@ -52,9 +51,7 @@ export default class KMLLayer extends AbstractLayer { const isExternal = kmlFileUrl.indexOf(API_SERVICE_KML_BASE_URL) === -1 super({ name: 'KML', - // format coming from https://github.com/geoadmin/web-mapviewer/blob/develop/adr/2021_03_16_url_param_structure.md - // NOTE the pipe character needs to be encoded in order to not break the parsing - id: `KML|${encodeExternalLayerParam(kmlFileUrl)}`, + id: kmlFileUrl, type: LayerTypes.KML, baseUrl: kmlFileUrl, opacity: opacity ?? 1.0, diff --git a/src/api/layers/LayerTypes.enum.js b/src/api/layers/LayerTypes.enum.js index fa0433872..ae8cbb4c7 100644 --- a/src/api/layers/LayerTypes.enum.js +++ b/src/api/layers/LayerTypes.enum.js @@ -3,13 +3,13 @@ * @enum {String} */ const LayerTypes = { - WMTS: 'wmts', - WMS: 'wms', - GEOJSON: 'geojson', - AGGREGATE: 'aggregate', - KML: 'kml', - GPX: 'gpx', - VECTOR: 'vector', - GROUP: 'group', + WMTS: 'WMTS', + WMS: 'WMS', + GEOJSON: 'GEOJSON', + AGGREGATE: 'AGGREGATE', + KML: 'KML', + GPX: 'GPX', + VECTOR: 'VECTOR', + GROUP: 'GROUP', } export default LayerTypes diff --git a/src/api/layers/WMSCapabilitiesParser.class.js b/src/api/layers/WMSCapabilitiesParser.class.js index de5e83928..fa7eb8bf1 100644 --- a/src/api/layers/WMSCapabilitiesParser.class.js +++ b/src/api/layers/WMSCapabilitiesParser.class.js @@ -187,11 +187,11 @@ export default class WMSCapabilitiesParser { ) ).filter((layer) => !!layer) return new ExternalGroupOfLayers({ + id: layerId, name: title, opacity, visible, baseUrl: url, - externalLayerId: layerId, layers, attributions, abstract, @@ -203,11 +203,11 @@ export default class WMSCapabilitiesParser { }) } return new ExternalWMSLayer({ + id: layerId, name: title, opacity, visible, baseUrl: url, - externalLayerId: layerId, attributions, wmsVersion: version, format: 'png', diff --git a/src/api/layers/WMTSCapabilitiesParser.class.js b/src/api/layers/WMTSCapabilitiesParser.class.js index fa809d5bc..888f02321 100644 --- a/src/api/layers/WMTSCapabilitiesParser.class.js +++ b/src/api/layers/WMTSCapabilitiesParser.class.js @@ -109,11 +109,11 @@ export default class WMTSCapabilitiesParser { }) return new ExternalWMTSLayer({ + id: attributes.layerId, name: attributes.title, opacity, visible, baseUrl: attributes.url, - externalLayerId: attributes.layerId, attributions: attributes.attributions, abstract: attributes.abstract, extent: attributes.extent, diff --git a/src/api/layers/__tests__/KMLLayer.class.spec.js b/src/api/layers/__tests__/KMLLayer.class.spec.js index 1ed3db58d..08ec78741 100644 --- a/src/api/layers/__tests__/KMLLayer.class.spec.js +++ b/src/api/layers/__tests__/KMLLayer.class.spec.js @@ -46,8 +46,8 @@ describe('KMLLayer', () => { const fileId = '-uQyFMtTSCWC_9rZE3EJ6B' const kmlFileUrl = `https://sys-public.dev.bgdi.ch/api/kml/files/${fileId}` const kmlLayer = new KMLLayer({ kmlFileUrl }) - const expectedID = `KML|${kmlFileUrl}` - expect(kmlLayer.id).toBe(expectedID) + expect(kmlLayer.id).toBe(kmlFileUrl) + expect(kmlLayer.baseUrl).toBe(kmlFileUrl) }) it('should identify legacy KML', () => { diff --git a/src/api/layers/__tests__/WMSCapabitliesParser.class.spec.js b/src/api/layers/__tests__/WMSCapabitliesParser.class.spec.js index 1d70e7815..a7c06a94c 100644 --- a/src/api/layers/__tests__/WMSCapabitliesParser.class.spec.js +++ b/src/api/layers/__tests__/WMSCapabitliesParser.class.spec.js @@ -33,21 +33,21 @@ describe('WMSCapabilitiesParser of wms-geoadmin-sample.xml', () => { it('Parse layer attributes', () => { // Base layer let layer = capabilities.getExternalLayerObject('wms-bgdi', WGS84) - expect(layer.externalLayerId).toBe('wms-bgdi') + expect(layer.id).toBe('wms-bgdi') expect(layer.name).toBe('WMS BGDI') expect(layer.abstract).toBe('Public Federal Geo Infrastructure (BGDI)') expect(layer.baseUrl).toBe('https://wms.geo.admin.ch/?') // General layer layer = capabilities.getExternalLayerObject('ch.swisstopo-vd.official-survey', WGS84) - expect(layer.externalLayerId).toBe('ch.swisstopo-vd.official-survey') + expect(layer.id).toBe('ch.swisstopo-vd.official-survey') expect(layer.name).toBe('OpenData-AV') expect(layer.abstract).toBe('The official survey (AV).') expect(layer.baseUrl).toBe('https://wms.geo.admin.ch/?') // Layer without .Name layer = capabilities.getExternalLayerObject('Periodic-Tracking', WGS84) - expect(layer.externalLayerId).toBe('Periodic-Tracking') + expect(layer.id).toBe('Periodic-Tracking') expect(layer.name).toBe('Periodic-Tracking') expect(layer.abstract).toBe('Layer without Name element should use the Title') expect(layer.baseUrl).toBe('https://wms.geo.admin.ch/?') @@ -55,7 +55,7 @@ describe('WMSCapabilitiesParser of wms-geoadmin-sample.xml', () => { it('Parse layer attribution', () => { // Attribution in root layer let layer = capabilities.getExternalLayerObject('ch.swisstopo-vd.official-survey', WGS84) - expect(layer.externalLayerId).toBe('ch.swisstopo-vd.official-survey') + expect(layer.id).toBe('ch.swisstopo-vd.official-survey') expectTypeOf(layer.attributions).toBeArray() expect(layer.attributions.length).toBe(1) expectTypeOf(layer.attributions[0]).toEqualTypeOf({ name: 'string', url: 'string' }) @@ -64,7 +64,7 @@ describe('WMSCapabilitiesParser of wms-geoadmin-sample.xml', () => { // Attribution in layer layer = capabilities.getExternalLayerObject('Periodic-Tracking', WGS84) - expect(layer.externalLayerId).toBe('Periodic-Tracking') + expect(layer.id).toBe('Periodic-Tracking') expectTypeOf(layer.attributions).toBeArray() expect(layer.attributions.length).toBe(1) expectTypeOf(layer.attributions[0]).toEqualTypeOf({ name: 'string', url: 'string' }) @@ -74,7 +74,7 @@ describe('WMSCapabilitiesParser of wms-geoadmin-sample.xml', () => { it('Get Layer Extent in LV95', () => { const externalLayers = capabilities.getAllExternalLayerObjects(LV95) // Extent from matching CRS BoundingBox - expect(externalLayers[0].externalLayerId).toBe('ch.swisstopo-vd.official-survey') + expect(externalLayers[0].id).toBe('ch.swisstopo-vd.official-survey') let expected = [ [2100000, 1030000], [2900000, 1400000], @@ -83,7 +83,7 @@ describe('WMSCapabilitiesParser of wms-geoadmin-sample.xml', () => { expect(externalLayers[0].extent).toEqual(expected) // Extent from non matching CRS BoundingBox - expect(externalLayers[1].externalLayerId).toBe('Periodic-Tracking') + expect(externalLayers[1].id).toBe('Periodic-Tracking') expected = [ [2485071.58, 1075346.3], [2828515.82, 1299941.79], @@ -99,7 +99,7 @@ describe('WMSCapabilitiesParser of wms-geoadmin-sample.xml', () => { it('Parse layer legend', () => { // General layer let layer = capabilities.getExternalLayerObject('ch.swisstopo-vd.official-survey', WGS84) - expect(layer.externalLayerId).toBe('ch.swisstopo-vd.official-survey') + expect(layer.id).toBe('ch.swisstopo-vd.official-survey') expect(layer.abstract).not.empty expect(layer.hasDescription).toBeTruthy() expect(layer.hasLegend).toBeFalsy() @@ -107,7 +107,7 @@ describe('WMSCapabilitiesParser of wms-geoadmin-sample.xml', () => { // Layer without .Name layer = capabilities.getExternalLayerObject('Periodic-Tracking', WGS84) - expect(layer.externalLayerId).toBe('Periodic-Tracking') + expect(layer.id).toBe('Periodic-Tracking') expect(layer.hasDescription).toBeTruthy() expect(layer.hasLegend).toBeTruthy() expect(layer.legends.length).toBe(1) @@ -121,7 +121,7 @@ describe('WMSCapabilitiesParser of wms-geoadmin-sample.xml', () => { // Layer without abstract and legend layer = capabilities.getExternalLayerObject('ch.swisstopo-vd.stand-oerebkataster', WGS84) - expect(layer.externalLayerId).toBe('ch.swisstopo-vd.stand-oerebkataster') + expect(layer.id).toBe('ch.swisstopo-vd.stand-oerebkataster') expect(layer.hasDescription).toBeFalsy() expect(layer.hasLegend).toBeFalsy() expect(layer.legends.length).toBe(0) @@ -206,7 +206,7 @@ describe('WMSCapabilitiesParser - attributions', () => { let capabilities = new WMSCapabilitiesParser(content, 'https://wms.geo.admin.ch') // No attribution, use Service let layer = capabilities.getExternalLayerObject('ch.swisstopo-vd.official-survey', WGS84) - expect(layer.externalLayerId).toBe('ch.swisstopo-vd.official-survey') + expect(layer.id).toBe('ch.swisstopo-vd.official-survey') expectTypeOf(layer.attributions).toBeArray() expect(layer.attributions.length).toBe(1) expectTypeOf(layer.attributions[0]).toEqualTypeOf({ name: 'string', url: 'string' }) @@ -236,7 +236,7 @@ describe('WMSCapabilitiesParser - attributions', () => { capabilities = new WMSCapabilitiesParser(content, 'https://wms.geo.admin.ch') // Attribution in service layer = capabilities.getExternalLayerObject('ch.swisstopo-vd.official-survey', WGS84) - expect(layer.externalLayerId).toBe('ch.swisstopo-vd.official-survey') + expect(layer.id).toBe('ch.swisstopo-vd.official-survey') expectTypeOf(layer.attributions).toBeArray() expect(layer.attributions.length).toBe(1) expectTypeOf(layer.attributions[0]).toEqualTypeOf({ name: 'string', url: 'string' }) @@ -260,7 +260,7 @@ describe('WMSCapabilitiesParser - attributions', () => { capabilities = new WMSCapabilitiesParser(content, 'https://wms.geo.admin.ch') // Attribution in service layer = capabilities.getExternalLayerObject('ch.swisstopo-vd.official-survey', WGS84) - expect(layer.externalLayerId).toBe('ch.swisstopo-vd.official-survey') + expect(layer.id).toBe('ch.swisstopo-vd.official-survey') expectTypeOf(layer.attributions).toBeArray() expect(layer.attributions.length).toBe(1) expectTypeOf(layer.attributions[0]).toEqualTypeOf({ name: 'string', url: 'string' }) @@ -297,7 +297,7 @@ describe('WMSCapabilitiesParser - attributions', () => { const capabilities = new WMSCapabilitiesParser(content, 'https://wms.geo.admin.ch') const layer = capabilities.getExternalLayerObject('ch.swisstopo-vd.official-survey', WGS84) - expect(layer.externalLayerId).toBe('ch.swisstopo-vd.official-survey') + expect(layer.id).toBe('ch.swisstopo-vd.official-survey') expectTypeOf(layer.attributions).toBeArray() expect(layer.attributions.length).toBe(1) expectTypeOf(layer.attributions[0]).toEqualTypeOf({ name: 'string', url: 'string' }) @@ -339,7 +339,7 @@ describe('WMSCapabilitiesParser - attributions', () => { let capabilities = new WMSCapabilitiesParser(content, 'https://wms.geo.admin.ch') // Attribution in layer let layer = capabilities.getExternalLayerObject('ch.swisstopo-vd.official-survey', WGS84) - expect(layer.externalLayerId).toBe('ch.swisstopo-vd.official-survey') + expect(layer.id).toBe('ch.swisstopo-vd.official-survey') expectTypeOf(layer.attributions).toBeArray() expect(layer.attributions.length).toBe(1) expectTypeOf(layer.attributions[0]).toEqualTypeOf({ name: 'string', url: 'string' }) @@ -373,7 +373,7 @@ describe('WMSCapabilitiesParser - attributions', () => { ` capabilities = new WMSCapabilitiesParser(content, 'https://wms.geo.admin.ch') layer = capabilities.getExternalLayerObject('ch.swisstopo-vd.official-survey', WGS84) - expect(layer.externalLayerId).toBe('ch.swisstopo-vd.official-survey') + expect(layer.id).toBe('ch.swisstopo-vd.official-survey') expectTypeOf(layer.attributions).toBeArray() expect(layer.attributions.length).toBe(1) expectTypeOf(layer.attributions[0]).toEqualTypeOf({ name: 'string', url: 'string' }) @@ -404,7 +404,7 @@ describe('WMSCapabilitiesParser - attributions', () => { let capabilities = new WMSCapabilitiesParser(content, 'https://wms.geo.admin.ch') // No attribution, use Service let layer = capabilities.getExternalLayerObject('ch.swisstopo-vd.official-survey', WGS84) - expect(layer.externalLayerId).toBe('ch.swisstopo-vd.official-survey') + expect(layer.id).toBe('ch.swisstopo-vd.official-survey') expectTypeOf(layer.attributions).toBeArray() expect(layer.attributions.length).toBe(1) expectTypeOf(layer.attributions[0]).toEqualTypeOf({ name: 'string', url: 'string' }) @@ -437,7 +437,7 @@ describe('WMSCapabilitiesParser - layer extent', () => { let capabilities = new WMSCapabilitiesParser(content, 'https://wms.geo.admin.ch') // LV95 let layer = capabilities.getExternalLayerObject('ch.swisstopo-vd.official-survey', LV95) - expect(layer.externalLayerId).toBe('ch.swisstopo-vd.official-survey') + expect(layer.id).toBe('ch.swisstopo-vd.official-survey') expectTypeOf(layer.extent).toBeArray() let expected = [ [2485071.58, 1075346.3], @@ -453,7 +453,7 @@ describe('WMSCapabilitiesParser - layer extent', () => { // WGS84 layer = capabilities.getExternalLayerObject('ch.swisstopo-vd.official-survey', WGS84) - expect(layer.externalLayerId).toBe('ch.swisstopo-vd.official-survey') + expect(layer.id).toBe('ch.swisstopo-vd.official-survey') expectTypeOf(layer.extent).toBeArray() expected = [ [5.96, 45.82], @@ -464,7 +464,7 @@ describe('WMSCapabilitiesParser - layer extent', () => { // Web mercator layer = capabilities.getExternalLayerObject('ch.swisstopo-vd.official-survey', WEBMERCATOR) - expect(layer.externalLayerId).toBe('ch.swisstopo-vd.official-survey') + expect(layer.id).toBe('ch.swisstopo-vd.official-survey') expectTypeOf(layer.extent).toBeArray() expected = [ [663464.17, 5751550.86], @@ -501,7 +501,7 @@ describe('WMSCapabilitiesParser - layer extent', () => { let capabilities = new WMSCapabilitiesParser(content, 'https://wms.geo.admin.ch') // LV95 let layer = capabilities.getExternalLayerObject('ch.swisstopo-vd.official-survey', LV95) - expect(layer.externalLayerId).toBe('ch.swisstopo-vd.official-survey') + expect(layer.id).toBe('ch.swisstopo-vd.official-survey') expectTypeOf(layer.extent).toBeArray() let expected = [ [2485071.58, 1075346.3], @@ -517,7 +517,7 @@ describe('WMSCapabilitiesParser - layer extent', () => { // WGS84 layer = capabilities.getExternalLayerObject('ch.swisstopo-vd.official-survey', WGS84) - expect(layer.externalLayerId).toBe('ch.swisstopo-vd.official-survey') + expect(layer.id).toBe('ch.swisstopo-vd.official-survey') expectTypeOf(layer.extent).toBeArray() expected = [ [5.96, 45.82], @@ -528,7 +528,7 @@ describe('WMSCapabilitiesParser - layer extent', () => { // Web mercator layer = capabilities.getExternalLayerObject('ch.swisstopo-vd.official-survey', WEBMERCATOR) - expect(layer.externalLayerId).toBe('ch.swisstopo-vd.official-survey') + expect(layer.id).toBe('ch.swisstopo-vd.official-survey') expectTypeOf(layer.extent).toBeArray() expected = [ [663464.17, 5751550.86], @@ -581,17 +581,17 @@ describe('EX_GeographicBoundingBox - Group of layers', () => { // LV95 let layers = capabilities.getAllExternalLayerObjects(LV95) expect(layers.length).toBe(1) - expect(layers[0].externalLayerId).toBe('ch.swisstopo-vd.official-survey') + expect(layers[0].id).toBe('ch.swisstopo-vd.official-survey') expect(layers[0]).toBeInstanceOf(ExternalGroupOfLayers) expect(layers[0].layers.length).toBe(3) expect(layers[0].layers[0]).toBeInstanceOf(ExternalWMSLayer) - expect(layers[0].layers[0].externalLayerId).toBe('ch.swisstopo-vd.official-survey-1') + expect(layers[0].layers[0].id).toBe('ch.swisstopo-vd.official-survey-1') expect(layers[0].layers[1]).toBeInstanceOf(ExternalWMSLayer) - expect(layers[0].layers[1].externalLayerId).toBe('ch.swisstopo-vd.official-survey-2') + expect(layers[0].layers[1].id).toBe('ch.swisstopo-vd.official-survey-2') expect(layers[0].layers[2]).toBeInstanceOf(ExternalWMSLayer) - expect(layers[0].layers[2].externalLayerId).toBe('ch.swisstopo-vd.official-survey-3') + expect(layers[0].layers[2].id).toBe('ch.swisstopo-vd.official-survey-3') }) it('Parse group of layers - multiple hierarchy', () => { const content = ` @@ -645,35 +645,31 @@ describe('EX_GeographicBoundingBox - Group of layers', () => { // LV95 let layers = capabilities.getAllExternalLayerObjects(LV95) expect(layers.length).toBe(1) - expect(layers[0].externalLayerId).toBe('ch.swisstopo-vd.official-survey') + expect(layers[0].id).toBe('ch.swisstopo-vd.official-survey') expect(layers[0]).toBeInstanceOf(ExternalGroupOfLayers) expect(layers[0].layers.length).toBe(3) expect(layers[0].layers[0]).toBeInstanceOf(ExternalWMSLayer) - expect(layers[0].layers[0].externalLayerId).toBe('ch.swisstopo-vd.official-survey-1') + expect(layers[0].layers[0].id).toBe('ch.swisstopo-vd.official-survey-1') expect(layers[0].layers[1]).toBeInstanceOf(ExternalWMSLayer) - expect(layers[0].layers[1].externalLayerId).toBe('ch.swisstopo-vd.official-survey-2') + expect(layers[0].layers[1].id).toBe('ch.swisstopo-vd.official-survey-2') expect(layers[0].layers[2]).toBeInstanceOf(ExternalGroupOfLayers) - expect(layers[0].layers[2].externalLayerId).toBe('ch.swisstopo-vd.official-survey-3') + expect(layers[0].layers[2].id).toBe('ch.swisstopo-vd.official-survey-3') expect(layers[0].layers[2].layers[0]).toBeInstanceOf(ExternalWMSLayer) - expect(layers[0].layers[2].layers[0].externalLayerId).toBe( - 'ch.swisstopo-vd.official-survey-3-sub-1' - ) + expect(layers[0].layers[2].layers[0].id).toBe('ch.swisstopo-vd.official-survey-3-sub-1') expect(layers[0].layers[2].layers[1]).toBeInstanceOf(ExternalGroupOfLayers) - expect(layers[0].layers[2].layers[1].externalLayerId).toBe( - 'ch.swisstopo-vd.official-survey-3-sub-2' - ) + expect(layers[0].layers[2].layers[1].id).toBe('ch.swisstopo-vd.official-survey-3-sub-2') expect(layers[0].layers[2].layers[1].layers[0]).toBeInstanceOf(ExternalWMSLayer) - expect(layers[0].layers[2].layers[1].layers[0].externalLayerId).toBe( + expect(layers[0].layers[2].layers[1].layers[0].id).toBe( 'ch.swisstopo-vd.official-survey-3-sub-2-1' ) expect(layers[0].layers[2].layers[1].layers[1]).toBeInstanceOf(ExternalWMSLayer) - expect(layers[0].layers[2].layers[1].layers[1].externalLayerId).toBe( + expect(layers[0].layers[2].layers[1].layers[1].id).toBe( 'ch.swisstopo-vd.official-survey-3-sub-2-2' ) }) @@ -733,12 +729,12 @@ describe('EX_GeographicBoundingBox - Group of layers', () => { // search root layer let layer = capabilities.getExternalLayerObject('ch.swisstopo-vd.official-survey', LV95) expect(layer).not.toBeNull() - expect(layer.externalLayerId).toBe('ch.swisstopo-vd.official-survey') + expect(layer.id).toBe('ch.swisstopo-vd.official-survey') // search first hierarchy layer layer = capabilities.getExternalLayerObject('ch.swisstopo-vd.official-survey-2', LV95) expect(layer).not.toBeNull() - expect(layer.externalLayerId).toBe('ch.swisstopo-vd.official-survey-2') + expect(layer.id).toBe('ch.swisstopo-vd.official-survey-2') // Search sublayer layer = capabilities.getExternalLayerObject( @@ -746,11 +742,11 @@ describe('EX_GeographicBoundingBox - Group of layers', () => { LV95 ) expect(layer).not.toBeNull() - expect(layer.externalLayerId).toBe('ch.swisstopo-vd.official-survey-3-sub-2-1') + expect(layer.id).toBe('ch.swisstopo-vd.official-survey-3-sub-2-1') // Search sublayer without name layer = capabilities.getExternalLayerObject('OpenData-AV 3.2.2', LV95) expect(layer).not.toBeNull() - expect(layer.externalLayerId).toBe('OpenData-AV 3.2.2') + expect(layer.id).toBe('OpenData-AV 3.2.2') }) }) diff --git a/src/api/layers/__tests__/WMTSCapabitliesParser.class.spec.js b/src/api/layers/__tests__/WMTSCapabitliesParser.class.spec.js index 0e22567f7..3432e0f22 100644 --- a/src/api/layers/__tests__/WMTSCapabitliesParser.class.spec.js +++ b/src/api/layers/__tests__/WMTSCapabitliesParser.class.spec.js @@ -30,14 +30,14 @@ describe('WMTSCapabilitiesParser of wmts-ogc-sample.xml', () => { it('Parse layer attributes', () => { // General layer let layer = capabilities.getExternalLayerObject('BlueMarbleSecondGenerationAG', WGS84) - expect(layer.externalLayerId).toBe('BlueMarbleSecondGenerationAG') + expect(layer.id).toBe('BlueMarbleSecondGenerationAG') expect(layer.name).toBe('Blue Marble Second Generation - AG') expect(layer.abstract).toBe('Blue Marble Second Generation Canton Aargau Product') expect(layer.baseUrl).toBe('http://maps.example.com/cgi-bin/map.cgi?') // Layer without .Identifier layer = capabilities.getExternalLayerObject('BlueMarbleThirdGenerationZH', WGS84) - expect(layer.externalLayerId).toBe('BlueMarbleThirdGenerationZH') + expect(layer.id).toBe('BlueMarbleThirdGenerationZH') expect(layer.name).toBe('BlueMarbleThirdGenerationZH') expect(layer.abstract).toBe('Blue Marble Third Generation Canton Zürich Product') expect(layer.baseUrl).toBe('http://maps.example.com/cgi-bin/map.cgi?') @@ -45,7 +45,7 @@ describe('WMTSCapabilitiesParser of wmts-ogc-sample.xml', () => { it('Parse layer attribution', () => { // General layer let layer = capabilities.getExternalLayerObject('BlueMarbleSecondGenerationAG', WGS84) - expect(layer.externalLayerId).toBe('BlueMarbleSecondGenerationAG') + expect(layer.id).toBe('BlueMarbleSecondGenerationAG') expectTypeOf(layer.attributions).toBeArray() expect(layer.attributions.length).toBe(1) expectTypeOf(layer.attributions[0]).toEqualTypeOf({ name: 'string', url: 'string' }) @@ -55,7 +55,7 @@ describe('WMTSCapabilitiesParser of wmts-ogc-sample.xml', () => { it('Get Layer Extent in LV95', () => { const externalLayers = capabilities.getAllExternalLayerObjects(LV95) // Extent from WGS84BoundingBox - expect(externalLayers[0].externalLayerId).toBe('BlueMarbleNextGenerationCH') + expect(externalLayers[0].id).toBe('BlueMarbleNextGenerationCH') let expected = [ [2485071.58, 1075346.31], [2828515.82, 1299941.79], @@ -69,7 +69,7 @@ describe('WMTSCapabilitiesParser of wmts-ogc-sample.xml', () => { expect(externalLayers[0].extent[1][1]).toBeCloseTo(expected[1][1], 2) // Extent from BoundingBox in WGS84 - expect(externalLayers[1].externalLayerId).toBe('BlueMarbleSecondGenerationAG') + expect(externalLayers[1].id).toBe('BlueMarbleSecondGenerationAG') expected = [ [2627438.37, 1215506.64], [2677504.99, 1277102.76], @@ -83,7 +83,7 @@ describe('WMTSCapabilitiesParser of wmts-ogc-sample.xml', () => { expect(externalLayers[1].extent[1][1]).toBeCloseTo(expected[1][1], 2) // Extent from BoundingBox without CRS - expect(externalLayers[2].externalLayerId).toBe('BlueMarbleThirdGenerationZH') + expect(externalLayers[2].id).toBe('BlueMarbleThirdGenerationZH') expected = [ [2665255.25, 1229142.44], [2720879.67, 1287842.18], @@ -97,7 +97,7 @@ describe('WMTSCapabilitiesParser of wmts-ogc-sample.xml', () => { expect(externalLayers[2].extent[1][1]).toBeCloseTo(expected[1][1], 2) // Extent from the TileMatrixSet - expect(externalLayers[3].externalLayerId).toBe('BlueMarbleFourthGenerationJU') + expect(externalLayers[3].id).toBe('BlueMarbleFourthGenerationJU') expected = [ [2552296.05, 1218970.79], [2609136.96, 1266593.74], @@ -111,7 +111,7 @@ describe('WMTSCapabilitiesParser of wmts-ogc-sample.xml', () => { expect(externalLayers[3].extent[1][1]).toBeCloseTo(expected[1][1], 2) // Extent from matching BoundingBox - expect(externalLayers[4].externalLayerId).toBe('BlueMarbleFifthGenerationGE') + expect(externalLayers[4].id).toBe('BlueMarbleFifthGenerationGE') expect(externalLayers[4].extent).toEqual([ [2484928.06, 1108705.32], [2514614.27, 1130449.26], @@ -121,7 +121,7 @@ describe('WMTSCapabilitiesParser of wmts-ogc-sample.xml', () => { it('Get Layer Extent in Web Mercator', () => { const externalLayers = capabilities.getAllExternalLayerObjects(WEBMERCATOR) // Extent from WGS84BoundingBox - expect(externalLayers[0].externalLayerId).toBe('BlueMarbleNextGenerationCH') + expect(externalLayers[0].id).toBe('BlueMarbleNextGenerationCH') let expected = [ [663464.16, 5751550.86], [1167741.46, 6075303.61], @@ -135,7 +135,7 @@ describe('WMTSCapabilitiesParser of wmts-ogc-sample.xml', () => { expect(externalLayers[0].extent[1][1]).toBeCloseTo(expected[1][1], 1) // Extent from BoundingBox in WGS84 - expect(externalLayers[1].externalLayerId).toBe('BlueMarbleSecondGenerationAG') + expect(externalLayers[1].id).toBe('BlueMarbleSecondGenerationAG') expected = [ [868292.03, 5956776.76], [942876.09, 6047171.27], @@ -149,7 +149,7 @@ describe('WMTSCapabilitiesParser of wmts-ogc-sample.xml', () => { expect(externalLayers[1].extent[1][1]).toBeCloseTo(expected[1][1], 1) // Extent from BoundingBox without CRS - expect(externalLayers[2].externalLayerId).toBe('BlueMarbleThirdGenerationZH') + expect(externalLayers[2].id).toBe('BlueMarbleThirdGenerationZH') expected = [ [923951.77, 5976419.03], [1007441.39, 6062053.42], @@ -163,7 +163,7 @@ describe('WMTSCapabilitiesParser of wmts-ogc-sample.xml', () => { expect(externalLayers[2].extent[1][1]).toBeCloseTo(expected[1][1], 1) // Extent from the TileMatrixSet - expect(externalLayers[3].externalLayerId).toBe('BlueMarbleFourthGenerationJU') + expect(externalLayers[3].id).toBe('BlueMarbleFourthGenerationJU') expected = [ [758085.73, 5961683.17], [841575.35, 6032314.73], @@ -180,28 +180,28 @@ describe('WMTSCapabilitiesParser of wmts-ogc-sample.xml', () => { it('Get Layer Extent in WGS84', () => { const externalLayers = capabilities.getAllExternalLayerObjects(WGS84) // Extent from WGS84BoundingBox - expect(externalLayers[0].externalLayerId).toBe('BlueMarbleNextGenerationCH') + expect(externalLayers[0].id).toBe('BlueMarbleNextGenerationCH') expect(externalLayers[0].extent).toEqual([ [5.96, 45.82], [10.49, 47.81], ]) // Extent from BoundingBox in WGS84 - expect(externalLayers[1].externalLayerId).toBe('BlueMarbleSecondGenerationAG') + expect(externalLayers[1].id).toBe('BlueMarbleSecondGenerationAG') expect(externalLayers[1].extent).toEqual([ [7.8, 47.09], [8.47, 47.64], ]) // Extent from BoundingBox without CRS - expect(externalLayers[2].externalLayerId).toBe('BlueMarbleThirdGenerationZH') + expect(externalLayers[2].id).toBe('BlueMarbleThirdGenerationZH') expect(externalLayers[2].extent).toEqual([ [8.3, 47.21], [9.05, 47.73], ]) // Extent from the TileMatrixSet - expect(externalLayers[3].externalLayerId).toBe('BlueMarbleFourthGenerationJU') + expect(externalLayers[3].id).toBe('BlueMarbleFourthGenerationJU') expect(externalLayers[3].extent).toEqual([ [6.81, 47.12], [7.56, 47.55], @@ -210,7 +210,7 @@ describe('WMTSCapabilitiesParser of wmts-ogc-sample.xml', () => { it('Parse layer legend', () => { // General layer let layer = capabilities.getExternalLayerObject('BlueMarbleSecondGenerationAG', WGS84) - expect(layer.externalLayerId).toBe('BlueMarbleSecondGenerationAG') + expect(layer.id).toBe('BlueMarbleSecondGenerationAG') expectTypeOf(layer.legends).toBeArray() expect(layer.legends.length).toBe(1) expect(layer.legends[0]).toBeInstanceOf(LayerLegend) diff --git a/src/api/print.api.js b/src/api/print.api.js index 7afec0400..f421e8806 100644 --- a/src/api/print.api.js +++ b/src/api/print.api.js @@ -7,7 +7,7 @@ import { } from '@geoblocks/mapfishprint' import axios from 'axios' -import { API_BASE_URL, API_SERVICES_BASE_URL, WMS_BASE_URL } from '@/config' +import { API_BASE_URL, WMS_BASE_URL } from '@/config' import i18n from '@/modules/i18n' import log from '@/utils/logging' @@ -15,7 +15,8 @@ const PRINTING_RESOLUTION = 96 // dpi const PRINTING_DEFAULT_POLL_INTERVAL = 2000 // interval between each polling of the printing job status (ms) const PRINTING_DEFAULT_POLL_TIMEOUT = 600000 // ms (10 minutes) -const SERVICE_PRINT_URL = `${API_SERVICES_BASE_URL}print3/print/default` +// const SERVICE_PRINT_URL = `${API_SERVICES_BASE_URL}print3/print/default` +const SERVICE_PRINT_URL = `https://sys-map.int.bgdi.ch/api/print3/print/default` class GeoAdminCustomizer extends BaseCustomizer { /** @param {string[]} layerIDsToExclude List of layer names to exclude from the print */ @@ -39,6 +40,35 @@ class GeoAdminCustomizer extends BaseCustomizer { // Call parent layerFilter method for other layers return super.layerFilter(layerState) } + + /** + * Remove the "editableFeature" adn "geodesic" property from the feature as it is not needed and + * can cause issues with mapfishprint + * + * @param {State} layerState + * @param {GeoJSONFeature} feature Manipulated feature + */ + feature(layerState, feature) { + // cause circular reference issues + delete feature.properties?.geodesic + // unnecessary properties for printing and cause mapfishprint to throw an error + delete feature.properties?.editableFeature + } + + /** + * Manipulate the symbolizer of a line feature before printing it. In this case replace the + * strokeDashstyle to dash instead of 8 (measurement line style in the mapfishprint3 backend) + * + * @param {State} layerState + * @param {MFPSymbolizerLine} symbolizer Interface for the symbolizer of a line feature + * @param {Stroke} stroke Stroke style of the line feature + */ + // eslint-disable-next-line no-unused-vars + line(layerState, symbolizer, stroke) { + if (symbolizer?.strokeDashstyle === '8') { + symbolizer.strokeDashstyle = 'dash' + } + } } /** @@ -196,6 +226,8 @@ export class PrintError extends Error { * the grid is to be printed (it can otherwise be null). Default is `null` * @param {String[]} [config.excludedLayerIDs=[]] List of the IDs of OpenLayers layer to exclude * from the print. Default is `[]` + * @param {String | null} [config.outputFilename=null] Output file name, without extension. When + * null, let the server decide. Default is `null` */ async function transformOlMapToPrintParams(olMap, config) { const { @@ -209,6 +241,7 @@ async function transformOlMapToPrintParams(olMap, config) { printGrid = false, projection = null, excludedLayerIDs = [], + outputFilename = null, } = config if (!qrCodeUrl) { @@ -267,6 +300,8 @@ async function transformOlMapToPrintParams(olMap, config) { }, format: 'pdf', layout: layout.name, + lang, + outputFilename, } if (layersWithLegends.length > 0) { spec.attributes.legend = { @@ -284,7 +319,7 @@ async function transformOlMapToPrintParams(olMap, config) { return spec } catch (error) { log.error("Couldn't encode map to print request", error) - throw new PrintError('Failed to print the map') + throw new PrintError(`Couldn't encode map to print request: ${error}`) } } @@ -309,6 +344,8 @@ async function transformOlMapToPrintParams(olMap, config) { * the grid is to be printed (it can otherwise be null). Default is `null` * @param {String[]} [config.excludedLayerIDs=[]] List of IDs of OpenLayers layer to exclude from * the print. Default is `[]` + * @param {String | null} [config.outputFilename=null] Output file name, without extension. When + * null, let the server decide. Default is `null` * @returns {Promise} A job running on our printing backend (needs to be polled * using {@link waitForPrintJobCompletion} to wait until its completion) */ @@ -324,6 +361,7 @@ export async function createPrintJob(map, config) { printGrid = false, projection = null, excludedLayerIDs = [], + outputFilename = null, } = config try { const printingSpec = await transformOlMapToPrintParams(map, { @@ -337,12 +375,13 @@ export async function createPrintJob(map, config) { printGrid, projection, excludedLayerIDs, + outputFilename, }) log.debug('Starting print for spec', printingSpec) return await requestReport(SERVICE_PRINT_URL, printingSpec) } catch (error) { log.error('Error while creating print job', error) - return null + throw new PrintError(`Error while creating print job: ${error}`) } } diff --git a/src/api/profile/profile.api.js b/src/api/profile/profile.api.js index 7855e8e15..bf5ddc76d 100644 --- a/src/api/profile/profile.api.js +++ b/src/api/profile/profile.api.js @@ -6,8 +6,16 @@ import ElevationProfilePoint from '@/api/profile/ElevationProfilePoint.class' import ElevationProfileSegment from '@/api/profile/ElevationProfileSegment.class' import { API_SERVICE_ALTI_BASE_URL } from '@/config' import { LV95 } from '@/utils/coordinates/coordinateSystems' +import { removeZValues, unwrapGeometryCoordinates } from '@/utils/coordinates/coordinateUtils.js' import log from '@/utils/logging' +export class ProfileError { + constructor(technicalError, messageKey) { + this.technicalError = technicalError + this.messageKey = messageKey + } +} + function parseProfileFromBackendResponse(backendResponse, startingDist, outputProjection) { const points = [] backendResponse.forEach((rawData) => { @@ -28,6 +36,7 @@ function parseProfileFromBackendResponse(backendResponse, startingDist, outputPr * @param {Number} startingDist * @param {CoordinateSystem} outputProjection * @returns {ElevationProfile} + * @throws ProfileError */ async function getProfileDataForChunk(chunk, startingPoint, startingDist, outputProjection) { if (chunk.isWithinBounds) { @@ -57,11 +66,17 @@ async function getProfileDataForChunk(chunk, startingPoint, startingDist, output ) } else { log.error('Incorrect/empty response while getting profile', dataForChunk) - return null + throw new ProfileError( + 'Incorrect/empty response while getting profile', + 'network_error' + ) } } catch (err) { log.error('Error while trying to fetch profile data', err) - return null + if (err instanceof ProfileError) { + throw err + } + throw new ProfileError('Error while trying to fetch profile data', 'network_error') } } // returning a chunk without data (and also evaluating distance between point as if we were on a flat plane) @@ -69,7 +84,7 @@ async function getProfileDataForChunk(chunk, startingPoint, startingDist, output let lastCoordinate = startingPoint if (!chunk?.coordinates) { log.error('Malformed chunk', chunk) - return null + throw new ProfileError('Malformed chunk', 'network_error') } return new ElevationProfileSegment([ ...chunk.coordinates.map((coordinate) => { @@ -98,15 +113,17 @@ async function getProfileDataForChunk(chunk, startingPoint, startingDist, output * @param {CoordinateSystem} projection The projection used to describe the coordinates * @returns {ElevationProfile | null} The profile, or null if there was no valid data to produce a * profile + * @throws ProfileError */ export default async (coordinates, projection) => { if (!coordinates || coordinates.length === 0) { const errorMessage = `Coordinates not provided` log.error(errorMessage) - throw errorMessage + throw new ProfileError(errorMessage, 'could_not_generate_profile') } // the service only works with LV95 coordinate, we have to transform them if they are not in this projection - let coordinatesInLV95 = [...coordinates] + // removing any 3d dimension that could come from OL + let coordinatesInLV95 = removeZValues(unwrapGeometryCoordinates(coordinates)) if (projection.epsg !== LV95.epsg) { coordinatesInLV95 = coordinates.map((coordinate) => proj4(projection.epsg, LV95.epsg, coordinate) @@ -115,8 +132,11 @@ export default async (coordinates, projection) => { const segments = [] let coordinateChunks = LV95.bounds.splitIfOutOfBounds(coordinatesInLV95) if (!coordinateChunks) { - log.error('No chunks found, no profile data could be fetched') - return null + log.error('No chunks found, no profile data could be fetched', coordinatesInLV95) + throw new ProfileError( + 'No chunks found, no profile data could be fetched', + 'could_not_generate_profile' + ) } let lastCoordinate = null let lastDist = 0 diff --git a/src/config.js b/src/config.js index 52de93fae..e616b0b12 100644 --- a/src/config.js +++ b/src/config.js @@ -258,3 +258,23 @@ export const WARNING_RIBBON_HOSTNAMES = ['test.map.geo.admin.ch'] * @type {String[]} */ export const WMS_SUPPORTED_VERSIONS = ['1.3.0'] + +/** + * Display Give Feedback on all these hosts + * + * @type {String[]} + */ +export const GIVE_FEEDBACK_HOSTNAMES = ['localhost', 'sys-map.dev.bgdi.ch', 'test.map.geo.admin.ch'] + +/** + * Display Report Problem on all these hosts + * + * @type {String[]} + */ +export const REPORT_PROBLEM_HOSTNAMES = [ + 'localhost', + 'sys-map.dev.bgdi.ch', + 'sys-map.int.bgdi.ch', + 'sys-map.prod.bgdi.ch', + 'map.geo.admin.ch', +] diff --git a/src/modules/drawing/DrawingModule.vue b/src/modules/drawing/DrawingModule.vue index 56127a877..b292699de 100644 --- a/src/modules/drawing/DrawingModule.vue +++ b/src/modules/drawing/DrawingModule.vue @@ -91,7 +91,7 @@ onMounted(() => { // Left clicking while in drawing mode has its own logic not covered in click-on-map-management.plugin.js // We force the featureInfo to be visible in drawing mode store.dispatch('setFeatureInfoPosition', { - featureInfo: FeatureInfoPositions.DEFAULT, + position: FeatureInfoPositions.DEFAULT, ...dispatcher, }) } diff --git a/src/modules/drawing/components/DrawingSelectInteraction.vue b/src/modules/drawing/components/DrawingSelectInteraction.vue index 9a4900e42..01f9d46c8 100644 --- a/src/modules/drawing/components/DrawingSelectInteraction.vue +++ b/src/modules/drawing/components/DrawingSelectInteraction.vue @@ -9,6 +9,7 @@ import SelectInteraction from 'ol/interaction/Select' import { computed, inject, onBeforeUnmount, onMounted, ref, watch } from 'vue' import { useStore } from 'vuex' +import { EditableFeatureTypes } from '@/api/features/EditableFeature.class' import { DRAWING_HIT_TOLERANCE } from '@/config' import useModifyInteraction from '@/modules/drawing/components/useModifyInteraction.composable' import { editingFeatureStyleFunction } from '@/modules/drawing/lib/style' @@ -33,7 +34,7 @@ useModifyInteraction(selectInteraction.getFeatures()) /** OpenLayers feature currently selected */ const currentlySelectedFeature = ref(null) -const selectedFeatures = computed(() => store.state.features.selectedFeatures) +const selectedFeatures = computed(() => store.getters.selectedFeatures) watch(selectedFeatures, (newSelectedFeatures) => { /* If the store doesn't contain any more feature, we clear our local variable on that topic @@ -55,6 +56,13 @@ watch(currentlySelectedFeature, (newFeature, oldFeature) => { // as the store feature is edited editableFeature.on('change:style', onFeatureChange) store.dispatch('setSelectedFeatures', { features: [editableFeature], ...dispatcher }) + if ( + [EditableFeatureTypes.MEASURE, EditableFeatureTypes.LINEPOLYGON].includes( + editableFeature.featureType + ) + ) { + store.dispatch('setProfileFeature', { feature: editableFeature, ...dispatcher }) + } } else { store.dispatch('clearAllSelectedFeatures', dispatcher) } diff --git a/src/modules/drawing/components/DrawingTooltip.vue b/src/modules/drawing/components/DrawingTooltip.vue index b1fd9e852..65bcabbe1 100644 --- a/src/modules/drawing/components/DrawingTooltip.vue +++ b/src/modules/drawing/components/DrawingTooltip.vue @@ -20,7 +20,7 @@ const store = useStore() const tooltipText = ref('') const drawingTooltip = ref(null) -const selectedFeatures = computed(() => store.state.features.selectedFeatures) +const selectedFeatures = computed(() => store.getters.selectedFeatures) const drawingMode = computed(() => store.state.drawing.mode) const tooltipOverlay = new Overlay({ diff --git a/src/modules/drawing/components/SharePopup.vue b/src/modules/drawing/components/SharePopup.vue index 8f06471fa..d3ed4dbf6 100644 --- a/src/modules/drawing/components/SharePopup.vue +++ b/src/modules/drawing/components/SharePopup.vue @@ -82,7 +82,7 @@ export default { }, adminUrl() { if (this.kmlLayerId && this.kmlAdminId) { - const query = { layers: `${this.kmlLayerId}@adminId=${this.kmlAdminId}` } + const query = { layers: `KML|${this.kmlLayerId}@adminId=${this.kmlAdminId}` } return `${this.baseUrl}?${stringifyQuery(query)}` } // if no adminID is available don't show the edit share link. diff --git a/src/modules/i18n/locales/de.json b/src/modules/i18n/locales/de.json index 4594ac47b..bc6b618bd 100644 --- a/src/modules/i18n/locales/de.json +++ b/src/modules/i18n/locales/de.json @@ -464,7 +464,8 @@ "swisstopo": "swisstopo", "swisstopo_service_link_href": "https://www.swisstopo.admin.ch/de/home.html", "swisstopo_service_link_label": "Bundesamt für Landestopografie swisstopo", - "test_host_warning": "TESTSEITE – NICHT TEILEN - NICHT FÜR PRODUKTIVEN GEBRAUCH
Diese Seite dient ausschliesslich Testzwecken und sollte nicht operativ eingesetzt werden. Es gibt seitens Betreiber dieser Seite keine Garantie für fehlerfreien Inhalt und störungsfreien Betrieb.", + "test_host_warning": "TESTSEITE – NICHT TEILEN - NICHT FÜR PRODUKTIVEN GEBRAUCH", + "test_host_full_disclaimer": "Diese Seite dient ausschliesslich Testzwecken und sollte nicht operativ eingesetzt werden. Es gibt seitens Betreiber dieser Seite keine Garantie für fehlerfreien Inhalt und störungsfreien Betrieb.", "text_to_display": "Link Beschreibung", "third_party_data_warning": "Warnung: diese Daten kommen von einem Drittanbieter. Dieser Permalink zeigt möglicherweise auf Daten eines Drittanbieters. Wollen Sie diese Daten dennoch laden?", "tile": "Kartenblatt", @@ -652,5 +653,9 @@ "kml_gpx_file_empty": "Die KML/GPX-Datei ist leer", "large_size": "Gross", "extra_large_size": "Extra Gross", - "duplicate_layer": "Karte duplizieren" + "duplicate_layer": "Karte duplizieren", + "feedback_empty_warning": "Die Berichtsnachricht darf nicht leer sein", + "operation_successful": "Erfolg!", + "operation_failed": "Hoppla! Etwas ist schiefgegangen. Bitte versuchen Sie es erneut.", + "operation_aborted": "Operation abgebrochen" } diff --git a/src/modules/i18n/locales/en.json b/src/modules/i18n/locales/en.json index db22d9684..137ecb61b 100644 --- a/src/modules/i18n/locales/en.json +++ b/src/modules/i18n/locales/en.json @@ -464,7 +464,8 @@ "swisstopo": "swisstopo", "swisstopo_service_link_href": "https://www.swisstopo.admin.ch/en/home.html", "swisstopo_service_link_label": "Federal Office of Topography swisstopo", - "test_host_warning": "TESTSITE – DO NOT-SHARE - NOT FOR OPERATIONAL USE
This site is for testing purposes only. It's not for operational use and there's no guarantee by the provider of this site.", + "test_host_warning": "TESTSITE – DO NOT-SHARE - NOT FOR OPERATIONAL USE", + "test_host_full_disclaimer": "This site is for testing purposes only. It's not for operational use and there's no guarantee by the provider of this site.", "text_to_display": "Link description", "third_party_data_warning": "Warning: Third party data and/or style shown. The permalink you use contains possibly reference to third party data. Would your really load these data?", "tile": "Sheet", @@ -652,5 +653,9 @@ "kml_gpx_file_empty": "KML/GPX file is empty", "large_size": "Large", "extra_large_size": "Extra Large", - "duplicate_layer": "Duplicate map" + "duplicate_layer": "Duplicate map", + "feedback_empty_warning": "Report message can not be empty", + "operation_successful": "Operation successful!", + "operation_failed": "Oops! Something went wrong. Please try again.", + "operation_aborted": "Operation aborted" } diff --git a/src/modules/i18n/locales/fr.json b/src/modules/i18n/locales/fr.json index 7579da434..6b16b2bdb 100644 --- a/src/modules/i18n/locales/fr.json +++ b/src/modules/i18n/locales/fr.json @@ -464,7 +464,8 @@ "swisstopo": "swisstopo", "swisstopo_service_link_href": "https://www.swisstopo.admin.ch/fr/home.html", "swisstopo_service_link_label": "Office fédéral de topographie swisstopo", - "test_host_warning": "TESTSITE – DO NOT-SHARE - NOT FOR OPERATIONAL USE
This site is for testing purposes only. It's not meant for operational use and there's no guarantee whatsoever.", + "test_host_warning": "SITE DE TEST - NE PAS PARTAGER - NE PAS UTILISER À DES FINS OPÉRATIONNELLES", + "test_host_full_disclaimer": "Ce site est destiné à être testé uniquement. Il n'est pas destiné à une utilisation opérationnelle et il n'y a aucune garantie.", "text_to_display": "Description du lien", "third_party_data_warning": "Mise en garde données tierces. Le permalien que vous utilisez contient peut-être des références à des données tierces ne provenant pas de map.geo.admin.ch. Voulez-vous également visualiser ces données sachant que map.geo.admin.ch ne prend aucune responsabilité quant à ces données?", "tile": "Feuille", @@ -652,5 +653,9 @@ "kml_gpx_file_empty": "Le fichier KML/GPX est vide", "large_size": "Grande", "extra_large_size": "Très Grande", - "duplicate_layer": "Duplication de carte" + "duplicate_layer": "Duplication de carte", + "feedback_empty_warning": "Le message ne peut pas être vide", + "operation_successful": "Succès !", + "operation_failed": "Oups ! Quelque chose s'est mal passé. Veuillez réessayer.", + "operation_aborted": "Opération annulée" } diff --git a/src/modules/i18n/locales/it.json b/src/modules/i18n/locales/it.json index c355715ef..ff0ca8336 100644 --- a/src/modules/i18n/locales/it.json +++ b/src/modules/i18n/locales/it.json @@ -464,7 +464,8 @@ "swisstopo": "swisstopo", "swisstopo_service_link_href": "https://www.swisstopo.admin.ch/it/home.html", "swisstopo_service_link_label": "Ufficio federale di topografia swisstopo ", - "test_host_warning": "TESTSITE – DO NOT-SHARE - NOT FOR OPERATIONAL USE
This site is for testing purposes only. It's not meant for operational use and there's no guarantee whatsoever.", + "test_host_warning": "SITO DI PROVA - NON CONDIVIDERE - NON PER USO OPERATIVO", + "test_host_full_disclaimer": "Questo sito è solo a scopo di test. Non è destinato all'uso operativo e non vi è alcuna garanzia.", "text_to_display": "Descrizione del link", "third_party_data_warning": "Attenzione: questi dati provengono da terze parti. Il permalink usato fa riferimento probabilmente a dati di terze parti. Volete veramente caricare questi dati?", "tile": "Foglio", @@ -652,5 +653,9 @@ "kml_gpx_file_empty": "Il file KML/GPX è vuoto", "large_size": "Grande", "extra_large_size": "Extra Grande", - "duplicate_layer": "Mappa duplicata" + "duplicate_layer": "Mappa duplicata", + "feedback_empty_warning": "Il messaggio di segnalazione non può essere vuoto", + "operation_successful": "Successo!", + "operation_failed": "Oops! Qualcosa è andato storto. Si prega di riprovare.", + "operation_aborted": "Operazione annullata." } diff --git a/src/modules/i18n/locales/rm.json b/src/modules/i18n/locales/rm.json index 1d4898329..88724ca42 100644 --- a/src/modules/i18n/locales/rm.json +++ b/src/modules/i18n/locales/rm.json @@ -462,7 +462,8 @@ "swisstopo": "swisstopo", "swisstopo_service_link_href": "https://www.swisstopo.admin.ch/de/home.html", "swisstopo_service_link_label": "Uffizi federal da topografia swisstopo", - "test_host_warning": "PAGINA DA TEST ? BETG PARTER – BETG PER IL DIEVER PRODUCTIV
Questa pagina è fatga mo per intents da test e na duess betg vegnir duvrada en conturns productivs. I na dat absolutamain nagina garanzia per il diever.", + "test_host_warning": "PAGINA DA TEST ? BETG PARTER – BETG PER IL DIEVER PRODUCTIV", + "test_host_full_disclaimer": "Questa pagina è fatga mo per intents da test e na duess betg vegnir duvrada en conturns productivs. I na dat absolutamain nagina garanzia per il diever.", "text_to_display": "Descripziun link", "third_party_data_warning": "Attenziun: questas datas e/u stil derivan d'in terz purschider. Quest permalink va eventualmain sin datas d'in terz purschider. Vulais Vus tuttina chargiar questas datas?", "tile": "Fegl da la charta", @@ -650,5 +651,9 @@ "kml_gpx_file_empty": "La datoteca KML/GPX è vegnida empruva", "large_size": "Grond", "extra_large_size": "Extra Grond", - "duplicate_layer": "Mapa duplicada" + "duplicate_layer": "Mapa duplicada", + "feedback_empty_warning": "La messadi dal raport po betg esser vegnida lasciada basa", + "operation_successful": "Success! ", + "operation_failed": "Oops! Qualche cosa è andada schabetg. Per favur, retentas.", + "operation_aborted": "Operaziun avorta" } diff --git a/src/modules/infobox/InfoboxModule.vue b/src/modules/infobox/InfoboxModule.vue index fb28f559f..1ce08652b 100644 --- a/src/modules/infobox/InfoboxModule.vue +++ b/src/modules/infobox/InfoboxModule.vue @@ -3,11 +3,9 @@ import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' import { computed, nextTick, ref, watch } from 'vue' import { useStore } from 'vuex' -import { EditableFeatureTypes } from '@/api/features/EditableFeature.class' import { FeatureInfoPositions } from '@/store/modules/ui.store' import promptUserToPrintHtmlContent from '@/utils/print' -import FeatureCombo from './components/FeatureCombo.vue' import FeatureEdit from './components/FeatureEdit.vue' import FeatureElevationProfile from './components/FeatureElevationProfile.vue' import FeatureList from './components/FeatureList.vue' @@ -17,29 +15,25 @@ const showContent = ref(true) const content = ref(null) const store = useStore() -const selectedFeatures = computed(() => store.state.features.selectedFeatures) -const bottomPanelFeatureInfo = computed(() => store.getters.bottomPanelFeatureInfo) -const tooltipFeatureInfo = computed(() => store.getters.tooltipFeatureInfo) +const selectedFeatures = computed(() => store.getters.selectedFeatures) +const showFeatureInfoInBottomPanel = computed(() => store.getters.showFeatureInfoInBottomPanel) +const showFeatureInfoInTooltip = computed(() => store.getters.showFeatureInfoInTooltip) const showDrawingOverlay = computed(() => store.state.ui.showDrawingOverlay) -const projection = computed(() => store.state.position.projection) const selectedFeature = computed(() => selectedFeatures.value[0]) -const isEdit = computed(() => selectedFeature.value?.isEditable) +const isSelectedFeatureEditable = computed(() => selectedFeature.value?.isEditable) -const showElevationProfile = computed(() => - [EditableFeatureTypes.LINEPOLYGON, EditableFeatureTypes.MEASURE].includes( - selectedFeature.value?.featureType - ) -) +const showElevationProfile = computed(() => store.state.features.profileFeature !== null) const showContainer = computed(() => { return ( selectedFeatures.value.length > 0 && - (bottomPanelFeatureInfo.value || (showElevationProfile.value && tooltipFeatureInfo.value)) + (showFeatureInfoInBottomPanel.value || + (showElevationProfile.value && showFeatureInfoInTooltip.value)) ) }) -const showTooltipToggle = computed(() => bottomPanelFeatureInfo.value) +const showTooltipToggle = computed(() => showFeatureInfoInBottomPanel.value) watch(selectedFeatures, (features) => { if (features.length === 0) { @@ -56,7 +50,7 @@ function onToggleContent() { } function setTooltipInfoPosition() { store.dispatch('setFeatureInfoPosition', { - featureInfo: FeatureInfoPositions.TOOLTIP, + position: FeatureInfoPositions.TOOLTIP, ...dispatcher, }) } @@ -65,6 +59,7 @@ function onPrint() { } function onClose() { store.dispatch('clearAllSelectedFeatures', dispatcher) + store.dispatch('clearClick', dispatcher) } @@ -100,29 +95,13 @@ function onClose() {
- - - - + - - +
diff --git a/src/modules/infobox/components/FeatureDetail.vue b/src/modules/infobox/components/FeatureDetail.vue index e0488c1e8..e5aa2824f 100644 --- a/src/modules/infobox/components/FeatureDetail.vue +++ b/src/modules/infobox/components/FeatureDetail.vue @@ -46,7 +46,6 @@ function sanitizeHtml(htmlText) {
-
{{ feature.title }}
{{ i18n.t(key) }}
@@ -84,10 +83,7 @@ function sanitizeHtml(htmlText) { text-align: start; } :global(.htmlpopup-header) { - background-color: $gainsboro; - padding: 7px; - margin-bottom: 7px; - font-weight: 700; + display: none; } :global(.htmlpopup-content) { padding: 7px; diff --git a/src/modules/infobox/components/FeatureElevationProfile.vue b/src/modules/infobox/components/FeatureElevationProfile.vue index e69a5133c..f4bf31eb3 100644 --- a/src/modules/infobox/components/FeatureElevationProfile.vue +++ b/src/modules/infobox/components/FeatureElevationProfile.vue @@ -1,18 +1,96 @@ + + - - diff --git a/src/modules/infobox/components/FeatureList.vue b/src/modules/infobox/components/FeatureList.vue index 476b32b32..f1f89b6b6 100644 --- a/src/modules/infobox/components/FeatureList.vue +++ b/src/modules/infobox/components/FeatureList.vue @@ -1,100 +1,92 @@ diff --git a/src/modules/infobox/components/FeatureListCategory.vue b/src/modules/infobox/components/FeatureListCategory.vue new file mode 100644 index 000000000..fb418ff54 --- /dev/null +++ b/src/modules/infobox/components/FeatureListCategory.vue @@ -0,0 +1,55 @@ + + + + + \ No newline at end of file diff --git a/src/modules/infobox/components/FeatureListCategoryItem.vue b/src/modules/infobox/components/FeatureListCategoryItem.vue new file mode 100644 index 000000000..846977aa2 --- /dev/null +++ b/src/modules/infobox/components/FeatureListCategoryItem.vue @@ -0,0 +1,150 @@ + + + + + diff --git a/src/modules/infobox/components/ShowGeometryProfileButton.vue b/src/modules/infobox/components/ShowGeometryProfileButton.vue new file mode 100644 index 000000000..81a40b2b6 --- /dev/null +++ b/src/modules/infobox/components/ShowGeometryProfileButton.vue @@ -0,0 +1,32 @@ + + + diff --git a/src/modules/map/components/MapPopover.vue b/src/modules/map/components/MapPopover.vue index 7e6035958..00f58d8cc 100644 --- a/src/modules/map/components/MapPopover.vue +++ b/src/modules/map/components/MapPopover.vue @@ -96,7 +96,6 @@ export default { position: absolute; z-index: $zindex-map + 1; .card { - max-width: $overlay-width; min-width: $overlay-width; pointer-events: auto; } diff --git a/src/modules/map/components/cesium/CesiumMap.vue b/src/modules/map/components/cesium/CesiumMap.vue index 25262086e..17c98e82e 100644 --- a/src/modules/map/components/cesium/CesiumMap.vue +++ b/src/modules/map/components/cesium/CesiumMap.vue @@ -64,7 +64,7 @@ - + state.position.camera, uiMode: (state) => state.ui.mode, previewYear: (state) => state.layers.previewYear, - selectedFeatures: (state) => state.features.selectedFeatures, projection: (state) => state.position.projection, isFullScreenMode: (state) => state.ui.fullscreenMode, }), ...mapGetters([ + 'selectedFeatures', 'centerEpsg4326', 'resolution', 'hasDevSiteWarning', 'visibleLayers', 'backgroundLayersFor3D', - 'tooltipFeatureInfo', + 'showFeatureInfoInTooltip', ]), isProjectionWebMercator() { return this.projection.epsg === WEBMERCATOR.epsg @@ -193,7 +193,7 @@ export default { ) }, isFeatureInfoInTooltip() { - return this.tooltipFeatureInfo + return this.showFeatureInfoInTooltip }, visiblePrimitiveLayers() { return this.visibleLayers.filter( @@ -295,6 +295,7 @@ export default { 'setCameraPosition', 'clearAllSelectedFeatures', 'click', + 'clearClick', 'setFeatureInfoPosition', 'setCenter', 'mapModuleReady', @@ -575,6 +576,7 @@ export default { onPopupClose() { unhighlightGroup(this.viewer) this.clearAllSelectedFeatures(dispatcher) + this.clearClick(dispatcher) }, onTouchStart(event) { this.clearLongPressTimer() @@ -609,7 +611,7 @@ export default { }, setBottomPanelFeatureInfoPosition() { this.setFeatureInfoPosition({ - featureInfo: FeatureInfoPositions.BOTTOMPANEL, + position: FeatureInfoPositions.BOTTOMPANEL, ...dispatcher, }) }, diff --git a/src/modules/map/components/cesium/CesiumWMSLayer.vue b/src/modules/map/components/cesium/CesiumWMSLayer.vue index d3b360006..c2fd232c2 100644 --- a/src/modules/map/components/cesium/CesiumWMSLayer.vue +++ b/src/modules/map/components/cesium/CesiumWMSLayer.vue @@ -42,7 +42,7 @@ export default { currentLang: (state) => state.i18n.lang, }), layerId() { - return this.wmsLayerConfig.technicalName || this.wmsLayerConfig.externalLayerId + return this.wmsLayerConfig.technicalName || this.wmsLayerConfig.id }, opacity() { return this.wmsLayerConfig.opacity || 1.0 diff --git a/src/modules/map/components/cesium/utils/olcs/FeatureConverter.ts b/src/modules/map/components/cesium/utils/olcs/FeatureConverter.ts index a57c300ce..bbe7cd939 100644 --- a/src/modules/map/components/cesium/utils/olcs/FeatureConverter.ts +++ b/src/modules/map/components/cesium/utils/olcs/FeatureConverter.ts @@ -74,6 +74,7 @@ import type ImageStyle from 'ol/style/Image' import type { default as Style, StyleFunction } from 'ol/style/Style' import type { VectorSourceEvent } from 'ol/source/Vector' import VectorSource from 'ol/source/Vector' +import type { Size } from 'ol/size' type ModelFromGltfOptions = Parameters[0] @@ -200,17 +201,17 @@ export default class FeatureConverter { feature: Feature, olGeometry: OLGeometry, geometry: CSGeometry | CircleGeometry, - color: CesiumColor | ImageMaterialProperty, + color?: CesiumColor, opt_lineWidth?: number ): Primitive | GroundPrimitive | null { const createInstance = function ( geometry: CSGeometry | CircleGeometry, - color: CesiumColor | ImageMaterialProperty + color?: CesiumColor ) { const instance = new GeometryInstance({ geometry, }) - if (color && !(color instanceof ImageMaterialProperty)) { + if (color) { instance.attributes = { color: ColorGeometryInstanceAttribute.fromColor(color), } @@ -251,29 +252,7 @@ export default class FeatureConverter { }) } - if (color instanceof ImageMaterialProperty) { - // FIXME: we created stylings which are not time related - // What should we pass here? - // @ts-ignore - const dataUri = color.image.getValue().toDataURL() - - primitive.appearance = new MaterialAppearance({ - flat: true, - renderState: { - depthTest: { - enabled: true, - }, - }, - material: new Material({ - fabric: { - type: 'Image', - uniforms: { - image: dataUri, - }, - }, - }), - }) - } else { + if (color) { primitive.appearance = new MaterialAppearance({ ...options, material: new Material({ @@ -302,9 +281,9 @@ export default class FeatureConverter { * * @param style * @param outline - * @returns {!CesiumColor} + * @returns {CesiumColor | undefined} */ - protected extractColorFromOlStyle(style: Style | Text, outline: boolean) { + protected extractColorFromOlStyle(style: Style | Text, outline: boolean) : CesiumColor | undefined { const fillColor: OLColorLike | OLColor | PatternDescriptor | null | undefined = style .getFill() ?.getColor() @@ -317,7 +296,15 @@ export default class FeatureConverter { olColor = fillColor } - return convertColorToCesium(olColor) + const cesiumColor: CesiumColor | ImageMaterialProperty = convertColorToCesium(olColor) + if (cesiumColor instanceof ImageMaterialProperty) { + if (cesiumColor.color instanceof CesiumColor) { + return cesiumColor.color + } else { + return undefined + } + } + return cesiumColor } /** @@ -343,8 +330,8 @@ export default class FeatureConverter { olStyle: Style, outlineGeometry?: CSGeometry | CircleOutlineGeometry ): PrimitiveCollection { - const fillColor = this.extractColorFromOlStyle(olStyle, false) - const outlineColor = this.extractColorFromOlStyle(olStyle, true) + const fillColor : CesiumColor | undefined = this.extractColorFromOlStyle(olStyle, false) + const outlineColor : CesiumColor | undefined = this.extractColorFromOlStyle(olStyle, true) const primitives = new PrimitiveCollection() if (olStyle.getFill()) { @@ -427,13 +414,13 @@ export default class FeatureConverter { */ csAddBillboard( billboards: BillboardCollection, - bbOptions: Parameters[0], + bbOptions: Parameters[0] | undefined, layer: PrimitiveLayer, feature: Feature, geometry: OLGeometry, style: Style ): Billboard { - if (!bbOptions.eyeOffset) { + if (bbOptions && !bbOptions.eyeOffset) { bbOptions.eyeOffset = this.defaultBillboardEyeOffset_ } const bb = billboards.add(bbOptions) @@ -787,7 +774,7 @@ export default class FeatureConverter { imageStyle.load() } - const image = imageStyle.getImage(1) // get normal density + const image : HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | ImageBitmap | null = imageStyle.getImage(1) // get normal density const isImageLoaded = function (image: HTMLImageElement) { return ( image.src != '' && @@ -803,9 +790,8 @@ export default class FeatureConverter { } if ( !( - image instanceof HTMLCanvasElement || - image instanceof Image || - image instanceof HTMLImageElement + typeof image === 'string' || + image instanceof HTMLCanvasElement ) ) { return @@ -818,7 +804,10 @@ export default class FeatureConverter { color = new CesiumColor(1.0, 1.0, 1.0, opacity) } - const scale = imageStyle.getScale() + const scale : number | Size = imageStyle.getScale() + if (Array.isArray(scale)) { + return + } const heightReference = self.getHeightReference(layer, feature, olGeometry) const bbOptions: Parameters[0] = { @@ -1079,8 +1068,8 @@ export default class FeatureConverter { geometry: OLGeometry, style: Text ): LabelCollection | null { - const text = style.getText() - if (!text) { + const text : string | string[] | undefined = style.getText() + if (!text || Array.isArray(text)) { return null } @@ -1092,19 +1081,16 @@ export default class FeatureConverter { const first = geometry.getFirstCoordinate() extentCenter[2] = first.length == 3 ? first[2] : 0.0 } - const options: Parameters[0] = {} - - options.position = ol4326CoordinateToCesiumCartesian(extentCenter) - - options.text = text - - options.heightReference = this.getHeightReference(layer, feature, geometry) + const options: Parameters[0] = { + position: ol4326CoordinateToCesiumCartesian(extentCenter), + text, + heightReference: this.getHeightReference(layer, feature, geometry) + } const offsetX = style.getOffsetX() const offsetY = style.getOffsetY() if (offsetX != 0 || offsetY != 0) { - const offset = new Cartesian2(offsetX, offsetY) - options.pixelOffset = offset + options.pixelOffset = new Cartesian2(offsetX, offsetY) } options.font = style.getFont() || '10px sans-serif' // OpenLayers default diff --git a/src/modules/map/components/common/z-index.composable.js b/src/modules/map/components/common/z-index.composable.js index a8c5408a5..1c7695cc5 100644 --- a/src/modules/map/components/common/z-index.composable.js +++ b/src/modules/map/components/common/z-index.composable.js @@ -14,7 +14,7 @@ export function useLayerZIndexCalculation() { } return [store.state.layers.currentBackgroundLayer] }) - const selectedFeatures = computed(() => store.state.features.selectedFeatures) + const selectedFeatures = computed(() => store.getters.selectedFeatures) const pinnedLocation = computed(() => store.state.map.pinnedLocation) const previewLocation = computed(() => store.state.map.previewedPinnedLocation) const crossHair = computed(() => store.state.position.crossHair) diff --git a/src/modules/map/components/openlayers/OpenLayersExternalWMTSLayer.vue b/src/modules/map/components/openlayers/OpenLayersExternalWMTSLayer.vue index 8dd16cd86..ef512a3da 100644 --- a/src/modules/map/components/openlayers/OpenLayersExternalWMTSLayer.vue +++ b/src/modules/map/components/openlayers/OpenLayersExternalWMTSLayer.vue @@ -31,7 +31,7 @@ const store = useStore() const projection = computed(() => store.state.position.projection) // extracting useful info from what we've linked so far -const layerId = computed(() => externalWmtsLayerConfig.value.externalLayerId) +const layerId = computed(() => externalWmtsLayerConfig.value.id) const opacity = computed(() => parentLayerOpacity.value || externalWmtsLayerConfig.value.opacity) const options = computed(() => externalWmtsLayerConfig.value.options) diff --git a/src/modules/map/components/openlayers/OpenLayersHighlightedFeatures.vue b/src/modules/map/components/openlayers/OpenLayersHighlightedFeatures.vue index 0d18187fe..b9b7c5238 100644 --- a/src/modules/map/components/openlayers/OpenLayersHighlightedFeatures.vue +++ b/src/modules/map/components/openlayers/OpenLayersHighlightedFeatures.vue @@ -28,19 +28,15 @@ const dispatcher = { dispatcher: 'OpenLayersHighlightedFeatures.vue' } // mapping relevant store values const store = useStore() -const selectedFeatures = computed(() => store.state.features.selectedFeatures) +const selectedFeatures = computed(() => store.getters.selectedFeatures) +const selectedEditableFeatures = computed(() => store.state.features.selectedEditableFeatures) +const selectedLayerFeatures = computed(() => store.getters.selectedLayerFeatures) const isCurrentlyDrawing = computed(() => store.state.ui.showDrawingOverlay) const projection = computed(() => store.state.position.projection) const highlightedFeatureId = computed(() => store.state.features.highlightedFeatureId) -const tooltipFeatureInfo = computed(() => store.getters.tooltipFeatureInfo) +const tooltipFeatureInfo = computed(() => store.getters.showFeatureInfoInTooltip) const tooltipIsInDefaultPosition = computed( - () => store.state.ui.FeatureInfoPosition === FeatureInfoPositions.DEFAULT -) -const editableFeatures = computed(() => - selectedFeatures.value.filter((feature) => feature.isEditable) -) -const nonEditableFeature = computed(() => - selectedFeatures.value.filter((feature) => !feature.isEditable) + () => store.state.ui.featureInfoPosition === FeatureInfoPositions.DEFAULT ) const featureTransformedAsOlFeatures = computed(() => { // While drawing module is active, we do not want any other feature as the editable one highlighted. @@ -49,7 +45,7 @@ const featureTransformedAsOlFeatures = computed(() => { if (isCurrentlyDrawing.value) { return [] } - return nonEditableFeature.value.map((feature) => { + return selectedLayerFeatures.value.map((feature) => { return new Feature({ id: `geom-${randomIntBetween(0, 100000)}`, geometry: new GeoJSON().readGeometry(feature.geometry), @@ -61,8 +57,8 @@ const featureTransformedAsOlFeatures = computed(() => { const southPole = point([0.0, -90.0]) const popoverCoordinate = computed(() => { // if we are dealing with any editable feature while drawing, we return its last coordinate - if (isCurrentlyDrawing.value && editableFeatures.value.length > 0) { - const [topEditableFeature] = editableFeatures.value + if (isCurrentlyDrawing.value && selectedEditableFeatures.value.length > 0) { + const [topEditableFeature] = selectedEditableFeatures.value return topEditableFeature.lastCoordinate } // If no editable feature is selected while drawing, we place the popover depending on the geometry of all @@ -92,15 +88,15 @@ const popoverCoordinate = computed(() => { // When new features are selected, if some of them have a complex geometry (polygon or line) we switch to // the "infobox" (non-floating) tooltip by default. // This should avoid the popup window to be out of screen if one of the selected features spreads too much south. -watch(nonEditableFeature, () => { +watch(selectedLayerFeatures, () => { const containsOnlyPoints = - nonEditableFeature.value.filter((feature) => + selectedLayerFeatures.value.filter((feature) => ['Point', 'MultiPoint'].includes(feature.geometry?.type) - ).length === nonEditableFeature.value.length + ).length === selectedLayerFeatures.value.length if (tooltipFeatureInfo.value && tooltipIsInDefaultPosition.value && !containsOnlyPoints) { // check if we're in default store.dispatch('setFeatureInfoPosition', { - featureInfo: FeatureInfoPositions.BOTTOMPANEL, + position: FeatureInfoPositions.BOTTOMPANEL, dispatcher: dispatcher, }) } @@ -117,10 +113,11 @@ useVectorLayer( function clearAllSelectedFeatures() { store.dispatch('clearAllSelectedFeatures', dispatcher) + store.dispatch('clearClick', dispatcher) } function setBottomPanelFeatureInfoPosition() { store.dispatch('setFeatureInfoPosition', { - featureInfo: FeatureInfoPositions.BOTTOMPANEL, + position: FeatureInfoPositions.BOTTOMPANEL, ...dispatcher, }) } @@ -131,7 +128,7 @@ function setBottomPanelFeatureInfoPosition() { v-if="tooltipFeatureInfo && selectedFeatures.length > 0" :coordinates="popoverCoordinate" authorize-print - :use-content-padding="editableFeatures.length > 0" + :use-content-padding="selectedEditableFeatures.length > 0" @close="clearAllSelectedFeatures" > - + diff --git a/src/modules/map/components/openlayers/OpenLayersMap.vue b/src/modules/map/components/openlayers/OpenLayersMap.vue index e2d71c9b5..f25624c7d 100644 --- a/src/modules/map/components/openlayers/OpenLayersMap.vue +++ b/src/modules/map/components/openlayers/OpenLayersMap.vue @@ -13,6 +13,7 @@ import OpenLayersCrossHair from '@/modules/map/components/openlayers/OpenLayersC import OpenLayersGeolocationFeedback from '@/modules/map/components/openlayers/OpenLayersGeolocationFeedback.vue' import OpenLayersHighlightedFeature from '@/modules/map/components/openlayers/OpenLayersHighlightedFeatures.vue' import OpenLayersPinnedLocation from '@/modules/map/components/openlayers/OpenLayersPinnedLocation.vue' +import OpenLayersRectangleSelectionFeedback from '@/modules/map/components/openlayers/OpenLayersRectangleSelectionFeedback.vue' import OpenLayersVisibleLayers from '@/modules/map/components/openlayers/OpenLayersVisibleLayers.vue' import useMapInteractions from '@/modules/map/components/openlayers/utils/useMapInteractions.composable' import usePrintAreaRenderer from '@/modules/map/components/openlayers/utils/usePrintAreaRenderer.composable' @@ -72,6 +73,7 @@ const { zIndexTileInfo, zIndexLayerExtents } = useLayerZIndexCalculation() + @@ -92,8 +94,13 @@ const { zIndexTileInfo, zIndexLayerExtents } = useLayerZIndexCalculation() z-index: $zindex-map; } +$dragbox-width: 3px; +// Show selected area when shift click + drag on map +:global(.ol-dragzoom) { + border: $dragbox-width solid $malibu; +} +// Show selected area when ctrl click + drag on map :global(.ol-dragbox) { - border: 3px solid $info; - border-radius: 2px; + border: $dragbox-width solid $red; } diff --git a/src/modules/map/components/openlayers/OpenLayersMouseTracker.vue b/src/modules/map/components/openlayers/OpenLayersMouseTracker.vue index e9f29b845..5b0662d43 100644 --- a/src/modules/map/components/openlayers/OpenLayersMouseTracker.vue +++ b/src/modules/map/components/openlayers/OpenLayersMouseTracker.vue @@ -78,17 +78,12 @@ function setDisplayedFormatWithId() { diff --git a/src/modules/menu/components/header/HeaderWithSearch.vue b/src/modules/menu/components/header/HeaderWithSearch.vue index f937fd3b4..328252170 100644 --- a/src/modules/menu/components/header/HeaderWithSearch.vue +++ b/src/modules/menu/components/header/HeaderWithSearch.vue @@ -25,7 +25,7 @@
- +
@@ -45,8 +45,8 @@ import LangSwitchToolbar from '@/modules/i18n/components/LangSwitchToolbar.vue' import HeaderMenuButton from '@/modules/menu/components/header/HeaderMenuButton.vue' import HeaderSwissConfederationText from '@/modules/menu/components/header/HeaderSwissConfederationText.vue' import SwissFlag from '@/modules/menu/components/header/SwissFlag.vue' -import FeedbackToolbar from '@/modules/menu/components/menu/feedback/FeedbackToolbar.vue' import SearchBar from '@/modules/menu/components/search/SearchBar.vue' +import LinksToolbar from '@/modules/menu/components/settings/LinksToolbar.vue' const dispatcher = { dispatcher: 'HeaderWithSearch.vue' } @@ -57,7 +57,7 @@ export default { HeaderSwissConfederationText, SwissFlag, LangSwitchToolbar, - FeedbackToolbar, + LinksToolbar, }, computed: { ...mapState({ diff --git a/src/modules/menu/components/menu/MenuSettings.vue b/src/modules/menu/components/menu/MenuSettings.vue deleted file mode 100644 index 0a6c7dab6..000000000 --- a/src/modules/menu/components/menu/MenuSettings.vue +++ /dev/null @@ -1,26 +0,0 @@ - - - diff --git a/src/modules/menu/components/menu/MenuTray.vue b/src/modules/menu/components/menu/MenuTray.vue index 4972095a2..65b430e06 100644 --- a/src/modules/menu/components/menu/MenuTray.vue +++ b/src/modules/menu/components/menu/MenuTray.vue @@ -72,8 +72,8 @@ import { mapActions, mapGetters, mapState } from 'vuex' import MenuActiveLayersList from '@/modules/menu/components/activeLayers/MenuActiveLayersList.vue' import MenuAdvancedToolsList from '@/modules/menu/components/advancedTools/MenuAdvancedToolsList.vue' import MenuSection from '@/modules/menu/components/menu/MenuSection.vue' -import MenuSettings from '@/modules/menu/components/menu/MenuSettings.vue' import MenuPrintSection from '@/modules/menu/components/print/MenuPrintSection.vue' +import MenuSettings from '@/modules/menu/components/settings/MenuSettings.vue' import MenuShareSection from '@/modules/menu/components/share/MenuShareSection.vue' import MenuTopicSection from '@/modules/menu/components/topics/MenuTopicSection.vue' diff --git a/src/modules/menu/components/menu/MoreInfo.vue b/src/modules/menu/components/menu/MoreInfo.vue deleted file mode 100644 index 8c716d047..000000000 --- a/src/modules/menu/components/menu/MoreInfo.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - diff --git a/src/modules/menu/components/menu/feedback/FeedbackButton.vue b/src/modules/menu/components/menu/feedback/FeedbackButton.vue deleted file mode 100644 index c065359f4..000000000 --- a/src/modules/menu/components/menu/feedback/FeedbackButton.vue +++ /dev/null @@ -1,199 +0,0 @@ - - - - - diff --git a/src/modules/menu/components/menu/feedback/FeedbackRating.vue b/src/modules/menu/components/menu/feedback/FeedbackRating.vue deleted file mode 100644 index 2ac9fc8a7..000000000 --- a/src/modules/menu/components/menu/feedback/FeedbackRating.vue +++ /dev/null @@ -1,84 +0,0 @@ - - - - - diff --git a/src/modules/menu/components/menu/feedback/FeedbackToolbar.vue b/src/modules/menu/components/menu/feedback/FeedbackToolbar.vue deleted file mode 100644 index e3c0095f2..000000000 --- a/src/modules/menu/components/menu/feedback/FeedbackToolbar.vue +++ /dev/null @@ -1,29 +0,0 @@ - - - diff --git a/src/modules/menu/components/print/MenuPrintSection.vue b/src/modules/menu/components/print/MenuPrintSection.vue index d7a8a5718..1c2a32b30 100644 --- a/src/modules/menu/components/print/MenuPrintSection.vue +++ b/src/modules/menu/components/print/MenuPrintSection.vue @@ -49,6 +49,12 @@ const selectedScale = computed({ }, }) +const printErrorMessage = computed(() => + printStatus.value === PrintStatus.FINISHED_ABORTED + ? i18n.t('operation_aborted') + : i18n.t('operation_failed') +) + watch(isSectionShown, () => { store.dispatch('setPrintSectionShown', { show: isSectionShown.value, ...dispatcher }) }) @@ -90,13 +96,24 @@ async function printMap() { window.location = documentUrl } } else { - log.error('Print failed, received null') + if (printStatus.value === PrintStatus.FINISHED_ABORTED) { + log.debug('Print is aborted by the user') + } else if (printStatus.value === PrintStatus.FINISHED_FAILED) { + log.error('Print failed, received null') + } } } catch (error) { log.error('Print failed', error) } } +function onOpenMenuSection(id) { + if (printStatus.value !== PrintStatus.PRINTING) { + printStatus.value = PrintStatus.IDLE + } + emits('openMenuSection', id) +} + defineExpose({ close, }) @@ -110,7 +127,7 @@ defineExpose({ data-cy="menu-print-section" secondary @click:header="togglePrintMenu" - @open-menu-section="(id) => emits('openMenuSection', id)" + @open-menu-section="onOpenMenuSection" > +
+ +
{{ printErrorMessage }}
+
{{ i18n.t('operation_successful') }}
+
- -
diff --git a/src/modules/menu/components/search/SearchBar.vue b/src/modules/menu/components/search/SearchBar.vue index caa1c704a..0fce903b5 100644 --- a/src/modules/menu/components/search/SearchBar.vue +++ b/src/modules/menu/components/search/SearchBar.vue @@ -52,8 +52,12 @@ const updateSearchQuery = (event) => { }, 100) } -const onSearchInputFocus = () => { - if (hasResults.value) { +const onSearchInputFocus = (event) => { + // When the focus event is due to a programatic focus event, the relatedTarget is not null + // and in this case we don't want to show the result. For example when selecting a result value + // we want to close the result and focus on the input, so that the user can directly change + // the search. + if (!event.relatedTarget && hasResults.value) { showResults.value = true } } @@ -101,6 +105,12 @@ const onClickOutside = (event) => { const focusSearchInput = () => { searchInput.value.focus() } + +const toggleResults = () => { + if (hasResults.value) { + showResults.value = !showResults.value + } +}