maplibre-gl-basemap-control 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -193,6 +193,7 @@ https://api.mapbox.com/styles/v1/mapbox/{styleId}?access_token={api-key}
193
193
  | `allowMultiple` | `boolean` | `false` | Stack raster basemaps instead of replacing the active one |
194
194
  | `showMultipleToggle` | `boolean` | `true` | Show the in-panel toggle that switches between adding and replacing |
195
195
  | `resizable` | `boolean` | `true` | Allow resizing the panel by dragging its bottom-left or bottom-right corner |
196
+ | `confirmStyleReplace` | `(confirmation) => boolean \| Promise<boolean>` | `undefined` | Confirm before a style basemap replaces stacked raster basemaps (only invoked in `allowMultiple` mode with at least one raster stacked); return `false` to cancel |
196
197
 
197
198
  ### Multiple Basemaps
198
199
 
@@ -222,6 +223,22 @@ a style basemap always replaces the active basemaps (and clears any stacked rast
222
223
  overlays). Use the `before_id` input to control where each raster basemap is
223
224
  inserted relative to existing layers.
224
225
 
226
+ Because that swap is destructive in stack mode, you can pass `confirmStyleReplace`
227
+ to confirm before the stacked rasters are discarded. It is only invoked in
228
+ `allowMultiple` mode when at least one raster basemap is currently stacked, and
229
+ receives the `{ basemap, replacedBasemapIds }` it is about to replace. Return (or
230
+ resolve to) `false` to cancel and keep the current basemaps.
231
+
232
+ ```typescript
233
+ const control = new BasemapControl({
234
+ allowMultiple: true,
235
+ confirmStyleReplace: ({ basemap, replacedBasemapIds }) =>
236
+ window.confirm(
237
+ `Switching to "${basemap.name}" will remove ${replacedBasemapIds.length} stacked basemap(s). Continue?`,
238
+ ),
239
+ });
240
+ ```
241
+
225
242
  ### Methods
226
243
 
227
244
  - `setBasemap(id)` - Apply a basemap and remove the previous plugin-managed basemap
@@ -1114,9 +1114,31 @@ const MAPTILER_API_KEY_EXAMPLE = "YOUR_MAPTILER_API_KEY";
1114
1114
  const MAPTILER_API_KEY_QUERY = "?key";
1115
1115
  const MAPTILER_API_KEY_EMPTY_QUERY = "?key=";
1116
1116
  const AWS_REGION_PLACEHOLDER = "{aws-region}";
1117
+ const PROVIDER_CREDENTIAL_HELP = {
1118
+ amazon: {
1119
+ url: "https://docs.aws.amazon.com/location/latest/developerguide/using-apikeys.html",
1120
+ label: "Get an Amazon API key"
1121
+ },
1122
+ maptiler: {
1123
+ url: "https://cloud.maptiler.com/account/keys/",
1124
+ label: "Get a MapTiler API key"
1125
+ },
1126
+ mapbox: {
1127
+ url: "https://docs.mapbox.com/help/getting-started/access-tokens/",
1128
+ label: "Get a Mapbox access token"
1129
+ }
1130
+ };
1117
1131
  const MIN_PANEL_WIDTH = 240;
1118
1132
  const MIN_PANEL_HEIGHT = 200;
1119
1133
  const PANEL_VIEWPORT_MARGIN = 12;
