feat(desktop): render ```map blocks with Mapbox GL like wondershop

Swap maplibre-gl/OpenFreeMap for mapbox-gl with the light-v11/dark-v11
styles wondershop uses. The public token comes from VITE_MAPBOX_TOKEN
(desktop/.env.local, gitignored); without it the block shows a readable
error. e2e uses a fake token and stubs api.mapbox.com.

Signed-off-by: Wintermute <a00fdff03f06355c4fc6d6268f3a09ebe752c20b98df8fdab5fe81e266d6630a@meshllm.communities.buzz.xyz>
This commit is contained in:
Wintermute
2026-10-09 14:14:14 -04:00
parent 8caff1c6f2
commit df9b118ed3
6 changed files with 41 additions and 202 deletions

View File

@@ -1 +1,2 @@
VITE_BUZZ_BESTIE=1
VITE_MAPBOX_TOKEN=pk.e2e-test-token

View File

@@ -69,7 +69,7 @@
"jdenticon": "^3.3.0",
"linkifyjs": "^4.3.2",
"lucide-react": "^1.0.0",
"maplibre-gl": "^5.24.0",
"mapbox-gl": "^3.18.1",
"mdast-util-from-markdown": "^2.0.3",
"motion": "^12.38.0",
"qrcode": "^1.5.4",

View File

@@ -32,7 +32,7 @@ export const CODE_BLOCK_CLASS =
"code-block-lines block min-w-full whitespace-pre font-mono text-sm font-medium text-foreground";
const DIFF_ADD_RE = /\s*\/\/\s*\[!code\s*\+\+\]\s*$/;
const DIFF_REMOVE_RE = /\s*\/\/\s*\[!code\s*--\]\s*$/;
// maplibre is heavy; only load it when a message or canvas contains a map.
// mapbox-gl is heavy; only load it when a message or canvas contains a map.
const MapBlock = React.lazy(() => import("./MapBlock"));
function ensureHighlighter(): Promise<void> {

View File

@@ -1,15 +1,16 @@
import maplibregl from "maplibre-gl";
import "maplibre-gl/dist/maplibre-gl.css";
import mapboxgl from "mapbox-gl";
import "mapbox-gl/dist/mapbox-gl.css";
import * as React from "react";
import { useTheme } from "@/shared/theme/ThemeProvider";
import { type MapSpec, mapSpecPoints, parseMapSpec } from "./mapSpec";
// OpenFreeMap: free vector tiles, no API key.
// Same Mapbox styles as wondershop. Public (pk.) token from VITE_MAPBOX_TOKEN.
const MAPBOX_TOKEN: string | undefined = import.meta.env.VITE_MAPBOX_TOKEN;
const STYLE_URL = {
light: "https://tiles.openfreemap.org/styles/liberty",
dark: "https://tiles.openfreemap.org/styles/dark",
light: "mapbox://styles/mapbox/light-v11",
dark: "mapbox://styles/mapbox/dark-v11",
};
const DEFAULT_COLOR = "#3b82f6";
const DEFAULT_HEIGHT = 360;
@@ -18,14 +19,14 @@ function safeColor(color: string | undefined) {
return color && CSS.supports("color", color) ? color : DEFAULT_COLOR;
}
function addOverlays(map: maplibregl.Map, spec: MapSpec) {
function addOverlays(map: mapboxgl.Map, spec: MapSpec) {
for (const marker of spec.markers) {
const pin = new maplibregl.Marker({ color: safeColor(marker.color) })
const pin = new mapboxgl.Marker({ color: safeColor(marker.color) })
.setLngLat([marker.lng, marker.lat])
.addTo(map);
if (marker.label) {
pin.getElement().title = marker.label;
pin.setPopup(new maplibregl.Popup({ offset: 24 }).setText(marker.label));
pin.setPopup(new mapboxgl.Popup({ offset: 24 }).setText(marker.label));
}
}
if (spec.lines.length === 0) return;
@@ -57,17 +58,19 @@ function MapView({ spec }: { spec: MapSpec }) {
const container = containerRef.current;
if (!container) return;
const points = mapSpecPoints(spec);
const map = new maplibregl.Map({
const map = new mapboxgl.Map({
accessToken: MAPBOX_TOKEN,
container,
style: STYLE_URL[isDark ? "dark" : "light"],
center: spec.center ?? points[0],
zoom: spec.zoom ?? 12,
attributionControl: { compact: true },
attributionControl: false,
cooperativeGestures: true,
});
map.addControl(new maplibregl.NavigationControl(), "top-right");
map.addControl(new mapboxgl.AttributionControl({ compact: true }));
map.addControl(new mapboxgl.NavigationControl(), "top-right");
if (!spec.center && points.length > 1) {
const bounds = new maplibregl.LngLatBounds(points[0], points[0]);
const bounds = new mapboxgl.LngLatBounds(points[0], points[0]);
for (const point of points) bounds.extend(point);
map.fitBounds(bounds, {
padding: 48,
@@ -89,14 +92,17 @@ function MapView({ spec }: { spec: MapSpec }) {
);
}
function MapError({ children }: { children: React.ReactNode }) {
return (
<p className="rounded-xl border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive">
{children}
</p>
);
}
export default function MapBlock({ code }: { code: string }) {
const result = React.useMemo(() => parseMapSpec(code), [code]);
if (!result.ok) {
return (
<p className="rounded-xl border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive">
{result.error}
</p>
);
}
if (!result.ok) return <MapError>{result.error}</MapError>;
if (!MAPBOX_TOKEN) return <MapError>Map needs VITE_MAPBOX_TOKEN.</MapError>;
return <MapView spec={result.spec} />;
}

View File

@@ -17,9 +17,12 @@ const spec = {
],
};
// Keep the test hermetic: serve a blank style instead of remote tiles.
// Keep the test hermetic: serve a blank style instead of Mapbox tiles.
async function stubTiles(page: Page) {
await page.route("https://tiles.openfreemap.org/**", (route) =>
await page.route("https://events.mapbox.com/**", (route) =>
route.fulfill({ status: 204 }),
);
await page.route("https://api.mapbox.com/styles/**", (route) =>
route.fulfill({
contentType: "application/json",
body: JSON.stringify({
@@ -70,8 +73,8 @@ test("```map blocks render an interactive map and report bad specs", async ({
const map = message.getByTestId("markdown-map-block");
await expect(map).toBeVisible();
await expect(map).toHaveCSS("height", "320px");
await expect(map.locator("canvas.maplibregl-canvas")).toBeVisible();
await expect(map.locator(".maplibregl-marker")).toHaveCount(2);
await expect(map.locator("canvas.mapboxgl-canvas")).toBeVisible();
await expect(map.locator(".mapboxgl-marker")).toHaveCount(2);
await expect(map.locator('[title="Store A"]')).toBeVisible();
await expect(message.locator("[data-code-block]")).toHaveCount(0);

183
pnpm-lock.yaml generated
View File

@@ -198,9 +198,9 @@ importers:
lucide-react:
specifier: ^1.0.0
version: 1.16.0(react@19.2.8)
maplibre-gl:
specifier: ^5.24.0
version: 5.24.0
mapbox-gl:
specifier: ^3.18.1
version: 3.32.0
mdast-util-from-markdown:
specifier: ^2.0.3
version: 2.0.3
@@ -713,42 +713,6 @@ packages:
'@jridgewell/trace-mapping@0.3.31':
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
'@mapbox/jsonlint-lines-primitives@2.0.3':
resolution: {integrity: sha512-0SElaV0uMxEnxzBhhX9WTuPyUeMsAN/SS0i16tjuba4/mio63MG9khjC1a0JAiPGXAwvwm4UfHJURCN7nyudQg==}
engines: {node: '>= 22'}
'@mapbox/point-geometry@1.1.0':
resolution: {integrity: sha512-YGcBz1cg4ATXDCM/71L9xveh4dynfGmcLDqufR+nQQy3fKwsAZsWd/x4621/6uJaeB9mwOHE6hPeDgXz9uViUQ==}
'@mapbox/tiny-sdf@2.3.0':
resolution: {integrity: sha512-gBvcNDBBB66bgQYvnaJ6Jk+VCaMmVq5+IZR2kWPisT88Z8s0kBQt6hfVi8QgRW8Vpg0UWZzBA4ZSyzHHC+VeRA==}
'@mapbox/unitbezier@0.0.1':
resolution: {integrity: sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==}
'@mapbox/unitbezier@1.0.0':
resolution: {integrity: sha512-fqd515fjBmANKGGsQ286E2Wvj/XvDFpGzwJxq4CI6jMQue6Oy04uCKp+JWKF00xRTmk6cEu1jPJ9p3xqH8YWqQ==}
'@mapbox/vector-tile@2.0.5':
resolution: {integrity: sha512-pXj8m7KTsqZt+1jsE0xIpGvqTSbblfkuEJL/NJmNePMtEwxO8V3XMDo9WMSfDeqHvCtBI9Lmt4mGcGR10zecmw==}
'@mapbox/whoots-js@3.1.0':
resolution: {integrity: sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==}
engines: {node: '>=6.0.0'}
'@maplibre/geojson-vt@6.1.2':
resolution: {integrity: sha512-2ZYhobdAY+y4/P/z1xe0698165LywD0yDdWugdu3NRUrajgVWut+tLkcz7i/RJguMTURwK7gxwmwYMFJbgbQFw==}
'@maplibre/maplibre-gl-style-spec@24.10.0':
resolution: {integrity: sha512-lichxSiagMEBBrqHF0trtMQH9RKh+9jUlIJl0qW0QHvt2H/tbvUWdE+ZzI2Jd0/pT7j/iavLonlPu7EQ/ixTOw==}
hasBin: true
'@maplibre/mlt@1.3.0':
resolution: {integrity: sha512-7M2O7ABM80Oi8XPkfkrjKB8mOBIxGoVgkA52Mu4RMWoBvvMdagQ522+WxVYujZsMpqIr3BpzrTbXrm4k8lCzCQ==}
'@maplibre/vt-pbf@4.3.2':
resolution: {integrity: sha512-j6p0AdjvAR19Z3XaCysle7A4ZSo08tYOzxD0Y9NQylwPAkwJJeYub5b2eVucdeDh7erhv69DahoLOevDRERRUw==}
'@mediapipe/tasks-vision@0.10.35':
resolution: {integrity: sha512-HOvadwVRE6JC+45nyYhmnywnr5h/J8KZvOeUNVOG9q/0875pZgItznFB9bRTvLc264YSJqiZ1NsIpCStJw/egg==}
@@ -2115,9 +2079,6 @@ packages:
'@types/estree@1.0.9':
resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==}
'@types/geojson@7946.0.16':
resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==}
'@types/hast@3.0.4':
resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
@@ -2457,9 +2418,6 @@ packages:
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
engines: {node: '>= 0.4'}
earcut@3.2.4:
resolution: {integrity: sha512-FHc6yNpnTORB0tM5kmZ03iD2mDuNakDE2lvf4Hw1XkfxtEHIGVi01B/GqUSwx+NcC1WGjidAfpTXzeALtPtfpg==}
electron-to-chromium@1.5.361:
resolution: {integrity: sha512-Q6Hts7N9FnJc5LeGRINFvLhCI9xZmNtTDe5ZbcVezQz7cU4a8Aua3GH1b8J2XY8Al9PF+OCwYqhgsOOheMdvkA==}
@@ -2612,9 +2570,6 @@ packages:
gitdiff-parser@0.3.1:
resolution: {integrity: sha512-YQJnY8aew65id8okGxKCksH3efDCJ9HzV7M9rsvd65habf39Pkh4cgYJ27AaoDMqo1X98pgNJhNMrm/kpV7UVQ==}
gl-matrix@3.4.4:
resolution: {integrity: sha512-latSnyDNt/8zYUB6VIJ6PCh2jBjJX6gnDsoCZ7LyW7GkqrD51EWwa9qCoGixj8YqBtETQK/xY7OmpTF8xz1DdQ==}
gopd@1.2.0:
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
engines: {node: '>= 0.4'}
@@ -2753,9 +2708,6 @@ packages:
engines: {node: '>=6'}
hasBin: true
json-stringify-pretty-compact@4.0.0:
resolution: {integrity: sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==}
json5@2.2.3:
resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
engines: {node: '>=6'}
@@ -2767,9 +2719,6 @@ packages:
just-once@1.1.0:
resolution: {integrity: sha512-+rZVpl+6VyTilK7vB/svlMPil4pxqIJZkbnN7DKZTOzyXfun6ZiFeq2Pk4EtCEHZ0VU4EkdFzG8ZK5F3PErcDw==}
kdbush@4.1.0:
resolution: {integrity: sha512-e9vurzrXJQrFX6ckpHP3bvj5l+9CnYzkxDNnNQ1h2QTqdWsUAJgXiKdGNcOa1EY85dU8KbQ+z/FdQdB7P+9yfQ==}
lightningcss-android-arm64@1.32.0:
resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==}
engines: {node: '>= 12.0.0'}
@@ -2883,9 +2832,8 @@ packages:
magic-string@0.30.21:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
maplibre-gl@5.24.0:
resolution: {integrity: sha512-ALyFxgtd5R+65UqZ/++lOqwWcC0SNho9c27fYSyLmG7AfnAul2o46F05aDJGPbFU57wos9dgcIySHs0Xe6ia3A==}
engines: {node: '>=16.14.0', npm: '>=8.1.0'}
mapbox-gl@3.32.0:
resolution: {integrity: sha512-+P4qrlyejQYLyz1Bfzoe+d5Ff5vAghH54RNHm1q2VeAZqkSjQ5e1XlovQoSHlf4xqpRJtJG58kn8nkLwPMQung==}
markdown-it-task-lists@2.1.1:
resolution: {integrity: sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA==}
@@ -3076,9 +3024,6 @@ packages:
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
murmurhash-js@1.0.0:
resolution: {integrity: sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==}
nanoid@3.3.16:
resolution: {integrity: sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@@ -3148,14 +3093,6 @@ packages:
pathe@2.0.3:
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
pbf@4.0.2:
resolution: {integrity: sha512-J0ajxARhZfpUEebxYs1vhMGMuLSXtBe1e+fFPDrf2uA2hgo+UshKfNUWOz92HJNz6/NFEXseQPddnHkTreWRqg==}
hasBin: true
pbf@5.1.2:
resolution: {integrity: sha512-mnvGdvOrIvJOBGUEdGkrVXjN8E/VkIJCkf2eS1DH2yv82ORUlLttmDt0rWY38yYZmVwciZwBUvHM20qxBZf40w==}
hasBin: true
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
@@ -3201,9 +3138,6 @@ packages:
resolution: {integrity: sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==}
engines: {node: ^10 || ^12 || >=14}
potpack@2.1.0:
resolution: {integrity: sha512-pcaShQc1Shq0y+E7GqJqvZj8DTthWV1KeHGdi0Z6IAin2Oi3JnLCOfwnCo84qc+HAp52wT9nK9H7FAJp5a44GQ==}
prettier@3.8.3:
resolution: {integrity: sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==}
engines: {node: '>=14'}
@@ -3259,9 +3193,6 @@ packages:
prosemirror-view@1.41.8:
resolution: {integrity: sha512-TnKDdohEatgyZNGCDWIdccOHXhYloJwbwU+phw/a23KBvJIR9lWQWW7WHHK3vBdOLDNuF7TaX98GObUZOWkOnA==}
protocol-buffers-schema@3.6.1:
resolution: {integrity: sha512-VG2K63Igkiv9p76tk1lilczEK1cT+kCjKtkdhw1dQZV3k3IXJbd3o6Ho8b9zJZaHSnT2hKe4I+ObmX9w6m5SmQ==}
punycode.js@2.3.1:
resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==}
engines: {node: '>=6'}
@@ -3280,9 +3211,6 @@ packages:
engines: {node: '>=10.13.0'}
hasBin: true
quickselect@3.0.0:
resolution: {integrity: sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==}
react-day-picker@10.0.1:
resolution: {integrity: sha512-eNh6BlwcYInWaJtRv18mXQ06Ys/H6rdTZAnTaSdOYJuTpwP1JMCHNd1FDRadA+gbeinq+psdULN5Xnowy9mV8w==}
engines: {node: '>=18'}
@@ -3393,9 +3321,6 @@ packages:
require-main-filename@2.0.0:
resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
resolve-protobuf-schema@2.1.0:
resolution: {integrity: sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==}
rolldown@1.0.3:
resolution: {integrity: sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -3527,9 +3452,6 @@ packages:
resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==}
engines: {node: '>=12.0.0'}
tinyqueue@3.0.0:
resolution: {integrity: sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==}
tinyrainbow@3.1.1:
resolution: {integrity: sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==}
engines: {node: '>=14.0.0'}
@@ -4156,47 +4078,6 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.5
'@mapbox/jsonlint-lines-primitives@2.0.3': {}
'@mapbox/point-geometry@1.1.0': {}
'@mapbox/tiny-sdf@2.3.0': {}
'@mapbox/unitbezier@0.0.1': {}
'@mapbox/unitbezier@1.0.0': {}
'@mapbox/vector-tile@2.0.5':
dependencies:
'@mapbox/point-geometry': 1.1.0
'@types/geojson': 7946.0.16
pbf: 4.0.2
'@mapbox/whoots-js@3.1.0': {}
'@maplibre/geojson-vt@6.1.2':
dependencies:
kdbush: 4.1.0
'@maplibre/maplibre-gl-style-spec@24.10.0':
dependencies:
'@mapbox/jsonlint-lines-primitives': 2.0.3
'@mapbox/unitbezier': 1.0.0
json-stringify-pretty-compact: 4.0.0
minimist: 1.2.8
quickselect: 3.0.0
tinyqueue: 3.0.0
'@maplibre/mlt@1.3.0':
dependencies:
'@mapbox/point-geometry': 1.1.0
'@maplibre/vt-pbf@4.3.2':
dependencies:
'@mapbox/point-geometry': 1.1.0
'@types/geojson': 7946.0.16
pbf: 5.1.2
'@mediapipe/tasks-vision@0.10.35': {}
'@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)':
@@ -5470,8 +5351,6 @@ snapshots:
'@types/estree@1.0.9': {}
'@types/geojson@7946.0.16': {}
'@types/hast@3.0.4':
dependencies:
'@types/unist': 3.0.3
@@ -5780,8 +5659,6 @@ snapshots:
es-errors: 1.3.0
gopd: 1.2.0
earcut@3.2.4: {}
electron-to-chromium@1.5.361: {}
embla-carousel-react@8.6.0(react@19.2.8):
@@ -5897,8 +5774,6 @@ snapshots:
gitdiff-parser@0.3.1: {}
gl-matrix@3.4.4: {}
gopd@1.2.0: {}
graceful-fs@4.2.11: {}
@@ -6072,16 +5947,12 @@ snapshots:
jsesc@3.1.0: {}
json-stringify-pretty-compact@4.0.0: {}
json5@2.2.3: {}
just-debounce-it@1.1.0: {}
just-once@1.1.0: {}
kdbush@4.1.0: {}
lightningcss-android-arm64@1.32.0:
optional: true
@@ -6165,27 +6036,7 @@ snapshots:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
maplibre-gl@5.24.0:
dependencies:
'@mapbox/jsonlint-lines-primitives': 2.0.3
'@mapbox/point-geometry': 1.1.0
'@mapbox/tiny-sdf': 2.3.0
'@mapbox/unitbezier': 0.0.1
'@mapbox/vector-tile': 2.0.5
'@mapbox/whoots-js': 3.1.0
'@maplibre/geojson-vt': 6.1.2
'@maplibre/maplibre-gl-style-spec': 24.10.0
'@maplibre/mlt': 1.3.0
'@maplibre/vt-pbf': 4.3.2
'@types/geojson': 7946.0.16
earcut: 3.2.4
gl-matrix: 3.4.4
kdbush: 4.1.0
murmurhash-js: 1.0.0
pbf: 4.0.2
potpack: 2.1.0
quickselect: 3.0.0
tinyqueue: 3.0.0
mapbox-gl@3.32.0: {}
markdown-it-task-lists@2.1.1: {}
@@ -6581,8 +6432,6 @@ snapshots:
ms@2.1.3: {}
murmurhash-js@1.0.0: {}
nanoid@3.3.16: {}
nanoid@3.3.17: {}
@@ -6649,14 +6498,6 @@ snapshots:
pathe@2.0.3: {}
pbf@4.0.2:
dependencies:
resolve-protobuf-schema: 2.1.0
pbf@5.1.2:
dependencies:
resolve-protobuf-schema: 2.1.0
picocolors@1.1.1: {}
picomatch@4.0.5: {}
@@ -6694,8 +6535,6 @@ snapshots:
picocolors: 1.1.1
source-map-js: 1.2.1
potpack@2.1.0: {}
prettier@3.8.3: {}
pretty-format@27.5.1:
@@ -6783,8 +6622,6 @@ snapshots:
prosemirror-state: 1.4.4
prosemirror-transform: 1.12.0
protocol-buffers-schema@3.6.1: {}
punycode.js@2.3.1: {}
punycode@2.3.1: {}
@@ -6799,8 +6636,6 @@ snapshots:
pngjs: 5.0.0
yargs: 15.4.1
quickselect@3.0.0: {}
react-day-picker@10.0.1(@types/react@19.2.18)(react@19.2.8):
dependencies:
'@date-fns/tz': 1.5.0
@@ -6944,10 +6779,6 @@ snapshots:
require-main-filename@2.0.0: {}
resolve-protobuf-schema@2.1.0:
dependencies:
protocol-buffers-schema: 3.6.1
rolldown@1.0.3:
dependencies:
'@oxc-project/types': 0.133.0
@@ -7090,8 +6921,6 @@ snapshots:
fdir: 6.5.0(picomatch@4.0.7)
picomatch: 4.0.7
tinyqueue@3.0.0: {}
tinyrainbow@3.1.1: {}
tiptap-markdown@0.9.0(@tiptap/core@3.22.5(@tiptap/pm@3.22.5)):