From 63b9e8ead0f4cc56bfa74c935a56d09868ae3132 Mon Sep 17 00:00:00 2001 From: KeziahMoselle Date: Wed, 20 Mar 2024 16:35:24 +0100 Subject: [PATCH 01/13] Add MapboxMap, MapboxMarker, MapboxPopup components --- package-lock.json | 331 +++++++++++++++++++++++++- packages/ui/MapboxMap/MapboxMap.ts | 89 +++++++ packages/ui/MapboxMap/MapboxMarker.ts | 58 +++++ packages/ui/MapboxMap/MapboxPopup.ts | 68 ++++++ packages/ui/MapboxMap/index.ts | 3 + packages/ui/index.ts | 1 + packages/ui/package.json | 6 +- 7 files changed, 552 insertions(+), 4 deletions(-) create mode 100644 packages/ui/MapboxMap/MapboxMap.ts create mode 100644 packages/ui/MapboxMap/MapboxMarker.ts create mode 100644 packages/ui/MapboxMap/MapboxPopup.ts create mode 100644 packages/ui/MapboxMap/index.ts diff --git a/package-lock.json b/package-lock.json index cf3918d5..cec87a69 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2450,6 +2450,63 @@ "tslib": "2" } }, + "node_modules/@mapbox/jsonlint-lines-primitives": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz", + "integrity": "sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==", + "dev": true, + "engines": { + "node": ">= 0.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==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@mapbox/point-geometry": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz", + "integrity": "sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==", + "dev": true, + "license": "ISC" + }, + "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==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/@mapbox/unitbezier": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz", + "integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/@mapbox/vector-tile": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz", + "integrity": "sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@mapbox/point-geometry": "~0.1.0" + } + }, + "node_modules/@mapbox/whoots-js": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz", + "integrity": "sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@motionone/easing": { "version": "10.18.0", "resolved": "https://registry.npmjs.org/@motionone/easing/-/easing-10.18.0.tgz", @@ -3517,6 +3574,23 @@ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "license": "MIT" }, + "node_modules/@types/geojson": { + "version": "7946.0.16", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", + "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/geojson-vt": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/@types/geojson-vt/-/geojson-vt-3.2.5.tgz", + "integrity": "sha512-qDO7wqtprzlpe8FfQ//ClPV9xiuoh2nkIgiouIptON9w5jvD/fA4szvP9GBlDVdJ5dldAl0kX/sy3URbWwLx0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, "node_modules/@types/hast": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", @@ -3562,6 +3636,25 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "license": "MIT" }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mapbox__vector-tile": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.4.tgz", + "integrity": "sha512-bpd8dRn9pr6xKvuEBQup8pwQfD4VUyqO/2deGjfpe6AwC8YRlyEipvefyRJUSiCJTZuCb8Pl1ciVV5ekqJ96Bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/geojson": "*", + "@types/mapbox__point-geometry": "*", + "@types/pbf": "*" + } + }, "node_modules/@types/mdast": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", @@ -3586,6 +3679,13 @@ "undici-types": "~7.8.0" } }, + "node_modules/@types/pbf": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.5.tgz", + "integrity": "sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/readdir-glob": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/@types/readdir-glob/-/readdir-glob-1.1.5.tgz", @@ -3601,6 +3701,16 @@ "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", "license": "MIT" }, + "node_modules/@types/supercluster": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.3.tgz", + "integrity": "sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, "node_modules/@types/unist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", @@ -5434,6 +5544,13 @@ "url": "https://github.com/sponsors/wooorm" } }, + "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==", + "dev": true, + "license": "ISC" + }, "node_modules/check-error": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", @@ -6140,6 +6257,13 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/csscolorparser": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz", + "integrity": "sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w==", + "dev": true, + "license": "MIT" + }, "node_modules/cssdb": { "version": "8.3.1", "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-8.3.1.tgz", @@ -6626,6 +6750,13 @@ "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "license": "MIT" }, + "node_modules/earcut": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.2.tgz", + "integrity": "sha512-X7hshQbLyMJ/3RPhyObLARM2sNxxmRALLKx1+NVFFnQ9gKzmCrxm9+uLIAdBcvc8FNLpctqlQ2V6AE92Ol9UDQ==", + "dev": true, + "license": "ISC" + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -7496,6 +7627,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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==", + "dev": true, + "license": "ISC" + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -7566,6 +7704,13 @@ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, + "node_modules/gl-matrix": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz", + "integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==", + "dev": true, + "license": "MIT" + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -7662,6 +7807,13 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, + "node_modules/grid-index": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/grid-index/-/grid-index-1.1.0.tgz", + "integrity": "sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA==", + "dev": true, + "license": "ISC" + }, "node_modules/gzip-size": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-7.0.0.tgz", @@ -8877,6 +9029,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/kdbush": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz", + "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==", + "dev": true, + "license": "ISC" + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -9233,6 +9392,48 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mapbox-gl": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-3.13.0.tgz", + "integrity": "sha512-TSSJIvDKsiSPk22889FWk9V4mmjljbizUf8Y2Jhho2j0Mj4zonC6kKwoVLf3oGqYWTZ+oQrd0Cxg6LCmZmPPbQ==", + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "workspaces": [ + "src/style-spec", + "test/build/typings" + ], + "dependencies": { + "@mapbox/jsonlint-lines-primitives": "^2.0.2", + "@mapbox/mapbox-gl-supported": "^3.0.0", + "@mapbox/point-geometry": "^0.1.0", + "@mapbox/tiny-sdf": "^2.0.6", + "@mapbox/unitbezier": "^0.0.1", + "@mapbox/vector-tile": "^1.3.1", + "@mapbox/whoots-js": "^3.1.0", + "@types/geojson": "^7946.0.16", + "@types/geojson-vt": "^3.2.5", + "@types/mapbox__point-geometry": "^0.1.4", + "@types/mapbox__vector-tile": "^1.3.4", + "@types/pbf": "^3.0.5", + "@types/supercluster": "^7.1.3", + "cheap-ruler": "^4.0.0", + "csscolorparser": "~1.0.3", + "earcut": "^3.0.1", + "geojson-vt": "^4.0.2", + "gl-matrix": "^3.4.3", + "grid-index": "^1.1.0", + "kdbush": "^4.0.2", + "martinez-polygon-clipping": "^0.7.4", + "murmurhash-js": "^1.0.0", + "pbf": "^3.2.1", + "potpack": "^2.0.0", + "quickselect": "^3.0.0", + "serialize-to-js": "^3.1.2", + "supercluster": "^8.0.1", + "tinyqueue": "^3.0.0", + "vt-pbf": "^3.1.3" + } + }, "node_modules/mark.js": { "version": "8.11.1", "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", @@ -9251,6 +9452,25 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/martinez-polygon-clipping": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/martinez-polygon-clipping/-/martinez-polygon-clipping-0.7.4.tgz", + "integrity": "sha512-jBEwrKtA0jTagUZj2bnmb4Yg2s4KnJGRePStgI7bAVjtcipKiF39R4LZ2V/UT61jMYWrTcBhPazexeqd6JAVtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "robust-predicates": "^2.0.4", + "splaytree": "^0.1.4", + "tinyqueue": "^1.2.0" + } + }, + "node_modules/martinez-polygon-clipping/node_modules/tinyqueue": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-1.2.3.tgz", + "integrity": "sha512-Qz9RgWuO9l8lT+Y9xvbzhPT2efIUIFd69N7eF7tJ9lnQl0iLj1M7peK7IoUGZL9DJHw9XftqLreccfxcQgYLxA==", + "dev": true, + "license": "ISC" + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -10297,6 +10517,13 @@ "dev": true, "license": "MIT" }, + "node_modules/murmurhash-js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", + "integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==", + "dev": true, + "license": "MIT" + }, "node_modules/mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", @@ -10840,6 +11067,20 @@ "node": ">= 14.16" } }, + "node_modules/pbf": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.3.0.tgz", + "integrity": "sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "ieee754": "^1.1.12", + "resolve-protobuf-schema": "^2.1.0" + }, + "bin": { + "pbf": "bin/pbf" + } + }, "node_modules/perfect-debounce": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", @@ -12190,6 +12431,13 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "license": "MIT" }, + "node_modules/potpack": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/potpack/-/potpack-2.1.0.tgz", + "integrity": "sha512-pcaShQc1Shq0y+E7GqJqvZj8DTthWV1KeHGdi0Z6IAin2Oi3JnLCOfwnCo84qc+HAp52wT9nK9H7FAJp5a44GQ==", + "dev": true, + "license": "ISC" + }, "node_modules/preact": { "version": "10.26.9", "resolved": "https://registry.npmjs.org/preact/-/preact-10.26.9.tgz", @@ -12279,6 +12527,13 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/protocol-buffers-schema": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", + "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==", + "dev": true, + "license": "MIT" + }, "node_modules/quansync": { "version": "0.2.10", "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.10.tgz", @@ -12316,6 +12571,13 @@ ], "license": "MIT" }, + "node_modules/quickselect": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz", + "integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==", + "dev": true, + "license": "ISC" + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -13409,6 +13671,16 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, + "node_modules/resolve-protobuf-schema": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz", + "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "protocol-buffers-schema": "^3.3.1" + } + }, "node_modules/resolve-url-loader": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz", @@ -13467,6 +13739,13 @@ "rimraf": "bin.js" } }, + "node_modules/robust-predicates": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-2.0.4.tgz", + "integrity": "sha512-l4NwboJM74Ilm4VKfbAtFeGq7aEjWL+5kVFcmgFA2MrdnQWx9iE/tUGvxY5HyMI7o/WpSIUFLbC5fbeaHgSCYg==", + "dev": true, + "license": "Unlicense" + }, "node_modules/rollup": { "version": "4.45.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.45.1.tgz", @@ -14053,6 +14332,16 @@ "randombytes": "^2.1.0" } }, + "node_modules/serialize-to-js": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/serialize-to-js/-/serialize-to-js-3.1.2.tgz", + "integrity": "sha512-owllqNuDDEimQat7EPG0tH7JjO090xKNzUtYz6X+Sk2BXDnOCilDdNLwjWeFywG9xkJul1ULvtUQa9O4pUaY0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", @@ -14563,6 +14852,13 @@ "node": ">=0.10.0" } }, + "node_modules/splaytree": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/splaytree/-/splaytree-0.1.4.tgz", + "integrity": "sha512-D50hKrjZgBzqD3FT2Ek53f2dcDLAQT8SSGrzj3vidNH5ISRgceeGVJ2dQIthKOuayqFXfFjXheHNo4bbt9LhRQ==", + "dev": true, + "license": "MIT" + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -14896,6 +15192,16 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/supercluster": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz", + "integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "kdbush": "^4.0.2" + } + }, "node_modules/superjson": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz", @@ -15429,6 +15735,13 @@ "node": "^18.0.0 || >=20.0.0" } }, + "node_modules/tinyqueue": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz", + "integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==", + "dev": true, + "license": "ISC" + }, "node_modules/tinyrainbow": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", @@ -16688,6 +17001,18 @@ } } }, + "node_modules/vt-pbf": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/vt-pbf/-/vt-pbf-3.1.3.tgz", + "integrity": "sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mapbox/point-geometry": "0.1.0", + "@mapbox/vector-tile": "^1.3.1", + "pbf": "^3.2.1" + } + }, "node_modules/vue": { "version": "3.5.17", "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.17.tgz", @@ -17423,10 +17748,12 @@ "morphdom": "^2.7.5" }, "devDependencies": { - "@studiometa/js-toolkit": "3.0.5" + "@studiometa/js-toolkit": "3.0.5", + "mapbox-gl": "^3.13.0" }, "peerDependencies": { - "@studiometa/js-toolkit": "^3.0.5" + "@studiometa/js-toolkit": "^3.0.5", + "mapbox-gl": "^3.13.0" } } } diff --git a/packages/ui/MapboxMap/MapboxMap.ts b/packages/ui/MapboxMap/MapboxMap.ts new file mode 100644 index 00000000..9d18e70e --- /dev/null +++ b/packages/ui/MapboxMap/MapboxMap.ts @@ -0,0 +1,89 @@ +import { + Base, + type BaseConfig, + type BaseConstructor, + type BaseProps, +} from '@studiometa/js-toolkit'; +import { Map } from 'mapbox-gl'; +import { MapboxMarker } from './MapboxMarker.js'; +import { MapboxPopup } from './MapboxPopup.js'; + +export interface MapboxMapProps extends BaseProps { + $refs: { + container: HTMLElement; + }, + $children: { + MapboxMarker: MapboxMarker[]; + }; + $options: { + accessToken: string; + zoom: number; + center: [number, number]; + }; +} + +function resolveWhenMapIsLoaded(Component: T) { + return (mapboxMap: MapboxMap): Promise => { + return new Promise((resolve) => { + if (mapboxMap.isLoaded) { + resolve(Component); + } else { + mapboxMap.$on( + 'map-load', + () => { + resolve(Component); + }, + { once: true }, + ); + } + }); + }; +} + +export class MapboxMap extends Base { + static config: BaseConfig = { + name: 'MapboxMap', + emits: ['map-load'], + refs: ['container'], + options: { + accessToken: String, + zoom: Number, + center: { type: Array, default: () => [0, 0] }, + }, + components: { + MapboxMarker: resolveWhenMapIsLoaded(MapboxMarker), + MapboxPopup: resolveWhenMapIsLoaded(MapboxPopup), + }, + }; + + isLoaded = false; + + __map: Map; + + get map() { + if (!this.__map) { + this.__map = new Map(this.mapboxOptions); + } + + return this.__map; + } + + get mapboxOptions() { + return { + container: this.$refs.container ?? this.$el, + ...this.$options, + }; + } + + async mounted() { + this.map.on('load', () => { + this.isLoaded = true; + this.$emit('map-load', this.map); + }); + } + + destroyed() { + this.map?.remove(); + this.__map = undefined; + } +} diff --git a/packages/ui/MapboxMap/MapboxMarker.ts b/packages/ui/MapboxMap/MapboxMarker.ts new file mode 100644 index 00000000..630958c8 --- /dev/null +++ b/packages/ui/MapboxMap/MapboxMarker.ts @@ -0,0 +1,58 @@ +import { Base, type BaseProps, type BaseConfig, getClosestParent } from '@studiometa/js-toolkit'; +import { Marker } from 'mapbox-gl'; +import { MapboxMap } from './MapboxMap.js'; + +export interface MapboxMarkerProps extends BaseProps { + $options: { + lng: number; + lat: number; + markerOptions: any; + }; +} + +export class MapboxMarker extends Base { + static config: BaseConfig = { + name: 'MapboxMarker', + options: { + lng: Number, + lat: Number, + // Marker options. (https://docs.mapbox.com/mapbox-gl-js/api/markers#marker) + markerOptions: Object, + }, + }; + + __marker: Marker; + + get marker() { + if (!this.__marker) { + this.__marker = new Marker(this.markerOptions); + } + + return this.__marker; + } + + get map() { + return getClosestParent(this, MapboxMap)?.map; + } + + get markerOptions() { + if (this.$options.markerOptions) { + return this.$options.markerOptions; + } + + return {}; + } + + get lngLat(): [number, number] { + return [this.$options.lng, this.$options.lat]; + } + + mounted() { + this.marker.setLngLat(this.lngLat).addTo(this.map); + } + + destroyed() { + this.marker?.remove(); + this.__marker = undefined; + } +} diff --git a/packages/ui/MapboxMap/MapboxPopup.ts b/packages/ui/MapboxMap/MapboxPopup.ts new file mode 100644 index 00000000..349732f1 --- /dev/null +++ b/packages/ui/MapboxMap/MapboxPopup.ts @@ -0,0 +1,68 @@ +import { Base, BaseConfig, BaseProps, getClosestParent } from '@studiometa/js-toolkit'; +import { Popup, PopupOptions } from 'mapbox-gl'; +import { MapboxMap } from './MapboxMap.js'; + +export interface MapboxPopupProps extends BaseProps { + $el: HTMLTemplateElement; + $options: { + lat: number; + lng: number; + /** + * Popup options. + * @see https://docs.mapbox.com/mapbox-gl-js/api/markers#popup + */ + popupOptions: PopupOptions; + }; +} + +export class MapboxPopup extends Base { + static config: BaseConfig = { + name: 'MapboxPopup', + options: { + lng: Number, + lat: Number, + popupOptions: Object, + }, + }; + + __popup: Popup; + + get popup() { + if (!this.__popup) { + this.__popup = new Popup(); + } + + return this.__popup; + } + + get map() { + return getClosestParent(this, MapboxMap)?.map; + } + + get popupOptions() { + if (this.$options.popupOptions) { + return this.$options.popupOptions; + } + + return {}; + } + + get lngLat(): [number, number] { + return [this.$options.lng, this.$options.lat]; + } + + mounted() { + this.popup.setLngLat(this.lngLat).addTo(this.map); + + if (this.$el.content.childNodes.length === 1) { + this.popup.setDOMContent(this.$el.content.firstChild); + } else if (this.$el.content.childNodes.length > 1) { + this.popup.setHTML(this.$el.innerHTML); + } + } + + destroyed() { + this.popup?.remove(); + this.__popup = undefined; + } +} diff --git a/packages/ui/MapboxMap/index.ts b/packages/ui/MapboxMap/index.ts new file mode 100644 index 00000000..8be253a9 --- /dev/null +++ b/packages/ui/MapboxMap/index.ts @@ -0,0 +1,3 @@ +export * from './MapboxMap.js'; +export * from './MapboxMarker.js'; +export * from './MapboxPopup.js'; diff --git a/packages/ui/index.ts b/packages/ui/index.ts index 48ca4f4d..6bd3f2c9 100644 --- a/packages/ui/index.ts +++ b/packages/ui/index.ts @@ -24,3 +24,4 @@ export * from './Slider/index.js'; export * from './Sticky/index.js'; export * from './Tabs/index.js'; export * from './Transition/index.js'; +export * from './MapboxMap/index.js'; diff --git a/packages/ui/package.json b/packages/ui/package.json index 841b998e..9eea2a54 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -33,9 +33,11 @@ "morphdom": "^2.7.5" }, "devDependencies": { - "@studiometa/js-toolkit": "3.0.5" + "@studiometa/js-toolkit": "3.0.5", + "mapbox-gl": "^3.13.0" }, "peerDependencies": { - "@studiometa/js-toolkit": "^3.0.5" + "@studiometa/js-toolkit": "^3.0.5", + "mapbox-gl": "^3.13.0" } } From 3b5a590c7965f59cc7b7942e987c35fa9a71ccfd Mon Sep 17 00:00:00 2001 From: Titouan Mathis Date: Fri, 25 Jul 2025 16:08:27 +0200 Subject: [PATCH 02/13] Update docs --- .../docs/components/MapboxMap/examples.md | 28 ++++++++++ packages/docs/components/MapboxMap/index.md | 51 +++++++++++++++++++ packages/docs/components/MapboxMap/js-api.md | 5 ++ .../components/MapboxMap/stories/map/app.css | 10 ++++ .../components/MapboxMap/stories/map/app.js | 13 +++++ .../components/MapboxMap/stories/map/app.twig | 5 ++ .../MapboxMap/stories/markers/app.css | 10 ++++ .../MapboxMap/stories/markers/app.js | 31 +++++++++++ .../MapboxMap/stories/markers/app.twig | 42 +++++++++++++++ packages/playground/meta.config.js | 1 + packages/playground/static/mapbox-gl.js | 4 ++ 11 files changed, 200 insertions(+) create mode 100644 packages/docs/components/MapboxMap/examples.md create mode 100644 packages/docs/components/MapboxMap/index.md create mode 100644 packages/docs/components/MapboxMap/js-api.md create mode 100644 packages/docs/components/MapboxMap/stories/map/app.css create mode 100644 packages/docs/components/MapboxMap/stories/map/app.js create mode 100644 packages/docs/components/MapboxMap/stories/map/app.twig create mode 100644 packages/docs/components/MapboxMap/stories/markers/app.css create mode 100644 packages/docs/components/MapboxMap/stories/markers/app.js create mode 100644 packages/docs/components/MapboxMap/stories/markers/app.twig create mode 100644 packages/playground/static/mapbox-gl.js diff --git a/packages/docs/components/MapboxMap/examples.md b/packages/docs/components/MapboxMap/examples.md new file mode 100644 index 00000000..fb61f6c9 --- /dev/null +++ b/packages/docs/components/MapboxMap/examples.md @@ -0,0 +1,28 @@ +--- +title: MapboxMap examples +--- + +# Examples + +## Simple map + + + + +## Markers + + diff --git a/packages/docs/components/MapboxMap/index.md b/packages/docs/components/MapboxMap/index.md new file mode 100644 index 00000000..c0492a88 --- /dev/null +++ b/packages/docs/components/MapboxMap/index.md @@ -0,0 +1,51 @@ +--- +badges: [JS] +--- + +# MapboxMap + +## Table of content + +- [Examples](./examples.md) +- [JS API](./js-api.md) + +## Usage + +Use this component to display a map with [mapbox-gl](https://github.com/mapbox/mapbox-gl-js). + +::: code-group + +```js twoslash [app.js] +import { Base, createApp } from '@studiometa/js-toolkit'; +import { MapboxMap } from '@studiometa/ui'; + +class App extends Base { + static config = { + name: 'App', + components: { + MapboxMap, + }, + }; +} + +export default createApp(App); +``` + +```html [index.html] +
+
+
+``` + +```css [app.css] +@import 'mapbox-gl/dist/mapbox-gl.css'; +``` + + diff --git a/packages/docs/components/MapboxMap/js-api.md b/packages/docs/components/MapboxMap/js-api.md new file mode 100644 index 00000000..ac5ca5fa --- /dev/null +++ b/packages/docs/components/MapboxMap/js-api.md @@ -0,0 +1,5 @@ +--- +title: MapboxMap JS API +--- + +# JS API diff --git a/packages/docs/components/MapboxMap/stories/map/app.css b/packages/docs/components/MapboxMap/stories/map/app.css new file mode 100644 index 00000000..b181222a --- /dev/null +++ b/packages/docs/components/MapboxMap/stories/map/app.css @@ -0,0 +1,10 @@ +@import 'https://esm.sh/mapbox-gl@3.13.0/dist/mapbox-gl.css'; + +html.dark { + background-color: #222; + color: #eee; +} + +body { + padding: 1rem; +} diff --git a/packages/docs/components/MapboxMap/stories/map/app.js b/packages/docs/components/MapboxMap/stories/map/app.js new file mode 100644 index 00000000..a56757ef --- /dev/null +++ b/packages/docs/components/MapboxMap/stories/map/app.js @@ -0,0 +1,13 @@ +import { Base, createApp } from '@studiometa/js-toolkit'; +import { MapboxMap } from '@studiometa/ui'; + +class App extends Base { + static config = { + name: 'App', + components: { + MapboxMap, + }, + }; +} + +createApp(App); diff --git a/packages/docs/components/MapboxMap/stories/map/app.twig b/packages/docs/components/MapboxMap/stories/map/app.twig new file mode 100644 index 00000000..6bea1db7 --- /dev/null +++ b/packages/docs/components/MapboxMap/stories/map/app.twig @@ -0,0 +1,5 @@ +
+
+
diff --git a/packages/docs/components/MapboxMap/stories/markers/app.css b/packages/docs/components/MapboxMap/stories/markers/app.css new file mode 100644 index 00000000..b181222a --- /dev/null +++ b/packages/docs/components/MapboxMap/stories/markers/app.css @@ -0,0 +1,10 @@ +@import 'https://esm.sh/mapbox-gl@3.13.0/dist/mapbox-gl.css'; + +html.dark { + background-color: #222; + color: #eee; +} + +body { + padding: 1rem; +} diff --git a/packages/docs/components/MapboxMap/stories/markers/app.js b/packages/docs/components/MapboxMap/stories/markers/app.js new file mode 100644 index 00000000..a5711e6e --- /dev/null +++ b/packages/docs/components/MapboxMap/stories/markers/app.js @@ -0,0 +1,31 @@ +import { Base, createApp } from '@studiometa/js-toolkit'; +import { createElement, randomInt, randomItem } from '@studiometa/js-toolkit/utils'; +import { MapboxMap } from '@studiometa/ui'; + +class App extends Base { + static config = { + name: 'App', + refs: ['add', 'remove'], + components: { + MapboxMap, + }, + }; + + onAddClick() { + this.$children.MapboxMap[0].$el.append( + createElement('div', { + dataComponent: 'MapboxMarker', + dataOptionLat: randomInt(-50, 50), + dataOptionLng: randomInt(-50, 50), + }), + ); + this.$children.MapboxMap[0].$update(); + } + + onRemoveClick() { + const marker = randomItem(this.$children.MapboxMap[0].$children.MapboxMarker); + marker?.$el.remove(); + } +} + +createApp(App); diff --git a/packages/docs/components/MapboxMap/stories/markers/app.twig b/packages/docs/components/MapboxMap/stories/markers/app.twig new file mode 100644 index 00000000..0428320c --- /dev/null +++ b/packages/docs/components/MapboxMap/stories/markers/app.twig @@ -0,0 +1,42 @@ +
+
+ + + +
+ +
+ {{ + include( + '@ui/Button/StyledButton.twig', + { + label: 'Add marker', + attr: { + data_ref: 'add' + } + } + ) + }} + + {{ + include( + '@ui/Button/StyledButton.twig', + { + label: 'Remove marker', + attr: { + data_ref: 'remove' + } + } + ) + }} +
diff --git a/packages/playground/meta.config.js b/packages/playground/meta.config.js index b063b16c..0076ecc8 100644 --- a/packages/playground/meta.config.js +++ b/packages/playground/meta.config.js @@ -28,6 +28,7 @@ export default defineWebpackConfig({ '@studiometa/ui': '/-/play/static/ui/index.js', deepmerge: '/-/play/static/deepmerge.js', morphdom: '/-/play/static/morphdom.js', + 'mapbox-gl': '/-/play/static/mapbox-gl.js', }, defaults: { html: `{% html_element 'span' with { class: 'dark:text-white font-bold border-b-2 border-current' } %} diff --git a/packages/playground/static/mapbox-gl.js b/packages/playground/static/mapbox-gl.js new file mode 100644 index 00000000..c66aef33 --- /dev/null +++ b/packages/playground/static/mapbox-gl.js @@ -0,0 +1,4 @@ +import mapboxgl from 'mapbox-gl'; +export { Map, Marker, Popup } from 'mapbox-gl'; + +export default mapboxgl; From f26c1ce08476d0903976aa853b921dd8f9c854cb Mon Sep 17 00:00:00 2001 From: Titouan Mathis Date: Fri, 25 Jul 2025 16:08:52 +0200 Subject: [PATCH 03/13] Allow masking of all editors for playground previews --- .../docs/.vitepress/theme/components/PreviewPlayground.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/docs/.vitepress/theme/components/PreviewPlayground.vue b/packages/docs/.vitepress/theme/components/PreviewPlayground.vue index e27e0e4e..e361dbcb 100644 --- a/packages/docs/.vitepress/theme/components/PreviewPlayground.vue +++ b/packages/docs/.vitepress/theme/components/PreviewPlayground.vue @@ -71,8 +71,8 @@ url.searchParams.set('style', css.value); } - url.searchParams.set('html-editor', html.value !== defaultContent ? 'true' : 'false'); - url.searchParams.set('script-editor', script.value !== defaultContent ? 'true' : 'false'); + url.searchParams.set('html-editor', html.value !== defaultContent && props.htmlEditor !== false ? 'true' : 'false'); + url.searchParams.set('script-editor', script.value !== defaultContent && props.scriptEditor !== false ? 'true' : 'false'); url.searchParams.set( 'style-editor', css.value !== defaultContent && [true, null].includes(props.cssEditor) ? 'true' : 'false', From f3195a9a35d6d7bf86e7bad5d686947a57a6562c Mon Sep 17 00:00:00 2001 From: Titouan Mathis Date: Fri, 25 Jul 2025 19:52:41 +0200 Subject: [PATCH 04/13] Use a lngLat options instead of 2 separate options --- packages/ui/MapboxMap/MapboxMarker.ts | 33 +++++++++++------------ packages/ui/MapboxMap/MapboxPopup.ts | 39 +++++++++++++++------------ 2 files changed, 38 insertions(+), 34 deletions(-) diff --git a/packages/ui/MapboxMap/MapboxMarker.ts b/packages/ui/MapboxMap/MapboxMarker.ts index 630958c8..4efabf1f 100644 --- a/packages/ui/MapboxMap/MapboxMarker.ts +++ b/packages/ui/MapboxMap/MapboxMarker.ts @@ -1,21 +1,28 @@ -import { Base, type BaseProps, type BaseConfig, getClosestParent } from '@studiometa/js-toolkit'; +import { type BaseProps, type BaseConfig } from '@studiometa/js-toolkit'; import { Marker } from 'mapbox-gl'; -import { MapboxMap } from './MapboxMap.js'; +import { AbstractMapboxMapChild, AbstractMapboxMapChildProps } from './AbstractMapboxMapChild.js'; -export interface MapboxMarkerProps extends BaseProps { +export interface MapboxMarkerProps extends AbstractMapboxMapChildProps { $options: { - lng: number; - lat: number; + lngLat: [number, number]; markerOptions: any; }; } -export class MapboxMarker extends Base { +/** + * Add a marker to Mapbox map. + * @see https://ui.studiometa.dev/-/components/MapboxMap/ + */ +export class MapboxMarker extends AbstractMapboxMapChild< + T & MapboxMarkerProps +> { static config: BaseConfig = { name: 'MapboxMarker', options: { - lng: Number, - lat: Number, + lngLat: { + type: Array, + default: () => [0, 0], + }, // Marker options. (https://docs.mapbox.com/mapbox-gl-js/api/markers#marker) markerOptions: Object, }, @@ -31,10 +38,6 @@ export class MapboxMarker extends Base extends Base extends Base { +/** + * Display a popup on a MapboxMap map. + * @see https://ui.studiometa.dev/-/components/MapboxMap + */ +export class MapboxPopup extends AbstractMapboxMapChild< + T & MapboxPopupProps +> { + /** + * Config. + */ static config: BaseConfig = { name: 'MapboxPopup', options: { - lng: Number, - lat: Number, + lngLat: { + type: Array, + default: () => [0, 0], + }, popupOptions: Object, }, }; @@ -35,10 +48,6 @@ export class MapboxPopup extends Base extends Base Date: Fri, 25 Jul 2025 19:53:05 +0200 Subject: [PATCH 05/13] Add components --- .../ui/MapboxMap/AbstractMapboxMapChild.ts | 18 +++++ packages/ui/MapboxMap/MapboxGeocoder.ts | 0 .../ui/MapboxMap/MapboxGeolocateControl.ts | 53 +++++++++++++ packages/ui/MapboxMap/MapboxLayer.ts | 38 +++++++++ packages/ui/MapboxMap/MapboxMap.ts | 78 ++++++++++--------- .../ui/MapboxMap/MapboxNavigationControl.ts | 53 +++++++++++++ packages/ui/MapboxMap/utils.ts | 20 +++++ 7 files changed, 223 insertions(+), 37 deletions(-) create mode 100644 packages/ui/MapboxMap/AbstractMapboxMapChild.ts create mode 100644 packages/ui/MapboxMap/MapboxGeocoder.ts create mode 100644 packages/ui/MapboxMap/MapboxGeolocateControl.ts create mode 100644 packages/ui/MapboxMap/MapboxLayer.ts create mode 100644 packages/ui/MapboxMap/MapboxNavigationControl.ts create mode 100644 packages/ui/MapboxMap/utils.ts diff --git a/packages/ui/MapboxMap/AbstractMapboxMapChild.ts b/packages/ui/MapboxMap/AbstractMapboxMapChild.ts new file mode 100644 index 00000000..8b5517c2 --- /dev/null +++ b/packages/ui/MapboxMap/AbstractMapboxMapChild.ts @@ -0,0 +1,18 @@ +import { Base, BaseProps } from '@studiometa/js-toolkit'; +import type { MapboxMap } from './MapboxMap.js'; + +export interface AbstractMapboxMapChildProps extends BaseProps { + $parent: MapboxMap; +} + +export class AbstractMapboxMapChild extends Base { + get map() { + const { map } = this.$parent; + + if (!map) { + this.$warn('Can not find the parent map, does this component has a parent MapboxMap component?'); + } + + return map; + } +} diff --git a/packages/ui/MapboxMap/MapboxGeocoder.ts b/packages/ui/MapboxMap/MapboxGeocoder.ts new file mode 100644 index 00000000..e69de29b diff --git a/packages/ui/MapboxMap/MapboxGeolocateControl.ts b/packages/ui/MapboxMap/MapboxGeolocateControl.ts new file mode 100644 index 00000000..4560d4c1 --- /dev/null +++ b/packages/ui/MapboxMap/MapboxGeolocateControl.ts @@ -0,0 +1,53 @@ +import { type BaseProps, type BaseConfig } from '@studiometa/js-toolkit'; +import { AbstractMapboxMapChild, AbstractMapboxMapChildProps } from './AbstractMapboxMapChild.js'; +import { type ControlPosition, type GeolocateControlOptions, GeolocateControl } from 'mapbox-gl'; + +export interface MapboxGeolocateControlProps extends AbstractMapboxMapChildProps { + $options: { + position: ControlPosition; + } & Omit; +} + +/** + * Add a navigation control to the map. + * @see https://ui.studiometa.dev/-/components/MapboxMap/ + */ +export class MapboxGeolocateControl extends AbstractMapboxMapChild< + T & MapboxGeolocateControlProps +> { + static config: BaseConfig = { + name: 'MapboxGeolocateControl', + options: { + position: { + type: String, + default: 'top-right', + }, + positionOptions: Object, + fitBoundsOptions: Object, + trackUserLocation: Boolean, + showAccuracyCircle: Boolean, + showUserLocation: Boolean, + showUserHeading: Boolean, + }, + }; + + __control: GeolocateControl; + + get control() { + if (!this.__control) { + const { position, ...options } = this.$options; + this.__control = new GeolocateControl(options); + } + + return this.__control; + } + + mounted() { + this.map.addControl(this.control, this.$options.position); + } + + destroyed() { + this.map.removeControl(this.control); + this.__control = undefined; + } +} diff --git a/packages/ui/MapboxMap/MapboxLayer.ts b/packages/ui/MapboxMap/MapboxLayer.ts new file mode 100644 index 00000000..61e1a078 --- /dev/null +++ b/packages/ui/MapboxMap/MapboxLayer.ts @@ -0,0 +1,38 @@ +import { type BaseProps, type BaseConfig } from '@studiometa/js-toolkit'; +import { AbstractMapboxMapChild, AbstractMapboxMapChildProps } from './AbstractMapboxMapChild.js'; +import type { LayerSpecification } from 'mapbox-gl'; + +export interface MapboxLayerProps extends AbstractMapboxMapChildProps { + $options: { + id: string; + layer: LayerSpecification; + beforeId: string; + }; +} + +export class MapboxLayer extends AbstractMapboxMapChild< + T & MapboxLayerProps +> { + static config: BaseConfig = { + name: 'MapboxLayer', + options: { + id: String, + layer: Object, + beforeId: String, + }, + }; + + mounted() { + const { beforeId, id, layer } = this.$options; + layer.id = id; + this.map.addLayer(layer, beforeId); + } + + destroyed() { + const { id } = this.$options; + + if (this.map.getLayer(id)) { + this.map.removeLayer(id); + } + } +} diff --git a/packages/ui/MapboxMap/MapboxMap.ts b/packages/ui/MapboxMap/MapboxMap.ts index 9d18e70e..4bd1c55f 100644 --- a/packages/ui/MapboxMap/MapboxMap.ts +++ b/packages/ui/MapboxMap/MapboxMap.ts @@ -1,17 +1,15 @@ -import { - Base, - type BaseConfig, - type BaseConstructor, - type BaseProps, -} from '@studiometa/js-toolkit'; +import { Base, type BaseConfig, type BaseProps } from '@studiometa/js-toolkit'; import { Map } from 'mapbox-gl'; import { MapboxMarker } from './MapboxMarker.js'; import { MapboxPopup } from './MapboxPopup.js'; +import { MapboxNavigationControl } from './MapboxNavigationControl.js'; +import { MapboxGeolocateControl } from './MapboxGeolocateControl.js'; +import { resolveWhenMapboxMapIsLoaded } from './utils.js'; export interface MapboxMapProps extends BaseProps { $refs: { container: HTMLElement; - }, + }; $children: { MapboxMarker: MapboxMarker[]; }; @@ -22,25 +20,14 @@ export interface MapboxMapProps extends BaseProps { }; } -function resolveWhenMapIsLoaded(Component: T) { - return (mapboxMap: MapboxMap): Promise => { - return new Promise((resolve) => { - if (mapboxMap.isLoaded) { - resolve(Component); - } else { - mapboxMap.$on( - 'map-load', - () => { - resolve(Component); - }, - { once: true }, - ); - } - }); - }; -} - +/** + * Display a Mapbox GL map. + * @see https://ui.studiometa.dev/-/components/MapboxMap/ + */ export class MapboxMap extends Base { + /** + * Config. + */ static config: BaseConfig = { name: 'MapboxMap', emits: ['map-load'], @@ -48,40 +35,57 @@ export class MapboxMap extends Base [0, 0] }, + center: { + type: Array, + default: () => [0, 0], + }, }, components: { - MapboxMarker: resolveWhenMapIsLoaded(MapboxMarker), - MapboxPopup: resolveWhenMapIsLoaded(MapboxPopup), + MapboxMarker: resolveWhenMapboxMapIsLoaded(MapboxMarker), + MapboxPopup: resolveWhenMapboxMapIsLoaded(MapboxPopup), + MapboxNavigationControl: resolveWhenMapboxMapIsLoaded(MapboxNavigationControl), + MapboxGeolocateControl: resolveWhenMapboxMapIsLoaded(MapboxGeolocateControl), }, }; + /** + * Is the map loaded? + */ isLoaded = false; + /** + * Map instance. + * @private + */ __map: Map; + /** + * The mapbox Map instance. + */ get map() { if (!this.__map) { - this.__map = new Map(this.mapboxOptions); + this.__map = new Map({ + container: this.$refs.container ?? this.$el, + ...this.$options, + }); } return this.__map; } - get mapboxOptions() { - return { - container: this.$refs.container ?? this.$el, - ...this.$options, - }; - } - - async mounted() { + /** + * Mounted hook. + */ + mounted() { this.map.on('load', () => { this.isLoaded = true; this.$emit('map-load', this.map); }); } + /** + * Destroyed hook. + */ destroyed() { this.map?.remove(); this.__map = undefined; diff --git a/packages/ui/MapboxMap/MapboxNavigationControl.ts b/packages/ui/MapboxMap/MapboxNavigationControl.ts new file mode 100644 index 00000000..9e9d286d --- /dev/null +++ b/packages/ui/MapboxMap/MapboxNavigationControl.ts @@ -0,0 +1,53 @@ +import { type BaseProps, type BaseConfig } from '@studiometa/js-toolkit'; +import { AbstractMapboxMapChild, AbstractMapboxMapChildProps } from './AbstractMapboxMapChild.js'; +import { ControlPosition, NavigationControl } from 'mapbox-gl'; + +export interface MapboxNavigationControlProps extends AbstractMapboxMapChildProps { + $options: { + position: ControlPosition; + showCompass: boolean; + showZoom: boolean; + visualizePitch: boolean; + }; +} + +/** + * Add a navigation control to the map. + * @see https://ui.studiometa.dev/-/components/MapboxMap/ + */ +export class MapboxNavigationControl< + T extends BaseProps = BaseProps, +> extends AbstractMapboxMapChild { + static config: BaseConfig = { + name: 'MapboxNavigationControl', + options: { + position: { + type: String, + default: 'top-right', + }, + showCompass: Boolean, + showZoom: Boolean, + visualizePitch: Boolean, + }, + }; + + __control: NavigationControl; + + get control() { + if (!this.__control) { + const { position, ...options } = this.$options; + this.__control = new NavigationControl(options); + } + + return this.__control; + } + + mounted() { + this.map.addControl(this.control, this.$options.position); + } + + destroyed() { + this.map.removeControl(this.control); + this.__control = undefined; + } +} diff --git a/packages/ui/MapboxMap/utils.ts b/packages/ui/MapboxMap/utils.ts new file mode 100644 index 00000000..42a1636f --- /dev/null +++ b/packages/ui/MapboxMap/utils.ts @@ -0,0 +1,20 @@ +import type { BaseConstructor } from '@studiometa/js-toolkit'; +import { type MapboxMap } from './MapboxMap.js'; + +export function resolveWhenMapboxMapIsLoaded(Component: T) { + return (mapboxMap: MapboxMap): Promise => { + return new Promise((resolve) => { + if (mapboxMap.isLoaded) { + resolve(Component); + } else { + mapboxMap.$on( + 'map-load', + () => { + resolve(Component); + }, + { once: true }, + ); + } + }); + }; +} From 10e5ca4c439a97366bdec5b02bc1a7b52a0c0cb3 Mon Sep 17 00:00:00 2001 From: Titouan Mathis Date: Fri, 25 Jul 2025 19:53:11 +0200 Subject: [PATCH 06/13] Update docs --- packages/docs/components/MapboxMap/stories/map/app.twig | 1 + .../docs/components/MapboxMap/stories/markers/app.js | 5 ++--- .../docs/components/MapboxMap/stories/markers/app.twig | 9 +++------ packages/playground/static/mapbox-gl.js | 2 +- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/packages/docs/components/MapboxMap/stories/map/app.twig b/packages/docs/components/MapboxMap/stories/map/app.twig index 6bea1db7..9129e130 100644 --- a/packages/docs/components/MapboxMap/stories/map/app.twig +++ b/packages/docs/components/MapboxMap/stories/map/app.twig @@ -2,4 +2,5 @@ data-option-access-token="pk.eyJ1IjoiYWdlbmNlc3R1ZGlvbWV0YSIsImEiOiJjbTZxZXZidzYxaXR3MmtzaG5qNzc3NGxqIn0.c_YVpXQptiZtOgzj_5jvaw" class="w-full max-w-4xl h-96 grid grid-cols-1 grid-rows-1">
+ diff --git a/packages/docs/components/MapboxMap/stories/markers/app.js b/packages/docs/components/MapboxMap/stories/markers/app.js index a5711e6e..3cde95b0 100644 --- a/packages/docs/components/MapboxMap/stories/markers/app.js +++ b/packages/docs/components/MapboxMap/stories/markers/app.js @@ -13,10 +13,9 @@ class App extends Base { onAddClick() { this.$children.MapboxMap[0].$el.append( - createElement('div', { + createElement('template', { dataComponent: 'MapboxMarker', - dataOptionLat: randomInt(-50, 50), - dataOptionLng: randomInt(-50, 50), + dataOptionLngLat: JSON.stringify([randomInt(-50, 50), randomInt(-50, 50)]), }), ); this.$children.MapboxMap[0].$update(); diff --git a/packages/docs/components/MapboxMap/stories/markers/app.twig b/packages/docs/components/MapboxMap/stories/markers/app.twig index 0428320c..2a940295 100644 --- a/packages/docs/components/MapboxMap/stories/markers/app.twig +++ b/packages/docs/components/MapboxMap/stories/markers/app.twig @@ -3,14 +3,11 @@ class="w-full max-w-4xl h-96 grid grid-cols-1 grid-rows-1">
+ data-option-lng-lat="[10,0]"> + data-option-lng-lat="[0,0]"> diff --git a/packages/playground/static/mapbox-gl.js b/packages/playground/static/mapbox-gl.js index c66aef33..afa1928a 100644 --- a/packages/playground/static/mapbox-gl.js +++ b/packages/playground/static/mapbox-gl.js @@ -1,4 +1,4 @@ import mapboxgl from 'mapbox-gl'; -export { Map, Marker, Popup } from 'mapbox-gl'; +export { Map, Marker, Popup, NavigationControl, GeolocateControl } from 'mapbox-gl'; export default mapboxgl; From 87daec0f3ab3b2c0c20dc1aba3896846be627420 Mon Sep 17 00:00:00 2001 From: Titouan Mathis Date: Sat, 26 Jul 2025 10:31:43 +0200 Subject: [PATCH 07/13] Add a MapboxGeocoder component --- package-lock.json | 1082 ++++++++++++++++++++++- packages/ui/MapboxMap/MapboxGeocoder.ts | 62 ++ packages/ui/MapboxMap/MapboxMap.ts | 6 +- packages/ui/MapboxMap/index.ts | 3 + packages/ui/package.json | 3 + 5 files changed, 1146 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index cec87a69..b3852f7a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2450,6 +2450,27 @@ "tslib": "2" } }, + "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==", + "dev": true, + "license": "BSD 2-Clause", + "dependencies": { + "is-plain-obj": "^1.1.0", + "xtend": "^4.0.1" + } + }, + "node_modules/@mapbox/fusspot/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@mapbox/jsonlint-lines-primitives": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz", @@ -2459,6 +2480,25 @@ "node": ">= 0.6" } }, + "node_modules/@mapbox/mapbox-gl-geocoder": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-geocoder/-/mapbox-gl-geocoder-5.1.0.tgz", + "integrity": "sha512-+3MhDrE5ksDnP3R/104SOjKoGv+Z3ty/glAINw8V5GGOw5ffiLbKuyqloFZpkIR/HmxNztiw5SaePS34SvGPzQ==", + "dev": true, + "license": "ISC", + "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", @@ -2466,6 +2506,53 @@ "dev": true, "license": "BSD-3-Clause" }, + "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==", + "dev": true, + "license": "BSD-2-Clause", + "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/mapbox-sdk/node_modules/eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@mapbox/mapbox-sdk/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "base-64": "^0.1.0" + } + }, "node_modules/@mapbox/point-geometry": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz", @@ -2473,6 +2560,18 @@ "dev": true, "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==", + "dev": true, + "dependencies": { + "meow": "^9.0.0" + }, + "bin": { + "polyline": "bin/polyline.bin.js" + } + }, "node_modules/@mapbox/tiny-sdf": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.0.6.tgz", @@ -3157,6 +3256,19 @@ "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", "license": "MIT" }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, "node_modules/@sinonjs/commons": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", @@ -3521,6 +3633,19 @@ "url": "https://github.com/sponsors/isaacs" } }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@types/archiver": { "version": "5.3.4", "resolved": "https://registry.npmjs.org/@types/archiver/-/archiver-5.3.4.tgz", @@ -3530,6 +3655,19 @@ "@types/readdir-glob": "*" } }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, "node_modules/@types/cors": { "version": "2.8.19", "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", @@ -3606,6 +3744,13 @@ "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", "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==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -3636,6 +3781,27 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "license": "MIT" }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/mapbox__mapbox-gl-geocoder": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/mapbox__mapbox-gl-geocoder/-/mapbox__mapbox-gl-geocoder-5.0.0.tgz", + "integrity": "sha512-eGBWdFiP2QgmwndPyhwK6eBeOfyB8vRscp2C6Acqasx5dH8FvTo/VgXWCrCKFR3zkWek/H4w4/CwmBFOs7OLBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/geojson": "*", + "@types/mapbox-gl": "*" + } + }, "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", @@ -3655,6 +3821,16 @@ "@types/pbf": "*" } }, + "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", @@ -3664,6 +3840,13 @@ "@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==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/ms": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", @@ -3679,6 +3862,13 @@ "undici-types": "~7.8.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==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/pbf": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.5.tgz", @@ -3695,6 +3885,16 @@ "@types/node": "*" } }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", @@ -4770,6 +4970,16 @@ "node": ">=8" } }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", @@ -4794,6 +5004,13 @@ "node": ">=0.8.0" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, "node_modules/at-least-node": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", @@ -4971,6 +5188,12 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, + "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==", + "dev": true + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -5363,6 +5586,35 @@ "node": ">=8" } }, + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "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", @@ -5429,6 +5681,16 @@ "tslib": "^2.0.3" } }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/camelcase-css": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", @@ -5438,6 +5700,34 @@ "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", @@ -5678,6 +5968,19 @@ "node": ">=6" } }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/collect.js": { "version": "4.36.1", "resolved": "https://registry.npmjs.org/collect.js/-/collect.js-4.36.1.tgz", @@ -5720,6 +6023,19 @@ "integrity": "sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==", "license": "MIT" }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/comma-separated-tokens": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", @@ -6430,6 +6746,43 @@ "ms": "2.0.0" } }, + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/decode-named-character-reference": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz", @@ -6443,6 +6796,35 @@ "url": "https://github.com/sponsors/wooorm" } }, + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/deep-eql": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", @@ -6461,6 +6843,16 @@ "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==", + "dev": true, + "license": "MIT", + "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", @@ -6525,6 +6917,16 @@ "node": ">=8" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -7077,6 +7479,22 @@ "node": ">= 0.4" } }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/esbuild": { "version": "0.25.6", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.6.tgz", @@ -7537,6 +7955,23 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/form-data": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.4.tgz", + "integrity": "sha512-f0cRzm6dkyVYV3nPoooP8XlccPQukegwhAnpoLcXy+X+A8KfpGOoXwDr9FLZd3wzgLaBGQBE3lY93Zm/i1JvIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.35" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fraction.js": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", @@ -7627,6 +8062,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/fuzzy": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/fuzzy/-/fuzzy-0.1.3.tgz", + "integrity": "sha512-/gZffu4ykarLrCiP3Ygsa86UAo1E5vEVlvTrpkKywXSbP9Xhln3oSp9QSV57gEq3JFFpGJ4GZ+5zdEp3FcUh4w==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/geojson-vt": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-4.0.2.tgz", @@ -7692,6 +8136,22 @@ "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-tsconfig": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", @@ -7801,6 +8261,32 @@ "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==", + "dev": true, + "license": "MIT", + "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/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -7843,6 +8329,16 @@ "node": ">=18.0.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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -7889,6 +8385,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -7974,6 +8486,32 @@ "dev": true, "license": "MIT" }, + "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==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/hot-accept-webpack-plugin": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/hot-accept-webpack-plugin/-/hot-accept-webpack-plugin-4.0.2.tgz", @@ -8169,6 +8707,13 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "dev": true, + "license": "BSD-2-Clause" + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -8208,6 +8753,20 @@ "node": ">=8.0.0" } }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, "node_modules/hyperdyperid": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", @@ -8959,6 +9518,13 @@ "node": ">=4.0.0" } }, + "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==", + "dev": true, + "license": "MIT" + }, "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", @@ -9036,6 +9602,16 @@ "dev": true, "license": "ISC" }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "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", @@ -9242,6 +9818,13 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "license": "MIT" }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -9348,6 +9931,16 @@ "tslib": "^2.0.3" } }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/lru-cache": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz", @@ -9392,6 +9985,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/mapbox-gl": { "version": "3.13.0", "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-3.13.0.tgz", @@ -9829,6 +10435,43 @@ "url": "https://github.com/sponsors/streamich" } }, + "node_modules/meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "dev": true, + "license": "MIT", + "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/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==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -10361,16 +11004,36 @@ "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==", + "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==", + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "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==", + "dev": true, "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, "engines": { - "node": ">= 0.6" + "node": ">=4" } }, "node_modules/minimatch": { @@ -10394,6 +11057,31 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/minimist-options/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", @@ -10584,6 +11272,22 @@ "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "license": "MIT" }, + "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==", + "dev": true, + "license": "BSD-2-Clause", + "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-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -10602,6 +11306,19 @@ "node": ">=0.10.0" } }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -10773,6 +11490,16 @@ "@oxlint/win32-x64": "1.6.0" } }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/p-limit": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", @@ -10818,6 +11545,16 @@ "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==", + "dev": true, + "license": "MIT", + "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", @@ -12534,6 +13271,17 @@ "dev": true, "license": "MIT" }, + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/quansync": { "version": "0.2.10", "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.10.tgz", @@ -12571,6 +13319,19 @@ ], "license": "MIT" }, + "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==", + "dev": true, + "license": "MIT", + "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", @@ -12626,6 +13387,156 @@ "pify": "^2.3.0" } }, + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "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==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "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==", + "dev": true, + "license": "ISC" + }, + "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==", + "dev": true, + "license": "BSD-2-Clause", + "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==", + "dev": true, + "license": "ISC", + "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==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -12682,6 +13593,20 @@ "node": ">=8.10.0" } }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/regenerator-runtime": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", @@ -13653,6 +14578,13 @@ "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==", + "dev": true, + "license": "MIT" + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -13709,6 +14641,19 @@ "node": ">= 0.8.0" } }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -14842,6 +15787,42 @@ "url": "https://github.com/sponsors/wooorm" } }, + "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==", + "dev": true, + "license": "Apache-2.0", + "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==", + "dev": true, + "license": "CC-BY-3.0" + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", + "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", + "dev": true, + "license": "CC0-1.0" + }, "node_modules/speakingurl": { "version": "14.0.1", "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", @@ -15064,6 +16045,19 @@ "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/stylehacks": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-7.0.6.tgz", @@ -15080,6 +16074,13 @@ "postcss": "^8.4.32" } }, + "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==", + "dev": true, + "license": "ISC" + }, "node_modules/sucrase": { "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", @@ -15192,6 +16193,17 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/suggestions": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/suggestions/-/suggestions-1.7.1.tgz", + "integrity": "sha512-gl5YPAhPYl07JZ5obiD9nTZsg4SyZswAQU/NNtnYiSnFkI3+ZHuXAiEsYm7AaZ71E0LXSFaGVaulGSWN3Gd71A==", + "dev": true, + "license": "ISC", + "dependencies": { + "fuzzy": "^0.1.1", + "xtend": "^4.0.0" + } + }, "node_modules/supercluster": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz", @@ -15848,6 +16860,16 @@ "url": "https://github.com/sponsors/wooorm" } }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/trough": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", @@ -15948,6 +16970,19 @@ "node": ">=4" } }, + "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==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/typescript": { "version": "5.8.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", @@ -16431,6 +17466,17 @@ "node": ">=8" } }, + "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==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "node_modules/varint": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", @@ -17592,6 +18638,16 @@ "node": ">=0.4.0" } }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -17601,6 +18657,13 @@ "node": ">=10" } }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, "node_modules/yaml": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", @@ -17748,10 +18811,13 @@ "morphdom": "^2.7.5" }, "devDependencies": { + "@mapbox/mapbox-gl-geocoder": "^5.1.0", "@studiometa/js-toolkit": "3.0.5", + "@types/mapbox__mapbox-gl-geocoder": "^5.0.0", "mapbox-gl": "^3.13.0" }, "peerDependencies": { + "@mapbox/mapbox-gl-geocoder": "^5.1.0", "@studiometa/js-toolkit": "^3.0.5", "mapbox-gl": "^3.13.0" } diff --git a/packages/ui/MapboxMap/MapboxGeocoder.ts b/packages/ui/MapboxMap/MapboxGeocoder.ts index e69de29b..f770b553 100644 --- a/packages/ui/MapboxMap/MapboxGeocoder.ts +++ b/packages/ui/MapboxMap/MapboxGeocoder.ts @@ -0,0 +1,62 @@ +import { type BaseProps, type BaseConfig } from '@studiometa/js-toolkit'; +import { AbstractMapboxMapChild, AbstractMapboxMapChildProps } from './AbstractMapboxMapChild.js'; +import GeocoderControl from '@mapbox/mapbox-gl-geocoder'; +import * as mapboxgl from 'mapbox-gl'; +import type { ControlPosition } from 'mapbox-gl'; + +export interface MapboxGeocoderProps extends AbstractMapboxMapChildProps { + $options: { + position: ControlPosition; + /** + * All MapboxGeocoder options, except the non serializable ones. + * @see https://github.com/mapbox/mapbox-gl-geocoder/blob/master/API.md#parameters + */ + options: Omit< + GeocoderControl.GeocoderOptions, + 'filter' | 'externalGeocoder' | 'render' | 'getItemValue' | 'localGeocoder' + >; + }; +} + +/** + * Add a navigation control to the map. + * @see https://ui.studiometa.dev/-/components/MapboxMap/ + */ +export class MapboxGeocoder extends AbstractMapboxMapChild< + T & MapboxGeocoderProps +> { + static config: BaseConfig = { + name: 'MapboxGeocoder', + options: { + position: { + type: String, + default: 'top-right', + }, + options: Object, + }, + }; + + __control: GeocoderControl; + + get control() { + if (!this.__control) { + const { options } = this.$options; + options.mapboxgl = mapboxgl; + if (!options.accessToken) { + options.accessToken = this.$parent.$options.accessToken; + } + this.__control = new GeocoderControl(options); + } + + return this.__control; + } + + mounted() { + this.map.addControl(this.control, this.$options.position); + } + + destroyed() { + this.map.removeControl(this.control); + this.__control = undefined; + } +} diff --git a/packages/ui/MapboxMap/MapboxMap.ts b/packages/ui/MapboxMap/MapboxMap.ts index 4bd1c55f..0975721d 100644 --- a/packages/ui/MapboxMap/MapboxMap.ts +++ b/packages/ui/MapboxMap/MapboxMap.ts @@ -4,6 +4,7 @@ import { MapboxMarker } from './MapboxMarker.js'; import { MapboxPopup } from './MapboxPopup.js'; import { MapboxNavigationControl } from './MapboxNavigationControl.js'; import { MapboxGeolocateControl } from './MapboxGeolocateControl.js'; +import { MapboxGeocoder } from './MapboxGeocoder.js'; import { resolveWhenMapboxMapIsLoaded } from './utils.js'; export interface MapboxMapProps extends BaseProps { @@ -41,10 +42,11 @@ export class MapboxMap extends Base Date: Sat, 26 Jul 2025 10:31:50 +0200 Subject: [PATCH 08/13] Update docs --- packages/playground/meta.config.js | 1 + packages/playground/static/mapbox-gl-geocoder.js | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 packages/playground/static/mapbox-gl-geocoder.js diff --git a/packages/playground/meta.config.js b/packages/playground/meta.config.js index 0076ecc8..35d61989 100644 --- a/packages/playground/meta.config.js +++ b/packages/playground/meta.config.js @@ -29,6 +29,7 @@ export default defineWebpackConfig({ deepmerge: '/-/play/static/deepmerge.js', morphdom: '/-/play/static/morphdom.js', 'mapbox-gl': '/-/play/static/mapbox-gl.js', + '@mapbox/mapbox-gl-geocoder': '/-/play/static/mapbox-gl-geocoder.js', }, defaults: { html: `{% html_element 'span' with { class: 'dark:text-white font-bold border-b-2 border-current' } %} diff --git a/packages/playground/static/mapbox-gl-geocoder.js b/packages/playground/static/mapbox-gl-geocoder.js new file mode 100644 index 00000000..839aa322 --- /dev/null +++ b/packages/playground/static/mapbox-gl-geocoder.js @@ -0,0 +1,3 @@ +import GeocoderControl from '@mapbox/mapbox-gl-geocoder'; + +export default GeocoderControl; From 0df14c1046aafbecdaf0e2f018206fb17fa16082 Mon Sep 17 00:00:00 2001 From: Titouan Mathis Date: Mon, 28 Jul 2025 09:13:51 +0200 Subject: [PATCH 09/13] Allow usage of geocoder outside of a map --- packages/ui/MapboxMap/MapboxGeocoder.ts | 27 ++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/packages/ui/MapboxMap/MapboxGeocoder.ts b/packages/ui/MapboxMap/MapboxGeocoder.ts index f770b553..7ba8b1b9 100644 --- a/packages/ui/MapboxMap/MapboxGeocoder.ts +++ b/packages/ui/MapboxMap/MapboxGeocoder.ts @@ -2,11 +2,14 @@ import { type BaseProps, type BaseConfig } from '@studiometa/js-toolkit'; import { AbstractMapboxMapChild, AbstractMapboxMapChildProps } from './AbstractMapboxMapChild.js'; import GeocoderControl from '@mapbox/mapbox-gl-geocoder'; import * as mapboxgl from 'mapbox-gl'; -import type { ControlPosition } from 'mapbox-gl'; +import type { Map } from 'mapbox-gl'; export interface MapboxGeocoderProps extends AbstractMapboxMapChildProps { $options: { - position: ControlPosition; + /** + * Wether to add the geocoder to the map or to the component's root element. + */ + addToMap: boolean; /** * All MapboxGeocoder options, except the non serializable ones. * @see https://github.com/mapbox/mapbox-gl-geocoder/blob/master/API.md#parameters @@ -28,10 +31,7 @@ export class MapboxGeocoder extends AbstractMap static config: BaseConfig = { name: 'MapboxGeocoder', options: { - position: { - type: String, - default: 'top-right', - }, + addToMap: Boolean, options: Object, }, }; @@ -51,10 +51,23 @@ export class MapboxGeocoder extends AbstractMap return this.__control; } + /** + * Target element for the geocoder. + */ + get target(): Map | HTMLElement | string { + return this.$options.addToMap ? this.map : this.$el; + } + + /** + * Mounted hook. + */ mounted() { - this.map.addControl(this.control, this.$options.position); + this.control.addTo(this.target); } + /** + * Destroyed hook. + */ destroyed() { this.map.removeControl(this.control); this.__control = undefined; From 2bb4b574d635c1a0dc48a0ee131a29e852205023 Mon Sep 17 00:00:00 2001 From: Titouan Mathis Date: Mon, 28 Jul 2025 09:16:16 +0200 Subject: [PATCH 10/13] Update tests --- package.json | 1 + packages/tests/index.spec.ts | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/package.json b/package.json index 62fda149..6987e05e 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ ], "scripts": { "test": "npm run test -w @studiometa/ui-tests", + "test:watch": "npm run test:watch -w @studiometa/ui-tests", "build": "rm -rf dist && npm run build:pkg && npm run build:sizes && npm run build:types && npm run build:twig && npm run build:cp-files", "build:cp-files": "cat packages/ui/package.json | sed 's/index\\.ts/index\\.js/' > dist/package.json && cat dist/package.json && cp LICENSE.md dist/ && cp README.md dist/", "build:twig": "rsync -avh --include='*/' --include='**/*.twig' --exclude='*' --prune-empty-dirs packages/ui/ dist/", diff --git a/packages/tests/index.spec.ts b/packages/tests/index.spec.ts index 0f83274b..e6a582bf 100644 --- a/packages/tests/index.spec.ts +++ b/packages/tests/index.spec.ts @@ -36,6 +36,12 @@ test('components exports', () => { "Hoverable", "LargeText", "LazyInclude", + "MapboxGeocoder", + "MapboxGeolocateControl", + "MapboxMap", + "MapboxMarker", + "MapboxNavigationControl", + "MapboxPopup", "Menu", "MenuBtn", "MenuList", From 248ca07187ef834dd28a15f0e55f1a1081241c17 Mon Sep 17 00:00:00 2001 From: Titouan Mathis Date: Wed, 30 Jul 2025 17:49:56 +0200 Subject: [PATCH 11/13] Add support for attaching a popup to a marker --- packages/ui/MapboxMap/MapboxMarker.ts | 14 ++++++++++++++ packages/ui/MapboxMap/MapboxPopup.ts | 13 ++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/packages/ui/MapboxMap/MapboxMarker.ts b/packages/ui/MapboxMap/MapboxMarker.ts index 4efabf1f..6eb0a1ea 100644 --- a/packages/ui/MapboxMap/MapboxMarker.ts +++ b/packages/ui/MapboxMap/MapboxMarker.ts @@ -1,12 +1,16 @@ import { type BaseProps, type BaseConfig } from '@studiometa/js-toolkit'; import { Marker } from 'mapbox-gl'; import { AbstractMapboxMapChild, AbstractMapboxMapChildProps } from './AbstractMapboxMapChild.js'; +import { MapboxPopup } from './MapboxPopup.js'; export interface MapboxMarkerProps extends AbstractMapboxMapChildProps { $options: { lngLat: [number, number]; markerOptions: any; }; + $children: { + MapboxPopup: MapboxPopup[]; + }; } /** @@ -26,6 +30,9 @@ export class MapboxMarker extends AbstractMapbo // Marker options. (https://docs.mapbox.com/mapbox-gl-js/api/markers#marker) markerOptions: Object, }, + components: { + MapboxPopup, + }, }; __marker: Marker; @@ -38,6 +45,10 @@ export class MapboxMarker extends AbstractMapbo return this.__marker; } + get popup() { + return this.$children.MapboxPopup[0]; + } + get markerOptions() { if (this.$options.markerOptions) { return this.$options.markerOptions; @@ -48,6 +59,9 @@ export class MapboxMarker extends AbstractMapbo mounted() { this.marker.setLngLat(this.$options.lngLat).addTo(this.map); + if (this.popup) { + this.marker.setPopup(this.popup.popup); + } } destroyed() { diff --git a/packages/ui/MapboxMap/MapboxPopup.ts b/packages/ui/MapboxMap/MapboxPopup.ts index 01ad135f..38825a66 100644 --- a/packages/ui/MapboxMap/MapboxPopup.ts +++ b/packages/ui/MapboxMap/MapboxPopup.ts @@ -1,11 +1,14 @@ -import { type BaseConfig, type BaseProps } from '@studiometa/js-toolkit'; +import { getClosestParent, type BaseConfig, type BaseProps } from '@studiometa/js-toolkit'; import { Popup, PopupOptions } from 'mapbox-gl'; import { AbstractMapboxMapChild, type AbstractMapboxMapChildProps, } from './AbstractMapboxMapChild.js'; +import { MapboxMap } from './MapboxMap.js'; +import { MapboxMarker } from './MapboxMarker.js'; -export interface MapboxPopupProps extends AbstractMapboxMapChildProps { +export interface MapboxPopupProps extends BaseProps { + $parent: MapboxMap | MapboxMarker; $el: HTMLTemplateElement; $options: { lngLat: [number, number]; @@ -57,13 +60,17 @@ export class MapboxPopup extends AbstractMapbox } mounted() { - this.popup.setLngLat(this.$options.lngLat).addTo(this.map); + this.popup.setLngLat(this.$options.lngLat); if (this.$el.content.childNodes.length === 1) { this.popup.setDOMContent(this.$el.content.firstChild); } else if (this.$el.content.childNodes.length > 1) { this.popup.setHTML(this.$el.innerHTML); } + + if (this.map && this.$parent instanceof MapboxMap) { + this.popup.addTo(this.map); + } } destroyed() { From 442f49d905da625e98fa1905dd2e021b0d6fc98f Mon Sep 17 00:00:00 2001 From: Titouan Mathis Date: Wed, 30 Jul 2025 17:50:17 +0200 Subject: [PATCH 12/13] Patch @studiometa/js-toolkit to enable template as root element --- patches/@studiometa+js-toolkit+3.0.5.patch | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 patches/@studiometa+js-toolkit+3.0.5.patch diff --git a/patches/@studiometa+js-toolkit+3.0.5.patch b/patches/@studiometa+js-toolkit+3.0.5.patch new file mode 100644 index 00000000..ac150f40 --- /dev/null +++ b/patches/@studiometa+js-toolkit+3.0.5.patch @@ -0,0 +1,21 @@ +diff --git a/node_modules/@studiometa/js-toolkit/Base/utils.js b/node_modules/@studiometa/js-toolkit/Base/utils.js +index 5c98cca..a50002a 100644 +--- a/node_modules/@studiometa/js-toolkit/Base/utils.js ++++ b/node_modules/@studiometa/js-toolkit/Base/utils.js +@@ -36,13 +36,14 @@ function getSelector(nameOrSelector) { + } + function getComponentElements(nameOrSelector, element = document) { + const selector = getSelector(nameOrSelector); ++ const el = element instanceof HTMLTemplateElement ? element.content : element; + let elements = []; + try { +- elements = Array.from(element.querySelectorAll(selector)); ++ elements = Array.from(el.querySelectorAll(selector)); + } catch { + } + if (elements.length === 0 && nameOrSelector[0] === nameOrSelector[0].toLowerCase()) { +- elements = Array.from(element.querySelectorAll(nameOrSelector)); ++ elements = Array.from(el.querySelectorAll(nameOrSelector)); + } + return elements; + } From 18cbd29de1b7c4c05d64d37a8ad9b6b311f91264 Mon Sep 17 00:00:00 2001 From: Titouan Mathis Date: Thu, 31 Jul 2025 11:00:41 +0200 Subject: [PATCH 13/13] WIP --- .../MapboxMap/stories/markers/app.js | 33 +++++++++++++++---- .../MapboxMap/stories/markers/app.twig | 10 +++--- packages/ui/MapboxMap/MapboxPopup.ts | 22 ++++++------- 3 files changed, 42 insertions(+), 23 deletions(-) diff --git a/packages/docs/components/MapboxMap/stories/markers/app.js b/packages/docs/components/MapboxMap/stories/markers/app.js index 3cde95b0..9995aa86 100644 --- a/packages/docs/components/MapboxMap/stories/markers/app.js +++ b/packages/docs/components/MapboxMap/stories/markers/app.js @@ -1,5 +1,9 @@ import { Base, createApp } from '@studiometa/js-toolkit'; -import { createElement, randomInt, randomItem } from '@studiometa/js-toolkit/utils'; +import { + createElement, + randomInt, + randomItem, +} from '@studiometa/js-toolkit/utils'; import { MapboxMap } from '@studiometa/ui'; class App extends Base { @@ -13,16 +17,33 @@ class App extends Base { onAddClick() { this.$children.MapboxMap[0].$el.append( - createElement('template', { - dataComponent: 'MapboxMarker', - dataOptionLngLat: JSON.stringify([randomInt(-50, 50), randomInt(-50, 50)]), - }), + createElement( + 'template', + { + dataComponent: 'MapboxMarker', + dataOptionLngLat: JSON.stringify([ + randomInt(-50, 50), + randomInt(-50, 50), + ]), + }, + [ + createElement( + 'template', + { + dataComponent: 'MapboxPopup', + }, + 'Hello world', + ), + ], + ), ); this.$children.MapboxMap[0].$update(); } onRemoveClick() { - const marker = randomItem(this.$children.MapboxMap[0].$children.MapboxMarker); + const marker = randomItem( + this.$children.MapboxMap[0].$children.MapboxMarker, + ); marker?.$el.remove(); } } diff --git a/packages/docs/components/MapboxMap/stories/markers/app.twig b/packages/docs/components/MapboxMap/stories/markers/app.twig index 2a940295..9c7e52f3 100644 --- a/packages/docs/components/MapboxMap/stories/markers/app.twig +++ b/packages/docs/components/MapboxMap/stories/markers/app.twig @@ -3,12 +3,10 @@ class="w-full max-w-4xl h-96 grid grid-cols-1 grid-rows-1">
- - diff --git a/packages/ui/MapboxMap/MapboxPopup.ts b/packages/ui/MapboxMap/MapboxPopup.ts index 38825a66..1a8331db 100644 --- a/packages/ui/MapboxMap/MapboxPopup.ts +++ b/packages/ui/MapboxMap/MapboxPopup.ts @@ -1,9 +1,6 @@ import { getClosestParent, type BaseConfig, type BaseProps } from '@studiometa/js-toolkit'; import { Popup, PopupOptions } from 'mapbox-gl'; -import { - AbstractMapboxMapChild, - type AbstractMapboxMapChildProps, -} from './AbstractMapboxMapChild.js'; +import { AbstractMapboxMapChild } from './AbstractMapboxMapChild.js'; import { MapboxMap } from './MapboxMap.js'; import { MapboxMarker } from './MapboxMarker.js'; @@ -60,16 +57,19 @@ export class MapboxPopup extends AbstractMapbox } mounted() { - this.popup.setLngLat(this.$options.lngLat); + const { popup, $el, map, $parent, $options } = this; - if (this.$el.content.childNodes.length === 1) { - this.popup.setDOMContent(this.$el.content.firstChild); - } else if (this.$el.content.childNodes.length > 1) { - this.popup.setHTML(this.$el.innerHTML); + popup.setLngLat($options.lngLat); + const el = $el instanceof HTMLTemplateElement ? $el.content : $el; + + if (el.childNodes.length === 1) { + popup.setDOMContent(el.firstChild); + } else if (el.childNodes.length > 1) { + popup.setHTML($el.innerHTML); } - if (this.map && this.$parent instanceof MapboxMap) { - this.popup.addTo(this.map); + if (map && $parent instanceof MapboxMap) { + popup.addTo(map); } }