1134
+ class MissingCredentialError extends Error {
1135
+ constructor(message, provider) {
1136
+ super(message);
1137
+ __publicField(this, "provider");
1138
+ this.name = "MissingCredentialError";
1139
+ this.provider = provider;
1140
+ }
1141
+ }
1120
1142
  class BasemapControl {
1121
1143
  constructor(options) {
1122
1144
  __publicField(this, "_map");
@@ -1138,6 +1160,10 @@ class BasemapControl {
1138
1160
  __publicField(this, "_awsRegion", "");
1139
1161
  __publicField(this, "_mapboxAccessToken", "");
1140
1162
  __publicField(this, "_providerSettingsCollapsed", true);
1163
+ // Provider of the most recent missing-credential error, used to pick the
1164
+ // matching help link. Kept in sync with `_state.error` (both are set together
1165
+ // in `_applyBasemapChange`'s catch) so it is never stale when consulted.
1166
+ __publicField(this, "_missingCredentialProvider");
1141
1167
  __publicField(this, "_resizeHandler", null);
1142
1168
  __publicField(this, "_mapResizeHandler", null);
1143
1169
  __publicField(this, "_resizeAnchor", null);
@@ -1363,6 +1389,16 @@ class BasemapControl {
1363
1389
  }
1364
1390
  const isRaster = basemap.source.type === "raster";
1365
1391
  const effectiveMode = isRaster ? mode : "replace";
1392
+ if (!isRaster && this._state.allowMultiple && this._managedRasters.size > 0 && this._options.confirmStyleReplace) {
1393
+ const replacedBasemapIds = [...this._managedRasters.keys()];
1394
+ let confirmed = false;
1395
+ try {
1396
+ confirmed = await this._options.confirmStyleReplace({ basemap, replacedBasemapIds });
1397
+ } catch {
1398
+ confirmed = false;
1399
+ }
1400
+ if (!confirmed) return;
1401
+ }
1366
1402
  this._state = { ...this._state, loading: true, error: void 0 };
1367
1403
  this._renderContent(true);
1368
1404
  this._emit({ type: "statechange", state: this.getState() });
@@ -1407,6 +1443,10 @@ class BasemapControl {
1407
1443
  } catch (cause) {
1408
1444
  const error = cause instanceof Error ? cause : new Error(String(cause));
1409
1445
  this._state = { ...this._state, loading: false, error: error.message };
1446
+ this._missingCredentialProvider = cause instanceof MissingCredentialError ? cause.provider : void 0;
1447
+ if (cause instanceof MissingCredentialError) {
1448
+ this._providerSettingsCollapsed = false;
1449
+ }
1410
1450
  this._renderContent(true);
1411
1451
  this._handleError(error, basemap);
1412
1452
  throw error;
@@ -1779,13 +1819,38 @@ class BasemapControl {
1779
1819
  if (this._state.loading) {
1780
1820
  status.textContent = "Applying basemap...";
1781
1821
  } else if (this._state.error) {
1782
- status.textContent = this._state.error;
1783
1822
  status.classList.add("is-error");
1823
+ const message = document.createElement("span");
1824
+ message.className = "basemap-control-status-message";
1825
+ message.textContent = this._state.error;
1826
+ status.appendChild(message);
1827
+ const help = this._credentialHelpForError(this._missingCredentialProvider);
1828
+ if (help) {
1829
+ const actions = document.createElement("span");
1830
+ actions.className = "basemap-control-status-actions";
1831
+ const link = document.createElement("a");
1832
+ link.className = "basemap-control-status-link";
1833
+ link.href = help.url;
1834
+ link.target = "_blank";
1835
+ link.rel = "noopener noreferrer";
1836
+ link.textContent = help.label;
1837
+ actions.appendChild(link);
1838
+ const hint = document.createElement("span");
1839
+ hint.className = "basemap-control-status-hint";
1840
+ hint.textContent = ", then add it under Provider settings below.";
1841
+ actions.appendChild(hint);
1842
+ status.appendChild(actions);
1843
+ }
1784
1844
  } else {
1785
1845
  status.textContent = `${resultCount} basemap${resultCount === 1 ? "" : "s"}`;
1786
1846
  }
1787
1847
  return status;
1788
1848
  }
1849
+ // Resolves the help link for a missing-credential provider, so the status can
1850
+ // offer a concrete next step. Returns undefined when there is no such error.
1851
+ _credentialHelpForError(provider) {
1852
+ return provider ? PROVIDER_CREDENTIAL_HELP[provider] : void 0;
1853
+ }
1789
1854
  _createResults(results) {
1790
1855
  const list = document.createElement("div");
1791
1856
  list.className = "basemap-control-results";
@@ -1934,7 +1999,10 @@ class BasemapControl {
1934
1999
  if (!needsMapTilerKey) return url;
1935
2000
  const apiKey = this._mapTilerApiKey.trim();
1936
2001
  if (!apiKey) {
1937
- throw new Error("Enter a MapTiler API key before applying this basemap.");
2002
+ throw new MissingCredentialError(
2003
+ "Enter a MapTiler API key before applying this basemap.",
2004
+ "maptiler"
2005
+ );
1938
2006
  }
1939
2007
  const encodedApiKey = encodeURIComponent(apiKey);
1940
2008
  if (url.endsWith(MAPTILER_API_KEY_QUERY)) {
@@ -1949,20 +2017,32 @@ class BasemapControl {
1949
2017
  const apiKey = this._amazonApiKey.trim();
1950
2018
  const awsRegion = this._awsRegion.trim();
1951
2019
  if (url.includes(API_KEY_PLACEHOLDER) && !apiKey) {
1952
- throw new Error("Enter an Amazon API key before applying this basemap.");
2020
+ throw new MissingCredentialError(
2021
+ "Enter an Amazon API key before applying this basemap.",
2022
+ "amazon"
2023
+ );
1953
2024
  }
1954
2025
  if (url.includes(AWS_REGION_PLACEHOLDER) && !awsRegion) {
1955
- throw new Error("Enter an AWS region before applying this basemap.");
2026
+ throw new MissingCredentialError(
2027
+ "Enter an AWS region before applying this basemap.",
2028
+ "amazon"
2029
+ );
1956
2030
  }
1957
2031
  return url.split(AWS_REGION_PLACEHOLDER).join(awsRegion).split(API_KEY_PLACEHOLDER).join(encodeURIComponent(apiKey));
1958
2032
  }
1959
2033
  _resolveMapboxStyleUrl(url) {
1960
2034
  const accessToken = this._mapboxAccessToken.trim();
1961
2035
  if (url.includes(API_KEY_PLACEHOLDER) && !accessToken) {
1962
- throw new Error("Enter a Mapbox access token before applying this basemap.");
2036
+ throw new MissingCredentialError(
2037
+ "Enter a Mapbox access token before applying this basemap.",
2038
+ "mapbox"
2039
+ );
1963
2040
  }
1964
2041
  if (this._isUrlLikeCredential(accessToken)) {
1965
- throw new Error("Enter a valid Mapbox access token, not a URL.");
2042
+ throw new MissingCredentialError(
2043
+ "Enter a valid Mapbox access token, not a URL.",
2044
+ "mapbox"
2045
+ );
1966
2046
  }
1967
2047
  return url.split(API_KEY_PLACEHOLDER).join(encodeURIComponent(accessToken));
1968
2048
  }
@@ -2156,4 +2236,4 @@ exports.createBasemapCatalog = createBasemapCatalog;
2156
2236
  exports.filterBasemaps = filterBasemaps;
2157
2237
  exports.getBasemapCategories = getBasemapCategories;
2158
2238
  exports.resolveBasemapProviders = resolveBasemapProviders;
2159
- //# sourceMappingURL=BasemapControl-DDvY9KVh.cjs.map
2239
+ //# sourceMappingURL=BasemapControl-B8WWNorQ.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BasemapControl-B8WWNorQ.cjs","sources":["../src/lib/core/catalog.ts","../src/lib/core/BasemapControl.ts"],"sourcesContent":["import type { BasemapDefinition, BasemapProvider } from './types';\n\nexport const DEFAULT_BASEMAP_PROVIDERS: BasemapProvider[] = [\n { id: 'amazon', name: 'Amazon Location', category: 'General' },\n { id: 'carto', name: 'Carto', category: 'General' },\n { id: 'cyclosm', name: 'CyclOSM', category: 'Cycling' },\n { id: 'esri', name: 'ESRI', category: 'Imagery' },\n { id: 'google', name: 'Google', category: 'General' },\n { id: 'mapbox', name: 'Mapbox', category: 'General' },\n { id: 'maptiler', name: 'MapTiler', category: 'General' },\n { id: 'nasa-gibs', name: 'NASA GIBS', category: 'Imagery' },\n { id: 'nlmaps', name: 'nlmaps', category: 'Regional' },\n { id: 'openfreemap', name: 'OpenFreeMap', category: 'Vector Styles' },\n { id: 'openrailwaymap', name: 'OpenRailwayMap', category: 'Transport' },\n { id: 'openstreetmap', name: 'OpenStreetMap', category: 'Community' },\n { id: 'opentopomap', name: 'OpenTopoMap', category: 'Terrain' },\n { id: 'swisstopo', name: 'Swiss Federal Geoportal', category: 'Regional' },\n { id: 'topplusopen', name: 'TopPlusOpen', category: 'Regional' },\n { id: 'usgs', name: 'USGS', category: 'United States' },\n { id: 'waymarkedtrails', name: 'Waymarked Trails', category: 'Outdoor' },\n];\n\nfunction rasterBasemap({\n id,\n name,\n provider,\n category,\n description,\n attribution,\n tiles,\n maxzoom = 19,\n tags = [],\n}: Omit<BasemapDefinition, 'type' | 'source'> & {\n tiles: string[];\n maxzoom?: number;\n}): BasemapDefinition {\n return {\n id,\n name,\n provider,\n type: 'raster',\n category,\n description,\n attribution,\n source: {\n type: 'raster',\n tiles,\n tileSize: 256,\n maxzoom,\n },\n tags,\n };\n}\n\nfunction styleBasemap({\n id,\n name,\n provider,\n category,\n description,\n attribution,\n url,\n view,\n tags = [],\n}: Omit<BasemapDefinition, 'type' | 'source'> & {\n url: string;\n}): BasemapDefinition {\n return {\n id,\n name,\n provider,\n type: 'style',\n category,\n description,\n attribution,\n source: {\n type: 'style',\n url,\n },\n view,\n tags,\n };\n}\n\nfunction mapTilerStyleBasemap({\n id,\n name,\n mapId,\n category,\n description,\n url,\n tags = [],\n}: {\n id: string;\n name: string;\n mapId: string;\n category: string;\n description: string;\n url?: string;\n tags?: string[];\n}): BasemapDefinition {\n return styleBasemap({\n id,\n name,\n provider: 'maptiler',\n category,\n description,\n attribution: MAPTILER_ATTRIBUTION,\n url: url ?? `https://api.maptiler.com/maps/${mapId}/style.json?key={api-key}`,\n tags: ['maptiler', 'vector', 'style', ...tags],\n });\n}\n\nfunction amazonStyleBasemap({\n id,\n name,\n mapStyle,\n category,\n description,\n tags = [],\n}: {\n id: string;\n name: string;\n mapStyle: string;\n category: string;\n description: string;\n tags?: string[];\n}): BasemapDefinition {\n return styleBasemap({\n id,\n name,\n provider: 'amazon',\n category,\n description,\n attribution: AMAZON_ATTRIBUTION,\n url: `https://maps.geo.{aws-region}.amazonaws.com/v2/styles/${mapStyle}/descriptor?key={api-key}`,\n tags: ['amazon', 'aws', 'location', 'style', ...tags],\n });\n}\n\nfunction mapboxStyleBasemap({\n id,\n name,\n styleId,\n category,\n description,\n tags = [],\n}: {\n id: string;\n name: string;\n styleId: string;\n category: string;\n description: string;\n tags?: string[];\n}): BasemapDefinition {\n return styleBasemap({\n id,\n name,\n provider: 'mapbox',\n category,\n description,\n attribution: MAPBOX_ATTRIBUTION,\n url: `https://api.mapbox.com/styles/v1/mapbox/${styleId}?access_token={api-key}`,\n tags: ['mapbox', 'vector', 'style', ...tags],\n });\n}\n\nfunction sortProviders(providers: BasemapProvider[]): BasemapProvider[] {\n return [...providers].sort((a, b) => a.name.localeCompare(b.name));\n}\n\nconst AMAZON_ATTRIBUTION = '&copy; Amazon Location Service';\nconst CARTO_ATTRIBUTION = '&copy; OpenStreetMap contributors &copy; CARTO';\nconst ESRI_ATTRIBUTION = 'Tiles &copy; Esri and the GIS User Community';\nconst MAPBOX_ATTRIBUTION = '&copy; Mapbox &copy; OpenStreetMap contributors';\nconst MAPTILER_ATTRIBUTION = '&copy; MapTiler &copy; OpenStreetMap contributors';\nconst OSM_ATTRIBUTION = '&copy; OpenStreetMap contributors';\nconst OPENFREEMAP_ATTRIBUTION = 'OpenFreeMap &copy; OpenMapTiles Data from OpenStreetMap';\n\nexport const DEFAULT_BASEMAPS: BasemapDefinition[] = [\n rasterBasemap({\n id: 'osm-standard',\n name: 'OpenStreetMap Standard',\n provider: 'openstreetmap',\n category: 'Street',\n description: 'Community-maintained street map.',\n attribution: OSM_ATTRIBUTION,\n tiles: [\n 'https://a.tile.openstreetmap.org/{z}/{x}/{y}.png',\n 'https://b.tile.openstreetmap.org/{z}/{x}/{y}.png',\n 'https://c.tile.openstreetmap.org/{z}/{x}/{y}.png',\n ],\n tags: ['osm', 'street', 'standard'],\n }),\n rasterBasemap({\n id: 'osm-hot',\n name: 'OpenStreetMap HOT',\n provider: 'openstreetmap',\n category: 'Street',\n description: 'Humanitarian OpenStreetMap Team style.',\n attribution: `${OSM_ATTRIBUTION}, Tiles style by Humanitarian OpenStreetMap Team`,\n tiles: ['https://a.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png'],\n tags: ['osm', 'hot', 'humanitarian'],\n }),\n rasterBasemap({\n id: 'osm-de',\n name: 'OpenStreetMap DE',\n provider: 'openstreetmap',\n category: 'Regional',\n description: 'German OpenStreetMap tile style.',\n attribution: OSM_ATTRIBUTION,\n tiles: ['https://tile.openstreetmap.de/{z}/{x}/{y}.png'],\n tags: ['osm', 'germany', 'regional'],\n }),\n rasterBasemap({\n id: 'osm-ch',\n name: 'OpenStreetMap CH',\n provider: 'openstreetmap',\n category: 'Regional',\n description: 'Swiss OpenStreetMap tile style.',\n attribution: OSM_ATTRIBUTION,\n tiles: ['https://tile.osm.ch/switzerland/{z}/{x}/{y}.png'],\n tags: ['osm', 'switzerland', 'regional'],\n }),\n rasterBasemap({\n id: 'google-maps',\n name: 'Google Maps',\n provider: 'google',\n category: 'Street',\n description: 'Google road map tiles from the QGIS basemaps source.',\n attribution: '&copy; Google',\n tiles: ['https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}'],\n maxzoom: 20,\n tags: ['google', 'street'],\n }),\n rasterBasemap({\n id: 'google-satellite',\n name: 'Google Satellite',\n provider: 'google',\n category: 'Imagery',\n description: 'Google satellite tiles from the QGIS basemaps source.',\n attribution: '&copy; Google',\n tiles: ['https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}'],\n maxzoom: 20,\n tags: ['google', 'satellite', 'imagery'],\n }),\n rasterBasemap({\n id: 'google-terrain',\n name: 'Google Terrain',\n provider: 'google',\n category: 'Terrain',\n description: 'Google terrain tiles from the QGIS basemaps source.',\n attribution: '&copy; Google',\n tiles: ['https://mt1.google.com/vt/lyrs=p&x={x}&y={y}&z={z}'],\n maxzoom: 20,\n tags: ['google', 'terrain'],\n }),\n rasterBasemap({\n id: 'google-hybrid',\n name: 'Google Hybrid',\n provider: 'google',\n category: 'Imagery',\n description: 'Google hybrid imagery tiles from the QGIS basemaps source.',\n attribution: '&copy; Google',\n tiles: ['https://mt1.google.com/vt/lyrs=y&x={x}&y={y}&z={z}'],\n maxzoom: 20,\n tags: ['google', 'hybrid', 'imagery'],\n }),\n amazonStyleBasemap({\n id: 'amazon-standard',\n name: 'Amazon Standard',\n mapStyle: 'Standard',\n category: 'Street',\n description: 'Amazon Location general-purpose vector map style.',\n tags: ['standard', 'street'],\n }),\n amazonStyleBasemap({\n id: 'amazon-monochrome',\n name: 'Amazon Monochrome',\n mapStyle: 'Monochrome',\n category: 'Light',\n description: 'Amazon Location grey scale map style for overlays.',\n tags: ['monochrome', 'light', 'dataviz'],\n }),\n amazonStyleBasemap({\n id: 'amazon-hybrid',\n name: 'Amazon Hybrid',\n mapStyle: 'Hybrid',\n category: 'Imagery',\n description: 'Amazon Location satellite imagery with road and label overlay.',\n tags: ['hybrid', 'satellite', 'imagery', 'labels'],\n }),\n amazonStyleBasemap({\n id: 'amazon-satellite',\n name: 'Amazon Satellite',\n mapStyle: 'Satellite',\n category: 'Imagery',\n description: 'Amazon Location satellite imagery map style.',\n tags: ['satellite', 'imagery'],\n }),\n mapboxStyleBasemap({\n id: 'mapbox-streets',\n name: 'Mapbox Streets',\n styleId: 'streets-v12',\n category: 'Street',\n description: 'Mapbox general-purpose street map style.',\n tags: ['streets', 'street'],\n }),\n mapboxStyleBasemap({\n id: 'mapbox-outdoors',\n name: 'Mapbox Outdoors',\n styleId: 'outdoors-v12',\n category: 'Outdoor',\n description: 'Mapbox outdoor recreation and terrain style.',\n tags: ['outdoors', 'terrain', 'recreation'],\n }),\n mapboxStyleBasemap({\n id: 'mapbox-light',\n name: 'Mapbox Light',\n styleId: 'light-v11',\n category: 'Light',\n description: 'Light Mapbox style for data overlays.',\n tags: ['light', 'dataviz'],\n }),\n mapboxStyleBasemap({\n id: 'mapbox-dark',\n name: 'Mapbox Dark',\n styleId: 'dark-v11',\n category: 'Dark',\n description: 'Dark Mapbox style for high-contrast overlays.',\n tags: ['dark'],\n }),\n mapboxStyleBasemap({\n id: 'mapbox-satellite',\n name: 'Mapbox Satellite',\n styleId: 'satellite-v9',\n category: 'Imagery',\n description: 'Mapbox satellite imagery style.',\n tags: ['satellite', 'imagery'],\n }),\n mapboxStyleBasemap({\n id: 'mapbox-satellite-streets',\n name: 'Mapbox Satellite Streets',\n styleId: 'satellite-streets-v12',\n category: 'Imagery',\n description: 'Mapbox satellite imagery with streets and labels.',\n tags: ['satellite', 'streets', 'imagery', 'labels'],\n }),\n mapboxStyleBasemap({\n id: 'mapbox-navigation-day',\n name: 'Mapbox Navigation Day',\n styleId: 'navigation-day-v1',\n category: 'Navigation',\n description: 'Mapbox daytime navigation style.',\n tags: ['navigation', 'day'],\n }),\n mapboxStyleBasemap({\n id: 'mapbox-navigation-night',\n name: 'Mapbox Navigation Night',\n styleId: 'navigation-night-v1',\n category: 'Navigation',\n description: 'Mapbox nighttime navigation style.',\n tags: ['navigation', 'night', 'dark'],\n }),\n mapTilerStyleBasemap({\n id: 'maptiler-aquarelle',\n name: 'MapTiler Aquarelle',\n mapId: 'aquarelle-v4',\n category: 'Artistic',\n description: 'Watercolor-style vector basemap.',\n tags: ['aquarelle', 'watercolor', 'artistic'],\n }),\n mapTilerStyleBasemap({\n id: 'maptiler-backdrop',\n name: 'MapTiler Backdrop',\n mapId: 'backdrop-v4',\n category: 'Light',\n description: 'Subtle monochrome context map.',\n tags: ['backdrop', 'monochrome', 'context'],\n }),\n mapTilerStyleBasemap({\n id: 'maptiler-base',\n name: 'MapTiler Base',\n mapId: 'base-v4',\n category: 'Street',\n description: 'General-purpose vector basemap.',\n tags: ['base', 'street'],\n }),\n mapTilerStyleBasemap({\n id: 'maptiler-dataviz',\n name: 'MapTiler Dataviz',\n mapId: 'dataviz-v4',\n category: 'Light',\n description: 'Minimal basemap for data visualization and overlays.',\n tags: ['dataviz', 'data', 'light'],\n }),\n mapTilerStyleBasemap({\n id: 'maptiler-landscape',\n name: 'MapTiler Landscape',\n mapId: 'landscape-v4',\n category: 'Terrain',\n description: 'Light terrain and hillshade map.',\n tags: ['landscape', 'terrain', 'hillshade'],\n }),\n mapTilerStyleBasemap({\n id: 'maptiler-ocean',\n name: 'MapTiler Ocean',\n mapId: 'ocean-v4',\n category: 'Marine',\n description: 'Ocean bathymetry and marine-focused basemap.',\n tags: ['ocean', 'marine', 'bathymetry'],\n }),\n mapTilerStyleBasemap({\n id: 'maptiler-openstreetmap',\n name: 'MapTiler OpenStreetMap',\n mapId: 'openstreetmap',\n category: 'Street',\n description: 'OpenStreetMap style hosted by MapTiler.',\n url: 'https://api.maptiler.com/maps/openstreetmap/style.json?key',\n tags: ['openstreetmap', 'osm', 'street'],\n }),\n mapTilerStyleBasemap({\n id: 'maptiler-outdoor',\n name: 'MapTiler Outdoor',\n mapId: 'outdoor-v4',\n category: 'Outdoor',\n description: 'Outdoor recreation basemap with terrain detail.',\n tags: ['outdoor', 'terrain', 'recreation'],\n }),\n mapTilerStyleBasemap({\n id: 'maptiler-satellite-hybrid',\n name: 'MapTiler Satellite Hybrid',\n mapId: 'hybrid-v4',\n category: 'Imagery',\n description: 'Satellite imagery with labels, roads, and borders.',\n tags: ['satellite', 'hybrid', 'imagery', 'labels'],\n }),\n mapTilerStyleBasemap({\n id: 'maptiler-satellite-plain',\n name: 'MapTiler Satellite Plain',\n mapId: 'satellite-v4',\n category: 'Imagery',\n description: 'Satellite imagery without the hybrid reference overlay.',\n tags: ['satellite', 'imagery'],\n }),\n mapTilerStyleBasemap({\n id: 'maptiler-streets',\n name: 'MapTiler Streets',\n mapId: 'streets-v4',\n category: 'Street',\n description: 'Detailed street map for general navigation.',\n tags: ['streets', 'street', 'navigation'],\n }),\n mapTilerStyleBasemap({\n id: 'maptiler-toner',\n name: 'MapTiler Toner',\n mapId: 'toner-v2',\n category: 'Dark',\n description: 'High-contrast monochrome basemap.',\n url: 'https://api.maptiler.com/maps/toner-v2/style.json?key=',\n tags: ['toner', 'monochrome', 'contrast'],\n }),\n mapTilerStyleBasemap({\n id: 'maptiler-topo',\n name: 'MapTiler Topo',\n mapId: 'topo-v4',\n category: 'Terrain',\n description: 'Topographic basemap with contours and terrain context.',\n tags: ['topo', 'topographic', 'terrain'],\n }),\n mapTilerStyleBasemap({\n id: 'maptiler-winter',\n name: 'MapTiler Winter',\n mapId: 'winter-v4',\n category: 'Outdoor',\n description: 'Winter sports and mountain activity basemap.',\n tags: ['winter', 'skiing', 'outdoor'],\n }),\n rasterBasemap({\n id: 'carto-positron',\n name: 'Carto Positron',\n provider: 'carto',\n category: 'Light',\n description: 'Light basemap for data overlays.',\n attribution: CARTO_ATTRIBUTION,\n tiles: [\n 'https://a.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',\n 'https://b.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',\n 'https://c.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',\n 'https://d.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',\n ],\n maxzoom: 20,\n tags: ['carto', 'light', 'positron'],\n }),\n rasterBasemap({\n id: 'carto-positron-no-labels',\n name: 'Carto Positron No Labels',\n provider: 'carto',\n category: 'Light',\n description: 'Light basemap without labels.',\n attribution: CARTO_ATTRIBUTION,\n tiles: ['https://a.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png'],\n maxzoom: 20,\n tags: ['carto', 'light', 'no labels'],\n }),\n rasterBasemap({\n id: 'carto-positron-only-labels',\n name: 'Carto Positron Only Labels',\n provider: 'carto',\n category: 'Labels',\n description: 'Carto Positron labels layer.',\n attribution: CARTO_ATTRIBUTION,\n tiles: ['https://a.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png'],\n maxzoom: 20,\n tags: ['carto', 'labels'],\n }),\n rasterBasemap({\n id: 'carto-dark-matter',\n name: 'Carto Dark Matter',\n provider: 'carto',\n category: 'Dark',\n description: 'Dark basemap for high-contrast overlays.',\n attribution: CARTO_ATTRIBUTION,\n tiles: [\n 'https://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',\n 'https://b.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',\n 'https://c.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',\n 'https://d.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',\n ],\n maxzoom: 20,\n tags: ['carto', 'dark', 'matter'],\n }),\n rasterBasemap({\n id: 'carto-dark-matter-no-labels',\n name: 'Carto Dark Matter No Labels',\n provider: 'carto',\n category: 'Dark',\n description: 'Dark basemap without labels.',\n attribution: CARTO_ATTRIBUTION,\n tiles: ['https://a.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png'],\n maxzoom: 20,\n tags: ['carto', 'dark', 'no labels'],\n }),\n rasterBasemap({\n id: 'carto-dark-matter-only-labels',\n name: 'Carto Dark Matter Only Labels',\n provider: 'carto',\n category: 'Labels',\n description: 'Carto Dark Matter labels layer.',\n attribution: CARTO_ATTRIBUTION,\n tiles: ['https://a.basemaps.cartocdn.com/dark_only_labels/{z}/{x}/{y}.png'],\n maxzoom: 20,\n tags: ['carto', 'dark', 'labels'],\n }),\n rasterBasemap({\n id: 'carto-voyager',\n name: 'Carto Voyager',\n provider: 'carto',\n category: 'Street',\n description: 'Detailed street basemap with subtle styling.',\n attribution: CARTO_ATTRIBUTION,\n tiles: [\n 'https://a.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png',\n 'https://b.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png',\n 'https://c.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png',\n 'https://d.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png',\n ],\n maxzoom: 20,\n tags: ['carto', 'street', 'voyager'],\n }),\n rasterBasemap({\n id: 'carto-voyager-no-labels',\n name: 'Carto Voyager No Labels',\n provider: 'carto',\n category: 'Street',\n description: 'Carto Voyager without labels.',\n attribution: CARTO_ATTRIBUTION,\n tiles: ['https://a.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png'],\n maxzoom: 20,\n tags: ['carto', 'voyager', 'no labels'],\n }),\n rasterBasemap({\n id: 'carto-voyager-only-labels',\n name: 'Carto Voyager Only Labels',\n provider: 'carto',\n category: 'Labels',\n description: 'Carto Voyager labels layer.',\n attribution: CARTO_ATTRIBUTION,\n tiles: ['https://a.basemaps.cartocdn.com/rastertiles/voyager_only_labels/{z}/{x}/{y}.png'],\n maxzoom: 20,\n tags: ['carto', 'voyager', 'labels'],\n }),\n rasterBasemap({\n id: 'carto-voyager-labels-under',\n name: 'Carto Voyager Labels Under',\n provider: 'carto',\n category: 'Street',\n description: 'Carto Voyager labels-under variant.',\n attribution: CARTO_ATTRIBUTION,\n tiles: ['https://a.basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}.png'],\n maxzoom: 20,\n tags: ['carto', 'voyager', 'labels'],\n }),\n rasterBasemap({\n id: 'cyclosm',\n name: 'CyclOSM',\n provider: 'cyclosm',\n category: 'Cycling',\n description: 'Cycling-focused OpenStreetMap style.',\n attribution: 'CyclOSM | Map data: &copy; OpenStreetMap contributors',\n tiles: ['https://a.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png'],\n tags: ['cycling', 'osm'],\n }),\n rasterBasemap({\n id: 'esri-world-imagery',\n name: 'World Imagery',\n provider: 'esri',\n category: 'Imagery',\n description: 'Satellite and aerial imagery.',\n attribution: 'Tiles &copy; Esri, Maxar, Earthstar Geographics, and the GIS User Community',\n tiles: [\n 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',\n ],\n tags: ['esri', 'satellite', 'imagery'],\n }),\n rasterBasemap({\n id: 'esri-world-topo',\n name: 'World Topographic',\n provider: 'esri',\n category: 'Terrain',\n description: 'Reference topographic map.',\n attribution: ESRI_ATTRIBUTION,\n tiles: [\n 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}',\n ],\n tags: ['esri', 'topographic', 'terrain'],\n }),\n rasterBasemap({\n id: 'esri-world-street-map',\n name: 'World Street Map',\n provider: 'esri',\n category: 'Street',\n description: 'ESRI street reference basemap.',\n attribution: ESRI_ATTRIBUTION,\n tiles: [\n 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}',\n ],\n tags: ['esri', 'street'],\n }),\n rasterBasemap({\n id: 'esri-world-gray-canvas',\n name: 'World Gray Canvas',\n provider: 'esri',\n category: 'Light',\n description: 'Light gray canvas basemap.',\n attribution: ESRI_ATTRIBUTION,\n tiles: [\n 'https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}',\n ],\n tags: ['esri', 'gray', 'canvas'],\n }),\n rasterBasemap({\n id: 'esri-natgeo-world-map',\n name: 'NatGeo World Map',\n provider: 'esri',\n category: 'Street',\n description: 'National Geographic style world map.',\n attribution: ESRI_ATTRIBUTION,\n tiles: [\n 'https://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}',\n ],\n tags: ['esri', 'natgeo'],\n }),\n rasterBasemap({\n id: 'esri-ocean-basemap',\n name: 'Ocean Basemap',\n provider: 'esri',\n category: 'Marine',\n description: 'Ocean reference basemap.',\n attribution: ESRI_ATTRIBUTION,\n tiles: [\n 'https://server.arcgisonline.com/ArcGIS/rest/services/Ocean/World_Ocean_Base/MapServer/tile/{z}/{y}/{x}',\n ],\n tags: ['esri', 'ocean', 'marine'],\n }),\n rasterBasemap({\n id: 'esri-world-physical',\n name: 'World Physical',\n provider: 'esri',\n category: 'Terrain',\n description: 'Physical world map.',\n attribution: ESRI_ATTRIBUTION,\n tiles: [\n 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer/tile/{z}/{y}/{x}',\n ],\n tags: ['esri', 'physical', 'terrain'],\n }),\n rasterBasemap({\n id: 'esri-world-shaded-relief',\n name: 'World Shaded Relief',\n provider: 'esri',\n category: 'Terrain',\n description: 'Shaded relief world map.',\n attribution: ESRI_ATTRIBUTION,\n tiles: [\n 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}',\n ],\n tags: ['esri', 'relief', 'terrain'],\n }),\n rasterBasemap({\n id: 'esri-world-terrain',\n name: 'World Terrain',\n provider: 'esri',\n category: 'Terrain',\n description: 'ESRI terrain base.',\n attribution: ESRI_ATTRIBUTION,\n tiles: [\n 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer/tile/{z}/{y}/{x}',\n ],\n tags: ['esri', 'terrain'],\n }),\n rasterBasemap({\n id: 'nasa-gibs-blue-marble',\n name: 'Blue Marble',\n provider: 'nasa-gibs',\n category: 'Imagery',\n description: 'NASA Blue Marble Next Generation imagery.',\n attribution: 'Imagery provided by NASA Global Imagery Browse Services',\n tiles: [\n 'https://gibs.earthdata.nasa.gov/wmts/epsg3857/best/BlueMarble_NextGeneration/default/GoogleMapsCompatible_Level8/{z}/{y}/{x}.jpeg',\n ],\n maxzoom: 8,\n tags: ['nasa', 'gibs', 'blue marble'],\n }),\n rasterBasemap({\n id: 'nasa-gibs-aster-gdem-shaded-relief',\n name: 'ASTER GDEM Shaded Relief',\n provider: 'nasa-gibs',\n category: 'Terrain',\n description: 'NASA ASTER GDEM greyscale shaded relief.',\n attribution: 'Imagery provided by NASA Global Imagery Browse Services',\n tiles: [\n 'https://gibs.earthdata.nasa.gov/wmts/epsg3857/best/ASTER_GDEM_Greyscale_Shaded_Relief/default/GoogleMapsCompatible_Level12/{z}/{y}/{x}.jpg',\n ],\n maxzoom: 12,\n tags: ['nasa', 'gibs', 'relief', 'terrain'],\n }),\n rasterBasemap({\n id: 'nasa-gibs-modis-terra-true-color',\n name: 'MODIS Terra True Color',\n provider: 'nasa-gibs',\n category: 'Imagery',\n description: 'NASA MODIS Terra corrected reflectance true color.',\n attribution: 'Imagery provided by NASA Global Imagery Browse Services',\n tiles: [\n 'https://map1.vis.earthdata.nasa.gov/wmts-webmerc/MODIS_Terra_CorrectedReflectance_TrueColor/default//GoogleMapsCompatible_Level9/{z}/{y}/{x}.jpg',\n ],\n maxzoom: 9,\n tags: ['nasa', 'gibs', 'modis', 'true color'],\n }),\n rasterBasemap({\n id: 'nasa-gibs-viirs-earth-at-night',\n name: 'VIIRS Earth At Night 2012',\n provider: 'nasa-gibs',\n category: 'Imagery',\n description: 'NASA VIIRS city lights imagery.',\n attribution: 'Imagery provided by NASA Global Imagery Browse Services',\n tiles: [\n 'https://map1.vis.earthdata.nasa.gov/wmts-webmerc/VIIRS_CityLights_2012/default//GoogleMapsCompatible_Level8/{z}/{y}/{x}.jpg',\n ],\n maxzoom: 8,\n tags: ['nasa', 'gibs', 'night', 'viirs'],\n }),\n rasterBasemap({\n id: 'openrailwaymap',\n name: 'OpenRailwayMap',\n provider: 'openrailwaymap',\n category: 'Transport',\n description: 'Railway infrastructure map.',\n attribution: 'Map data: &copy; OpenStreetMap contributors | Map style: OpenRailwayMap',\n tiles: ['https://a.tiles.openrailwaymap.org/standard/{z}/{x}/{y}.png'],\n tags: ['rail', 'transport', 'osm'],\n }),\n rasterBasemap({\n id: 'opentopomap',\n name: 'OpenTopoMap',\n provider: 'opentopomap',\n category: 'Terrain',\n description: 'Topographic map with relief and contour styling.',\n attribution: 'Map data &copy; OpenStreetMap contributors, SRTM | Map style &copy; OpenTopoMap',\n tiles: ['https://a.tile.opentopomap.org/{z}/{x}/{y}.png'],\n maxzoom: 17,\n tags: ['terrain', 'topo', 'relief'],\n }),\n rasterBasemap({\n id: 'swisstopo-national-map-color',\n name: 'Swiss National Map Color',\n provider: 'swisstopo',\n category: 'Regional',\n description: 'Swiss federal color national map.',\n attribution: '&copy; swisstopo',\n tiles: [\n 'https://wmts.geo.admin.ch/1.0.0/ch.swisstopo.pixelkarte-farbe/default/current/3857/{z}/{x}/{y}.jpeg',\n ],\n maxzoom: 18,\n tags: ['switzerland', 'regional'],\n }),\n rasterBasemap({\n id: 'swisstopo-national-map-grey',\n name: 'Swiss National Map Grey',\n provider: 'swisstopo',\n category: 'Regional',\n description: 'Swiss federal grey national map.',\n attribution: '&copy; swisstopo',\n tiles: [\n 'https://wmts.geo.admin.ch/1.0.0/ch.swisstopo.pixelkarte-grau/default/current/3857/{z}/{x}/{y}.jpeg',\n ],\n maxzoom: 18,\n tags: ['switzerland', 'regional', 'grey'],\n }),\n rasterBasemap({\n id: 'swisstopo-swissimage',\n name: 'SWISSIMAGE',\n provider: 'swisstopo',\n category: 'Imagery',\n description: 'Swiss federal aerial imagery.',\n attribution: '&copy; swisstopo',\n tiles: [\n 'https://wmts.geo.admin.ch/1.0.0/ch.swisstopo.swissimage/default/current/3857/{z}/{x}/{y}.jpeg',\n ],\n maxzoom: 18,\n tags: ['switzerland', 'imagery'],\n }),\n rasterBasemap({\n id: 'topplusopen-color',\n name: 'TopPlusOpen Color',\n provider: 'topplusopen',\n category: 'Regional',\n description: 'German TopPlusOpen color basemap.',\n attribution: 'Map data: &copy; dl-de/by-2-0',\n tiles: [\n 'https://sgx.geodatenzentrum.de/wmts_topplus_open/tile/1.0.0/web/default/WEBMERCATOR/{z}/{y}/{x}.png',\n ],\n maxzoom: 18,\n tags: ['germany', 'regional'],\n }),\n rasterBasemap({\n id: 'topplusopen-grey',\n name: 'TopPlusOpen Grey',\n provider: 'topplusopen',\n category: 'Regional',\n description: 'German TopPlusOpen grey basemap.',\n attribution: 'Map data: &copy; dl-de/by-2-0',\n tiles: [\n 'https://sgx.geodatenzentrum.de/wmts_topplus_open/tile/1.0.0/web_grau/default/WEBMERCATOR/{z}/{y}/{x}.png',\n ],\n maxzoom: 18,\n tags: ['germany', 'regional', 'grey'],\n }),\n rasterBasemap({\n id: 'usgs-us-imagery',\n name: 'USGS US Imagery',\n provider: 'usgs',\n category: 'Imagery',\n description: 'USGS imagery-only basemap.',\n attribution: 'Tiles courtesy of the U.S. Geological Survey',\n tiles: [\n 'https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryOnly/MapServer/tile/{z}/{y}/{x}',\n ],\n tags: ['usgs', 'imagery', 'united states'],\n }),\n rasterBasemap({\n id: 'usgs-us-imagery-topo',\n name: 'USGS US Imagery Topo',\n provider: 'usgs',\n category: 'Imagery',\n description: 'USGS imagery with topographic reference.',\n attribution: 'Tiles courtesy of the U.S. Geological Survey',\n tiles: [\n 'https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryTopo/MapServer/tile/{z}/{y}/{x}',\n ],\n tags: ['usgs', 'imagery', 'topo', 'united states'],\n }),\n rasterBasemap({\n id: 'usgs-us-topo',\n name: 'USGS US Topo',\n provider: 'usgs',\n category: 'Terrain',\n description: 'USGS topographic basemap.',\n attribution: 'Tiles courtesy of the U.S. Geological Survey',\n tiles: [\n 'https://basemap.nationalmap.gov/arcgis/rest/services/USGSTopo/MapServer/tile/{z}/{y}/{x}',\n ],\n tags: ['usgs', 'topo', 'united states'],\n }),\n rasterBasemap({\n id: 'waymarkedtrails-hiking',\n name: 'Waymarked Trails Hiking',\n provider: 'waymarkedtrails',\n category: 'Outdoor',\n description: 'Hiking routes from Waymarked Trails.',\n attribution: 'Map data: &copy; OpenStreetMap contributors | Map style: Waymarked Trails',\n tiles: ['https://tile.waymarkedtrails.org/hiking/{z}/{x}/{y}.png'],\n tags: ['hiking', 'outdoor', 'trails'],\n }),\n rasterBasemap({\n id: 'waymarkedtrails-cycling',\n name: 'Waymarked Trails Cycling',\n provider: 'waymarkedtrails',\n category: 'Cycling',\n description: 'Cycling routes from Waymarked Trails.',\n attribution: 'Map data: &copy; OpenStreetMap contributors | Map style: Waymarked Trails',\n tiles: ['https://tile.waymarkedtrails.org/cycling/{z}/{x}/{y}.png'],\n tags: ['cycling', 'outdoor', 'trails'],\n }),\n rasterBasemap({\n id: 'waymarkedtrails-mtb',\n name: 'Waymarked Trails MTB',\n provider: 'waymarkedtrails',\n category: 'Cycling',\n description: 'Mountain biking routes from Waymarked Trails.',\n attribution: 'Map data: &copy; OpenStreetMap contributors | Map style: Waymarked Trails',\n tiles: ['https://tile.waymarkedtrails.org/mtb/{z}/{x}/{y}.png'],\n tags: ['mtb', 'outdoor', 'trails'],\n }),\n rasterBasemap({\n id: 'waymarkedtrails-slopes',\n name: 'Waymarked Trails Slopes',\n provider: 'waymarkedtrails',\n category: 'Outdoor',\n description: 'Slope routes from Waymarked Trails.',\n attribution: 'Map data: &copy; OpenStreetMap contributors | Map style: Waymarked Trails',\n tiles: ['https://tile.waymarkedtrails.org/slopes/{z}/{x}/{y}.png'],\n tags: ['slopes', 'outdoor', 'trails'],\n }),\n rasterBasemap({\n id: 'nlmaps-standaard',\n name: 'nlmaps Standaard',\n provider: 'nlmaps',\n category: 'Regional',\n description: 'Netherlands standard background map.',\n attribution: 'Kaartgegevens &copy; Kadaster',\n tiles: [\n 'https://service.pdok.nl/brt/achtergrondkaart/wmts/v2_0/standaard/EPSG:3857/{z}/{x}/{y}.png',\n ],\n tags: ['netherlands', 'regional'],\n }),\n rasterBasemap({\n id: 'nlmaps-grijs',\n name: 'nlmaps Grijs',\n provider: 'nlmaps',\n category: 'Regional',\n description: 'Netherlands grey background map.',\n attribution: 'Kaartgegevens &copy; Kadaster',\n tiles: [\n 'https://service.pdok.nl/brt/achtergrondkaart/wmts/v2_0/grijs/EPSG:3857/{z}/{x}/{y}.png',\n ],\n tags: ['netherlands', 'regional', 'grey'],\n }),\n rasterBasemap({\n id: 'nlmaps-pastel',\n name: 'nlmaps Pastel',\n provider: 'nlmaps',\n category: 'Regional',\n description: 'Netherlands pastel background map.',\n attribution: 'Kaartgegevens &copy; Kadaster',\n tiles: [\n 'https://service.pdok.nl/brt/achtergrondkaart/wmts/v2_0/pastel/EPSG:3857/{z}/{x}/{y}.png',\n ],\n tags: ['netherlands', 'regional', 'pastel'],\n }),\n rasterBasemap({\n id: 'nlmaps-water',\n name: 'nlmaps Water',\n provider: 'nlmaps',\n category: 'Regional',\n description: 'Netherlands water-focused background map.',\n attribution: 'Kaartgegevens &copy; Kadaster',\n tiles: [\n 'https://service.pdok.nl/brt/achtergrondkaart/wmts/v2_0/water/EPSG:3857/{z}/{x}/{y}.png',\n ],\n tags: ['netherlands', 'regional', 'water'],\n }),\n rasterBasemap({\n id: 'nlmaps-luchtfoto',\n name: 'nlmaps Luchtfoto',\n provider: 'nlmaps',\n category: 'Imagery',\n description: 'Netherlands aerial photography.',\n attribution: 'Kaartgegevens &copy; Kadaster',\n tiles: [\n 'https://service.pdok.nl/hwh/luchtfotorgb/wmts/v1_0/Actueel_ortho25/EPSG:3857/{z}/{x}/{y}.jpeg',\n ],\n tags: ['netherlands', 'imagery', 'aerial'],\n }),\n {\n id: 'openfreemap-positron',\n name: 'OpenFreeMap Positron',\n provider: 'openfreemap',\n type: 'style',\n category: 'Light',\n description: 'Light, minimal OpenFreeMap vector style for data overlays.',\n attribution: OPENFREEMAP_ATTRIBUTION,\n source: {\n type: 'style',\n url: 'https://tiles.openfreemap.org/styles/positron',\n },\n tags: ['openfreemap', 'vector', 'style', 'positron', 'light'],\n },\n {\n id: 'openfreemap-bright',\n name: 'OpenFreeMap Bright',\n provider: 'openfreemap',\n type: 'style',\n category: 'Street',\n description: 'Colorful OpenFreeMap vector street style.',\n attribution: OPENFREEMAP_ATTRIBUTION,\n source: {\n type: 'style',\n url: 'https://tiles.openfreemap.org/styles/bright',\n },\n tags: ['openfreemap', 'vector', 'style', 'bright', 'street'],\n },\n {\n id: 'openfreemap-liberty',\n name: 'OpenFreeMap Liberty',\n provider: 'openfreemap',\n type: 'style',\n category: 'Vector',\n description: 'Open vector style loaded as a full MapLibre style.',\n attribution: OPENFREEMAP_ATTRIBUTION,\n source: {\n type: 'style',\n url: 'https://tiles.openfreemap.org/styles/liberty',\n },\n tags: ['openfreemap', 'vector', 'style'],\n },\n {\n id: 'openfreemap-dark',\n name: 'OpenFreeMap Dark',\n provider: 'openfreemap',\n type: 'style',\n category: 'Dark',\n description: 'Dark OpenFreeMap vector style.',\n attribution: OPENFREEMAP_ATTRIBUTION,\n source: {\n type: 'style',\n url: 'https://tiles.openfreemap.org/styles/dark',\n },\n tags: ['openfreemap', 'vector', 'style', 'dark'],\n },\n {\n id: 'openfreemap-fiord',\n name: 'OpenFreeMap Fiord',\n provider: 'openfreemap',\n type: 'style',\n category: 'Dark',\n description: 'Blue-toned dark OpenFreeMap vector style.',\n attribution: OPENFREEMAP_ATTRIBUTION,\n source: {\n type: 'style',\n url: 'https://tiles.openfreemap.org/styles/fiord',\n },\n tags: ['openfreemap', 'vector', 'style', 'fiord', 'dark'],\n },\n {\n id: 'openfreemap-3d',\n name: 'OpenFreeMap 3D',\n provider: 'openfreemap',\n type: 'style',\n category: '3D',\n description: 'OpenFreeMap Liberty style with a pitched 3D camera view.',\n attribution: OPENFREEMAP_ATTRIBUTION,\n source: {\n type: 'style',\n url: 'https://tiles.openfreemap.org/styles/liberty',\n },\n view: {\n center: [-0.114, 51.506],\n zoom: 14.2,\n bearing: 55.2,\n pitch: 60,\n },\n tags: ['openfreemap', 'vector', 'style', '3d', 'liberty'],\n },\n];\n\nexport function combineProviders(\n defaults: BasemapProvider[],\n custom: BasemapProvider[] = [],\n): BasemapProvider[] {\n const byId = new Map<string, BasemapProvider>();\n defaults.forEach((provider) => byId.set(provider.id, provider));\n custom.forEach((provider) => byId.set(provider.id, provider));\n return sortProviders([...byId.values()]);\n}\n\nexport function resolveBasemapProviders(\n basemaps: BasemapDefinition[],\n customProviders: BasemapProvider[] = [],\n includeDefaultProviders = true,\n): BasemapProvider[] {\n const byId = new Map<string, BasemapProvider>();\n if (includeDefaultProviders) {\n DEFAULT_BASEMAP_PROVIDERS.forEach((provider) => byId.set(provider.id, provider));\n }\n customProviders.forEach((provider) => byId.set(provider.id, provider));\n // Derive any provider referenced by the catalog but not yet listed so the\n // filter never omits a custom provider or shows defaults with no results.\n basemaps.forEach((basemap) => {\n if (basemap.provider && !byId.has(basemap.provider)) {\n byId.set(basemap.provider, { id: basemap.provider, name: basemap.provider });\n }\n });\n return sortProviders([...byId.values()]);\n}\n\nexport function createBasemapCatalog(\n customBasemaps: BasemapDefinition[] = [],\n includeDefaultBasemaps = true,\n): BasemapDefinition[] {\n const basemaps = includeDefaultBasemaps\n ? [...DEFAULT_BASEMAPS, ...customBasemaps]\n : [...customBasemaps];\n const byId = new Map<string, BasemapDefinition>();\n basemaps.forEach((basemap) => byId.set(basemap.id, basemap));\n return [...byId.values()];\n}\n\nexport interface BasemapFilter {\n query?: string;\n provider?: string;\n category?: string;\n}\n\nexport function filterBasemaps(\n basemaps: BasemapDefinition[],\n filter: BasemapFilter,\n): BasemapDefinition[] {\n const query = filter.query?.trim().toLowerCase() ?? '';\n\n return basemaps.filter((basemap) => {\n if (filter.provider && basemap.provider !== filter.provider) return false;\n if (filter.category && basemap.category !== filter.category) return false;\n if (!query) return true;\n\n const haystack = [\n basemap.name,\n basemap.provider,\n basemap.category,\n basemap.description,\n ...(basemap.tags ?? []),\n ]\n .filter(Boolean)\n .join(' ')\n .toLowerCase();\n\n return haystack.includes(query);\n });\n}\n\nexport function getBasemapCategories(basemaps: BasemapDefinition[]): string[] {\n return [...new Set(basemaps.map((basemap) => basemap.category).filter(Boolean) as string[])].sort();\n}\n","import type {\n IControl,\n LayerSpecification,\n Map as MapLibreMap,\n SourceSpecification,\n StyleSpecification,\n} from 'maplibre-gl';\nimport {\n createBasemapCatalog,\n filterBasemaps,\n getBasemapCategories,\n resolveBasemapProviders,\n} from './catalog';\nimport type {\n BasemapControlEvent,\n BasemapControlEventHandler,\n BasemapControlOptions,\n BasemapControlPosition,\n BasemapControlState,\n BasemapDefinition,\n BasemapProvider,\n ManagedRasterBasemap,\n} from './types';\n\nconst DEFAULT_OPTIONS: Required<\n Pick<\n BasemapControlOptions,\n | 'collapsed'\n | 'position'\n | 'title'\n | 'panelWidth'\n | 'className'\n | 'includeDefaultBasemaps'\n | 'allowMultiple'\n | 'showMultipleToggle'\n | 'resizable'\n >\n> = {\n collapsed: true,\n position: 'top-right',\n title: 'Basemaps',\n panelWidth: 340,\n className: '',\n includeDefaultBasemaps: true,\n allowMultiple: false,\n showMultipleToggle: true,\n resizable: true,\n};\n\nconst CONTROL_SOURCE_PREFIX = 'maplibre-basemap-control-source';\nconst CONTROL_LAYER_PREFIX = '';\nconst API_KEY_PLACEHOLDER = '{api-key}';\nconst MAPTILER_API_KEY_EXAMPLE = 'YOUR_MAPTILER_API_KEY';\nconst MAPTILER_API_KEY_QUERY = '?key';\nconst MAPTILER_API_KEY_EMPTY_QUERY = '?key=';\nconst AWS_REGION_PLACEHOLDER = '{aws-region}';\n\n// Where users can obtain the credentials each provider requires. Surfaced as a\n// \"Get a ...\" link beside a missing-credential error so the message points at a\n// concrete next step instead of dead-ending.\nconst PROVIDER_CREDENTIAL_HELP: Record<string, { url: string; label: string }> = {\n amazon: {\n url: 'https://docs.aws.amazon.com/location/latest/developerguide/using-apikeys.html',\n label: 'Get an Amazon API key',\n },\n maptiler: {\n url: 'https://cloud.maptiler.com/account/keys/',\n label: 'Get a MapTiler API key',\n },\n mapbox: {\n url: 'https://docs.mapbox.com/help/getting-started/access-tokens/',\n label: 'Get a Mapbox access token',\n },\n};\n\nconst MIN_PANEL_WIDTH = 240;\nconst MIN_PANEL_HEIGHT = 200;\nconst PANEL_VIEWPORT_MARGIN = 12;\n\n// Thrown when a style basemap cannot be applied because the provider's\n// credentials are missing. Carries the provider id so the panel can show the\n// matching \"Get a ...\" link and reveal the provider settings input.\nclass MissingCredentialError extends Error {\n readonly provider: string;\n\n constructor(message: string, provider: string) {\n super(message);\n this.name = 'MissingCredentialError';\n this.provider = provider;\n }\n}\n\ninterface ResizeAnchor {\n x: number;\n y: number;\n isLeft: boolean;\n isTop: boolean;\n}\n\ntype EventHandlersMap = globalThis.Map<BasemapControlEvent, Set<BasemapControlEventHandler>>;\ntype SetStyleOptions = NonNullable<Parameters<MapLibreMap['setStyle']>[1]>;\n\nexport class BasemapControl implements IControl {\n private _map?: MapLibreMap;\n private _mapContainer?: HTMLElement;\n private _container?: HTMLElement;\n private _panel?: HTMLElement;\n private _content?: HTMLElement;\n private _options: Required<\n Pick<\n BasemapControlOptions,\n | 'collapsed'\n | 'position'\n | 'title'\n | 'panelWidth'\n | 'className'\n | 'includeDefaultBasemaps'\n | 'allowMultiple'\n | 'showMultipleToggle'\n | 'resizable'\n >\n > &\n Omit<\n BasemapControlOptions,\n | 'collapsed'\n | 'position'\n | 'title'\n | 'panelWidth'\n | 'className'\n | 'includeDefaultBasemaps'\n | 'allowMultiple'\n | 'showMultipleToggle'\n | 'resizable'\n >;\n private _state: BasemapControlState;\n private _basemaps: BasemapDefinition[];\n private _providers: BasemapProvider[];\n private _eventHandlers: EventHandlersMap = new globalThis.Map();\n // Active managed raster basemaps keyed by basemap id, in insertion order. In\n // single mode this holds at most one entry; in multiple mode it tracks every\n // stacked raster overlay so each can be added or removed independently.\n private _managedRasters: globalThis.Map<string, ManagedRasterBasemap> = new globalThis.Map();\n private _mapTilerApiKey = '';\n private _amazonApiKey = '';\n private _awsRegion = '';\n private _mapboxAccessToken = '';\n private _providerSettingsCollapsed = true;\n // Provider of the most recent missing-credential error, used to pick the\n // matching help link. Kept in sync with `_state.error` (both are set together\n // in `_applyBasemapChange`'s catch) so it is never stale when consulted.\n private _missingCredentialProvider?: keyof typeof PROVIDER_CREDENTIAL_HELP;\n private _resizeHandler: (() => void) | null = null;\n private _mapResizeHandler: (() => void) | null = null;\n private _resizeAnchor: ResizeAnchor | null = null;\n private _resizeHandleEl: HTMLElement | null = null;\n\n constructor(options?: BasemapControlOptions) {\n this._options = { ...DEFAULT_OPTIONS, ...options };\n this._mapTilerApiKey = options?.mapTilerApiKey ?? '';\n this._amazonApiKey = options?.amazonApiKey ?? '';\n this._awsRegion = options?.awsRegion ?? 'us-east-1';\n this._mapboxAccessToken = options?.mapboxAccessToken ?? '';\n this._basemaps = createBasemapCatalog(\n options?.basemaps,\n this._options.includeDefaultBasemaps,\n );\n this._providers = resolveBasemapProviders(\n this._basemaps,\n options?.providers,\n this._options.includeDefaultBasemaps,\n );\n this._state = {\n collapsed: this._options.collapsed,\n panelWidth: this._options.panelWidth,\n activeBasemapId: this._options.defaultBasemapId,\n activeBasemapIds: this._options.defaultBasemapId ? [this._options.defaultBasemapId] : [],\n allowMultiple: this._options.allowMultiple,\n query: '',\n providerFilter: '',\n categoryFilter: '',\n beforeId: '',\n loading: false,\n };\n }\n\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._mapContainer = map.getContainer();\n this._container = this._createContainer();\n this._panel = this._createPanel();\n this._mapContainer.appendChild(this._panel);\n this._setupEventListeners();\n\n if (!this._state.collapsed) {\n this._panel.classList.add('expanded');\n requestAnimationFrame(() => this._updatePanelPosition());\n }\n\n this._renderContent();\n\n if (this._state.activeBasemapId) {\n // Apply the configured default basemap. This always sets it (rather than\n // routing through the panel's toggle handler) so multiple mode does not\n // immediately toggle the pre-seeded default basemap back off.\n this.setBasemap(this._state.activeBasemapId).catch(() => {});\n }\n\n return this._container;\n }\n\n onRemove(): void {\n if (this._resizeHandler) {\n window.removeEventListener('resize', this._resizeHandler);\n this._resizeHandler = null;\n }\n if (this._mapResizeHandler && this._map) {\n this._map.off('resize', this._mapResizeHandler);\n this._mapResizeHandler = null;\n }\n window.removeEventListener('pointermove', this._onResizeMove);\n window.removeEventListener('pointerup', this._onResizeEnd);\n window.removeEventListener('pointercancel', this._onResizeEnd);\n this._resizeAnchor = null;\n this._resizeHandleEl = null;\n this._panel?.parentNode?.removeChild(this._panel);\n this._container?.parentNode?.removeChild(this._container);\n\n this._map = undefined;\n this._mapContainer = undefined;\n this._container = undefined;\n this._panel = undefined;\n this._content = undefined;\n this._eventHandlers.clear();\n }\n\n getState(): BasemapControlState {\n return { ...this._state };\n }\n\n setState(newState: Partial<BasemapControlState>): void {\n this._state = { ...this._state, ...newState };\n this._syncActiveBasemapState(newState);\n this._renderContent();\n this._emit({ type: 'statechange', state: this.getState() });\n }\n\n // Keeps `activeBasemapId` and `activeBasemapIds` consistent when a caller\n // updates only one of them through setState (the React wrapper and external\n // consumers commonly set just `activeBasemapId`).\n private _syncActiveBasemapState(applied: Partial<BasemapControlState>): void {\n const hasId = 'activeBasemapId' in applied;\n const hasIds = 'activeBasemapIds' in applied;\n if (hasId && !hasIds) {\n const id = this._state.activeBasemapId;\n this._state = { ...this._state, activeBasemapIds: id ? [id] : [] };\n } else if (hasIds && !hasId) {\n const ids = this._state.activeBasemapIds;\n this._state = { ...this._state, activeBasemapId: ids[ids.length - 1] };\n }\n }\n\n getBasemaps(): BasemapDefinition[] {\n return [...this._basemaps];\n }\n\n setBasemaps(basemaps: BasemapDefinition[]): void {\n this._basemaps = [...basemaps];\n this._providers = resolveBasemapProviders(\n this._basemaps,\n this._options.providers,\n this._options.includeDefaultBasemaps,\n );\n const activeBasemapIds = this._state.activeBasemapIds.filter((id) =>\n this._basemaps.some((basemap) => basemap.id === id),\n );\n this._state = {\n ...this._state,\n activeBasemapIds,\n activeBasemapId:\n this._state.activeBasemapId && activeBasemapIds.includes(this._state.activeBasemapId)\n ? this._state.activeBasemapId\n : activeBasemapIds[activeBasemapIds.length - 1],\n };\n this._renderContent();\n this._emit({ type: 'statechange', state: this.getState() });\n }\n\n setMapTilerApiKey(apiKey: string): void {\n this._mapTilerApiKey = apiKey;\n this._state = { ...this._state, error: undefined };\n this._renderContent();\n this._emit({ type: 'statechange', state: this.getState() });\n }\n\n setAmazonCredentials(apiKey: string, awsRegion = this._awsRegion): void {\n this._amazonApiKey = apiKey;\n this._awsRegion = awsRegion;\n this._state = { ...this._state, error: undefined };\n this._renderContent();\n this._emit({ type: 'statechange', state: this.getState() });\n }\n\n setMapboxAccessToken(accessToken: string): void {\n this._mapboxAccessToken = accessToken;\n this._state = { ...this._state, error: undefined };\n this._renderContent();\n this._emit({ type: 'statechange', state: this.getState() });\n }\n\n getActiveBasemap(): BasemapDefinition | undefined {\n return this._basemaps.find((basemap) => basemap.id === this._state.activeBasemapId);\n }\n\n getActiveBasemaps(): BasemapDefinition[] {\n return this._state.activeBasemapIds\n .map((id) => this._basemaps.find((basemap) => basemap.id === id))\n .filter((basemap): basemap is BasemapDefinition => Boolean(basemap));\n }\n\n isBasemapActive(id: string): boolean {\n return this._state.activeBasemapIds.includes(id);\n }\n\n // Apply a basemap, replacing any previously active basemaps.\n async setBasemap(id: string): Promise<void> {\n return this._applyBasemapChange(id, 'replace');\n }\n\n // Add a raster basemap as an additional overlay without removing the active\n // ones. Style basemaps cannot stack, so they always replace the map style.\n async addBasemap(id: string): Promise<void> {\n return this._applyBasemapChange(id, 'add');\n }\n\n // Remove a previously added managed raster basemap from the map.\n async removeBasemap(id: string): Promise<void> {\n const basemap = this._basemaps.find((candidate) => candidate.id === id);\n if (!basemap) {\n const error = new Error(`Basemap \"${id}\" was not found.`);\n this._handleError(error);\n throw error;\n }\n if (!this._map) {\n const error = new Error('BasemapControl must be added to a map before removing a basemap.');\n this._handleError(error, basemap);\n throw error;\n }\n\n const managedRaster = this._removeManagedRaster(id);\n const activeBasemapIds = this._state.activeBasemapIds.filter((value) => value !== id);\n this._state = {\n ...this._state,\n activeBasemapIds,\n activeBasemapId: activeBasemapIds[activeBasemapIds.length - 1],\n error: undefined,\n };\n this._renderContent(true);\n this._emit({ type: 'basemapremove', state: this.getState(), basemap, managedRaster });\n this._emit({ type: 'statechange', state: this.getState() });\n }\n\n // Add the basemap if it is not active, otherwise remove it.\n async toggleBasemap(id: string): Promise<void> {\n if (this.isBasemapActive(id)) {\n return this.removeBasemap(id);\n }\n return this.addBasemap(id);\n }\n\n private async _applyBasemapChange(id: string, mode: 'replace' | 'add'): Promise<void> {\n const basemap = this._basemaps.find((candidate) => candidate.id === id);\n if (!basemap) {\n const error = new Error(`Basemap \"${id}\" was not found.`);\n this._handleError(error);\n throw error;\n }\n if (!this._map) {\n const error = new Error('BasemapControl must be added to a map before setting a basemap.');\n this._handleError(error, basemap);\n throw error;\n }\n\n const isRaster = basemap.source.type === 'raster';\n // Style basemaps replace the entire map style and cannot be stacked.\n const effectiveMode: 'replace' | 'add' = isRaster ? mode : 'replace';\n\n // A style basemap swaps the whole map style, discarding every stacked\n // raster overlay. In stack mode that is a destructive, easy-to-trigger\n // surprise, so give the host a chance to confirm before the rasters are\n // lost. Skipped in single mode, where replacing the one active basemap is\n // expected, and when no host confirm hook is provided.\n if (\n !isRaster &&\n this._state.allowMultiple &&\n this._managedRasters.size > 0 &&\n this._options.confirmStyleReplace\n ) {\n const replacedBasemapIds = [...this._managedRasters.keys()];\n let confirmed = false;\n try {\n confirmed = await this._options.confirmStyleReplace({ basemap, replacedBasemapIds });\n } catch {\n confirmed = false;\n }\n if (!confirmed) return;\n }\n\n this._state = { ...this._state, loading: true, error: undefined };\n this._renderContent(true);\n this._emit({ type: 'statechange', state: this.getState() });\n\n try {\n let managedRaster: ManagedRasterBasemap | undefined;\n if (isRaster) {\n await this._waitForStyleReady();\n if (effectiveMode === 'replace') {\n this._removeManagedBasemap();\n } else {\n // Re-selecting an already-managed raster re-adds it on top using the\n // current before_id, so drop the previous instance first.\n this._removeManagedRaster(basemap.id);\n }\n managedRaster = this._addRasterBasemap(basemap);\n } else {\n const styleUrl = this._resolveStyleUrl(basemap);\n const styleOptions = this._getStyleOptions(basemap);\n // A full style swap discards every managed raster overlay, so forget\n // the ones we were tracking.\n this._removeManagedBasemap();\n if (styleOptions) {\n this._map.setStyle(styleUrl, styleOptions);\n } else {\n this._map.setStyle(styleUrl);\n }\n }\n\n this._applyBasemapView(basemap);\n\n const activeBasemapIds =\n effectiveMode === 'add'\n ? [...this._state.activeBasemapIds.filter((value) => value !== basemap.id), basemap.id]\n : [basemap.id];\n\n this._state = {\n ...this._state,\n activeBasemapId: basemap.id,\n activeBasemapIds,\n loading: false,\n error: undefined,\n };\n this._renderContent(true);\n this._emit({\n type: 'basemapchange',\n state: this.getState(),\n basemap,\n managedRaster,\n mode: effectiveMode,\n });\n this._emit({ type: 'statechange', state: this.getState() });\n } catch (cause) {\n const error = cause instanceof Error ? cause : new Error(String(cause));\n this._state = { ...this._state, loading: false, error: error.message };\n this._missingCredentialProvider =\n cause instanceof MissingCredentialError\n ? (cause.provider as keyof typeof PROVIDER_CREDENTIAL_HELP)\n : undefined;\n // Reveal the credential inputs so a missing-credential error has an\n // obvious next step instead of dead-ending in a collapsed section.\n if (cause instanceof MissingCredentialError) {\n this._providerSettingsCollapsed = false;\n }\n this._renderContent(true);\n this._handleError(error, basemap);\n throw error;\n }\n }\n\n // The public mutators rethrow after emitting the error event so callers that\n // await them can react. The panel's click handler uses this instead to avoid\n // unhandled promise rejections; the failure is still reported via `error`.\n // In multiple mode a raster basemap click toggles the overlay on or off.\n private _selectBasemap(id: string): void {\n const basemap = this._basemaps.find((candidate) => candidate.id === id);\n const isRaster = basemap?.source.type === 'raster';\n if (this._state.allowMultiple && isRaster) {\n this.toggleBasemap(id).catch(() => {});\n return;\n }\n this.setBasemap(id).catch(() => {});\n }\n\n toggle(): void {\n this._state = { ...this._state, collapsed: !this._state.collapsed };\n\n if (this._panel) {\n if (this._state.collapsed) {\n this._panel.classList.remove('expanded');\n this._emit({ type: 'collapse', state: this.getState() });\n } else {\n this._panel.classList.add('expanded');\n this._updatePanelPosition();\n this._emit({ type: 'expand', state: this.getState() });\n }\n }\n\n this._emit({ type: 'statechange', state: this.getState() });\n }\n\n expand(): void {\n if (this._state.collapsed) this.toggle();\n }\n\n collapse(): void {\n if (!this._state.collapsed) this.toggle();\n }\n\n on(event: BasemapControlEvent, handler: BasemapControlEventHandler): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n off(event: BasemapControlEvent, handler: BasemapControlEventHandler): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n getMap(): MapLibreMap | undefined {\n return this._map;\n }\n\n getContainer(): HTMLElement | undefined {\n return this._container;\n }\n\n private _emit(event: Parameters<BasemapControlEventHandler>[0]): void {\n this._eventHandlers.get(event.type)?.forEach((handler) => handler(event));\n }\n\n private _handleError(error: Error, basemap?: BasemapDefinition): void {\n this._emit({ type: 'error', state: this.getState(), error, basemap });\n this._emit({ type: 'statechange', state: this.getState() });\n }\n\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibregl-ctrl-group basemap-control${\n this._options.className ? ` ${this._options.className}` : ''\n }`;\n\n const toggleBtn = document.createElement('button');\n toggleBtn.className = 'basemap-control-toggle';\n toggleBtn.type = 'button';\n toggleBtn.title = this._options.title;\n toggleBtn.setAttribute('aria-label', this._options.title);\n toggleBtn.innerHTML = `\n <span class=\"basemap-control-icon\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\" width=\"22\" height=\"22\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"m3 6 6-3 6 3 6-3v15l-6 3-6-3-6 3V6Z\"/>\n <path d=\"M9 3v15\"/>\n <path d=\"M15 6v15\"/>\n </svg>\n </span>\n `;\n toggleBtn.addEventListener('click', () => this.toggle());\n container.appendChild(toggleBtn);\n\n return container;\n }\n\n private _createPanel(): HTMLElement {\n const panel = document.createElement('div');\n panel.className = 'basemap-control-panel';\n panel.style.width = `${this._state.panelWidth}px`;\n if (this._state.panelHeight !== undefined) {\n panel.style.height = `${this._state.panelHeight}px`;\n panel.classList.add('is-resized');\n }\n\n const header = document.createElement('div');\n header.className = 'basemap-control-header';\n\n const title = document.createElement('span');\n title.className = 'basemap-control-title';\n title.textContent = this._options.title;\n\n const closeBtn = document.createElement('button');\n closeBtn.className = 'basemap-control-close';\n closeBtn.type = 'button';\n closeBtn.setAttribute('aria-label', 'Close basemap panel');\n closeBtn.innerHTML = '&times;';\n closeBtn.addEventListener('click', () => this.collapse());\n\n header.appendChild(title);\n header.appendChild(closeBtn);\n\n this._content = document.createElement('div');\n this._content.className = 'basemap-control-content';\n\n panel.appendChild(header);\n panel.appendChild(this._content);\n\n if (this._options.resizable) {\n panel.appendChild(this._createResizeHandle('bottom-left'));\n panel.appendChild(this._createResizeHandle('bottom-right'));\n }\n\n return panel;\n }\n\n private _createResizeHandle(corner: 'bottom-left' | 'bottom-right'): HTMLElement {\n const handle = document.createElement('div');\n handle.className = `basemap-control-resize-handle basemap-control-resize-${corner}`;\n handle.setAttribute('aria-hidden', 'true');\n handle.addEventListener('pointerdown', (event) => this._startResize(event));\n return handle;\n }\n\n private _renderContent(preserveResultsScroll = false): void {\n if (!this._content) return;\n\n const categories = getBasemapCategories(this._basemaps);\n const results = this._getFilteredBasemaps();\n const previousResultsScrollTop = preserveResultsScroll\n ? this._content.querySelector('.basemap-control-results')?.scrollTop\n : undefined;\n\n this._content.replaceChildren(\n this._createSearchRow(),\n ...(this._options.showMultipleToggle ? [this._createMultipleToggleRow()] : []),\n ...(this._hasProviderSettings() ? [this._createProviderSettingsSection()] : []),\n this._createFilterRow(this._providers, categories),\n this._createStatus(results.length),\n this._createResults(results),\n );\n\n if (previousResultsScrollTop !== undefined) {\n const resultsElement = this._content.querySelector('.basemap-control-results');\n if (resultsElement) resultsElement.scrollTop = previousResultsScrollTop;\n }\n }\n\n private _renderFilteredResults(): void {\n if (!this._content) return;\n\n const results = this._getFilteredBasemaps();\n this._content.querySelector('.basemap-control-status')?.replaceWith(\n this._createStatus(results.length),\n );\n this._content.querySelector('.basemap-control-results')?.replaceWith(\n this._createResults(results),\n );\n }\n\n private _getFilteredBasemaps(): BasemapDefinition[] {\n return filterBasemaps(this._basemaps, {\n query: this._state.query,\n provider: this._state.providerFilter,\n category: this._state.categoryFilter,\n });\n }\n\n private _createSearchRow(): HTMLElement {\n const row = document.createElement('div');\n row.className = 'basemap-control-search-row';\n row.appendChild(this._createSearchInput());\n row.appendChild(this._createBeforeIdInput());\n return row;\n }\n\n private _createMultipleToggleRow(): HTMLElement {\n const label = document.createElement('label');\n label.className = 'basemap-control-multiple-toggle';\n\n const checkbox = document.createElement('input');\n checkbox.type = 'checkbox';\n checkbox.className = 'basemap-control-multiple-checkbox';\n checkbox.checked = this._state.allowMultiple;\n checkbox.setAttribute('aria-label', 'Add basemaps instead of replacing');\n checkbox.addEventListener('change', () => {\n this._state = { ...this._state, allowMultiple: checkbox.checked };\n this._emit({ type: 'statechange', state: this.getState() });\n });\n\n const text = document.createElement('span');\n text.className = 'basemap-control-multiple-toggle-text';\n text.textContent = 'Add basemaps (stack instead of replace)';\n\n label.appendChild(checkbox);\n label.appendChild(text);\n return label;\n }\n\n private _createSearchInput(): HTMLElement {\n const wrapper = document.createElement('div');\n wrapper.className = 'basemap-control-search';\n\n const input = document.createElement('input');\n input.className = 'basemap-control-input';\n input.type = 'search';\n input.placeholder = 'Search basemaps';\n input.value = this._state.query;\n input.setAttribute('aria-label', 'Search basemaps');\n input.addEventListener('input', () => {\n this._state = { ...this._state, query: input.value };\n this._renderFilteredResults();\n this._emit({ type: 'statechange', state: this.getState() });\n });\n\n wrapper.appendChild(input);\n return wrapper;\n }\n\n private _createBeforeIdInput(): HTMLElement {\n const wrapper = document.createElement('div');\n wrapper.className = 'basemap-control-before-id';\n\n const input = document.createElement('input');\n input.className = 'basemap-control-input';\n input.type = 'text';\n input.placeholder = 'before_id: none';\n input.value = this._state.beforeId;\n input.setAttribute('aria-label', 'before_id');\n input.addEventListener('input', () => {\n this._state = { ...this._state, beforeId: input.value };\n this._emit({ type: 'statechange', state: this.getState() });\n });\n\n wrapper.appendChild(input);\n return wrapper;\n }\n\n private _createProviderSettingsSection(): HTMLElement {\n const details = document.createElement('details');\n details.className = 'basemap-control-provider-settings';\n details.open = !this._providerSettingsCollapsed;\n details.addEventListener('toggle', () => {\n this._providerSettingsCollapsed = !details.open;\n });\n\n const summary = document.createElement('summary');\n summary.className = 'basemap-control-provider-settings-summary';\n summary.textContent = 'Provider settings';\n details.appendChild(summary);\n\n const fields = document.createElement('div');\n fields.className = 'basemap-control-provider-settings-fields';\n\n if (this._hasMapTilerBasemaps()) {\n fields.appendChild(\n this._createProviderSettingsInput({\n className: 'basemap-control-maptiler-key',\n type: 'password',\n placeholder: 'MapTiler API key',\n ariaLabel: 'MapTiler API key',\n value: this._mapTilerApiKey,\n onInput: (value) => {\n this._mapTilerApiKey = value;\n },\n }),\n );\n }\n\n if (this._hasMapboxBasemaps()) {\n fields.appendChild(\n this._createProviderSettingsInput({\n className: 'basemap-control-mapbox-token',\n type: 'password',\n placeholder: 'Mapbox access token',\n ariaLabel: 'Mapbox access token',\n value: this._mapboxAccessToken,\n onInput: (value) => {\n this._mapboxAccessToken = value;\n },\n }),\n );\n }\n\n if (this._hasAmazonBasemaps()) {\n fields.appendChild(\n this._createProviderSettingsInput({\n className: 'basemap-control-amazon-key',\n type: 'password',\n placeholder: 'Amazon API key',\n ariaLabel: 'Amazon API key',\n value: this._amazonApiKey,\n onInput: (value) => {\n this._amazonApiKey = value;\n },\n }),\n );\n fields.appendChild(\n this._createProviderSettingsInput({\n className: 'basemap-control-aws-region',\n type: 'text',\n placeholder: 'AWS region',\n ariaLabel: 'AWS region',\n value: this._awsRegion,\n onInput: (value) => {\n this._awsRegion = value;\n },\n }),\n );\n }\n\n details.appendChild(fields);\n return details;\n }\n\n private _createProviderSettingsInput({\n className,\n type,\n placeholder,\n ariaLabel,\n value,\n onInput,\n }: {\n className: string;\n type: string;\n placeholder: string;\n ariaLabel: string;\n value: string;\n onInput: (value: string) => void;\n }): HTMLElement {\n const wrapper = document.createElement('div');\n wrapper.className = className;\n\n const input = document.createElement('input');\n input.className = 'basemap-control-input';\n input.type = type;\n input.placeholder = placeholder;\n input.value = value;\n input.name = ariaLabel.toLowerCase().replace(/\\s+/g, '-');\n input.autocomplete = 'new-password';\n input.autocapitalize = 'none';\n input.spellcheck = false;\n input.setAttribute('autocorrect', 'off');\n input.setAttribute('aria-label', ariaLabel);\n input.addEventListener('input', () => {\n onInput(input.value);\n this._state = { ...this._state, error: undefined };\n this._renderFilteredResults();\n this._emit({ type: 'statechange', state: this.getState() });\n });\n\n wrapper.appendChild(input);\n return wrapper;\n }\n\n private _createFilterRow(providers: BasemapProvider[], categories: string[]): HTMLElement {\n const row = document.createElement('div');\n row.className = 'basemap-control-filters';\n row.appendChild(\n this._createSelect(\n 'Provider',\n this._state.providerFilter,\n providers.map((provider) => ({ value: provider.id, label: provider.name })),\n (value) => {\n this._state = { ...this._state, providerFilter: value };\n this._renderContent();\n this._emit({ type: 'statechange', state: this.getState() });\n },\n ),\n );\n row.appendChild(\n this._createSelect(\n 'Category',\n this._state.categoryFilter,\n categories.map((category) => ({ value: category, label: category })),\n (value) => {\n this._state = { ...this._state, categoryFilter: value };\n this._renderContent();\n this._emit({ type: 'statechange', state: this.getState() });\n },\n ),\n );\n return row;\n }\n\n private _createSelect(\n label: string,\n value: string,\n options: Array<{ value: string; label: string }>,\n onChange: (value: string) => void,\n ): HTMLElement {\n const select = document.createElement('select');\n select.className = 'basemap-control-select';\n select.setAttribute('aria-label', label);\n\n const all = document.createElement('option');\n all.value = '';\n all.textContent = `All ${label.toLowerCase()}s`;\n select.appendChild(all);\n\n options.forEach((option) => {\n const element = document.createElement('option');\n element.value = option.value;\n element.textContent = option.label;\n select.appendChild(element);\n });\n\n select.value = value;\n select.addEventListener('change', () => onChange(select.value));\n return select;\n }\n\n private _createStatus(resultCount: number): HTMLElement {\n const status = document.createElement('div');\n status.className = 'basemap-control-status';\n if (this._state.loading) {\n status.textContent = 'Applying basemap...';\n } else if (this._state.error) {\n status.classList.add('is-error');\n const message = document.createElement('span');\n message.className = 'basemap-control-status-message';\n message.textContent = this._state.error;\n status.appendChild(message);\n\n // A missing-credential error is otherwise a dead end: append a link to\n // where the credential is issued and point at the Provider settings\n // inputs (which the error also auto-expands).\n const help = this._credentialHelpForError(this._missingCredentialProvider);\n if (help) {\n const actions = document.createElement('span');\n actions.className = 'basemap-control-status-actions';\n\n const link = document.createElement('a');\n link.className = 'basemap-control-status-link';\n link.href = help.url;\n link.target = '_blank';\n link.rel = 'noopener noreferrer';\n link.textContent = help.label;\n actions.appendChild(link);\n\n const hint = document.createElement('span');\n hint.className = 'basemap-control-status-hint';\n hint.textContent = ', then add it under Provider settings below.';\n actions.appendChild(hint);\n\n status.appendChild(actions);\n }\n } else {\n status.textContent = `${resultCount} basemap${resultCount === 1 ? '' : 's'}`;\n }\n return status;\n }\n\n // Resolves the help link for a missing-credential provider, so the status can\n // offer a concrete next step. Returns undefined when there is no such error.\n private _credentialHelpForError(\n provider?: keyof typeof PROVIDER_CREDENTIAL_HELP,\n ): { url: string; label: string } | undefined {\n return provider ? PROVIDER_CREDENTIAL_HELP[provider] : undefined;\n }\n\n private _createResults(results: BasemapDefinition[]): HTMLElement {\n const list = document.createElement('div');\n list.className = 'basemap-control-results';\n\n if (results.length === 0) {\n const empty = document.createElement('div');\n empty.className = 'basemap-control-empty';\n empty.textContent = 'No basemaps match your search.';\n list.appendChild(empty);\n return list;\n }\n\n results.forEach((basemap) => {\n const row = document.createElement('button');\n row.type = 'button';\n row.className = 'basemap-control-result';\n row.dataset.basemapId = basemap.id;\n if (this._state.activeBasemapIds.includes(basemap.id)) {\n row.classList.add('is-active');\n row.setAttribute('aria-current', 'true');\n }\n row.disabled = this._state.loading;\n row.addEventListener('click', () => {\n this._selectBasemap(basemap.id);\n });\n\n const main = document.createElement('span');\n main.className = 'basemap-control-result-main';\n\n const name = document.createElement('span');\n name.className = 'basemap-control-result-name';\n name.textContent = basemap.name;\n\n const meta = document.createElement('span');\n meta.className = 'basemap-control-result-meta';\n meta.textContent = this._formatBasemapMeta(basemap);\n\n main.appendChild(name);\n main.appendChild(meta);\n\n const type = document.createElement('span');\n type.className = 'basemap-control-result-type';\n type.textContent = basemap.type === 'raster' ? 'Raster' : 'Style';\n\n row.appendChild(main);\n row.appendChild(type);\n\n if (basemap.attribution) {\n const attribution = document.createElement('span');\n attribution.className = 'basemap-control-result-attribution';\n attribution.textContent = this._stripHtml(basemap.attribution);\n row.appendChild(attribution);\n }\n\n list.appendChild(row);\n });\n\n return list;\n }\n\n private _formatBasemapMeta(basemap: BasemapDefinition): string {\n const provider = this._providers.find((candidate) => candidate.id === basemap.provider);\n return [provider?.name ?? basemap.provider, basemap.category].filter(Boolean).join(' / ');\n }\n\n private _stripHtml(value: string): string {\n const template = document.createElement('template');\n template.innerHTML = value;\n return template.content.textContent ?? value;\n }\n\n private _hasMapTilerBasemaps(): boolean {\n return this._basemaps.some((basemap) => basemap.provider === 'maptiler');\n }\n\n private _hasAmazonBasemaps(): boolean {\n return this._basemaps.some((basemap) => basemap.provider === 'amazon');\n }\n\n private _hasMapboxBasemaps(): boolean {\n return this._basemaps.some((basemap) => basemap.provider === 'mapbox');\n }\n\n private _hasProviderSettings(): boolean {\n return this._hasMapTilerBasemaps() || this._hasAmazonBasemaps() || this._hasMapboxBasemaps();\n }\n\n private _resolveStyleUrl(basemap: BasemapDefinition): string {\n if (basemap.source.type === 'raster') {\n throw new Error(`Basemap \"${basemap.id}\" is not a style basemap.`);\n }\n\n const url = basemap.source.url;\n if (basemap.provider === 'amazon') {\n return this._resolveAmazonStyleUrl(url);\n }\n\n if (basemap.provider === 'maptiler') {\n return this._resolveMapTilerStyleUrl(url);\n }\n\n if (basemap.provider === 'mapbox') {\n return this._resolveMapboxStyleUrl(url);\n }\n\n return url;\n }\n\n private _getStyleOptions(basemap: BasemapDefinition): SetStyleOptions | undefined {\n if (basemap.provider === 'mapbox') {\n return {\n validate: false,\n transformStyle: (_previousStyle, nextStyle) =>\n this._transformMapboxStyle(nextStyle, this._mapboxAccessToken.trim()),\n };\n }\n return undefined;\n }\n\n private _transformMapboxStyle(style: StyleSpecification, accessToken: string): StyleSpecification {\n const encodedAccessToken = encodeURIComponent(accessToken);\n const sources = Object.fromEntries(\n Object.entries(style.sources).map(([id, source]) => {\n if ('url' in source && typeof source.url === 'string') {\n return [id, { ...source, url: this._resolveMapboxInternalUrl(source.url, encodedAccessToken) }];\n }\n return [id, source];\n }),\n );\n\n return {\n ...style,\n glyphs:\n typeof style.glyphs === 'string'\n ? this._resolveMapboxInternalUrl(style.glyphs, encodedAccessToken)\n : style.glyphs,\n sprite: this._resolveMapboxSprite(style.sprite, encodedAccessToken),\n projection: { type: 'mercator' },\n sources,\n };\n }\n\n private _resolveMapboxSprite(\n sprite: StyleSpecification['sprite'],\n encodedAccessToken: string,\n ): StyleSpecification['sprite'] {\n if (typeof sprite === 'string') {\n return this._resolveMapboxInternalUrl(sprite, encodedAccessToken);\n }\n\n if (Array.isArray(sprite)) {\n return sprite.map((item) => ({\n ...item,\n url: this._resolveMapboxInternalUrl(item.url, encodedAccessToken),\n }));\n }\n\n return sprite;\n }\n\n private _resolveMapboxInternalUrl(url: string, encodedAccessToken: string): string {\n if (url.startsWith('mapbox://sprites/')) {\n const [, owner, styleId] = /^mapbox:\\/\\/sprites\\/([^/]+)\\/(.+)$/.exec(url) ?? [];\n if (owner && styleId) {\n return `https://api.mapbox.com/styles/v1/${owner}/${styleId}/sprite?access_token=${encodedAccessToken}`;\n }\n }\n\n if (url.startsWith('mapbox://fonts/')) {\n const [, owner, fontPath] = /^mapbox:\\/\\/fonts\\/([^/]+)\\/(.+)$/.exec(url) ?? [];\n if (owner && fontPath) {\n return `https://api.mapbox.com/fonts/v1/${owner}/${fontPath}?access_token=${encodedAccessToken}`;\n }\n }\n\n if (url.startsWith('mapbox://')) {\n const tileset = url.replace(/^mapbox:\\/\\//, '');\n return `https://api.mapbox.com/v4/${tileset}.json?secure&access_token=${encodedAccessToken}`;\n }\n\n return url;\n }\n\n private _resolveMapTilerStyleUrl(url: string): string {\n const needsMapTilerKey =\n url.includes(API_KEY_PLACEHOLDER) ||\n url.includes(MAPTILER_API_KEY_EXAMPLE) ||\n url.endsWith(MAPTILER_API_KEY_QUERY) ||\n url.endsWith(MAPTILER_API_KEY_EMPTY_QUERY);\n\n if (!needsMapTilerKey) return url;\n\n const apiKey = this._mapTilerApiKey.trim();\n if (!apiKey) {\n throw new MissingCredentialError(\n 'Enter a MapTiler API key before applying this basemap.',\n 'maptiler',\n );\n }\n\n const encodedApiKey = encodeURIComponent(apiKey);\n if (url.endsWith(MAPTILER_API_KEY_QUERY)) {\n return `${url}=${encodedApiKey}`;\n }\n if (url.endsWith(MAPTILER_API_KEY_EMPTY_QUERY)) {\n return `${url}${encodedApiKey}`;\n }\n\n return url\n .split(API_KEY_PLACEHOLDER)\n .join(encodedApiKey)\n .split(MAPTILER_API_KEY_EXAMPLE)\n .join(encodedApiKey);\n }\n\n private _resolveAmazonStyleUrl(url: string): string {\n const apiKey = this._amazonApiKey.trim();\n const awsRegion = this._awsRegion.trim();\n\n if (url.includes(API_KEY_PLACEHOLDER) && !apiKey) {\n throw new MissingCredentialError(\n 'Enter an Amazon API key before applying this basemap.',\n 'amazon',\n );\n }\n if (url.includes(AWS_REGION_PLACEHOLDER) && !awsRegion) {\n throw new MissingCredentialError(\n 'Enter an AWS region before applying this basemap.',\n 'amazon',\n );\n }\n\n return url\n .split(AWS_REGION_PLACEHOLDER)\n .join(awsRegion)\n .split(API_KEY_PLACEHOLDER)\n .join(encodeURIComponent(apiKey));\n }\n\n private _resolveMapboxStyleUrl(url: string): string {\n const accessToken = this._mapboxAccessToken.trim();\n\n if (url.includes(API_KEY_PLACEHOLDER) && !accessToken) {\n throw new MissingCredentialError(\n 'Enter a Mapbox access token before applying this basemap.',\n 'mapbox',\n );\n }\n if (this._isUrlLikeCredential(accessToken)) {\n throw new MissingCredentialError(\n 'Enter a valid Mapbox access token, not a URL.',\n 'mapbox',\n );\n }\n\n return url.split(API_KEY_PLACEHOLDER).join(encodeURIComponent(accessToken));\n }\n\n private _isUrlLikeCredential(value: string): boolean {\n return /^https?:\\/\\//i.test(value);\n }\n\n private _addRasterBasemap(basemap: BasemapDefinition): ManagedRasterBasemap | undefined {\n if (!this._map || basemap.source.type !== 'raster') return undefined;\n\n const sourceId = `${CONTROL_SOURCE_PREFIX}-${basemap.id}`;\n const layerId = [CONTROL_LAYER_PREFIX, basemap.id].filter(Boolean).join('-');\n const beforeId = this._getBasemapInsertBeforeId();\n const source: SourceSpecification = {\n type: 'raster',\n tiles: basemap.source.tiles,\n tileSize: basemap.source.tileSize ?? 256,\n minzoom: basemap.source.minzoom,\n maxzoom: basemap.source.maxzoom,\n scheme: basemap.source.scheme,\n attribution: basemap.attribution,\n };\n const layer: LayerSpecification = {\n id: layerId,\n type: 'raster',\n source: sourceId,\n };\n\n this._map.addSource(sourceId, source);\n this._map.addLayer(layer, beforeId);\n const managed: ManagedRasterBasemap = { sourceId, layerId, beforeId };\n this._managedRasters.set(basemap.id, managed);\n\n return managed;\n }\n\n private _waitForStyleReady(): Promise<void> {\n if (!this._map) return Promise.resolve();\n if (typeof this._map.isStyleLoaded !== 'function' || this._map.isStyleLoaded()) {\n return Promise.resolve();\n }\n\n return new Promise((resolve) => {\n let settled = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const done = () => {\n if (settled) return;\n settled = true;\n if (timer !== undefined) clearTimeout(timer);\n this._map?.off('load', done);\n this._map?.off('style.load', done);\n resolve();\n };\n // Fall back after a short wait so a missed `load`/`style.load` event\n // (e.g. when basemaps are switched faster than styles settle) can never\n // leave the control stuck in its loading state with a wait cursor.\n timer = setTimeout(done, 1500);\n this._map?.once('load', done);\n this._map?.once('style.load', done);\n });\n }\n\n // Remove every managed raster basemap from the map.\n private _removeManagedBasemap(): void {\n if (!this._map) return;\n for (const id of [...this._managedRasters.keys()]) {\n this._removeManagedRaster(id);\n }\n }\n\n // Remove a single managed raster basemap by its basemap id, returning the\n // managed source/layer record that was removed (if any).\n private _removeManagedRaster(id: string): ManagedRasterBasemap | undefined {\n const managed = this._managedRasters.get(id);\n if (!managed) return undefined;\n\n if (this._map?.getLayer(managed.layerId)) {\n this._map.removeLayer(managed.layerId);\n }\n if (this._map?.getSource(managed.sourceId)) {\n this._map.removeSource(managed.sourceId);\n }\n this._managedRasters.delete(id);\n return managed;\n }\n\n private _applyBasemapView(basemap: BasemapDefinition): void {\n if (!this._map || !basemap.view) return;\n\n this._map.jumpTo({\n center: basemap.view.center,\n zoom: basemap.view.zoom,\n bearing: basemap.view.bearing,\n pitch: basemap.view.pitch,\n });\n }\n\n private _getBasemapInsertBeforeId(): string | undefined {\n const beforeId = this._state.beforeId.trim();\n if (!beforeId || beforeId.toLowerCase() === 'none') return undefined;\n return beforeId;\n }\n\n private _setupEventListeners(): void {\n this._resizeHandler = () => {\n if (!this._state.collapsed) this._updatePanelPosition();\n };\n window.addEventListener('resize', this._resizeHandler);\n\n this._mapResizeHandler = () => {\n if (!this._state.collapsed) this._updatePanelPosition();\n };\n this._map?.on('resize', this._mapResizeHandler);\n }\n\n private _getControlPosition(): BasemapControlPosition {\n const parent = this._container?.parentElement;\n if (!parent) return this._options.position;\n\n if (parent.classList.contains('maplibregl-ctrl-top-left')) return 'top-left';\n if (parent.classList.contains('maplibregl-ctrl-top-right')) return 'top-right';\n if (parent.classList.contains('maplibregl-ctrl-bottom-left')) return 'bottom-left';\n if (parent.classList.contains('maplibregl-ctrl-bottom-right')) return 'bottom-right';\n\n return this._options.position;\n }\n\n private _updatePanelPosition(): void {\n if (!this._container || !this._panel || !this._mapContainer) return;\n\n const button = this._container.querySelector('.basemap-control-toggle');\n if (!button) return;\n\n const buttonRect = button.getBoundingClientRect();\n const mapRect = this._mapContainer.getBoundingClientRect();\n const position = this._getControlPosition();\n const buttonTop = buttonRect.top - mapRect.top;\n const buttonBottom = mapRect.bottom - buttonRect.bottom;\n const buttonLeft = buttonRect.left - mapRect.left;\n const buttonRight = mapRect.right - buttonRect.right;\n const panelGap = 5;\n\n this._panel.style.top = '';\n this._panel.style.bottom = '';\n this._panel.style.left = '';\n this._panel.style.right = '';\n\n switch (position) {\n case 'top-left':\n this._panel.style.top = `${buttonTop + buttonRect.height + panelGap}px`;\n this._panel.style.left = `${buttonLeft}px`;\n break;\n case 'top-right':\n this._panel.style.top = `${buttonTop + buttonRect.height + panelGap}px`;\n this._panel.style.right = `${buttonRight}px`;\n break;\n case 'bottom-left':\n this._panel.style.bottom = `${buttonBottom + buttonRect.height + panelGap}px`;\n this._panel.style.left = `${buttonLeft}px`;\n break;\n case 'bottom-right':\n this._panel.style.bottom = `${buttonBottom + buttonRect.height + panelGap}px`;\n this._panel.style.right = `${buttonRight}px`;\n break;\n }\n }\n\n // Begin a panel resize from a bottom corner. The panel stays pinned to its\n // toggle button, so resizing is measured from the button-anchored corner:\n // dragging either bottom handle grows or shrinks the panel away from it.\n private _startResize(event: PointerEvent): void {\n if (!this._panel) return;\n event.preventDefault();\n event.stopPropagation();\n\n const position = this._getControlPosition();\n const isLeft = position === 'top-left' || position === 'bottom-left';\n const isTop = position === 'top-left' || position === 'top-right';\n const rect = this._panel.getBoundingClientRect();\n this._resizeAnchor = {\n x: isLeft ? rect.left : rect.right,\n y: isTop ? rect.top : rect.bottom,\n isLeft,\n isTop,\n };\n\n // Listen on the window so the drag keeps tracking even when the pointer\n // moves off the small handle; pointer capture is a best-effort nicety.\n const handle = event.currentTarget as HTMLElement;\n this._resizeHandleEl = handle;\n handle.setPointerCapture?.(event.pointerId);\n window.addEventListener('pointermove', this._onResizeMove);\n window.addEventListener('pointerup', this._onResizeEnd);\n window.addEventListener('pointercancel', this._onResizeEnd);\n }\n\n private _onResizeMove = (event: PointerEvent): void => {\n if (!this._panel || !this._resizeAnchor) return;\n const { x, y, isLeft, isTop } = this._resizeAnchor;\n const bounds = this._getResizeBounds();\n const rawWidth = isLeft ? event.clientX - x : x - event.clientX;\n const rawHeight = isTop ? event.clientY - y : y - event.clientY;\n const width = this._clampSize(rawWidth, MIN_PANEL_WIDTH, bounds.maxWidth);\n const height = this._clampSize(rawHeight, MIN_PANEL_HEIGHT, bounds.maxHeight);\n\n this._panel.style.width = `${width}px`;\n this._panel.style.height = `${height}px`;\n this._panel.classList.add('is-resized');\n this._state = { ...this._state, panelWidth: width, panelHeight: height };\n this._updatePanelPosition();\n };\n\n private _onResizeEnd = (event: PointerEvent): void => {\n window.removeEventListener('pointermove', this._onResizeMove);\n window.removeEventListener('pointerup', this._onResizeEnd);\n window.removeEventListener('pointercancel', this._onResizeEnd);\n this._resizeHandleEl?.releasePointerCapture?.(event.pointerId);\n this._resizeHandleEl = null;\n if (!this._resizeAnchor) return;\n this._resizeAnchor = null;\n this._emit({ type: 'statechange', state: this.getState() });\n };\n\n private _getResizeBounds(): { maxWidth: number; maxHeight: number } {\n const mapRect = this._mapContainer?.getBoundingClientRect();\n const availableWidth = (mapRect?.width ?? window.innerWidth) - PANEL_VIEWPORT_MARGIN * 2;\n const availableHeight = (mapRect?.height ?? window.innerHeight) - PANEL_VIEWPORT_MARGIN * 2;\n return {\n maxWidth: Math.max(MIN_PANEL_WIDTH, availableWidth),\n maxHeight: Math.max(MIN_PANEL_HEIGHT, availableHeight),\n };\n }\n\n private _clampSize(value: number, min: number, max: number): number {\n return Math.round(Math.min(Math.max(value, min), max));\n }\n}\n"],"names":["_a","_b"],"mappings":"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"}