diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index e3dcb61ce..d354c062b 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -31,7 +31,7 @@ jobs: - name: Create env file run: | touch website/.env - echo PUBLIC_MAPBOX_TOKEN=${{ secrets.PUBLIC_MAPBOX_TOKEN }} >> website/.env + echo PUBLIC_MAPTILER_KEY=${{ secrets.PUBLIC_MAPTILER_KEY }} >> website/.env cat website/.env - name: Build website diff --git a/README.md b/README.md index bd0960d26..3c1309f37 100644 --- a/README.md +++ b/README.md @@ -42,11 +42,11 @@ npm run build ### Running the website -To be able to load the map, you will need to create your own Mapbox access token and store it in a `.env` file in the `website` directory. +To be able to load the map, you will need to create your own MapTiler key and store it in a `.env` file in the `website` directory. ```bash cd website -echo PUBLIC_MAPBOX_TOKEN={YOUR_MAPBOX_TOKEN} >> .env +echo PUBLIC_MAPTILER_KEY={YOUR_MAPTILER_KEY} >> .env npm install npm run dev ``` @@ -69,9 +69,9 @@ This project has been made possible thanks to the following open source projects - [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) — fast GPX file parsing - [SortableJS](https://github.com/SortableJS/Sortable) — creating a sortable file tree - Mapping: - - [Mapbox GL JS](https://github.com/mapbox/mapbox-gl-js) — beautiful and fast interactive maps + - [MapLibre GL JS](https://github.com/maplibre/maplibre-gl-js) — beautiful and fast interactive map rendering - [GraphHopper](https://github.com/graphhopper/graphhopper) — routing engine - - [OpenStreetMap](https://www.openstreetmap.org) — map data used by Mapbox and GraphHopper + - [OpenStreetMap](https://www.openstreetmap.org) — map data used by most of the map layers, and by the routing engine - Search: - [DocSearch](https://github.com/algolia/docsearch) — search engine for the documentation diff --git a/website/.env.example b/website/.env.example index 4d6b95bd3..dc5ca3183 100644 --- a/website/.env.example +++ b/website/.env.example @@ -1 +1 @@ -PUBLIC_MAPBOX_TOKEN=YOUR_MAPBOX_TOKEN \ No newline at end of file +PUBLIC_MAPTILER_KEY=YOUR_MAPTILER_KEY \ No newline at end of file diff --git a/website/package-lock.json b/website/package-lock.json index a4e6d3904..d94142b80 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -10,10 +10,9 @@ "dependencies": { "@docsearch/js": "^3.9.0", "@internationalized/date": "^3.8.2", - "@mapbox/mapbox-gl-geocoder": "^5.0.3", "@mapbox/sphericalmercator": "^2.0.1", "@mapbox/tilebelt": "^2.0.2", - "@types/mapbox__sphericalmercator": "^1.2.3", + "@maplibre/maplibre-gl-geocoder": "^1.9.4", "chart.js": "^4.5.1", "chartjs-plugin-zoom": "^2.2.0", "clsx": "^2.1.1", @@ -22,9 +21,8 @@ "gpx": "file:../gpx", "immer": "^10.1.1", "jszip": "^3.10.1", - "mapbox-gl": "^3.17.0", "mapillary-js": "^4.1.2", - "png.js": "^0.2.1", + "maplibre-gl": "^5.16.0", "sanitize-html": "^2.17.0", "sortablejs": "^1.15.6", "tailwind-merge": "^3.3.0" @@ -39,10 +37,9 @@ "@types/eslint": "^9.6.1", "@types/events": "^3.0.3", "@types/file-saver": "^2.0.7", + "@types/mapbox__sphericalmercator": "^1.2.3", "@types/mapbox__tilebelt": "^1.0.4", - "@types/mapbox-gl": "^3.4.1", "@types/node": "^22.15.30", - "@types/png.js": "^0.2.3", "@types/sanitize-html": "^2.16.0", "@types/sortablejs": "^1.15.8", "@typescript-eslint/eslint-plugin": "^8.33.1", @@ -329,27 +326,6 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/code-frame": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", - "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.25.9", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@docsearch/css": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.9.0.tgz", @@ -1635,13 +1611,29 @@ "svelte": "^5" } }, - "node_modules/@mapbox/fusspot": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@mapbox/fusspot/-/fusspot-0.4.0.tgz", - "integrity": "sha512-6sys1vUlhNCqMvJOqPEPSi0jc9tg7aJ//oG1A16H3PXoIt9whtNngD7UzBHUVTH15zunR/vRvMtGNVsogm1KzA==", + "node_modules/@mapbox/geojson-rewind": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@mapbox/geojson-rewind/-/geojson-rewind-0.5.2.tgz", + "integrity": "sha512-tJaT+RbYGJYStt7wI3cq4Nl4SXxG8W7JDG5DMJu97V25RnbNg3QtQtf+KD+VLjNpWKYsRvXDNmNrBgEETr1ifA==", + "license": "ISC", "dependencies": { - "is-plain-obj": "^1.1.0", - "xtend": "^4.0.1" + "get-stream": "^6.0.1", + "minimist": "^1.2.6" + }, + "bin": { + "geojson-rewind": "geojson-rewind" + } + }, + "node_modules/@mapbox/geojson-rewind/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@mapbox/jsonlint-lines-primitives": { @@ -1652,71 +1644,12 @@ "node": ">= 0.6" } }, - "node_modules/@mapbox/mapbox-gl-geocoder": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-geocoder/-/mapbox-gl-geocoder-5.0.3.tgz", - "integrity": "sha512-aeu2ZM+UKoMUGqqKy4UVVEKsIaNj2KSsiQ4p4YbNSAjZj2vcP33KSod+DPeRwhvoY+MU6KgyvdZ/1xdmH+C62g==", - "dependencies": { - "@mapbox/mapbox-sdk": "^0.16.1", - "events": "^3.3.0", - "lodash.debounce": "^4.0.6", - "nanoid": "^3.1.31", - "subtag": "^0.5.0", - "suggestions": "^1.6.0", - "xtend": "^4.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@mapbox/mapbox-gl-supported": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-3.0.0.tgz", - "integrity": "sha512-2XghOwu16ZwPJLOFVuIOaLbN0iKMn867evzXFyf0P22dqugezfJwLmdanAgU25ITvz1TvOfVP4jsDImlDJzcWg==" - }, - "node_modules/@mapbox/mapbox-sdk": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/@mapbox/mapbox-sdk/-/mapbox-sdk-0.16.1.tgz", - "integrity": "sha512-dyZrmg+UL/Gp5mGG3CDbcwGSUMYYrfbd9hdp0rcA3pHSf3A9eYoXO9nFiIk6SzBwBVMzHENJz84ZHdqM0MDncQ==", - "dependencies": { - "@mapbox/fusspot": "^0.4.0", - "@mapbox/parse-mapbox-token": "^0.2.0", - "@mapbox/polyline": "^1.0.0", - "eventemitter3": "^3.1.0", - "form-data": "^3.0.0", - "got": "^11.8.5", - "is-plain-obj": "^1.1.0", - "xtend": "^4.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@mapbox/parse-mapbox-token": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@mapbox/parse-mapbox-token/-/parse-mapbox-token-0.2.0.tgz", - "integrity": "sha512-BjeuG4sodYaoTygwXIuAWlZV6zUv4ZriYAQhXikzx+7DChycMUQ9g85E79Htat+AsBg+nStFALehlOhClYm5cQ==", - "dependencies": { - "base-64": "^0.1.0" - } - }, "node_modules/@mapbox/point-geometry": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-1.1.0.tgz", "integrity": "sha512-YGcBz1cg4ATXDCM/71L9xveh4dynfGmcLDqufR+nQQy3fKwsAZsWd/x4621/6uJaeB9mwOHE6hPeDgXz9uViUQ==", "license": "ISC" }, - "node_modules/@mapbox/polyline": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@mapbox/polyline/-/polyline-1.2.1.tgz", - "integrity": "sha512-sn0V18O3OzW4RCcPoUIVDWvEGQaBNH9a0y5lgqrf5hUycyw1CzrhEoxV5irzrMNXKCkw1xRsZXcaVbsVZggHXA==", - "dependencies": { - "meow": "^9.0.0" - }, - "bin": { - "polyline": "bin/polyline.bin.js" - } - }, "node_modules/@mapbox/sphericalmercator": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@mapbox/sphericalmercator/-/sphericalmercator-2.0.1.tgz", @@ -1729,9 +1662,10 @@ "license": "MIT" }, "node_modules/@mapbox/tiny-sdf": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.0.6.tgz", - "integrity": "sha512-qMqa27TLw+ZQz5Jk+RcwZGH7BQf5G/TrutJhspsca/3SHwmgKQ1iq+d3Jxz5oysPVYTGP6aXxCo5Lk9Er6YBAA==" + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.0.7.tgz", + "integrity": "sha512-25gQLQMcpivjOSA40g3gO6qgiFPDpWRoMfd+G/GoppPIeP6JDaMMkMrEJnMZhKyyS6iKwVt5YKu02vCUyJM3Ug==", + "license": "BSD-2-Clause" }, "node_modules/@mapbox/unitbezier": { "version": "0.0.1", @@ -1769,6 +1703,87 @@ "node": ">=6.0.0" } }, + "node_modules/@maplibre/geojson-vt": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@maplibre/geojson-vt/-/geojson-vt-5.0.4.tgz", + "integrity": "sha512-KGg9sma45S+stfH9vPCJk1J0lSDLWZgCT9Y8u8qWZJyjFlP8MNP1WGTxIMYJZjDvVT3PDn05kN1C95Sut1HpgQ==", + "license": "ISC" + }, + "node_modules/@maplibre/maplibre-gl-geocoder": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-geocoder/-/maplibre-gl-geocoder-1.9.4.tgz", + "integrity": "sha512-ss0NMpjUgK1/8YrrikrAtdda41jERiGg+XqwPkj52AhwvQTLZEnZSU7IhqdyuE1FZ/QhlzAauMbyzJUTTxDscw==", + "license": "ISC", + "dependencies": { + "events": "^3.3.0", + "lodash.debounce": "^4.0.6", + "subtag": "^0.5.0", + "suggestions-list": "^0.0.2", + "xtend": "^4.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "maplibre-gl": ">=4.0.0" + } + }, + "node_modules/@maplibre/maplibre-gl-style-spec": { + "version": "24.4.1", + "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-24.4.1.tgz", + "integrity": "sha512-UKhA4qv1h30XT768ccSv5NjNCX+dgfoq2qlLVmKejspPcSQTYD4SrVucgqegmYcKcmwf06wcNAa/kRd0NHWbUg==", + "license": "ISC", + "dependencies": { + "@mapbox/jsonlint-lines-primitives": "~2.0.2", + "@mapbox/unitbezier": "^0.0.1", + "json-stringify-pretty-compact": "^4.0.0", + "minimist": "^1.2.8", + "quickselect": "^3.0.0", + "rw": "^1.3.3", + "tinyqueue": "^3.0.0" + }, + "bin": { + "gl-style-format": "dist/gl-style-format.mjs", + "gl-style-migrate": "dist/gl-style-migrate.mjs", + "gl-style-validate": "dist/gl-style-validate.mjs" + } + }, + "node_modules/@maplibre/mlt": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@maplibre/mlt/-/mlt-1.1.2.tgz", + "integrity": "sha512-SQKdJ909VGROkA6ovJgtHNs9YXV4YXUPS+VaZ50I2Mt951SLlUm2Cv34x5Xwc1HiFlsd3h2Yrs5cn7xzqBmENw==", + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "@mapbox/point-geometry": "^1.1.0" + } + }, + "node_modules/@maplibre/vt-pbf": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@maplibre/vt-pbf/-/vt-pbf-4.2.1.tgz", + "integrity": "sha512-IxZBGq/+9cqf2qdWlFuQ+ZfoMhWpxDUGQZ/poPHOJBvwMUT1GuxLo6HgYTou+xxtsOsjfbcjI8PZaPCtmt97rA==", + "license": "MIT", + "dependencies": { + "@mapbox/point-geometry": "^1.1.0", + "@mapbox/vector-tile": "^2.0.4", + "@maplibre/geojson-vt": "^5.0.4", + "@types/geojson": "^7946.0.16", + "@types/supercluster": "^7.1.3", + "pbf": "^4.0.1", + "supercluster": "^8.0.1" + } + }, + "node_modules/@maplibre/vt-pbf/node_modules/pbf": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pbf/-/pbf-4.0.1.tgz", + "integrity": "sha512-SuLdBvS42z33m8ejRbInMapQe8n0D3vN/Xd5fmWM3tufNgRQFBpaW2YVJxQZV4iPNqb0vEFvssMEo5w9c6BTIA==", + "license": "BSD-3-Clause", + "dependencies": { + "resolve-protobuf-schema": "^2.1.0" + }, + "bin": { + "pbf": "bin/pbf" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2147,17 +2162,6 @@ "win32" ] }, - "node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, "node_modules/@sveltejs/acorn-typescript": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.5.tgz", @@ -2277,17 +2281,6 @@ "tslib": "^2.4.0" } }, - "node_modules/@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "dependencies": { - "defer-to-connect": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@tailwindcss/node": { "version": "4.1.8", "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.8.tgz", @@ -2565,17 +2558,6 @@ "vite": "^5.2.0 || ^6" } }, - "node_modules/@types/cacheable-request": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", - "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", - "dependencies": { - "@types/http-cache-semantics": "*", - "@types/keyv": "^3.1.4", - "@types/node": "*", - "@types/responselike": "^1.0.0" - } - }, "node_modules/@types/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", @@ -2628,6 +2610,7 @@ "version": "3.2.5", "resolved": "https://registry.npmjs.org/@types/geojson-vt/-/geojson-vt-3.2.5.tgz", "integrity": "sha512-qDO7wqtprzlpe8FfQ//ClPV9xiuoh2nkIgiouIptON9w5jvD/fA4szvP9GBlDVdJ5dldAl0kX/sy3URbWwLx0g==", + "license": "MIT", "dependencies": { "@types/geojson": "*" } @@ -2638,35 +2621,17 @@ "integrity": "sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw==", "license": "MIT" }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" - }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, - "node_modules/@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/mapbox__point-geometry": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.4.tgz", - "integrity": "sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA==", - "license": "MIT" - }, "node_modules/@types/mapbox__sphericalmercator": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@types/mapbox__sphericalmercator/-/mapbox__sphericalmercator-1.2.3.tgz", - "integrity": "sha512-gBXMMNhRTA8HzAzLdBzVYET0dH1p8jDPYZoT9+KnfFRYIRwHnbW+3IyiSlwS7kvr97PMn501QY+Dd3kjxb2dAA==" + "integrity": "sha512-gBXMMNhRTA8HzAzLdBzVYET0dH1p8jDPYZoT9+KnfFRYIRwHnbW+3IyiSlwS7kvr97PMn501QY+Dd3kjxb2dAA==", + "dev": true }, "node_modules/@types/mapbox__tilebelt": { "version": "1.0.4", @@ -2677,16 +2642,6 @@ "@types/geojson": "*" } }, - "node_modules/@types/mapbox-gl": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@types/mapbox-gl/-/mapbox-gl-3.4.1.tgz", - "integrity": "sha512-NsGKKtgW93B+UaLPti6B7NwlxYlES5DpV5Gzj9F75rK5ALKsqSk15CiEHbOnTr09RGbr6ZYiCdI+59NNNcAImg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/geojson": "*" - } - }, "node_modules/@types/mdast": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", @@ -2697,25 +2652,16 @@ "@types/unist": "*" } }, - "node_modules/@types/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==" - }, "node_modules/@types/node": { "version": "22.15.30", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.30.tgz", "integrity": "sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA==", + "dev": true, "license": "MIT", "dependencies": { "undici-types": "~6.21.0" } }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", - "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==" - }, "node_modules/@types/pako": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.7.tgz", @@ -2726,12 +2672,6 @@ "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.5.tgz", "integrity": "sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==" }, - "node_modules/@types/png.js": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@types/png.js/-/png.js-0.2.3.tgz", - "integrity": "sha512-7F2LTRf/WJDpw9n9cPKi096a+gAdY2LS7WGlaEbGD7YZ7F7+t5tHRNHgvNvvigP6cZyjNW2Qsi/aR6AC2XN9xQ==", - "dev": true - }, "node_modules/@types/polylabel": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@types/polylabel/-/polylabel-1.1.3.tgz", @@ -2742,14 +2682,6 @@ "resolved": "https://registry.npmjs.org/@types/rbush/-/rbush-3.0.4.tgz", "integrity": "sha512-knSt9cCW8jj1ZSFcFeBZaX++OucmfPxxHiRwTahZfJlnQsek7O0bazTJHWD2RVj9LEoejUYF2de3/stf+QXcXw==" }, - "node_modules/@types/responselike": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", - "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/sanitize-html": { "version": "2.16.0", "resolved": "https://registry.npmjs.org/@types/sanitize-html/-/sanitize-html-2.16.0.tgz", @@ -3142,14 +3074,6 @@ "node": ">= 0.4" } }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/asn1.js": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", @@ -3180,11 +3104,6 @@ "util": "^0.12.5" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -3215,11 +3134,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/base-64": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz", - "integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA==" - }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -3525,31 +3439,6 @@ "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", "dev": true }, - "node_modules/cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", - "engines": { - "node": ">=10.6.0" - } - }, - "node_modules/cacheable-request": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", - "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", @@ -3607,38 +3496,6 @@ "node": ">=6" } }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", - "dependencies": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/camelcase-keys/node_modules/quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "engines": { - "node": ">=8" - } - }, "node_modules/camelize": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", @@ -3688,11 +3545,6 @@ "chart.js": ">=3.2.0" } }, - "node_modules/cheap-ruler": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cheap-ruler/-/cheap-ruler-4.0.0.tgz", - "integrity": "sha512-0BJa8f4t141BYKQyn9NSQt1PguFQXMXwZiA5shfoaBYHAb2fFk2RAX+tiWMoQU+Agtzt3mdt0JtuyshAXqZ+Vw==" - }, "node_modules/chownr": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", @@ -3713,17 +3565,6 @@ "safe-buffer": "^5.0.1" } }, - "node_modules/clone-response": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", - "dependencies": { - "mimic-response": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", @@ -3776,17 +3617,6 @@ "simple-swizzle": "^0.2.2" } }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -3905,11 +3735,6 @@ "node": "*" } }, - "node_modules/csscolorparser": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz", - "integrity": "sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w==" - }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -3940,62 +3765,6 @@ } } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decamelize-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", - "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", - "dependencies": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decamelize-keys/node_modules/map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -4010,14 +3779,6 @@ "node": ">=0.10.0" } }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "engines": { - "node": ">=10" - } - }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -4052,14 +3813,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", @@ -4202,9 +3955,9 @@ } }, "node_modules/earcut": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.1.tgz", - "integrity": "sha512-0l1/0gOjESMeQyYaK5IDiPNvFeu93Z/cO0TjZh9eZ1vyCtZnA7KMZ8rQggpsJHIbGSdrqYq9OhuveadOVHCshw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.2.tgz", + "integrity": "sha512-X7hshQbLyMJ/3RPhyObLARM2sNxxmRALLKx1+NVFFnQ9gKzmCrxm9+uLIAdBcvc8FNLpctqlQ2V6AE92Ol9UDQ==", "license": "ISC" }, "node_modules/eastasianwidth": { @@ -4243,14 +3996,6 @@ "dev": true, "license": "MIT" }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dependencies": { - "once": "^1.4.0" - } - }, "node_modules/enhanced-resolve": { "version": "5.18.1", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", @@ -4286,14 +4031,6 @@ "xtend": "~4.0.0" } }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -4663,11 +4400,6 @@ "individual": "^3.0.0" } }, - "node_modules/eventemitter3": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" - }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -4842,19 +4574,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -4873,6 +4592,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -4888,7 +4608,8 @@ "node_modules/geojson-vt": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-4.0.2.tgz", - "integrity": "sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A==" + "integrity": "sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A==", + "license": "ISC" }, "node_modules/get-intrinsic": { "version": "1.3.0", @@ -4927,20 +4648,6 @@ "node": ">= 0.4" } }, - "node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/get-tsconfig": { "version": "4.8.1", "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz", @@ -5045,30 +4752,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/got": { - "version": "11.8.6", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", - "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", - "dependencies": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=10.19.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, "node_modules/gpx": { "resolved": "../gpx", "link": true @@ -5086,11 +4769,6 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, - "node_modules/grid-index": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/grid-index/-/grid-index-1.1.0.tgz", - "integrity": "sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA==" - }, "node_modules/hammerjs": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz", @@ -5099,14 +4777,6 @@ "node": ">=0.8.0" } }, - "node_modules/hard-rejection": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", - "engines": { - "node": ">=6" - } - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -5182,6 +4852,7 @@ "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" }, @@ -5200,17 +4871,6 @@ "minimalistic-crypto-utils": "^1.0.1" } }, - "node_modules/hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/htmlparser2": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", @@ -5229,23 +4889,6 @@ "entities": "^4.4.0" } }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" - }, - "node_modules/http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, "node_modules/https-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", @@ -5332,14 +4975,6 @@ "node": ">=0.8.19" } }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "engines": { - "node": ">=8" - } - }, "node_modules/individual": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/individual/-/individual-3.0.0.tgz", @@ -5373,11 +5008,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" - }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -5394,6 +5024,7 @@ "version": "2.15.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "dev": true, "dependencies": { "hasown": "^2.0.2" }, @@ -5483,14 +5114,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", @@ -5570,11 +5193,6 @@ "jiti": "lib/jiti-cli.mjs" } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -5591,12 +5209,8 @@ "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true }, "node_modules/json-schema-traverse": { "version": "0.4.1", @@ -5611,6 +5225,12 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/json-stringify-pretty-compact": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-4.0.0.tgz", + "integrity": "sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==", + "license": "MIT" + }, "node_modules/jszip": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", @@ -5668,18 +5288,11 @@ "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, "dependencies": { "json-buffer": "3.0.1" } }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/kleur": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", @@ -5966,11 +5579,6 @@ "node": ">=10" } }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" - }, "node_modules/locate-character": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", @@ -5995,7 +5603,8 @@ "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", @@ -6011,25 +5620,6 @@ "node": ">=0.6" } }, - "node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/lucide-static": { "version": "0.513.0", "resolved": "https://registry.npmjs.org/lucide-static/-/lucide-static-0.513.0.tgz", @@ -6057,69 +5647,6 @@ "@jridgewell/sourcemap-codec": "^1.5.0" } }, - "node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mapbox-gl": { - "version": "3.17.0", - "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-3.17.0.tgz", - "integrity": "sha512-nCrDKRlr5di6xUksUDslNWwxroJ5yv1hT8pyVFtcpWJOOKsYQxF/wOFTMie8oxMnXeFkrz1Tl1TwA1XN1yX0KA==", - "license": "SEE LICENSE IN LICENSE.txt", - "workspaces": [ - "src/style-spec", - "test/build/vite", - "test/build/webpack", - "test/build/typings" - ], - "dependencies": { - "@mapbox/jsonlint-lines-primitives": "^2.0.2", - "@mapbox/mapbox-gl-supported": "^3.0.0", - "@mapbox/point-geometry": "^1.1.0", - "@mapbox/tiny-sdf": "^2.0.6", - "@mapbox/unitbezier": "^0.0.1", - "@mapbox/vector-tile": "^2.0.4", - "@mapbox/whoots-js": "^3.1.0", - "@types/geojson": "^7946.0.16", - "@types/geojson-vt": "^3.2.5", - "@types/mapbox__point-geometry": "^0.1.4", - "@types/pbf": "^3.0.5", - "@types/supercluster": "^7.1.3", - "cheap-ruler": "^4.0.0", - "csscolorparser": "~1.0.3", - "earcut": "^3.0.1", - "geojson-vt": "^4.0.2", - "gl-matrix": "^3.4.4", - "grid-index": "^1.1.0", - "kdbush": "^4.0.2", - "martinez-polygon-clipping": "^0.7.4", - "murmurhash-js": "^1.0.0", - "pbf": "^4.0.1", - "potpack": "^2.0.0", - "quickselect": "^3.0.0", - "supercluster": "^8.0.1", - "tinyqueue": "^3.0.0" - } - }, - "node_modules/mapbox-gl/node_modules/pbf": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pbf/-/pbf-4.0.1.tgz", - "integrity": "sha512-SuLdBvS42z33m8ejRbInMapQe8n0D3vN/Xd5fmWM3tufNgRQFBpaW2YVJxQZV4iPNqb0vEFvssMEo5w9c6BTIA==", - "license": "BSD-3-Clause", - "dependencies": { - "resolve-protobuf-schema": "^2.1.0" - }, - "bin": { - "pbf": "bin/pbf" - } - }, "node_modules/mapillary-js": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/mapillary-js/-/mapillary-js-4.1.2.tgz", @@ -6155,6 +5682,56 @@ "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==" }, + "node_modules/maplibre-gl": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-5.16.0.tgz", + "integrity": "sha512-/VDY89nr4jgLJyzmhy325cG6VUI02WkZ/UfVuDbG/piXzo6ODnM+omDFIwWY8tsEsBG26DNDmNMn3Y2ikHsBiA==", + "license": "BSD-3-Clause", + "dependencies": { + "@mapbox/geojson-rewind": "^0.5.2", + "@mapbox/jsonlint-lines-primitives": "^2.0.2", + "@mapbox/point-geometry": "^1.1.0", + "@mapbox/tiny-sdf": "^2.0.7", + "@mapbox/unitbezier": "^0.0.1", + "@mapbox/vector-tile": "^2.0.4", + "@mapbox/whoots-js": "^3.1.0", + "@maplibre/maplibre-gl-style-spec": "^24.4.1", + "@maplibre/mlt": "^1.1.2", + "@maplibre/vt-pbf": "^4.2.0", + "@types/geojson": "^7946.0.16", + "@types/geojson-vt": "3.2.5", + "@types/supercluster": "^7.1.3", + "earcut": "^3.0.2", + "geojson-vt": "^4.0.2", + "gl-matrix": "^3.4.4", + "kdbush": "^4.0.2", + "murmurhash-js": "^1.0.0", + "pbf": "^4.0.1", + "potpack": "^2.1.0", + "quickselect": "^3.0.0", + "supercluster": "^8.0.1", + "tinyqueue": "^3.0.0" + }, + "engines": { + "node": ">=16.14.0", + "npm": ">=8.1.0" + }, + "funding": { + "url": "https://github.com/maplibre/maplibre-gl-js?sponsor=1" + } + }, + "node_modules/maplibre-gl/node_modules/pbf": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pbf/-/pbf-4.0.1.tgz", + "integrity": "sha512-SuLdBvS42z33m8ejRbInMapQe8n0D3vN/Xd5fmWM3tufNgRQFBpaW2YVJxQZV4iPNqb0vEFvssMEo5w9c6BTIA==", + "license": "BSD-3-Clause", + "dependencies": { + "resolve-protobuf-schema": "^2.1.0" + }, + "bin": { + "pbf": "bin/pbf" + } + }, "node_modules/martinez-polygon-clipping": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/martinez-polygon-clipping/-/martinez-polygon-clipping-0.7.4.tgz", @@ -6208,42 +5785,6 @@ "svelte": "^3.56.0 || ^4.0.0 || ^5.0.0-next.120" } }, - "node_modules/meow": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", - "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", - "dependencies": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize": "^1.2.0", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.18.0", - "yargs-parser": "^20.2.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow/node_modules/type-fest": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", - "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -6285,33 +5826,6 @@ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "engines": { - "node": ">=4" - } - }, "node_modules/min-document": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", @@ -6320,14 +5834,6 @@ "dom-walk": "^0.1.0" } }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "engines": { - "node": ">=4" - } - }, "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -6355,17 +5861,13 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", - "dependencies": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, - "engines": { - "node": ">= 6" + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/minipass": { @@ -6519,31 +6021,6 @@ "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", "dev": true }, - "node_modules/normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", - "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", @@ -6601,14 +6078,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -6632,14 +6101,6 @@ "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", "dev": true }, - "node_modules/p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "engines": { - "node": ">=8" - } - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -6670,14 +6131,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" - } - }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", @@ -6749,23 +6202,6 @@ "node": ">= 0.10" } }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/parse-srcset": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz", @@ -6781,6 +6217,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, "engines": { "node": ">=8" } @@ -6797,7 +6234,8 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true }, "node_modules/path-scurry": { "version": "2.0.0", @@ -6884,11 +6322,6 @@ "node": ">=10" } }, - "node_modules/png.js": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/png.js/-/png.js-0.2.1.tgz", - "integrity": "sha512-EXQ+wk98iL3KuuPY6bUcfPeM1CZCK8/exKoTxY4H6EjU2hMYtV5ofx7gxmjL1mnJpcvexXexKuC3c5U7f7KVFg==" - }, "node_modules/polylabel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/polylabel/-/polylabel-1.1.0.tgz", @@ -7033,9 +6466,10 @@ } }, "node_modules/potpack": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/potpack/-/potpack-2.0.0.tgz", - "integrity": "sha512-Q+/tYsFU9r7xoOJ+y/ZTtdVQwTWfzjbiXBDMM/JKUux3+QPP02iUuIoeBQ+Ot6oEDlC+/PGjB/5A3K7KKb7hcw==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/potpack/-/potpack-2.1.0.tgz", + "integrity": "sha512-pcaShQc1Shq0y+E7GqJqvZj8DTthWV1KeHGdi0Z6IAin2Oi3JnLCOfwnCo84qc+HAp52wT9nK9H7FAJp5a44GQ==", + "license": "ISC" }, "node_modules/preact": { "version": "10.24.1", @@ -7136,15 +6570,6 @@ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true }, - "node_modules/pump": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", - "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -7199,17 +6624,6 @@ } ] }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/quickselect": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz", @@ -7247,124 +6661,6 @@ "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==" }, - "node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg/node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" - }, - "node_modules/read-pkg/node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/read-pkg/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "engines": { - "node": ">=8" - } - }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -7379,22 +6675,11 @@ "node": ">= 6" } }, - "node_modules/redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -7407,11 +6692,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" - }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -7439,17 +6719,6 @@ "protocol-buffers-schema": "^3.3.1" } }, - "node_modules/responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", - "dependencies": { - "lowercase-keys": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -7554,6 +6823,12 @@ "svelte": "^5.7.0" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "license": "BSD-3-Clause" + }, "node_modules/rxjs": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", @@ -7627,6 +6902,7 @@ "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -7892,34 +7168,6 @@ "node": ">=0.10.0" } }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==" - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.20", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", - "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==" - }, "node_modules/splaytree": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/splaytree/-/splaytree-0.1.4.tgz", @@ -8065,17 +7313,6 @@ "node": ">=8" } }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -8102,12 +7339,14 @@ "node_modules/subtag": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/subtag/-/subtag-0.5.0.tgz", - "integrity": "sha512-CaIBcTSb/nyk4xiiSOtZYz1B+F12ZxW8NEp54CdT+84vmh/h4sUnHGC6+KQXUfED8u22PQjCYWfZny8d2ELXwg==" + "integrity": "sha512-CaIBcTSb/nyk4xiiSOtZYz1B+F12ZxW8NEp54CdT+84vmh/h4sUnHGC6+KQXUfED8u22PQjCYWfZny8d2ELXwg==", + "license": "ISC" }, - "node_modules/suggestions": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/suggestions/-/suggestions-1.7.1.tgz", - "integrity": "sha512-gl5YPAhPYl07JZ5obiD9nTZsg4SyZswAQU/NNtnYiSnFkI3+ZHuXAiEsYm7AaZ71E0LXSFaGVaulGSWN3Gd71A==", + "node_modules/suggestions-list": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/suggestions-list/-/suggestions-list-0.0.2.tgz", + "integrity": "sha512-Yw0fdq14c6RQWQIfE1/8WEi9Dp8rjyCD6FhYA/Tit2/ADbE9Y4ADG4ezlvivsa8Civ5nz++pyVVBMjOMlgIUJw==", + "license": "ISC", "dependencies": { "fuzzy": "^0.1.1", "xtend": "^4.0.0" @@ -8137,6 +7376,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -8598,14 +7838,6 @@ "node": ">=6" } }, - "node_modules/trim-newlines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", - "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", - "engines": { - "node": ">=8" - } - }, "node_modules/ts-api-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", @@ -8691,6 +7923,7 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, "license": "MIT" }, "node_modules/unist-util-is": { @@ -8795,15 +8028,6 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, "node_modules/vaul-svelte": { "version": "1.0.0-next.7", "resolved": "https://registry.npmjs.org/vaul-svelte/-/vaul-svelte-1.0.0-next.7.tgz", @@ -9172,11 +8396,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, "node_modules/x-is-array": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/x-is-array/-/x-is-array-0.1.0.tgz", @@ -9195,11 +8414,6 @@ "node": ">=0.4" } }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/yaml": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", @@ -9215,14 +8429,6 @@ "node": ">= 14.6" } }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "engines": { - "node": ">=10" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/website/package.json b/website/package.json index c03e5d40d..37a9bbcca 100644 --- a/website/package.json +++ b/website/package.json @@ -23,10 +23,9 @@ "@types/eslint": "^9.6.1", "@types/events": "^3.0.3", "@types/file-saver": "^2.0.7", + "@types/mapbox__sphericalmercator": "^1.2.3", "@types/mapbox__tilebelt": "^1.0.4", - "@types/mapbox-gl": "^3.4.1", "@types/node": "^22.15.30", - "@types/png.js": "^0.2.3", "@types/sanitize-html": "^2.16.0", "@types/sortablejs": "^1.15.8", "@typescript-eslint/eslint-plugin": "^8.33.1", @@ -62,10 +61,9 @@ "dependencies": { "@docsearch/js": "^3.9.0", "@internationalized/date": "^3.8.2", - "@mapbox/mapbox-gl-geocoder": "^5.0.3", "@mapbox/sphericalmercator": "^2.0.1", "@mapbox/tilebelt": "^2.0.2", - "@types/mapbox__sphericalmercator": "^1.2.3", + "@maplibre/maplibre-gl-geocoder": "^1.9.4", "chart.js": "^4.5.1", "chartjs-plugin-zoom": "^2.2.0", "clsx": "^2.1.1", @@ -74,9 +72,8 @@ "gpx": "file:../gpx", "immer": "^10.1.1", "jszip": "^3.10.1", - "mapbox-gl": "^3.17.0", "mapillary-js": "^4.1.2", - "png.js": "^0.2.1", + "maplibre-gl": "^5.16.0", "sanitize-html": "^2.17.0", "sortablejs": "^1.15.6", "tailwind-merge": "^3.3.0" diff --git a/website/src/lib/assets/img/home/mapbox-satellite.png b/website/src/lib/assets/img/home/maptiler-satellite.png similarity index 100% rename from website/src/lib/assets/img/home/mapbox-satellite.png rename to website/src/lib/assets/img/home/maptiler-satellite.png diff --git a/website/src/lib/assets/img/home/mapbox-outdoors.png b/website/src/lib/assets/img/home/maptiler-topo.png similarity index 100% rename from website/src/lib/assets/img/home/mapbox-outdoors.png rename to website/src/lib/assets/img/home/maptiler-topo.png diff --git a/website/src/lib/assets/layers.ts b/website/src/lib/assets/layers.ts index 44b1cf72e..ff6813171 100644 --- a/website/src/lib/assets/layers.ts +++ b/website/src/lib/assets/layers.ts @@ -22,15 +22,18 @@ import { Binoculars, Toilet, } from 'lucide-static'; -import { type RasterDEMSourceSpecification, type StyleSpecification } from 'mapbox-gl'; +import { type RasterDEMSourceSpecification, type StyleSpecification } from 'maplibre-gl'; import ignFrTopo from './custom/ign-fr-topo.json'; import ignFrPlan from './custom/ign-fr-plan.json'; import ignFrSatellite from './custom/ign-fr-satellite.json'; import bikerouterGravel from './custom/bikerouter-gravel.json'; +export const maptilerKeyPlaceHolder = 'MAPTILER_KEY'; + export const basemaps: { [key: string]: string | StyleSpecification } = { - mapboxOutdoors: 'mapbox://styles/mapbox/outdoors-v12', - mapboxSatellite: 'mapbox://styles/mapbox/satellite-streets-v12', + maptilerTopo: `https://api.maptiler.com/maps/topo-v4/style.json?key=${maptilerKeyPlaceHolder}`, + maptilerOutdoors: `https://api.maptiler.com/maps/outdoor-v4/style.json?key=${maptilerKeyPlaceHolder}`, + maptilerSatellite: `https://api.maptiler.com/maps/hybrid-v4/style.json?key=${maptilerKeyPlaceHolder}`, openStreetMap: { version: 8, sources: { @@ -773,8 +776,9 @@ export type LayerTreeType = { [key: string]: LayerTreeType | boolean }; export const basemapTree: LayerTreeType = { basemaps: { world: { - mapboxOutdoors: true, - mapboxSatellite: true, + maptilerTopo: true, + maptilerOutdoors: true, + maptilerSatellite: true, openStreetMap: true, openTopoMap: true, openHikingMap: true, @@ -907,7 +911,7 @@ export const overpassTree: LayerTreeType = { }; // Default basemap used -export const defaultBasemap = 'mapboxOutdoors'; +export const defaultBasemap = 'maptilerTopo'; // Default overlays used (none) export const defaultOverlays: LayerTreeType = { @@ -996,8 +1000,9 @@ export const defaultOverpassQueries: LayerTreeType = { export const defaultBasemapTree: LayerTreeType = { basemaps: { world: { - mapboxOutdoors: true, - mapboxSatellite: true, + maptilerTopo: true, + maptilerOutdoors: true, + maptilerSatellite: true, openStreetMap: true, openTopoMap: true, openHikingMap: true, @@ -1136,7 +1141,7 @@ export type CustomLayer = { maxZoom: number; layerType: 'basemap' | 'overlay'; resourceType: 'raster' | 'vector'; - value: string | {}; + value: string | maplibregl.StyleSpecification; }; type OverpassQueryData = { @@ -1455,11 +1460,9 @@ export const overpassQueryData: Record = { }; export const terrainSources: { [key: string]: RasterDEMSourceSpecification } = { - 'mapbox-dem': { + 'maptiler-dem': { type: 'raster-dem', - url: 'mapbox://mapbox.mapbox-terrain-dem-v1', - tileSize: 512, - maxzoom: 14, + url: `https://api.maptiler.com/tiles/terrain-rgb-v2/tiles.json?key=${maptilerKeyPlaceHolder}`, }, mapterhorn: { type: 'raster-dem', @@ -1467,4 +1470,4 @@ export const terrainSources: { [key: string]: RasterDEMSourceSpecification } = { }, }; -export const defaultTerrainSource = 'mapbox-dem'; +export const defaultTerrainSource = 'maptiler-dem'; diff --git a/website/src/lib/components/GPXStatistics.svelte b/website/src/lib/components/GPXStatistics.svelte index ecc38577b..40838010f 100644 --- a/website/src/lib/components/GPXStatistics.svelte +++ b/website/src/lib/components/GPXStatistics.svelte @@ -31,13 +31,13 @@ diff --git a/website/src/lib/components/Logo.svelte b/website/src/lib/components/Logo.svelte index f06d9351c..c23a18bb6 100644 --- a/website/src/lib/components/Logo.svelte +++ b/website/src/lib/components/Logo.svelte @@ -8,7 +8,7 @@ ...others }: { iconOnly?: boolean; - company?: 'gpx.studio' | 'mapbox' | 'github' | 'crowdin' | 'facebook' | 'reddit'; + company?: 'gpx.studio' | 'maptiler' | 'github' | 'crowdin' | 'facebook' | 'reddit'; [key: string]: any; } = $props(); @@ -19,10 +19,10 @@ alt="Logo of gpx.studio." {...others} /> -{:else if company === 'mapbox'} +{:else if company === 'maptiler'} Logo of Mapbox. {:else if company === 'github'} diff --git a/website/src/lib/components/docs/DocsLayers.svelte b/website/src/lib/components/docs/DocsLayers.svelte index 4c5abadc7..ba6e46ba3 100644 --- a/website/src/lib/components/docs/DocsLayers.svelte +++ b/website/src/lib/components/docs/DocsLayers.svelte @@ -1,10 +1,10 @@
- + ; slicedGPXStatistics: Writable<[GPXGlobalStatistics, number, number] | undefined>; + hoveredPoint: Writable; additionalDatasets: Writable; elevationFill: Writable<'slope' | 'surface' | 'highway' | undefined>; showControls?: boolean; @@ -47,6 +49,7 @@ elevationProfile = new ElevationProfile( gpxStatistics, slicedGPXStatistics, + hoveredPoint, additionalDatasets, elevationFill, canvas, @@ -61,7 +64,7 @@ }); -
+
{#if showControls} diff --git a/website/src/lib/components/elevation-profile/elevation-profile.ts b/website/src/lib/components/elevation-profile/elevation-profile.ts index 54b398139..4aa8b969f 100644 --- a/website/src/lib/components/elevation-profile/elevation-profile.ts +++ b/website/src/lib/components/elevation-profile/elevation-profile.ts @@ -20,10 +20,8 @@ import Chart, { type ScriptableLineSegmentContext, type TooltipItem, } from 'chart.js/auto'; -import mapboxgl from 'mapbox-gl'; import { get, type Readable, type Writable } from 'svelte/store'; -import { map } from '$lib/components/map/map'; -import type { GPXGlobalStatistics, GPXStatisticsGroup } from 'gpx'; +import type { Coordinates, GPXGlobalStatistics, GPXStatisticsGroup } from 'gpx'; import { mode } from 'mode-watcher'; import { getHighwayColor, getSlopeColor, getSurfaceColor } from '$lib/assets/colors'; @@ -42,7 +40,7 @@ interface ElevationProfilePoint { length: number; }; extensions: Record; - coordinates: [number, number]; + coordinates: Coordinates; index: number; } @@ -50,18 +48,19 @@ export class ElevationProfile { private _chart: Chart | null = null; private _canvas: HTMLCanvasElement; private _overlay: HTMLCanvasElement; - private _marker: mapboxgl.Marker | null = null; private _dragging = false; private _panning = false; private _gpxStatistics: Readable; private _slicedGPXStatistics: Writable<[GPXGlobalStatistics, number, number] | undefined>; + private _hoveredPoint: Writable; private _additionalDatasets: Readable; private _elevationFill: Readable<'slope' | 'surface' | 'highway' | undefined>; constructor( gpxStatistics: Readable, slicedGPXStatistics: Writable<[GPXGlobalStatistics, number, number] | undefined>, + hoveredPoint: Writable, additionalDatasets: Readable, elevationFill: Readable<'slope' | 'surface' | 'highway' | undefined>, canvas: HTMLCanvasElement, @@ -69,17 +68,12 @@ export class ElevationProfile { ) { this._gpxStatistics = gpxStatistics; this._slicedGPXStatistics = slicedGPXStatistics; + this._hoveredPoint = hoveredPoint; this._additionalDatasets = additionalDatasets; this._elevationFill = elevationFill; this._canvas = canvas; this._overlay = overlay; - let element = document.createElement('div'); - element.className = 'h-4 w-4 rounded-full bg-cyan-500 border-2 border-white'; - this._marker = new mapboxgl.Marker({ - element, - }); - import('chartjs-plugin-zoom').then((module) => { Chart.register(module.default); this.initialize(); @@ -162,14 +156,10 @@ export class ElevationProfile { label: (context: TooltipItem<'line'>) => { let point = context.raw as ElevationProfilePoint; if (context.datasetIndex === 0) { - const map_ = get(map); - if (map_ && this._marker) { - if (this._dragging) { - this._marker.remove(); - } else { - this._marker.setLngLat(point.coordinates); - this._marker.addTo(map_); - } + if (this._dragging) { + this._hoveredPoint.set(null); + } else { + this._hoveredPoint.set(point.coordinates); } return `${i18n._('quantities.elevation')}: ${getElevationWithUnits(point.y, false)}`; } else if (context.datasetIndex === 1) { @@ -312,10 +302,7 @@ export class ElevationProfile { events: ['mouseout'], afterEvent: (chart: Chart, args: { event: ChartEvent }) => { if (args.event.type === 'mouseout') { - const map_ = get(map); - if (map_ && this._marker) { - this._marker.remove(); - } + this._hoveredPoint.set(null); } }, }, @@ -637,8 +624,5 @@ export class ElevationProfile { this._chart.destroy(); this._chart = null; } - if (this._marker) { - this._marker.remove(); - } } } diff --git a/website/src/lib/components/embedding/Embedding.svelte b/website/src/lib/components/embedding/Embedding.svelte index 48d0bd931..bba44c349 100644 --- a/website/src/lib/components/embedding/Embedding.svelte +++ b/website/src/lib/components/embedding/Embedding.svelte @@ -16,7 +16,7 @@ import { setMode } from 'mode-watcher'; import { settings } from '$lib/logic/settings'; import { fileStateCollection } from '$lib/logic/file-state'; - import { gpxStatistics, slicedGPXStatistics } from '$lib/logic/statistics'; + import { gpxStatistics, hoveredPoint, slicedGPXStatistics } from '$lib/logic/statistics'; import { loadFile } from '$lib/logic/file-actions'; import { selection } from '$lib/logic/selection'; import { untrack } from 'svelte'; @@ -102,7 +102,7 @@
url.length > 0), ids: driveIds.split(',').filter((id) => id.length > 0), elevation: { @@ -102,8 +102,8 @@
- - + + diff --git a/website/src/lib/components/embedding/embedding.ts b/website/src/lib/components/embedding/embedding.ts index 027fb4ea4..d68cc2c06 100644 --- a/website/src/lib/components/embedding/embedding.ts +++ b/website/src/lib/components/embedding/embedding.ts @@ -1,8 +1,8 @@ -import { PUBLIC_MAPBOX_TOKEN } from '$env/static/public'; +import { PUBLIC_MAPTILER_KEY } from '$env/static/public'; import { basemaps } from '$lib/assets/layers'; export type EmbeddingOptions = { - token: string; + key: string; files: string[]; ids: string[]; basemap: string; @@ -26,10 +26,10 @@ export type EmbeddingOptions = { }; export const defaultEmbeddingOptions = { - token: '', + key: '', files: [], ids: [], - basemap: 'mapboxOutdoors', + basemap: 'maptilerTopo', elevation: { show: true, height: 170, @@ -107,7 +107,7 @@ export function getURLForGoogleDriveFile(fileId: string): string { export function convertOldEmbeddingOptions(options: URLSearchParams): any { let newOptions: any = { - token: PUBLIC_MAPBOX_TOKEN, + key: PUBLIC_MAPTILER_KEY, files: [], ids: [], }; @@ -123,7 +123,7 @@ export function convertOldEmbeddingOptions(options: URLSearchParams): any { if (options.has('source')) { let basemap = options.get('source')!; if (basemap === 'satellite') { - newOptions.basemap = 'mapboxSatellite'; + newOptions.basemap = 'maptilerSatellite'; } else if (basemap === 'otm') { newOptions.basemap = 'openTopoMap'; } else if (basemap === 'ohm') { diff --git a/website/src/lib/components/map/CoordinatesPopup.svelte b/website/src/lib/components/map/CoordinatesPopup.svelte index f49be578f..53628d94c 100644 --- a/website/src/lib/components/map/CoordinatesPopup.svelte +++ b/website/src/lib/components/map/CoordinatesPopup.svelte @@ -5,6 +5,16 @@ map.onLoad((map_) => { map_.on('contextmenu', (e) => { + if ( + map_.queryRenderedFeatures(e.point, { + layers: map_ + .getLayersOrder() + .filter((layerId) => layerId.startsWith('routing-controls')), + }).length + ) { + // Clicked on routing control, ignoring + return; + } trackpointPopup?.setItem({ item: new TrackPoint({ attributes: { diff --git a/website/src/lib/components/map/Map.svelte b/website/src/lib/components/map/Map.svelte index 1a884dc7b..9b5d539db 100644 --- a/website/src/lib/components/map/Map.svelte +++ b/website/src/lib/components/map/Map.svelte @@ -1,30 +1,25 @@ @@ -84,6 +85,7 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an diff --git a/website/src/lib/docs/en/home/funding.mdx b/website/src/lib/docs/en/home/funding.mdx index f9d1e90d9..6327bd332 100644 --- a/website/src/lib/docs/en/home/funding.mdx +++ b/website/src/lib/docs/en/home/funding.mdx @@ -5,7 +5,7 @@ ## Help keep the website free (and ad-free) Each time you add or move GPS points, our servers calculate the best route on the road network. -We also use APIs from Mapbox to display beautiful maps, retrieve elevation data and allow you to search for places. +We also use APIs from MapTiler to display beautiful maps, retrieve elevation data and allow you to search for places. Unfortunately, this is expensive. If you enjoy using this tool and find it valuable, please consider making a small donation to help keep the website free and ad-free. diff --git a/website/src/lib/docs/en/home/mapbox.mdx b/website/src/lib/docs/en/home/mapbox.mdx deleted file mode 100644 index 3085ec537..000000000 --- a/website/src/lib/docs/en/home/mapbox.mdx +++ /dev/null @@ -1,5 +0,0 @@ -Mapbox is the company that provides some of the beautiful maps on this website. -They also develop the map engine which powers **gpx.studio**. - -We are incredibly fortunate and grateful to be part of their Community program, which supports nonprofits, educational institutions, and positive impact organizations. -This partnership allows **gpx.studio** to benefit from Mapbox tools at discounted prices, greatly contributing to the financial viability of the project and enabling us to offer the best possible user experience. diff --git a/website/src/lib/docs/en/integration.mdx b/website/src/lib/docs/en/integration.mdx index 739df9903..ee13b1c30 100644 --- a/website/src/lib/docs/en/integration.mdx +++ b/website/src/lib/docs/en/integration.mdx @@ -12,7 +12,7 @@ title: Integration You can use **gpx.studio** to create maps showing your GPX files and embed them in your website. All you need is: -1. A Mapbox access token to load the map, and +1. A MapTiler key to load the map, and 1. GPX files hosted on your server or on Google Drive, or accessible via a public URL. You can then play with the configurator below to customize your map and generate the corresponding HTML code. diff --git a/website/src/lib/docs/en/map-controls.mdx b/website/src/lib/docs/en/map-controls.mdx index ad34dd626..5d3dfb1c5 100644 --- a/website/src/lib/docs/en/map-controls.mdx +++ b/website/src/lib/docs/en/map-controls.mdx @@ -58,7 +58,7 @@ Only one basemap can be displayed at a time.
- Hover over the map to show the Waymarked Trails hiking overlay on top of the Mapbox Outdoors basemap. + Hover over the map to show the Waymarked Trails hiking overlay on top of the MapTiler Topo basemap.
@@ -67,4 +67,4 @@ They can be enabled in the [map layer settings dialog](./menu/settings). In these settings, you can also manage the opacity of the overlays. -For advanced users, it is possible to add custom basemaps and overlays by providing WMTS, WMS, or Mapbox style JSON URLs. +For advanced users, it is possible to add custom basemaps and overlays by providing WMTS, WMS, or MapLibre style JSON URLs. diff --git a/website/src/lib/docs/en/toolbar/elevation.mdx b/website/src/lib/docs/en/toolbar/elevation.mdx index e3e5e9f50..fedae8c99 100644 --- a/website/src/lib/docs/en/toolbar/elevation.mdx +++ b/website/src/lib/docs/en/toolbar/elevation.mdx @@ -18,7 +18,7 @@ This tool allows you to add elevation data to traces and [points of interest](.. -Elevation data is provided by Mapbox. -You can learn more about its origin and accuracy in the documentation. +Elevation data is provided by MapTiler. +You can learn more about its origin and accuracy in the documentation. \ No newline at end of file diff --git a/website/src/lib/logic/bounds.ts b/website/src/lib/logic/bounds.ts index 4c19b3d33..707d14c30 100644 --- a/website/src/lib/logic/bounds.ts +++ b/website/src/lib/logic/bounds.ts @@ -1,6 +1,6 @@ import { get } from 'svelte/store'; import { selection } from '$lib/logic/selection'; -import mapboxgl from 'mapbox-gl'; +import maplibregl from 'maplibre-gl'; import { ListFileItem, ListWaypointItem } from '$lib/components/file-list/file-list'; import { fileStateCollection, GPXFileStateCollectionObserver } from '$lib/logic/file-state'; import { gpxStatistics } from '$lib/logic/statistics'; @@ -10,7 +10,7 @@ import type { Coordinates } from 'gpx'; import { page } from '$app/state'; export class BoundsManager { - private _bounds: mapboxgl.LngLatBounds = new mapboxgl.LngLatBounds(); + private _bounds: maplibregl.LngLatBounds = new maplibregl.LngLatBounds(); private _files: Set = new Set(); private _fileStateCollectionObserver: GPXFileStateCollectionObserver | null = null; private _unsubscribes: (() => void)[] = []; @@ -87,12 +87,12 @@ export class BoundsManager { } this._unsubscribes.forEach((unsubscribe) => unsubscribe()); this._unsubscribes = []; - this._bounds = new mapboxgl.LngLatBounds([180, 90, -180, -90]); + this._bounds = new maplibregl.LngLatBounds([180, 90, -180, -90]); } centerMapOnSelection() { let selected = get(selection).getSelected(); - let bounds = new mapboxgl.LngLatBounds(); + let bounds = new maplibregl.LngLatBounds(); if (selected.find((item) => item instanceof ListWaypointItem)) { selection.applyToOrderedSelectedItemsFromFile((fileId, level, items) => { diff --git a/website/src/lib/logic/map-cursor.ts b/website/src/lib/logic/map-cursor.ts index 1c5f61f2d..d83565756 100644 --- a/website/src/lib/logic/map-cursor.ts +++ b/website/src/lib/logic/map-cursor.ts @@ -7,7 +7,8 @@ export enum MapCursorState { TOOL_WITH_CROSSHAIR, WAYPOINT_HOVER, WAYPOINT_DRAGGING, - TRACKPOINT_DRAGGING, + ANCHOR_HOVER, + ANCHOR_DRAGGING, SCISSORS, SPLIT_CONTROL, MAPILLARY_HOVER, @@ -20,7 +21,8 @@ const cursorStyles = { [MapCursorState.LAYER_HOVER]: 'pointer', [MapCursorState.WAYPOINT_HOVER]: 'pointer', [MapCursorState.WAYPOINT_DRAGGING]: 'grabbing', - [MapCursorState.TRACKPOINT_DRAGGING]: 'grabbing', + [MapCursorState.ANCHOR_HOVER]: 'pointer', + [MapCursorState.ANCHOR_DRAGGING]: 'grabbing', [MapCursorState.TOOL_WITH_CROSSHAIR]: 'crosshair', [MapCursorState.SCISSORS]: scissorsCursor, [MapCursorState.SPLIT_CONTROL]: 'pointer', diff --git a/website/src/lib/logic/settings.ts b/website/src/lib/logic/settings.ts index c86df6ac0..3ec53e5c9 100644 --- a/website/src/lib/logic/settings.ts +++ b/website/src/lib/logic/settings.ts @@ -1,6 +1,7 @@ import { type Database } from '$lib/db'; import { liveQuery } from 'dexie'; import { + basemaps, defaultBasemap, defaultBasemapTree, defaultOpacities, @@ -9,7 +10,10 @@ import { defaultOverpassQueries, defaultOverpassTree, defaultTerrainSource, + overlays, + overpassQueryData, type CustomLayer, + type LayerTreeType, } from '$lib/assets/layers'; import { browser } from '$app/environment'; import { get, writable, type Writable } from 'svelte/store'; @@ -19,10 +23,12 @@ export class Setting { private _subscription: { unsubscribe: () => void } | null = null; private _key: string; private _value: Writable; + private _validator?: (value: V) => V; - constructor(key: string, initial: V) { + constructor(key: string, initial: V, validator?: (value: V) => V) { this._key = key; this._value = writable(initial); + this._validator = validator; } connectToDatabase(db: Database) { @@ -36,6 +42,9 @@ export class Setting { this._value.set(value); } } else { + if (this._validator) { + value = this._validator(value); + } this._value.set(value); } first = false; @@ -73,11 +82,13 @@ export class SettingInitOnFirstRead { private _key: string; private _value: Writable; private _initial: V; + private _validator?: (value: V) => V; - constructor(key: string, initial: V) { + constructor(key: string, initial: V, validator?: (value: V) => V) { this._key = key; this._value = writable(undefined); this._initial = initial; + this._validator = validator; } connectToDatabase(db: Database) { @@ -93,6 +104,9 @@ export class SettingInitOnFirstRead { this._value.set(value); } } else { + if (this._validator) { + value = this._validator(value); + } this._value.set(value); } first = false; @@ -128,37 +142,166 @@ export class SettingInitOnFirstRead { } } +function getValueValidator(allowed: V[], fallback: V) { + const dict = new Set(allowed); + return (value: V) => (dict.has(value) ? value : fallback); +} + +function getArrayValidator(allowed: V[]) { + const dict = new Set(allowed); + return (value: V[]) => value.filter((v) => dict.has(v)); +} + +function getLayerValidator(allowed: Record, fallback: string) { + return (layer: string) => + allowed.hasOwnProperty(layer) || + layer.startsWith('custom-') || + layer.startsWith('extension-') + ? layer + : fallback; +} + +function filterLayerTree(t: LayerTreeType, allowed: Record): LayerTreeType { + const filtered: LayerTreeType = {}; + Object.entries(t).forEach(([key, value]) => { + if (typeof value === 'object') { + filtered[key] = filterLayerTree(value, allowed); + } else if ( + allowed.hasOwnProperty(key) || + key.startsWith('custom-') || + key.startsWith('extension-') + ) { + filtered[key] = value; + } + }); + return filtered; +} + +function getLayerTreeValidator(allowed: Record) { + return (value: LayerTreeType) => filterLayerTree(value, allowed); +} + +type DistanceUnits = 'metric' | 'imperial' | 'nautical'; +type VelocityUnits = 'speed' | 'pace'; +type TemperatureUnits = 'celsius' | 'fahrenheit'; +type AdditionalDataset = 'speed' | 'hr' | 'cad' | 'atemp' | 'power'; +type ElevationFill = 'slope' | 'surface' | undefined; +type RoutingProfile = + | 'bike' + | 'racing_bike' + | 'gravel_bike' + | 'mountain_bike' + | 'foot' + | 'motorcycle' + | 'water' + | 'railway'; +type TerrainSource = 'maptiler-dem' | 'mapterhorn'; +type StreetViewSource = 'mapillary' | 'google'; + export const settings = { - distanceUnits: new Setting<'metric' | 'imperial' | 'nautical'>('distanceUnits', 'metric'), - velocityUnits: new Setting<'speed' | 'pace'>('velocityUnits', 'speed'), - temperatureUnits: new Setting<'celsius' | 'fahrenheit'>('temperatureUnits', 'celsius'), + distanceUnits: new Setting( + 'distanceUnits', + 'metric', + getValueValidator(['metric', 'imperial', 'nautical'], 'metric') + ), + velocityUnits: new Setting( + 'velocityUnits', + 'speed', + getValueValidator(['speed', 'pace'], 'speed') + ), + temperatureUnits: new Setting( + 'temperatureUnits', + 'celsius', + getValueValidator(['celsius', 'fahrenheit'], 'celsius') + ), elevationProfile: new Setting('elevationProfile', true), - additionalDatasets: new Setting('additionalDatasets', []), - elevationFill: new Setting<'slope' | 'surface' | undefined>('elevationFill', undefined), + additionalDatasets: new Setting( + 'additionalDatasets', + [], + getArrayValidator(['speed', 'hr', 'cad', 'atemp', 'power']) + ), + elevationFill: new Setting( + 'elevationFill', + undefined, + getValueValidator(['slope', 'surface', undefined], undefined) + ), treeFileView: new Setting('fileView', false), minimizeRoutingMenu: new Setting('minimizeRoutingMenu', false), routing: new Setting('routing', true), - routingProfile: new Setting('routingProfile', 'bike'), + routingProfile: new Setting( + 'routingProfile', + 'bike', + getValueValidator( + [ + 'bike', + 'racing_bike', + 'gravel_bike', + 'mountain_bike', + 'foot', + 'motorcycle', + 'water', + 'railway', + ], + 'bike' + ) + ), privateRoads: new Setting('privateRoads', false), - currentBasemap: new Setting('currentBasemap', defaultBasemap), - previousBasemap: new Setting('previousBasemap', defaultBasemap), - selectedBasemapTree: new Setting('selectedBasemapTree', defaultBasemapTree), - currentOverlays: new SettingInitOnFirstRead('currentOverlays', defaultOverlays), - previousOverlays: new Setting('previousOverlays', defaultOverlays), - selectedOverlayTree: new Setting('selectedOverlayTree', defaultOverlayTree), + currentBasemap: new Setting( + 'currentBasemap', + defaultBasemap, + getLayerValidator(basemaps, defaultBasemap) + ), + previousBasemap: new Setting( + 'previousBasemap', + defaultBasemap, + getLayerValidator(Object.keys(basemaps), defaultBasemap) + ), + selectedBasemapTree: new Setting( + 'selectedBasemapTree', + defaultBasemapTree, + getLayerTreeValidator(basemaps) + ), + currentOverlays: new SettingInitOnFirstRead( + 'currentOverlays', + defaultOverlays, + getLayerTreeValidator(overlays) + ), + previousOverlays: new Setting( + 'previousOverlays', + defaultOverlays, + getLayerTreeValidator(overlays) + ), + selectedOverlayTree: new Setting( + 'selectedOverlayTree', + defaultOverlayTree, + getLayerTreeValidator(overlays) + ), currentOverpassQueries: new SettingInitOnFirstRead( 'currentOverpassQueries', - defaultOverpassQueries + defaultOverpassQueries, + getLayerTreeValidator(overpassQueryData) + ), + selectedOverpassTree: new Setting( + 'selectedOverpassTree', + defaultOverpassTree, + getLayerTreeValidator(overpassQueryData) ), - selectedOverpassTree: new Setting('selectedOverpassTree', defaultOverpassTree), opacities: new Setting('opacities', defaultOpacities), customLayers: new Setting>('customLayers', {}), customBasemapOrder: new Setting('customBasemapOrder', []), customOverlayOrder: new Setting('customOverlayOrder', []), - terrainSource: new Setting('terrainSource', defaultTerrainSource), + terrainSource: new Setting( + 'terrainSource', + defaultTerrainSource, + getValueValidator(['maptiler-dem', 'mapterhorn'], defaultTerrainSource) + ), directionMarkers: new Setting('directionMarkers', false), distanceMarkers: new Setting('distanceMarkers', false), - streetViewSource: new Setting('streetViewSource', 'mapillary'), + streetViewSource: new Setting( + 'streetViewSource', + 'mapillary', + getValueValidator(['mapillary', 'google'], 'mapillary') + ), fileOrder: new Setting('fileOrder', []), defaultOpacity: new Setting('defaultOpacity', 0.7), defaultWidth: new Setting('defaultWidth', browser && window.innerWidth < 600 ? 8 : 5), diff --git a/website/src/lib/logic/statistics-tree.ts b/website/src/lib/logic/statistics-tree.ts index 6ef8041c3..38d6a6a0c 100644 --- a/website/src/lib/logic/statistics-tree.ts +++ b/website/src/lib/logic/statistics-tree.ts @@ -1,18 +1,24 @@ import { ListItem, ListLevel } from '$lib/components/file-list/file-list'; import { GPXFile, GPXStatistics, GPXStatisticsGroup, type Track } from 'gpx'; +import maplibregl from 'maplibre-gl'; export class GPXStatisticsTree { level: ListLevel; statistics: { [key: string]: GPXStatisticsTree | GPXStatistics; } = {}; + wptBounds: maplibregl.LngLatBounds; constructor(element: GPXFile | Track) { + this.wptBounds = new maplibregl.LngLatBounds(); if (element instanceof GPXFile) { this.level = ListLevel.FILE; element.children.forEach((child, index) => { this.statistics[index] = new GPXStatisticsTree(child); }); + element.wpt.forEach((wpt) => { + this.wptBounds.extend(wpt.getCoordinates()); + }); } else { this.level = ListLevel.TRACK; element.children.forEach((child, index) => { @@ -42,5 +48,27 @@ export class GPXStatisticsTree { } return statistics; } + + intersectsBBox(bounds: maplibregl.LngLatBounds): boolean { + for (let key in this.statistics) { + const stats = this.statistics[key]; + if (stats instanceof GPXStatistics) { + const bbox = new maplibregl.LngLatBounds( + stats.global.bounds.southWest, + stats.global.bounds.northEast + ); + if (!bbox.isEmpty() && bbox.intersects(bounds)) { + return true; + } + } else if (stats.intersectsBBox(bounds)) { + return true; + } + } + return false; + } + + intersectsWaypointBBox(bounds: maplibregl.LngLatBounds): boolean { + return !this.wptBounds.isEmpty() && this.wptBounds.intersects(bounds); + } } export type GPXFileWithStatistics = { file: GPXFile; statistics: GPXStatisticsTree }; diff --git a/website/src/lib/logic/statistics.ts b/website/src/lib/logic/statistics.ts index 1193c21a0..45322ce9c 100644 --- a/website/src/lib/logic/statistics.ts +++ b/website/src/lib/logic/statistics.ts @@ -1,5 +1,5 @@ import { selection } from '$lib/logic/selection'; -import { GPXGlobalStatistics, GPXStatisticsGroup } from 'gpx'; +import { GPXGlobalStatistics, GPXStatisticsGroup, type Coordinates } from 'gpx'; import { fileStateCollection, GPXFileState } from '$lib/logic/file-state'; import { ListFileItem, @@ -82,6 +82,8 @@ export const gpxStatistics = new SelectedGPXStatistics(); export const slicedGPXStatistics: Writable<[GPXGlobalStatistics, number, number] | undefined> = writable(undefined); +export const hoveredPoint: Writable = writable(null); + gpxStatistics.subscribe(() => { slicedGPXStatistics.set(undefined); }); diff --git a/website/src/lib/utils.ts b/website/src/lib/utils.ts index 035de5e97..a030374a1 100644 --- a/website/src/lib/utils.ts +++ b/website/src/lib/utils.ts @@ -3,12 +3,11 @@ import { twMerge } from 'tailwind-merge'; import { base } from '$app/paths'; import { languages } from '$lib/languages'; import { TrackPoint, Waypoint, type Coordinates, crossarcDistance, distance, GPXFile } from 'gpx'; -import mapboxgl from 'mapbox-gl'; +import maplibregl from 'maplibre-gl'; import { pointToTile, pointToTileFraction } from '@mapbox/tilebelt'; -import { PUBLIC_MAPBOX_TOKEN } from '$env/static/public'; -import PNGReader from 'png.js'; import type { GPXStatisticsTree } from '$lib/logic/statistics-tree'; import { ListTrackSegmentItem } from '$lib/components/file-list/file-list'; +import { PUBLIC_MAPTILER_KEY } from '$env/static/public'; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); @@ -62,7 +61,7 @@ export function getClosestTrackSegments( let segmentBounds = segmentStatistics.global.bounds; let northEast = segmentBounds.northEast; let southWest = segmentBounds.southWest; - let bounds = new mapboxgl.LngLatBounds(southWest, northEast); + let bounds = new maplibregl.LngLatBounds(southWest, northEast); if (bounds.contains(point)) { segmentBoundsDistances.push([0, trackIndex, segmentIndex]); } else { @@ -110,33 +109,49 @@ export function getElevation( let coordinates = points.map((point) => point instanceof TrackPoint || point instanceof Waypoint ? point.getCoordinates() : point ); - let bbox = new mapboxgl.LngLatBounds(); + let bbox = new maplibregl.LngLatBounds(); coordinates.forEach((coord) => bbox.extend(coord)); let tiles = coordinates.map((coord) => pointToTile(coord.lon, coord.lat, ELEVATION_ZOOM)); let uniqueTiles = Array.from(new Set(tiles.map((tile) => tile.join(',')))).map((tile) => tile.split(',').map((x) => parseInt(x)) ); - let pngs = new Map(); + let images = new Map(); + + const getPixelFromImageData = (imageData: ImageData, x: number, y: number): number[] => { + const index = (y * imageData.width + x) * 4; + return [imageData.data[index], imageData.data[index + 1], imageData.data[index + 2]]; + }; let promises = uniqueTiles.map((tile) => fetch( - `https://api.mapbox.com/v4/mapbox.mapbox-terrain-dem-v1/${ELEVATION_ZOOM}/${tile[0]}/${tile[1]}@2x.pngraw?access_token=${PUBLIC_MAPBOX_TOKEN}`, + `https://api.maptiler.com/tiles/terrain-rgb-v2/${ELEVATION_ZOOM}/${tile[0]}/${tile[1]}.webp?key=${PUBLIC_MAPTILER_KEY}`, { cache: 'force-cache' } ) - .then((response) => response.arrayBuffer()) + .then((response) => response.blob()) .then( - (buffer) => - new Promise((resolve) => { - let png = new PNGReader(new Uint8Array(buffer)); - png.parse((err, png) => { - if (err) { - resolve(false); // Also resolve so that Promise.all doesn't fail - } else { - pngs.set(tile.join(','), png); - resolve(true); + (blob) => + new Promise((resolve) => { + const url = URL.createObjectURL(blob); + const img = new Image(); + img.onload = () => { + const canvas = document.createElement('canvas'); + canvas.width = img.width; + canvas.height = img.height; + const ctx = canvas.getContext('2d'); + if (ctx) { + ctx.drawImage(img, 0, 0); + const imageData = ctx.getImageData(0, 0, img.width, img.height); + images.set(tile.join(','), imageData); } - }); + URL.revokeObjectURL(url); + resolve(); + }; + img.onerror = () => { + URL.revokeObjectURL(url); + resolve(); + }; + img.src = url; }) ) ); @@ -144,9 +159,9 @@ export function getElevation( return Promise.all(promises).then(() => coordinates.map((coord, index) => { let tile = tiles[index]; - let png = pngs.get(tile.join(',')); + let imageData = images.get(tile.join(',')); - if (!png) { + if (!imageData) { return 0; } @@ -158,10 +173,11 @@ export function getElevation( let dx = x - _x; let dy = y - _y; - const p00 = png.getPixel(_x, _y); - const p01 = png.getPixel(_x, _y + (_y + 1 == tileSize ? 0 : 1)); - const p10 = png.getPixel(_x + (_x + 1 == tileSize ? 0 : 1), _y); - const p11 = png.getPixel( + const p00 = getPixelFromImageData(imageData, _x, _y); + const p01 = getPixelFromImageData(imageData, _x, _y + (_y + 1 == tileSize ? 0 : 1)); + const p10 = getPixelFromImageData(imageData, _x + (_x + 1 == tileSize ? 0 : 1), _y); + const p11 = getPixelFromImageData( + imageData, _x + (_x + 1 == tileSize ? 0 : 1), _y + (_y + 1 == tileSize ? 0 : 1) ); @@ -181,6 +197,18 @@ export function getElevation( ); } +export function loadSVGIcon(map: maplibregl.Map, id: string, svg: string, size: number = 100) { + if (!map.hasImage(id)) { + let icon = new Image(size, size); + icon.onload = () => { + if (!map.hasImage(id)) { + map.addImage(id, icon); + } + }; + icon.src = 'data:image/svg+xml,' + encodeURIComponent(svg); + } +} + export function isMac() { return navigator.userAgent.toUpperCase().indexOf('MAC') >= 0; } diff --git a/website/src/locales/en.json b/website/src/locales/en.json index 61a8b816a..77d3b103f 100644 --- a/website/src/locales/en.json +++ b/website/src/locales/en.json @@ -233,7 +233,7 @@ }, "elevation": { "button": "Request elevation data", - "help": "Requesting elevation data will erase the existing elevation data, if any, and replace it with data from Mapbox.", + "help": "Requesting elevation data will erase the existing elevation data, if any, and replace it with data from MapTiler.", "help_no_selection": "Select a file item to request elevation data." }, "waypoint": { @@ -275,7 +275,7 @@ "new": "New custom layer", "edit": "Edit custom layer", "urls": "URL(s)", - "url_placeholder": "WMTS, WMS or Mapbox style JSON", + "url_placeholder": "WMTS, WMS or MapLibre style JSON", "max_zoom": "Max zoom", "layer_type": "Layer type", "basemap": "Basemap", @@ -302,8 +302,9 @@ "switzerland": "Switzerland", "united_kingdom": "United Kingdom", "united_states": "United States", - "mapboxOutdoors": "Mapbox Outdoors", - "mapboxSatellite": "Mapbox Satellite", + "maptilerTopo": "MapTiler Topo", + "maptilerOutdoors": "MapTiler Outdoors", + "maptilerSatellite": "MapTiler Satellite", "openStreetMap": "OpenStreetMap", "openTopoMap": "OpenTopoMap", "openHikingMap": "OpenHikingMap", @@ -383,7 +384,7 @@ "tram-stop": "Tram Stop", "bus-stop": "Bus Stop", "ferry": "Ferry", - "mapbox-dem": "Mapbox DEM", + "maptiler-dem": "MapTiler DEM", "mapterhorn": "Mapterhorn" } }, @@ -525,7 +526,7 @@ }, "embedding": { "title": "Create your own map", - "mapbox_token": "Mapbox access token", + "maptiler_key": "MapTiler key", "file_urls": "File URLs (separated by commas)", "drive_ids": "Google Drive file IDs (separated by commas)", "basemap": "Basemap", diff --git a/website/src/routes/[[language]]/+page.svelte b/website/src/routes/[[language]]/+page.svelte index 6e787d33b..fedc63bd8 100644 --- a/website/src/routes/[[language]]/+page.svelte +++ b/website/src/routes/[[language]]/+page.svelte @@ -29,12 +29,12 @@ data: { fundingModule: Promise; translationModule: Promise; - mapboxModule: Promise; }; } = $props(); let gpxStatistics = writable(exampleGPXFile.getStatistics()); let slicedGPXStatistics = writable(undefined); + let hoveredPoint = writable(null); let additionalDatasets = writable(['speed', 'atemp']); let elevationFill = writable(undefined); @@ -152,14 +152,14 @@ class="relative w-full max-w-[320px] aspect-square rounded-2xl shadow-xl overflow-clip" > @@ -197,6 +197,7 @@ @@ -270,23 +271,4 @@
-
-
-
-
- ❤️ {i18n._('homepage.supported_by')} -
- - - -
- {#await data.mapboxModule then mapboxModule} - - {/await} -
-
diff --git a/website/src/routes/[[language]]/+page.ts b/website/src/routes/[[language]]/+page.ts index 3d34cc7ea..64f864778 100644 --- a/website/src/routes/[[language]]/+page.ts +++ b/website/src/routes/[[language]]/+page.ts @@ -9,6 +9,5 @@ export async function load({ params }) { return { fundingModule: getModule(language, 'funding'), translationModule: getModule(language, 'translation'), - mapboxModule: getModule(language, 'mapbox'), }; } diff --git a/website/src/routes/[[language]]/app/+page.svelte b/website/src/routes/[[language]]/app/+page.svelte index 56f0098d5..5cec7b973 100644 --- a/website/src/routes/[[language]]/app/+page.svelte +++ b/website/src/routes/[[language]]/app/+page.svelte @@ -16,7 +16,7 @@ import { loadFiles } from '$lib/logic/file-actions'; import { onDestroy, onMount } from 'svelte'; import { page } from '$app/state'; - import { gpxStatistics, slicedGPXStatistics } from '$lib/logic/statistics'; + import { gpxStatistics, hoveredPoint, slicedGPXStatistics } from '$lib/logic/statistics'; import { getURLForGoogleDriveFile } from '$lib/components/embedding/embedding'; import { db } from '$lib/db'; import { fileStateCollection } from '$lib/logic/file-state'; @@ -30,6 +30,11 @@ elevationFill, } = settings; + let bottomPanelWidth: number | undefined = $state(); + let bottomPanelOrientation = $derived( + bottomPanelWidth && bottomPanelWidth >= 540 && $elevationProfile ? 'horizontal' : 'vertical' + ); + onMount(async () => { settings.connectToDatabase(db); fileStateCollection.connectToDatabase(db).then(() => { @@ -127,19 +132,23 @@ /> {/if}
{#if $elevationProfile} diff --git a/website/static/mapbox-logo-black.svg b/website/static/mapbox-logo-black.svg deleted file mode 100644 index a0cbd94d5..000000000 --- a/website/static/mapbox-logo-black.svg +++ /dev/null @@ -1,38 +0,0 @@ - - - -Mapbox_Logo_08 - - - - - - - - - - - - - - - diff --git a/website/static/mapbox-logo-white.svg b/website/static/mapbox-logo-white.svg deleted file mode 100644 index 8d62aef0e..000000000 --- a/website/static/mapbox-logo-white.svg +++ /dev/null @@ -1,42 +0,0 @@ - - - - -Mapbox_Logo_08 - - - - - - - - - - - - - - - diff --git a/website/static/maptiler-logo-dark.svg b/website/static/maptiler-logo-dark.svg new file mode 100644 index 000000000..2f60017f2 --- /dev/null +++ b/website/static/maptiler-logo-dark.svg @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/static/maptiler-logo.svg b/website/static/maptiler-logo.svg new file mode 100644 index 000000000..626f9f69b --- /dev/null +++ b/website/static/maptiler-logo.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + +