maplibre-gl-layer-control 0.10.0 → 0.11.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/dist/index.cjs +12 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +12 -0
- package/dist/index.mjs.map +1 -1
- package/dist/maplibre-gl-layer-control.css +13 -0
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/lib/core/CustomLayerRegistry.ts","../src/lib/utils/layerUtils.ts","../src/lib/utils/styleCache.ts","../src/lib/utils/colorUtils.ts","../src/lib/utils/formatters.ts","../src/lib/utils/symbolUtils.ts","../src/lib/core/LayerControl.ts"],"sourcesContent":["import type { CustomLayerAdapter, LayerState } from './types';\n\n/**\n * Registry for managing custom layer adapters.\n * Routes layer operations to the appropriate adapter based on layer ID.\n */\nexport class CustomLayerRegistry {\n private adapters: Map<string, CustomLayerAdapter> = new Map();\n private changeListeners: Array<(event: 'add' | 'remove', layerId: string) => void> = [];\n private unsubscribers: Map<string, () => void> = new Map();\n\n /**\n * Register a custom layer adapter.\n * @param adapter The adapter to register\n */\n register(adapter: CustomLayerAdapter): void {\n this.adapters.set(adapter.type, adapter);\n\n // Subscribe to adapter's layer changes if supported\n if (adapter.onLayerChange) {\n const unsubscribe = adapter.onLayerChange((event, layerId) => {\n this.notifyChange(event, layerId);\n });\n this.unsubscribers.set(adapter.type, unsubscribe);\n }\n }\n\n /**\n * Unregister an adapter by type.\n * @param type The adapter type to unregister\n */\n unregister(type: string): void {\n // Clean up the subscription for this adapter\n const unsubscribe = this.unsubscribers.get(type);\n if (unsubscribe) {\n unsubscribe();\n this.unsubscribers.delete(type);\n }\n this.adapters.delete(type);\n }\n\n /**\n * Get all custom layer IDs across all adapters.\n * @returns Array of layer IDs\n */\n getAllLayerIds(): string[] {\n const ids: string[] = [];\n this.adapters.forEach(adapter => {\n ids.push(...adapter.getLayerIds());\n });\n return ids;\n }\n\n /**\n * Check if a layer ID is managed by any adapter.\n * @param layerId The layer ID to check\n * @returns true if the layer is managed by an adapter\n */\n hasLayer(layerId: string): boolean {\n for (const adapter of this.adapters.values()) {\n if (adapter.getLayerIds().includes(layerId)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Get the adapter responsible for a specific layer.\n * @param layerId The layer ID\n * @returns The adapter or null if not found\n */\n getAdapterForLayer(layerId: string): CustomLayerAdapter | null {\n for (const adapter of this.adapters.values()) {\n if (adapter.getLayerIds().includes(layerId)) {\n return adapter;\n }\n }\n return null;\n }\n\n /**\n * Get the state of a custom layer.\n * @param layerId The layer ID\n * @returns The layer state or null if not found\n */\n getLayerState(layerId: string): LayerState | null {\n const adapter = this.getAdapterForLayer(layerId);\n return adapter ? adapter.getLayerState(layerId) : null;\n }\n\n /**\n * Set visibility of a custom layer.\n * @param layerId The layer ID\n * @param visible Whether the layer should be visible\n * @returns true if the operation was handled by an adapter\n */\n setVisibility(layerId: string, visible: boolean): boolean {\n const adapter = this.getAdapterForLayer(layerId);\n if (adapter) {\n adapter.setVisibility(layerId, visible);\n return true;\n }\n return false;\n }\n\n /**\n * Set opacity of a custom layer.\n * @param layerId The layer ID\n * @param opacity The opacity value (0-1)\n * @returns true if the operation was handled by an adapter\n */\n setOpacity(layerId: string, opacity: number): boolean {\n const adapter = this.getAdapterForLayer(layerId);\n if (adapter) {\n adapter.setOpacity(layerId, opacity);\n return true;\n }\n return false;\n }\n\n /**\n * Get the symbol type for a custom layer (for UI display).\n * @param layerId The layer ID\n * @returns The symbol type or null if not available\n */\n getSymbolType(layerId: string): string | null {\n const adapter = this.getAdapterForLayer(layerId);\n if (adapter && adapter.getSymbolType) {\n return adapter.getSymbolType(layerId);\n }\n return null;\n }\n\n /**\n * Get the bounds of a custom layer (for zoom-to-layer).\n * @param layerId The layer ID\n * @returns The bounds [west, south, east, north] or null if not available\n */\n getBounds(layerId: string): [number, number, number, number] | null {\n const adapter = this.getAdapterForLayer(layerId);\n if (adapter && adapter.getBounds) {\n return adapter.getBounds(layerId);\n }\n return null;\n }\n\n /**\n * Remove a custom layer through its adapter.\n * @param layerId The layer ID to remove\n * @returns true if the operation was handled by an adapter\n */\n removeLayer(layerId: string): boolean {\n const adapter = this.getAdapterForLayer(layerId);\n if (adapter && adapter.removeLayer) {\n adapter.removeLayer(layerId);\n return true;\n }\n return false;\n }\n\n /**\n * Subscribe to layer changes across all adapters.\n * @param callback Function called when layers are added or removed\n * @returns Unsubscribe function\n */\n onChange(callback: (event: 'add' | 'remove', layerId: string) => void): () => void {\n this.changeListeners.push(callback);\n return () => {\n const idx = this.changeListeners.indexOf(callback);\n if (idx >= 0) {\n this.changeListeners.splice(idx, 1);\n }\n };\n }\n\n private notifyChange(event: 'add' | 'remove', layerId: string): void {\n this.changeListeners.forEach(cb => cb(event, layerId));\n }\n\n /**\n * Clean up all subscriptions and adapters.\n */\n destroy(): void {\n this.unsubscribers.forEach(unsub => unsub());\n this.unsubscribers.clear();\n this.adapters.clear();\n this.changeListeners = [];\n }\n}\n","import type { Map as MapLibreMap } from 'maplibre-gl';\nimport type { StyleableLayerType } from '../core/types';\n\n/**\n * Get the opacity property name for a given layer type\n * Supports all MapLibre layer types: fill, line, symbol, circle, heatmap,\n * fill-extrusion, raster, hillshade, color-relief, background\n * @param layerType MapLibre layer type\n * @returns Opacity property name(s), or null if the layer type doesn't support opacity\n */\nexport function getOpacityProperty(layerType: string): string | string[] | null {\n switch (layerType) {\n case 'fill':\n return 'fill-opacity';\n case 'line':\n return 'line-opacity';\n case 'circle':\n return 'circle-opacity';\n case 'symbol':\n // Symbol layers have both icon and text opacity\n return ['icon-opacity', 'text-opacity'];\n case 'raster':\n return 'raster-opacity';\n case 'background':\n return 'background-opacity';\n case 'heatmap':\n return 'heatmap-opacity';\n case 'fill-extrusion':\n return 'fill-extrusion-opacity';\n case 'hillshade':\n // Hillshade uses exaggeration for intensity, not opacity\n return 'hillshade-exaggeration';\n case 'color-relief':\n // Color-relief doesn't have a standard opacity property\n return null;\n default:\n // For custom layer types, try the standard pattern\n return `${layerType}-opacity`;\n }\n}\n\n/**\n * Get the current opacity value for a layer\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @param layerType Layer type\n * @returns Current opacity value (0-1), or 1.0 if the layer type doesn't support opacity\n */\nexport function getLayerOpacity(\n map: MapLibreMap,\n layerId: string,\n layerType: string\n): number {\n const opacityProp = getOpacityProperty(layerType);\n\n // Layer type doesn't support opacity\n if (opacityProp === null) {\n return 1.0;\n }\n\n if (Array.isArray(opacityProp)) {\n // For symbol layers, use icon-opacity as the primary value\n const opacity = map.getPaintProperty(layerId, opacityProp[0]);\n return (opacity !== undefined && opacity !== null) ? opacity as number : 1.0;\n }\n\n const opacity = map.getPaintProperty(layerId, opacityProp);\n return (opacity !== undefined && opacity !== null) ? opacity as number : 1.0;\n}\n\n/**\n * Set the opacity for a layer\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @param layerType Layer type\n * @param opacity Opacity value (0-1)\n */\nexport function setLayerOpacity(\n map: MapLibreMap,\n layerId: string,\n layerType: string,\n opacity: number\n): void {\n const opacityProp = getOpacityProperty(layerType);\n\n // Layer type doesn't support opacity\n if (opacityProp === null) {\n return;\n }\n\n if (Array.isArray(opacityProp)) {\n // For symbol layers, set both icon and text opacity\n opacityProp.forEach((prop) => {\n map.setPaintProperty(layerId, prop, opacity);\n });\n } else {\n map.setPaintProperty(layerId, opacityProp, opacity);\n }\n}\n\n/**\n * Check if a layer type supports style editing\n * @param layerType Layer type\n * @returns True if the layer type supports style editing\n */\nexport function isStyleableLayerType(layerType: string): layerType is StyleableLayerType {\n return [\n 'fill',\n 'line',\n 'circle',\n 'symbol',\n 'raster',\n 'heatmap',\n 'fill-extrusion',\n 'hillshade',\n ].includes(layerType);\n}\n\n/**\n * Get layer type from map\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @returns Layer type or null if layer not found\n */\nexport function getLayerType(map: MapLibreMap, layerId: string): string | null {\n try {\n const layer = map.getLayer(layerId);\n return layer ? layer.type : null;\n } catch (error) {\n console.warn(`Failed to get layer type for ${layerId}:`, error);\n return null;\n }\n}\n","import type { Map as MapLibreMap } from 'maplibre-gl';\nimport type { OriginalStyle } from '../core/types';\n\n/**\n * Deep clone a paint value (handles complex MapLibre expressions)\n * @param value Paint value to clone\n * @returns Cloned value\n */\nexport function clonePaintValue(value: any): any {\n if (Array.isArray(value)) {\n return value.map((item) => clonePaintValue(item));\n }\n if (value && typeof value === 'object') {\n try {\n return JSON.parse(JSON.stringify(value));\n } catch (error) {\n return value;\n }\n }\n return value;\n}\n\n/**\n * Cache the original paint properties for a layer\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @param originalStyles Map to store original styles\n */\nexport function cacheOriginalLayerStyle(\n map: MapLibreMap,\n layerId: string,\n originalStyles: Map<string, OriginalStyle>\n): void {\n if (originalStyles.has(layerId)) {\n return; // Already cached\n }\n\n try {\n const layer = map.getLayer(layerId);\n if (!layer) {\n return;\n }\n\n const paint: Record<string, any> = {};\n const style = map.getStyle();\n const layerDef = style.layers?.find(l => l.id === layerId);\n\n // For raster layers, handle all properties with defaults\n if (layer.type === 'raster') {\n // Default values from MapLibre GL spec\n const rasterDefaults: Record<string, number> = {\n 'raster-opacity': 1,\n 'raster-brightness-min': 0,\n 'raster-brightness-max': 1,\n 'raster-saturation': 0,\n 'raster-contrast': 0,\n 'raster-hue-rotate': 0\n };\n\n // Start with defaults\n Object.assign(paint, rasterDefaults);\n\n // Override with values from layer definition\n if (layerDef && 'paint' in layerDef && layerDef.paint) {\n Object.entries(layerDef.paint).forEach(([prop, value]) => {\n if (prop.startsWith('raster-')) {\n paint[prop] = clonePaintValue(value);\n }\n });\n }\n } else {\n // For non-raster layers, just get values from the layer definition\n if (layerDef && 'paint' in layerDef && layerDef.paint) {\n Object.entries(layerDef.paint).forEach(([prop, value]) => {\n paint[prop] = clonePaintValue(value);\n });\n }\n }\n\n originalStyles.set(layerId, { paint });\n } catch (error) {\n console.warn(`Failed to cache original style for ${layerId}:`, error);\n }\n}\n\n/**\n * Get the current value of a paint property\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @param property Property name\n * @param fallback Fallback value if property is not set\n * @returns Current property value\n */\nexport function getCurrentPaintValue(\n map: MapLibreMap,\n layerId: string,\n property: string,\n fallback?: any\n): any {\n try {\n const value = map.getPaintProperty(layerId, property);\n return value !== undefined ? value : fallback;\n } catch (error) {\n return fallback;\n }\n}\n\n/**\n * Restore original paint properties for a layer\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @param originalStyles Map of original styles\n * @returns Object with restored properties\n */\nexport function restoreOriginalStyle(\n map: MapLibreMap,\n layerId: string,\n originalStyles: Map<string, OriginalStyle>\n): Record<string, any> {\n const original = originalStyles.get(layerId);\n if (!original) {\n return {};\n }\n\n const applied: Record<string, any> = {};\n\n Object.entries(original.paint).forEach(([property, value]) => {\n try {\n const restoredValue = clonePaintValue(value);\n map.setPaintProperty(layerId, property, restoredValue);\n applied[property] = restoredValue;\n } catch (error) {\n console.warn(`Failed to restore ${property} for ${layerId}:`, error);\n }\n });\n\n return applied;\n}\n","/**\n * Convert RGB values to hex color string\n * @param r Red component (0-255)\n * @param g Green component (0-255)\n * @param b Blue component (0-255)\n * @returns Hex color string (e.g., '#ff0000')\n */\nexport function rgbToHex(r: number, g: number, b: number): string {\n const clamp = (v: number) => Math.max(0, Math.min(255, Math.round(v)));\n const toHex = (v: number) => {\n const hex = clamp(v).toString(16);\n return hex.length === 1 ? `0${hex}` : hex;\n };\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\n}\n\n/**\n * Normalize a color value to hex format\n * Handles hex strings, RGB strings, and RGB arrays\n * @param value Color value in various formats\n * @returns Normalized hex color string (always 6 digits)\n */\nexport function normalizeColor(value: any): string {\n if (typeof value === 'string') {\n // Already hex format\n if (value.startsWith('#')) {\n // Expand shorthand hex (#RGB to #RRGGBB)\n if (value.length === 4) {\n const r = value[1];\n const g = value[2];\n const b = value[3];\n return `#${r}${r}${g}${g}${b}${b}`;\n }\n return value;\n }\n\n // RGB string format: 'rgb(51, 136, 255)'\n if (value.startsWith('rgb')) {\n const match = value.match(/\\d+/g);\n if (match && match.length >= 3) {\n const [r, g, b] = match.map((num) => parseInt(num, 10));\n return rgbToHex(r, g, b);\n }\n }\n } else if (Array.isArray(value) && value.length >= 3) {\n // RGB array format: [51, 136, 255]\n return rgbToHex(value[0], value[1], value[2]);\n }\n\n // Fallback color (MapLibre default blue)\n return '#3388ff';\n}\n","/**\n * Format a numeric value based on the step size\n * @param value Numeric value to format\n * @param step Step size (determines decimal places)\n * @returns Formatted string\n */\nexport function formatNumericValue(value: number, step: number): string {\n let decimals = 0;\n\n if (step && Number(step) !== 1) {\n const stepNumber = Number(step);\n if (stepNumber > 0 && stepNumber < 1) {\n decimals = Math.min(4, Math.ceil(Math.abs(Math.log10(stepNumber))));\n }\n }\n\n return value.toFixed(decimals);\n}\n\n/**\n * Clamp a numeric value between min and max\n * @param value Value to clamp\n * @param min Minimum value\n * @param max Maximum value\n * @returns Clamped value\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n","import type { Map as MapLibreMap, LayerSpecification } from 'maplibre-gl';\nimport { normalizeColor, rgbToHex } from './colorUtils';\n\n/**\n * Map of layer types to their primary color property\n */\nconst COLOR_PROPERTY_MAP: Record<string, string[]> = {\n fill: ['fill-color', 'fill-outline-color'],\n line: ['line-color'],\n circle: ['circle-color', 'circle-stroke-color'],\n symbol: ['icon-color', 'text-color'],\n background: ['background-color'],\n heatmap: ['heatmap-color'],\n 'fill-extrusion': ['fill-extrusion-color'],\n};\n\n/**\n * Extract the first color value from a MapLibre expression\n * Handles expressions like ['case', ...], ['match', ...], ['interpolate', ...]\n * @param expression The MapLibre expression to extract color from\n * @returns The first color found, or null\n */\nfunction extractColorFromExpression(expression: any[]): string | null {\n if (!Array.isArray(expression) || expression.length === 0) return null;\n\n // Recursively search for color values\n for (const item of expression) {\n if (typeof item === 'string') {\n // Check if it's a color string\n if (\n item.startsWith('#') ||\n item.startsWith('rgb') ||\n item.startsWith('hsl')\n ) {\n return normalizeColor(item);\n }\n } else if (Array.isArray(item)) {\n const result = extractColorFromExpression(item);\n if (result) return result;\n }\n }\n return null;\n}\n\n/**\n * Get the primary color from a layer's paint properties\n * @param map The MapLibre map instance\n * @param layerId The layer ID\n * @param layerType The layer type\n * @returns The normalized hex color, or null if not found\n */\nexport function getLayerColor(\n map: MapLibreMap,\n layerId: string,\n layerType: string\n): string | null {\n const propertyNames = COLOR_PROPERTY_MAP[layerType];\n if (!propertyNames) return null;\n\n // Try each property in order\n for (const propertyName of propertyNames) {\n // First try runtime property (may have been changed)\n try {\n const runtimeColor = map.getPaintProperty(layerId, propertyName);\n if (runtimeColor) {\n if (typeof runtimeColor === 'string') {\n return normalizeColor(runtimeColor);\n }\n if (Array.isArray(runtimeColor)) {\n // Handle expressions\n const extracted = extractColorFromExpression(runtimeColor);\n if (extracted) return extracted;\n }\n }\n } catch {\n // Property doesn't exist, continue\n }\n\n // Try from layer definition\n const style = map.getStyle();\n const layer = style?.layers?.find(\n (l: LayerSpecification) => l.id === layerId\n );\n if (layer && 'paint' in layer && layer.paint) {\n const paintColor = (layer.paint as Record<string, any>)[propertyName];\n if (paintColor) {\n if (typeof paintColor === 'string') {\n return normalizeColor(paintColor);\n }\n if (Array.isArray(paintColor)) {\n const extracted = extractColorFromExpression(paintColor);\n if (extracted) return extracted;\n }\n }\n }\n }\n\n return null;\n}\n\n/**\n * Get the primary color directly from a layer specification\n * @param layer The layer specification\n * @returns The normalized hex color, or null if not found\n */\nexport function getLayerColorFromSpec(layer: LayerSpecification): string | null {\n const propertyNames = COLOR_PROPERTY_MAP[layer.type];\n if (!propertyNames) return null;\n\n for (const propertyName of propertyNames) {\n if ('paint' in layer && layer.paint) {\n const paintColor = (layer.paint as Record<string, any>)[propertyName];\n if (paintColor) {\n if (typeof paintColor === 'string') {\n return normalizeColor(paintColor);\n }\n if (Array.isArray(paintColor)) {\n const extracted = extractColorFromExpression(paintColor);\n if (extracted) return extracted;\n }\n }\n }\n }\n\n return null;\n}\n\n/**\n * Darken a hex color by a given amount\n * @param hexColor The hex color to darken (e.g., '#ff0000')\n * @param amount Amount to darken (0-1, where 1 is fully black)\n * @returns The darkened hex color\n */\nexport function darkenColor(hexColor: string, amount: number): string {\n // Normalize to 6-digit hex\n let hex = hexColor.replace('#', '');\n if (hex.length === 3) {\n hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];\n }\n\n const r = Math.max(\n 0,\n parseInt(hex.slice(0, 2), 16) - Math.round(255 * amount)\n );\n const g = Math.max(\n 0,\n parseInt(hex.slice(2, 4), 16) - Math.round(255 * amount)\n );\n const b = Math.max(\n 0,\n parseInt(hex.slice(4, 6), 16) - Math.round(255 * amount)\n );\n return rgbToHex(r, g, b);\n}\n\n// SVG Symbol Templates\n\n/**\n * Create a fill symbol (filled rectangle)\n */\nfunction createFillSymbol(size: number, color: string): string {\n const padding = 2;\n const borderColor = darkenColor(color, 0.3);\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"1\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a line symbol (horizontal line)\n */\nfunction createLineSymbol(\n size: number,\n color: string,\n strokeWidth: number = 2\n): string {\n const y = size / 2;\n const padding = 2;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <line x1=\"${padding}\" y1=\"${y}\" x2=\"${size - padding}\" y2=\"${y}\"\n stroke=\"${color}\" stroke-width=\"${strokeWidth}\" stroke-linecap=\"round\"/>\n </svg>`;\n}\n\n/**\n * Create a circle symbol (filled circle)\n */\nfunction createCircleSymbol(size: number, color: string): string {\n const cx = size / 2;\n const cy = size / 2;\n const r = size / 2 - 3;\n const borderColor = darkenColor(color, 0.3);\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"${cx}\" cy=\"${cy}\" r=\"${r}\" fill=\"${color}\"\n stroke=\"${borderColor}\" stroke-width=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a marker/pin symbol for symbol layers\n */\nfunction createMarkerSymbol(size: number, color: string): string {\n const borderColor = darkenColor(color, 0.3);\n // Simple pin/marker shape\n const cx = size / 2;\n const pinWidth = size * 0.5;\n const pinHeight = size * 0.7;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M${cx} ${size - 2}\n L${cx - pinWidth / 2} ${size - pinHeight}\n A${pinWidth / 2} ${pinWidth / 2} 0 1 1 ${cx + pinWidth / 2} ${size - pinHeight}\n Z\"\n fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"1\"/>\n <circle cx=\"${cx}\" cy=\"${size - pinHeight - pinWidth / 4}\" r=\"${pinWidth / 5}\" fill=\"white\"/>\n </svg>`;\n}\n\n/**\n * Create a raster symbol (gradient pattern)\n */\nfunction createRasterSymbol(size: number): string {\n const padding = 2;\n const id = `rasterGrad_${Math.random().toString(36).slice(2, 9)}`;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"${id}\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stop-color=\"#e0e0e0\"/>\n <stop offset=\"50%\" stop-color=\"#808080\"/>\n <stop offset=\"100%\" stop-color=\"#404040\"/>\n </linearGradient>\n </defs>\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"url(#${id})\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a background symbol (rectangle with inner indicator)\n */\nfunction createBackgroundSymbol(size: number, color: string): string {\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"1\" y=\"1\" width=\"${size - 2}\" height=\"${size - 2}\" fill=\"${color}\" rx=\"2\"/>\n <rect x=\"3\" y=\"3\" width=\"${size - 6}\" height=\"${size - 6}\" fill=\"none\"\n stroke=\"white\" stroke-width=\"1\" stroke-opacity=\"0.5\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a heatmap symbol (orange-red gradient)\n */\nfunction createHeatmapSymbol(size: number): string {\n const padding = 2;\n const id = `heatmapGrad_${Math.random().toString(36).slice(2, 9)}`;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <radialGradient id=\"${id}\" cx=\"50%\" cy=\"50%\" r=\"50%\">\n <stop offset=\"0%\" stop-color=\"#ffff00\"/>\n <stop offset=\"50%\" stop-color=\"#ff8800\"/>\n <stop offset=\"100%\" stop-color=\"#ff0000\"/>\n </radialGradient>\n </defs>\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"url(#${id})\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a hillshade symbol (gray gradient)\n */\nfunction createHillshadeSymbol(size: number): string {\n const padding = 2;\n const id = `hillshadeGrad_${Math.random().toString(36).slice(2, 9)}`;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"${id}\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stop-color=\"#ffffff\"/>\n <stop offset=\"100%\" stop-color=\"#666666\"/>\n </linearGradient>\n </defs>\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"url(#${id})\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a fill-extrusion symbol (3D-ish rectangle)\n */\nfunction createFillExtrusionSymbol(size: number, color: string): string {\n const borderColor = darkenColor(color, 0.3);\n const topColor = color;\n const sideColor = darkenColor(color, 0.2);\n const depth = 3;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <polygon points=\"${2 + depth},2 ${size - 2},2 ${size - 2},${size - 2 - depth} ${size - 2 - depth},${size - 2} 2,${size - 2} 2,${2 + depth}\"\n fill=\"${topColor}\" stroke=\"${borderColor}\" stroke-width=\"1\"/>\n <polygon points=\"2,${2 + depth} ${2 + depth},2 ${2 + depth},${size - 2 - depth} 2,${size - 2}\"\n fill=\"${sideColor}\" stroke=\"${borderColor}\" stroke-width=\"0.5\"/>\n <polygon points=\"${2 + depth},${size - 2 - depth} ${size - 2},${size - 2 - depth} ${size - 2 - depth},${size - 2} 2,${size - 2}\"\n fill=\"${sideColor}\" stroke=\"${borderColor}\" stroke-width=\"0.5\"/>\n </svg>`;\n}\n\n/**\n * Create a default symbol (simple square)\n */\nfunction createDefaultSymbol(size: number, color: string): string {\n const padding = 2;\n const borderColor = darkenColor(color, 0.3);\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a COG (Cloud Optimized GeoTIFF) symbol\n * Grid pattern representing raster tiles\n */\nfunction createCOGSymbol(size: number, color: string): string {\n const padding = 2;\n const borderColor = darkenColor(color, 0.3);\n const cellSize = (size - padding * 2) / 2;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${cellSize}\" height=\"${cellSize}\" fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"0.5\"/>\n <rect x=\"${padding + cellSize}\" y=\"${padding}\" width=\"${cellSize}\" height=\"${cellSize}\" fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.8\"/>\n <rect x=\"${padding}\" y=\"${padding + cellSize}\" width=\"${cellSize}\" height=\"${cellSize}\" fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.6\"/>\n <rect x=\"${padding + cellSize}\" y=\"${padding + cellSize}\" width=\"${cellSize}\" height=\"${cellSize}\" fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.4\"/>\n </svg>`;\n}\n\n/**\n * Create a Zarr symbol\n * Layered grid pattern representing multidimensional data\n */\nfunction createZarrSymbol(size: number, color: string): string {\n const padding = 2;\n const borderColor = darkenColor(color, 0.3);\n const innerSize = size - padding * 2;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"${padding + 2}\" y=\"${padding}\" width=\"${innerSize - 2}\" height=\"${innerSize - 2}\" fill=\"${darkenColor(color, 0.2)}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" rx=\"1\"/>\n <rect x=\"${padding + 1}\" y=\"${padding + 1}\" width=\"${innerSize - 2}\" height=\"${innerSize - 2}\" fill=\"${darkenColor(color, 0.1)}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" rx=\"1\"/>\n <rect x=\"${padding}\" y=\"${padding + 2}\" width=\"${innerSize - 2}\" height=\"${innerSize - 2}\" fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" rx=\"1\"/>\n <line x1=\"${padding + 3}\" y1=\"${padding + 5}\" x2=\"${padding + innerSize - 5}\" y2=\"${padding + 5}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.5\"/>\n <line x1=\"${padding + 3}\" y1=\"${padding + 8}\" x2=\"${padding + innerSize - 5}\" y2=\"${padding + 8}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.5\"/>\n </svg>`;\n}\n\n/**\n * Create a generic custom raster symbol\n * Gradient grid representing custom raster layers\n */\nfunction createCustomRasterSymbol(size: number, color: string): string {\n const padding = 2;\n const borderColor = darkenColor(color, 0.3);\n const id = `customRasterGrad_${Math.random().toString(36).slice(2, 9)}`;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"${id}\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stop-color=\"${color}\"/>\n <stop offset=\"100%\" stop-color=\"${darkenColor(color, 0.4)}\"/>\n </linearGradient>\n </defs>\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"url(#${id})\" stroke=\"${borderColor}\" stroke-width=\"1\" rx=\"1\"/>\n <line x1=\"${size / 2}\" y1=\"${padding}\" x2=\"${size / 2}\" y2=\"${size - padding}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.3\"/>\n <line x1=\"${padding}\" y1=\"${size / 2}\" x2=\"${size - padding}\" y2=\"${size / 2}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.3\"/>\n </svg>`;\n}\n\n/**\n * Create a stacked layers symbol for background layer groups\n * Shows multiple overlapping rectangles to represent multiple layers\n */\nfunction createStackedLayersSymbol(size: number): string {\n const colors = ['#a8d4a8', '#8ec4e8', '#d4c4a8'];\n const borderColor = '#666666';\n // Three stacked rectangles offset diagonally\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"4\" y=\"1\" width=\"${size - 6}\" height=\"${size - 6}\" fill=\"${colors[2]}\" stroke=\"${borderColor}\" stroke-width=\"0.75\" rx=\"1\"/>\n <rect x=\"2\" y=\"3\" width=\"${size - 6}\" height=\"${size - 6}\" fill=\"${colors[1]}\" stroke=\"${borderColor}\" stroke-width=\"0.75\" rx=\"1\"/>\n <rect x=\"0\" y=\"5\" width=\"${size - 6}\" height=\"${size - 6}\" fill=\"${colors[0]}\" stroke=\"${borderColor}\" stroke-width=\"0.75\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Symbol generation options\n */\nexport interface SymbolOptions {\n /** Symbol size in pixels (default: 16) */\n size?: number;\n /** Stroke width for line symbols (default: 2) */\n strokeWidth?: number;\n}\n\n/**\n * Create an SVG symbol for a layer type\n * @param layerType The MapLibre layer type\n * @param color The primary color (hex format), or null for default\n * @param options Optional configuration\n * @returns SVG markup string\n */\nexport function createLayerSymbolSVG(\n layerType: string,\n color: string | null,\n options: SymbolOptions = {}\n): string {\n const size = options.size || 16;\n const strokeWidth = options.strokeWidth || 2;\n const fillColor = color || '#888888'; // Fallback gray\n\n switch (layerType) {\n case 'fill':\n return createFillSymbol(size, fillColor);\n case 'line':\n return createLineSymbol(size, fillColor, strokeWidth);\n case 'circle':\n return createCircleSymbol(size, fillColor);\n case 'symbol':\n return createMarkerSymbol(size, fillColor);\n case 'raster':\n return createRasterSymbol(size);\n case 'background':\n return createBackgroundSymbol(size, fillColor);\n case 'heatmap':\n return createHeatmapSymbol(size);\n case 'hillshade':\n return createHillshadeSymbol(size);\n case 'fill-extrusion':\n return createFillExtrusionSymbol(size, fillColor);\n case 'background-group':\n return createStackedLayersSymbol(size);\n case 'cog':\n return createCOGSymbol(size, fillColor);\n case 'zarr':\n return createZarrSymbol(size, fillColor);\n case 'custom-raster':\n return createCustomRasterSymbol(size, fillColor);\n default:\n return createDefaultSymbol(size, fillColor);\n }\n}\n\n/**\n * Create an SVG symbol for the Background layer group\n * @param size Symbol size in pixels (default: 16)\n * @returns SVG markup string\n */\nexport function createBackgroundGroupSymbolSVG(size: number = 16): string {\n return createStackedLayersSymbol(size);\n}\n","import type { IControl, Map as MapLibreMap, LayerSpecification } from 'maplibre-gl';\nimport type {\n LayerControlOptions,\n LayerState,\n OriginalStyle,\n InternalControlState,\n CustomLayerAdapter,\n} from './types';\nimport { CustomLayerRegistry } from './CustomLayerRegistry';\nimport { getLayerType, getLayerOpacity, setLayerOpacity } from '../utils/layerUtils';\nimport { cacheOriginalLayerStyle, restoreOriginalStyle } from '../utils/styleCache';\nimport { normalizeColor } from '../utils/colorUtils';\nimport { formatNumericValue } from '../utils/formatters';\nimport {\n getLayerColor,\n getLayerColorFromSpec,\n createLayerSymbolSVG,\n createBackgroundGroupSymbolSVG,\n} from '../utils/symbolUtils';\n\n/**\n * LayerControl - A comprehensive layer control for MapLibre GL\n * Provides visibility toggle, opacity control, and advanced style editing\n */\nexport class LayerControl implements IControl {\n private map!: MapLibreMap;\n private mapContainer!: HTMLElement;\n private container!: HTMLDivElement;\n private button!: HTMLButtonElement;\n private panel!: HTMLDivElement;\n\n // Panel positioning\n private resizeHandler: (() => void) | null = null;\n private mapResizeHandler: (() => void) | null = null;\n\n // State management\n private state: InternalControlState;\n private targetLayers: string[];\n private styleEditors: Map<string, HTMLElement>;\n private initialSourceIds: Set<string> | null = null;\n private initialLayerIds: Set<string> | null = null;\n\n // Panel width management\n private minPanelWidth: number;\n private maxPanelWidth: number;\n private maxPanelHeight: number;\n private showStyleEditor: boolean;\n private showOpacitySlider: boolean;\n private showLayerSymbol: boolean;\n private excludeDrawnLayers: boolean;\n private excludeLayerPatterns: RegExp[];\n private customLayerRegistry: CustomLayerRegistry | null = null;\n private customLayerUnsubscribe: (() => void) | null = null;\n private basemapStyleUrl: string | null = null;\n private basemapLayerIds: Set<string> | null = null;\n private widthSliderEl: HTMLElement | null = null;\n private widthThumbEl: HTMLElement | null = null;\n private widthValueEl: HTMLElement | null = null;\n private isWidthSliderActive = false;\n private widthDragRectWidth: number | null = null;\n private widthDragStartX: number | null = null;\n private widthDragStartWidth: number | null = null;\n private widthFrame: number | null = null;\n\n // Context menu and drag-drop\n private contextMenuEl: HTMLDivElement | null = null;\n private enableContextMenu: boolean;\n private enableDragAndDrop: boolean;\n private onLayerRename?: (layerId: string, oldName: string, newName: string) => void;\n private onLayerReorder?: (layerOrder: string[]) => void;\n private onLayerRemove?: (layerId: string) => void;\n\n constructor(options: LayerControlOptions = {}) {\n this.minPanelWidth = options.panelMinWidth || 240;\n this.maxPanelWidth = options.panelMaxWidth || 420;\n this.maxPanelHeight = options.panelMaxHeight || 600;\n this.showStyleEditor = options.showStyleEditor !== false;\n this.showOpacitySlider = options.showOpacitySlider !== false;\n this.showLayerSymbol = options.showLayerSymbol !== false;\n this.excludeDrawnLayers = options.excludeDrawnLayers !== false;\n this.excludeLayerPatterns = this.wildcardPatternsToRegex(options.excludeLayers || []);\n\n // Context menu and drag-drop options\n this.enableContextMenu = options.enableContextMenu !== false;\n this.enableDragAndDrop = options.enableDragAndDrop !== false;\n this.onLayerRename = options.onLayerRename;\n this.onLayerReorder = options.onLayerReorder;\n this.onLayerRemove = options.onLayerRemove;\n\n this.state = {\n collapsed: options.collapsed !== false,\n panelWidth: options.panelWidth || 350,\n activeStyleEditor: null,\n layerStates: options.layerStates || {},\n originalStyles: new Map<string, OriginalStyle>(),\n userInteractingWithSlider: false,\n backgroundLegendOpen: false,\n backgroundLayerVisibility: new Map<string, boolean>(),\n onlyRenderedFilter: false,\n contextMenu: {\n visible: false,\n targetLayerId: null,\n x: 0,\n y: 0,\n },\n renamingLayerId: null,\n customLayerNames: new Map<string, string>(),\n drag: {\n active: false,\n layerId: null,\n startY: 0,\n currentY: 0,\n placeholder: null,\n draggedElement: null,\n },\n isStyleOperationInProgress: false,\n };\n\n this.targetLayers = options.layers || Object.keys(this.state.layerStates);\n this.styleEditors = new Map<string, HTMLElement>();\n\n // Initialize custom layer registry if adapters are provided\n if (options.customLayerAdapters && options.customLayerAdapters.length > 0) {\n this.customLayerRegistry = new CustomLayerRegistry();\n options.customLayerAdapters.forEach(adapter => {\n this.customLayerRegistry!.register(adapter);\n });\n }\n\n // Store basemap style URL for reliable layer detection\n this.basemapStyleUrl = options.basemapStyleUrl || null;\n }\n\n /**\n * Called when the control is added to the map\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this.map = map;\n this.mapContainer = map.getContainer();\n\n // Capture initial source IDs and layer IDs (basemap) before auto-detecting layers\n // Sources and layers added after this point are considered user-added\n const style = this.map.getStyle();\n if (style && style.sources) {\n this.initialSourceIds = new Set(Object.keys(style.sources));\n } else {\n this.initialSourceIds = new Set();\n }\n\n // Capture initial layer IDs - any layer added after this is user-added\n if (style && style.layers) {\n this.initialLayerIds = new Set(style.layers.map(layer => layer.id));\n } else {\n this.initialLayerIds = new Set();\n }\n\n this.container = this.createContainer();\n this.button = this.createToggleButton();\n this.panel = this.createPanel();\n\n this.container.appendChild(this.button);\n // Append panel to map container for independent positioning (avoids overlap with other controls)\n this.mapContainer.appendChild(this.panel);\n\n // Create context menu element (appended to map container)\n if (this.enableContextMenu) {\n this.contextMenuEl = this.createContextMenu();\n this.mapContainer.appendChild(this.contextMenuEl);\n }\n\n // Now that panel is attached, update width display\n this.updateWidthDisplay();\n\n // Setup event listeners\n this.setupEventListeners();\n\n // If basemapStyleUrl is provided, fetch it first for reliable layer detection\n if (this.basemapStyleUrl && !this.basemapLayerIds) {\n this.fetchBasemapStyle().then(() => {\n // Auto-detect layers after basemap style is fetched\n if (Object.keys(this.state.layerStates).length === 0) {\n this.autoDetectLayers();\n }\n // Build layer items\n this.buildLayerItems();\n }).catch(error => {\n console.warn('Failed to fetch basemap style, falling back to heuristic detection:', error);\n // Fall back to heuristic detection\n if (Object.keys(this.state.layerStates).length === 0) {\n this.autoDetectLayers();\n }\n this.buildLayerItems();\n });\n } else {\n // Auto-detect layers using source-based heuristics\n if (Object.keys(this.state.layerStates).length === 0) {\n this.autoDetectLayers();\n }\n // Build layer items\n this.buildLayerItems();\n }\n\n // If panel starts expanded, update position after control is added to DOM\n if (!this.state.collapsed) {\n // Use requestAnimationFrame to wait until container is in DOM and positioned\n requestAnimationFrame(() => {\n this.updatePanelPosition();\n });\n }\n\n return this.container;\n }\n\n /**\n * Fetch the basemap style JSON and extract layer IDs.\n * This provides reliable distinction between basemap and user-added layers.\n */\n private async fetchBasemapStyle(): Promise<void> {\n if (!this.basemapStyleUrl) return;\n\n try {\n const response = await fetch(this.basemapStyleUrl);\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n const styleJson = await response.json();\n\n // Extract layer IDs from the basemap style\n if (styleJson && Array.isArray(styleJson.layers)) {\n this.basemapLayerIds = new Set(\n styleJson.layers.map((layer: { id: string }) => layer.id)\n );\n } else {\n this.basemapLayerIds = new Set();\n }\n } catch (error) {\n console.warn('Failed to fetch basemap style from URL:', this.basemapStyleUrl, error);\n throw error;\n }\n }\n\n /**\n * Called when the control is removed from the map\n */\n onRemove(): void {\n // Clean up custom layer registry subscription\n if (this.customLayerUnsubscribe) {\n this.customLayerUnsubscribe();\n this.customLayerUnsubscribe = null;\n }\n if (this.customLayerRegistry) {\n this.customLayerRegistry.destroy();\n this.customLayerRegistry = null;\n }\n\n // Remove resize event listeners\n if (this.resizeHandler) {\n window.removeEventListener('resize', this.resizeHandler);\n this.resizeHandler = null;\n }\n if (this.mapResizeHandler) {\n this.map.off('resize', this.mapResizeHandler);\n this.mapResizeHandler = null;\n }\n\n // Clean up context menu\n if (this.contextMenuEl) {\n this.contextMenuEl.parentNode?.removeChild(this.contextMenuEl);\n this.contextMenuEl = null;\n }\n\n // Clean up any active drag state\n this.cleanupDragState();\n\n // Remove panel from map container\n this.panel.parentNode?.removeChild(this.panel);\n\n // Remove button container from control stack\n this.container.parentNode?.removeChild(this.container);\n }\n\n /**\n * Auto-detect layers from the map and populate layerStates\n */\n private autoDetectLayers(): void {\n const style = this.map.getStyle();\n if (!style || !style.layers) {\n return;\n }\n\n // Get all layer IDs from the map\n const allLayerIds = style.layers.map(layer => layer.id);\n\n if (this.targetLayers.length === 0) {\n // No layers specified - auto-detect user-added layers vs background layers\n const userAddedLayers: string[] = [];\n const backgroundLayerIds: string[] = [];\n\n // Detection priority for INITIAL detection:\n // 1. basemapLayerIds (from basemapStyleUrl) - most reliable\n // 2. Source-based heuristics - works for layers added before OR after control\n // Note: initialLayerIds is NOT used here because it would incorrectly classify\n // user layers added BEFORE the control as basemap layers\n const useBasemapStyleDetection = this.basemapLayerIds !== null && this.basemapLayerIds.size > 0;\n\n // Identify which sources are user-added (for source-based heuristic detection)\n const userAddedSourceIds = useBasemapStyleDetection\n ? new Set<string>()\n : this.detectUserAddedSources();\n\n allLayerIds.forEach(layerId => {\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n // Skip drawn layers if excludeDrawnLayers is enabled\n if (this.excludeDrawnLayers && this.isDrawnLayer(layerId)) {\n backgroundLayerIds.push(layerId);\n return;\n }\n\n // Skip layers matching user-defined exclusion patterns\n if (this.isExcludedByPattern(layerId)) {\n backgroundLayerIds.push(layerId);\n return;\n }\n\n if (useBasemapStyleDetection) {\n // Use basemap style layer IDs for reliable detection\n if (this.basemapLayerIds!.has(layerId)) {\n // This layer is from the basemap style\n backgroundLayerIds.push(layerId);\n } else {\n // This layer is not in the basemap style - it's user-added\n userAddedLayers.push(layerId);\n }\n } else {\n // Use source-based heuristics\n // Check if this layer uses a user-added source\n const sourceId = (layer as any).source;\n if (sourceId && userAddedSourceIds.has(sourceId)) {\n userAddedLayers.push(layerId);\n } else {\n // Layer uses a basemap source or has no source (like background color layer)\n backgroundLayerIds.push(layerId);\n }\n }\n });\n\n // Add Background entry if there are background layers\n if (backgroundLayerIds.length > 0) {\n this.state.layerStates['Background'] = {\n visible: true,\n opacity: 1.0,\n name: 'Background'\n };\n }\n\n // Add entries for auto-detected user layers\n userAddedLayers.forEach(layerId => {\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n const visibility = this.map.getLayoutProperty(layerId, 'visibility');\n const isVisible = visibility !== 'none';\n const layerType = layer.type;\n const opacity = getLayerOpacity(this.map, layerId, layerType);\n const friendlyName = this.generateFriendlyName(layerId);\n\n this.state.layerStates[layerId] = {\n visible: isVisible,\n opacity: opacity,\n name: friendlyName\n };\n });\n } else {\n // Specific layers requested - separate into user layers + Background\n const userLayers: string[] = [];\n const basemapLayers: string[] = [];\n\n allLayerIds.forEach(layerId => {\n // Skip layers matching user-defined exclusion patterns\n if (this.isExcludedByPattern(layerId)) {\n basemapLayers.push(layerId);\n return;\n }\n\n if (this.targetLayers.includes(layerId)) {\n userLayers.push(layerId);\n } else {\n basemapLayers.push(layerId);\n }\n });\n\n // Add Background entry if there are basemap layers\n if (basemapLayers.length > 0) {\n this.state.layerStates['Background'] = {\n visible: true,\n opacity: 1.0,\n name: 'Background'\n };\n }\n\n // Add entries for user-specified layers\n userLayers.forEach(layerId => {\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n // Get visibility\n const visibility = this.map.getLayoutProperty(layerId, 'visibility');\n const isVisible = visibility !== 'none';\n\n // Get opacity\n const layerType = layer.type;\n const opacity = getLayerOpacity(this.map, layerId, layerType);\n\n // Generate friendly name from layer ID\n const friendlyName = this.generateFriendlyName(layerId);\n\n this.state.layerStates[layerId] = {\n visible: isVisible,\n opacity: opacity,\n name: friendlyName\n };\n });\n }\n\n // Detect custom layers from registry\n if (this.customLayerRegistry) {\n const customLayerIds = this.customLayerRegistry.getAllLayerIds();\n customLayerIds.forEach(layerId => {\n // Skip if already in state\n if (this.state.layerStates[layerId]) return;\n\n const customState = this.customLayerRegistry!.getLayerState(layerId);\n if (customState) {\n this.state.layerStates[layerId] = {\n visible: customState.visible,\n opacity: customState.opacity,\n name: customState.name,\n isCustomLayer: true,\n customLayerType: this.customLayerRegistry!.getSymbolType(layerId) || undefined,\n };\n }\n });\n }\n\n // Update targetLayers to include detected layers\n this.targetLayers = Object.keys(this.state.layerStates);\n }\n\n /**\n * Detect which sources are user-added (not from the basemap style)\n * User-added sources are identified by:\n * - Sources that were NOT present when the control was first added\n * - Additionally for sources added later:\n * - GeoJSON sources with inline data objects (not URL strings)\n * - Image, video, canvas sources\n * - Raster, raster-dem, vector sources from non-basemap tile providers\n */\n private detectUserAddedSources(): Set<string> {\n const userAddedSources = new Set<string>();\n const style = this.map.getStyle();\n if (!style || !style.sources) return userAddedSources;\n\n // First, detect the basemap's domain from sprite/glyphs URLs\n const basemapDomains = new Set<string>();\n\n // Known basemap providers\n const knownBasemapProviders = [\n 'demotiles.maplibre.org',\n 'api.maptiler.com',\n 'tiles.stadiamaps.com',\n 'api.mapbox.com',\n 'basemaps.cartocdn.com',\n 'tiles.mapbox.com',\n 'a.basemaps.cartocdn.com',\n 'b.basemaps.cartocdn.com',\n 'c.basemaps.cartocdn.com',\n 'd.basemaps.cartocdn.com',\n 'tiles.arcgis.com',\n 'server.arcgisonline.com',\n 'services.arcgisonline.com',\n ];\n\n // Detect domains from sprite/glyphs URLs (these are likely basemap domains)\n const spriteUrl = style.sprite as string | undefined;\n if (spriteUrl && typeof spriteUrl === 'string') {\n try {\n const url = new URL(spriteUrl);\n basemapDomains.add(url.hostname);\n } catch { /* ignore */ }\n }\n if (style.glyphs) {\n try {\n const url = new URL(style.glyphs.replace('{fontstack}', 'x').replace('{range}', 'x'));\n basemapDomains.add(url.hostname);\n } catch { /* ignore */ }\n }\n\n // Check each source\n for (const [sourceId, source] of Object.entries(style.sources)) {\n // If we have a snapshot of initial sources, use that as the primary check\n // Sources that existed when the control was added are basemap sources\n if (this.initialSourceIds && this.initialSourceIds.has(sourceId)) {\n // This source was present in the initial style, it's a basemap source\n continue;\n }\n\n const src = source as any;\n const sourceType = src.type;\n\n // Image, video, and canvas sources are always user-added\n if (sourceType === 'image' || sourceType === 'video' || sourceType === 'canvas') {\n userAddedSources.add(sourceId);\n continue;\n }\n\n // GeoJSON sources with inline data objects are user-added (if added after initial load)\n if (sourceType === 'geojson') {\n if (src.data && typeof src.data === 'object') {\n userAddedSources.add(sourceId);\n } else if (src.data && typeof src.data === 'string') {\n // GeoJSON with URL - check if it's from a basemap domain\n try {\n const url = new URL(src.data);\n const isBasemap = knownBasemapProviders.some(p => url.hostname.includes(p)) ||\n basemapDomains.has(url.hostname);\n if (!isBasemap) {\n userAddedSources.add(sourceId);\n }\n } catch {\n // Relative URL or invalid - assume user-added\n userAddedSources.add(sourceId);\n }\n }\n continue;\n }\n\n // Check tile URLs for raster, raster-dem, and vector sources\n if (sourceType === 'raster' || sourceType === 'raster-dem' || sourceType === 'vector') {\n const tileUrl = src.url || (src.tiles && src.tiles[0]) || '';\n if (tileUrl) {\n try {\n const url = new URL(tileUrl.replace(/{[^}]+}/g, '0'));\n const hostname = url.hostname;\n\n // Check if this is a known basemap provider\n const isKnownBasemap = knownBasemapProviders.some(provider =>\n hostname === provider || hostname.endsWith('.' + provider)\n );\n\n // Check if this matches detected basemap domains\n const matchesBasemapDomain = basemapDomains.has(hostname);\n\n // If not a basemap source, it's user-added\n if (!isKnownBasemap && !matchesBasemapDomain) {\n userAddedSources.add(sourceId);\n }\n } catch {\n // If URL parsing fails, assume it could be user-added\n userAddedSources.add(sourceId);\n }\n }\n }\n }\n\n return userAddedSources;\n }\n\n /**\n * Generate a friendly display name from a layer ID\n */\n private generateFriendlyName(layerId: string): string {\n // Remove common prefixes\n let name = layerId.replace(/^(layer[-_]?|gl[-_]?)/, '');\n\n // Replace dashes and underscores with spaces\n name = name.replace(/[-_]/g, ' ');\n\n // Capitalize first letter of each word\n name = name.replace(/\\b\\w/g, char => char.toUpperCase());\n\n return name || layerId; // Fallback to original if empty\n }\n\n /**\n * Check if a layer ID belongs to a drawing library (Geoman, Mapbox GL Draw, etc.)\n * @param layerId The layer ID to check\n * @returns true if the layer is from a drawing library\n */\n private isDrawnLayer(layerId: string): boolean {\n const drawnLayerPatterns = [\n /^gm[-_\\s]/i, // Geoman (gm-main-*, gm_*, Gm Temporary...)\n /^gl-draw[-_]/i, // Mapbox GL Draw\n /^mapbox-gl-draw[-_]/i, // Mapbox GL Draw alternative\n /^terra-draw[-_]/i, // Terra Draw\n /^maplibre-gl-draw[-_]/i, // MapLibre GL Draw\n /^draw[-_]layer/i, // Generic draw layers\n ];\n\n return drawnLayerPatterns.some(pattern => pattern.test(layerId));\n }\n\n /**\n * Convert wildcard patterns (e.g., '*-temp-*', 'debug-*') to RegExp objects\n */\n private wildcardPatternsToRegex(patterns: string[]): RegExp[] {\n return patterns.map(pattern => {\n // Escape special regex characters except *\n const escaped = pattern.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&');\n // Convert * to .* for wildcard matching\n const regexStr = escaped.replace(/\\*/g, '.*');\n return new RegExp(`^${regexStr}$`, 'i');\n });\n }\n\n /**\n * Check if a layer matches any of the user-defined exclusion patterns\n */\n private isExcludedByPattern(layerId: string): boolean {\n return this.excludeLayerPatterns.some(pattern => pattern.test(layerId));\n }\n\n /**\n * Create the main container element\n */\n private createContainer(): HTMLDivElement {\n const container = document.createElement('div');\n container.className = 'maplibregl-ctrl maplibregl-ctrl-group maplibregl-ctrl-layer-control';\n return container;\n }\n\n /**\n * Create the toggle button\n */\n private createToggleButton(): HTMLButtonElement {\n const button = document.createElement('button');\n button.type = 'button';\n button.title = 'Layer Control';\n button.setAttribute('aria-label', 'Layer Control');\n\n // Create layers icon (SVG)\n const icon = document.createElement('span');\n icon.className = 'layer-control-icon';\n icon.innerHTML =\n '<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\" ' +\n 'fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">' +\n '<polygon points=\"12 3 3 8.25 12 13.5 21 8.25 12 3\"></polygon>' +\n '<polyline points=\"3 12.75 12 18 21 12.75\"></polyline>' +\n '<polyline points=\"3 17.25 12 22 21 17.25\"></polyline>' +\n '</svg>';\n\n button.appendChild(icon);\n return button;\n }\n\n /**\n * Create the panel element\n */\n private createPanel(): HTMLDivElement {\n const panel = document.createElement('div');\n panel.className = 'layer-control-panel';\n\n // Set initial width and max height directly on the element\n panel.style.width = `${this.state.panelWidth}px`;\n panel.style.maxHeight = `${this.maxPanelHeight}px`;\n\n if (!this.state.collapsed) {\n panel.classList.add('expanded');\n }\n\n // Add header\n const header = this.createPanelHeader();\n panel.appendChild(header);\n\n // Add action buttons (Show All / Hide All)\n const actionButtons = this.createActionButtons();\n panel.appendChild(actionButtons);\n\n return panel;\n }\n\n /**\n * Detect which corner the control is positioned in\n * @returns The position: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'\n */\n private getControlPosition(): 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' {\n const parent = this.container.parentElement;\n if (!parent) return 'top-right'; // Default\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 'top-right'; // Default\n }\n\n /**\n * Update the panel position based on button location and control corner\n * Positions the panel next to the button, expanding in the appropriate direction\n */\n private updatePanelPosition(): void {\n if (!this.button || !this.panel || !this.mapContainer) return;\n\n const buttonRect = this.button.getBoundingClientRect();\n const mapRect = this.mapContainer.getBoundingClientRect();\n const position = this.getControlPosition();\n\n // Calculate button position relative to map container\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\n const panelGap = 5; // Gap between button and panel\n\n // Reset all positioning\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 // Panel expands down and to the right\n this.panel.style.top = `${buttonTop + buttonRect.height + panelGap}px`;\n this.panel.style.left = `${buttonLeft}px`;\n break;\n\n case 'top-right':\n // Panel expands down and to the left\n this.panel.style.top = `${buttonTop + buttonRect.height + panelGap}px`;\n this.panel.style.right = `${buttonRight}px`;\n break;\n\n case 'bottom-left':\n // Panel expands up and to the right\n this.panel.style.bottom = `${buttonBottom + buttonRect.height + panelGap}px`;\n this.panel.style.left = `${buttonLeft}px`;\n break;\n\n case 'bottom-right':\n // Panel expands up and to the left\n this.panel.style.bottom = `${buttonBottom + buttonRect.height + panelGap}px`;\n this.panel.style.right = `${buttonRight}px`;\n break;\n }\n }\n\n /**\n * Create action buttons for Show All / Hide All\n */\n private createActionButtons(): HTMLElement {\n const container = document.createElement('div');\n container.className = 'layer-control-actions';\n\n const showAllBtn = document.createElement('button');\n showAllBtn.type = 'button';\n showAllBtn.className = 'layer-control-action-btn';\n showAllBtn.textContent = 'Show All';\n showAllBtn.title = 'Show all layers';\n showAllBtn.addEventListener('click', () => this.setAllLayersVisibility(true));\n\n const hideAllBtn = document.createElement('button');\n hideAllBtn.type = 'button';\n hideAllBtn.className = 'layer-control-action-btn';\n hideAllBtn.textContent = 'Hide All';\n hideAllBtn.title = 'Hide all layers';\n hideAllBtn.addEventListener('click', () => this.setAllLayersVisibility(false));\n\n container.appendChild(showAllBtn);\n container.appendChild(hideAllBtn);\n\n return container;\n }\n\n /**\n * Set visibility of all layers\n */\n private setAllLayersVisibility(visible: boolean): void {\n Object.keys(this.state.layerStates).forEach(layerId => {\n // Use toggleLayerVisibility which handles both native and custom layers\n this.toggleLayerVisibility(layerId, visible);\n\n // Update checkbox in UI\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`);\n if (itemEl) {\n const checkbox = itemEl.querySelector('.layer-control-checkbox') as HTMLInputElement;\n if (checkbox) {\n checkbox.checked = visible;\n checkbox.indeterminate = false;\n }\n }\n });\n }\n\n /**\n * Create the panel header with title and width control\n */\n private createPanelHeader(): HTMLElement {\n const header = document.createElement('div');\n header.className = 'layer-control-panel-header';\n\n const title = document.createElement('span');\n title.className = 'layer-control-panel-title';\n title.textContent = 'Layers';\n header.appendChild(title);\n\n // Add width control\n const widthControl = this.createWidthControl();\n header.appendChild(widthControl);\n\n return header;\n }\n\n /**\n * Create the width control slider\n */\n private createWidthControl(): HTMLElement {\n const widthControl = document.createElement('label');\n widthControl.className = 'layer-control-width-control';\n widthControl.title = 'Adjust layer panel width';\n\n const widthLabel = document.createElement('span');\n widthLabel.textContent = 'Width';\n widthControl.appendChild(widthLabel);\n\n const widthSlider = document.createElement('div');\n widthSlider.className = 'layer-control-width-slider';\n widthSlider.setAttribute('role', 'slider');\n widthSlider.setAttribute('aria-valuemin', String(this.minPanelWidth));\n widthSlider.setAttribute('aria-valuemax', String(this.maxPanelWidth));\n widthSlider.setAttribute('aria-valuenow', String(this.state.panelWidth));\n widthSlider.setAttribute('aria-valuestep', '10');\n widthSlider.setAttribute('aria-label', 'Layer panel width');\n widthSlider.tabIndex = 0;\n\n const widthTrack = document.createElement('div');\n widthTrack.className = 'layer-control-width-track';\n const widthThumb = document.createElement('div');\n widthThumb.className = 'layer-control-width-thumb';\n\n widthSlider.appendChild(widthTrack);\n widthSlider.appendChild(widthThumb);\n\n this.widthSliderEl = widthSlider;\n this.widthThumbEl = widthThumb;\n\n // Add width value display\n const widthValue = document.createElement('span');\n widthValue.className = 'layer-control-width-value';\n this.widthValueEl = widthValue;\n\n widthControl.appendChild(widthSlider);\n widthControl.appendChild(widthValue);\n\n this.updateWidthDisplay();\n this.setupWidthSliderEvents(widthSlider);\n\n return widthControl;\n }\n\n /**\n * Setup event listeners for width slider\n */\n private setupWidthSliderEvents(widthSlider: HTMLElement): void {\n // Pointer events for dragging\n widthSlider.addEventListener('pointerdown', (event) => {\n event.preventDefault();\n const rect = widthSlider.getBoundingClientRect();\n this.widthDragRectWidth = rect.width || 1;\n this.widthDragStartX = event.clientX;\n this.widthDragStartWidth = this.state.panelWidth;\n this.isWidthSliderActive = true;\n widthSlider.setPointerCapture(event.pointerId);\n this.updateWidthFromPointer(event, true);\n });\n\n widthSlider.addEventListener('pointermove', (event) => {\n if (!this.isWidthSliderActive) return;\n this.updateWidthFromPointer(event);\n });\n\n const endPointerDrag = (event: PointerEvent) => {\n if (!this.isWidthSliderActive) return;\n if (event.pointerId !== undefined) {\n try {\n widthSlider.releasePointerCapture(event.pointerId);\n } catch (error) {\n // Ignore release errors\n }\n }\n this.isWidthSliderActive = false;\n this.widthDragRectWidth = null;\n this.widthDragStartX = null;\n this.widthDragStartWidth = null;\n this.updateWidthDisplay();\n };\n\n widthSlider.addEventListener('pointerup', endPointerDrag);\n widthSlider.addEventListener('pointercancel', endPointerDrag);\n widthSlider.addEventListener('lostpointercapture', endPointerDrag);\n\n // Keyboard navigation\n widthSlider.addEventListener('keydown', (event) => {\n let handled = true;\n const step = event.shiftKey ? 20 : 10;\n\n switch (event.key) {\n case 'ArrowLeft':\n case 'ArrowDown':\n this.applyPanelWidth(this.state.panelWidth - step, true);\n break;\n case 'ArrowRight':\n case 'ArrowUp':\n this.applyPanelWidth(this.state.panelWidth + step, true);\n break;\n case 'Home':\n this.applyPanelWidth(this.minPanelWidth, true);\n break;\n case 'End':\n this.applyPanelWidth(this.maxPanelWidth, true);\n break;\n case 'PageUp':\n this.applyPanelWidth(this.state.panelWidth + 50, true);\n break;\n case 'PageDown':\n this.applyPanelWidth(this.state.panelWidth - 50, true);\n break;\n default:\n handled = false;\n }\n\n if (handled) {\n event.preventDefault();\n this.updateWidthDisplay();\n }\n });\n }\n\n /**\n * Update panel width from pointer event\n */\n private updateWidthFromPointer(event: PointerEvent, resetBaseline = false): void {\n if (!this.widthSliderEl) return;\n\n const sliderWidth = this.widthDragRectWidth || this.widthSliderEl.getBoundingClientRect().width || 1;\n const widthRange = this.maxPanelWidth - this.minPanelWidth;\n\n let width: number;\n if (resetBaseline) {\n const rect = this.widthSliderEl.getBoundingClientRect();\n const relative = rect.width > 0 ? (event.clientX - rect.left) / rect.width : 0;\n const clampedRatio = Math.min(1, Math.max(0, relative));\n width = this.minPanelWidth + clampedRatio * widthRange;\n this.widthDragStartWidth = width;\n this.widthDragStartX = event.clientX;\n } else {\n const delta = event.clientX - (this.widthDragStartX || event.clientX);\n width = (this.widthDragStartWidth || this.state.panelWidth) + (delta / sliderWidth) * widthRange;\n }\n\n this.applyPanelWidth(width, this.isWidthSliderActive);\n }\n\n /**\n * Apply panel width (clamped to min/max)\n */\n private applyPanelWidth(width: number, immediate = false): void {\n const clamped = Math.round(Math.min(this.maxPanelWidth, Math.max(this.minPanelWidth, width)));\n\n const applyWidth = () => {\n this.state.panelWidth = clamped;\n const px = `${clamped}px`;\n this.panel.style.width = px;\n this.updateWidthDisplay();\n };\n\n if (immediate) {\n applyWidth();\n return;\n }\n\n if (this.widthFrame) {\n cancelAnimationFrame(this.widthFrame);\n }\n this.widthFrame = requestAnimationFrame(() => {\n applyWidth();\n this.widthFrame = null;\n });\n }\n\n /**\n * Update width display (value label and thumb position)\n */\n private updateWidthDisplay(): void {\n if (this.widthValueEl) {\n this.widthValueEl.textContent = `${this.state.panelWidth}px`;\n }\n if (this.widthSliderEl) {\n this.widthSliderEl.setAttribute('aria-valuenow', String(this.state.panelWidth));\n const ratio = (this.state.panelWidth - this.minPanelWidth) / (this.maxPanelWidth - this.minPanelWidth || 1);\n if (this.widthThumbEl) {\n const sliderWidth = this.widthSliderEl.clientWidth;\n // If element not yet rendered, defer the update\n if (sliderWidth === 0) {\n requestAnimationFrame(() => this.updateWidthDisplay());\n return;\n }\n const thumbWidth = this.widthThumbEl.offsetWidth || 14;\n const padding = 16;\n const available = Math.max(0, sliderWidth - padding - thumbWidth);\n const clampedRatio = Math.min(1, Math.max(0, ratio));\n const leftPx = 8 + available * clampedRatio;\n this.widthThumbEl.style.left = `${leftPx}px`;\n }\n }\n }\n\n /**\n * Setup main event listeners\n */\n private setupEventListeners(): void {\n // Toggle button click\n this.button.addEventListener('click', () => this.toggle());\n\n // Click outside to close panel and context menu\n document.addEventListener('click', (e) => {\n const target = e.target as Node;\n\n // Close context menu if clicking outside of it\n if (this.contextMenuEl && this.state.contextMenu.visible) {\n if (!this.contextMenuEl.contains(target)) {\n this.hideContextMenu();\n }\n }\n\n // Close panel if clicking outside\n if (!this.container.contains(target) && !this.panel.contains(target)) {\n this.collapse();\n }\n });\n\n // Update panel position on window resize\n this.resizeHandler = () => {\n if (!this.state.collapsed) {\n this.updatePanelPosition();\n }\n };\n window.addEventListener('resize', this.resizeHandler);\n\n // Update panel position on map resize (e.g., sidebar toggle)\n this.mapResizeHandler = () => {\n if (!this.state.collapsed) {\n this.updatePanelPosition();\n }\n };\n this.map.on('resize', this.mapResizeHandler);\n\n // Listen for map layer changes\n this.setupLayerChangeListeners();\n }\n\n /**\n * Setup listeners for map layer changes\n */\n private setupLayerChangeListeners(): void {\n this.map.on('styledata', () => {\n setTimeout(() => {\n this.updateLayerStatesFromMap();\n this.checkForNewLayers();\n }, 100);\n });\n\n this.map.on('data', (e) => {\n if (e.sourceDataType === 'content') {\n setTimeout(() => {\n this.updateLayerStatesFromMap();\n this.checkForNewLayers();\n }, 100);\n }\n });\n\n this.map.on('sourcedata', (e) => {\n if (e.sourceDataType === 'metadata') {\n setTimeout(() => {\n this.checkForNewLayers();\n }, 150);\n }\n });\n\n // Subscribe to custom layer registry changes\n if (this.customLayerRegistry) {\n this.customLayerUnsubscribe = this.customLayerRegistry.onChange(() => {\n setTimeout(() => this.checkForNewLayers(), 100);\n });\n }\n }\n\n /**\n * Toggle panel expanded/collapsed state\n */\n private toggle(): void {\n if (this.state.collapsed) {\n this.expand();\n } else {\n this.collapse();\n }\n }\n\n /**\n * Expand the panel\n */\n private expand(): void {\n this.state.collapsed = false;\n this.panel.classList.add('expanded');\n this.updatePanelPosition();\n }\n\n /**\n * Collapse the panel\n */\n private collapse(): void {\n this.state.collapsed = true;\n this.panel.classList.remove('expanded');\n }\n\n /**\n * Build layer items (called initially and when layers change)\n */\n private buildLayerItems(): void {\n // Clear existing items\n const existingItems = this.panel.querySelectorAll('.layer-control-item');\n existingItems.forEach(item => item.remove());\n this.styleEditors.clear();\n\n // Add items for all layers in our state\n Object.entries(this.state.layerStates).forEach(([layerId, state]) => {\n if (this.targetLayers.length === 0 || this.targetLayers.includes(layerId)) {\n this.addLayerItem(layerId, state);\n }\n });\n }\n\n /**\n * Add a single layer item to the panel\n */\n private addLayerItem(layerId: string, state: LayerState): void {\n const item = document.createElement('div');\n item.className = 'layer-control-item';\n item.setAttribute('data-layer-id', layerId);\n\n const row = document.createElement('div');\n row.className = 'layer-control-row';\n\n // Add drag handle (disabled for Background layer for alignment)\n if (this.enableDragAndDrop) {\n if (layerId === 'Background') {\n const disabledHandle = this.createDisabledDragHandle();\n row.appendChild(disabledHandle);\n } else {\n const dragHandle = this.createDragHandle(layerId);\n row.appendChild(dragHandle);\n }\n }\n\n // Visibility checkbox\n const checkbox = document.createElement('input');\n checkbox.type = 'checkbox';\n checkbox.className = 'layer-control-checkbox';\n checkbox.checked = state.visible;\n checkbox.addEventListener('change', () => {\n this.toggleLayerVisibility(layerId, checkbox.checked);\n });\n\n // Layer name - use custom name if set\n const displayName = this.state.customLayerNames.get(layerId) || state.name || layerId;\n const name = document.createElement('span');\n name.className = 'layer-control-name';\n name.textContent = displayName;\n name.title = displayName;\n\n row.appendChild(checkbox);\n\n // Add layer symbol (if enabled)\n if (this.showLayerSymbol) {\n if (layerId === 'Background') {\n // Special stacked layers symbol for background group\n const symbol = this.createBackgroundGroupSymbol();\n row.appendChild(symbol);\n } else {\n const symbol = this.createLayerSymbol(layerId);\n if (symbol) {\n row.appendChild(symbol);\n }\n }\n }\n\n row.appendChild(name);\n\n // Opacity slider (conditionally shown)\n if (this.showOpacitySlider) {\n const opacity = document.createElement('input');\n opacity.type = 'range';\n opacity.className = 'layer-control-opacity';\n opacity.min = '0';\n opacity.max = '1';\n opacity.step = '0.01';\n opacity.value = String(state.opacity);\n opacity.title = `Opacity: ${Math.round(state.opacity * 100)}%`;\n\n // Handle slider interaction tracking\n opacity.addEventListener('mousedown', () => {\n this.state.userInteractingWithSlider = true;\n });\n opacity.addEventListener('mouseup', () => {\n this.state.userInteractingWithSlider = false;\n });\n\n opacity.addEventListener('input', () => {\n this.changeLayerOpacity(layerId, parseFloat(opacity.value));\n opacity.title = `Opacity: ${Math.round(parseFloat(opacity.value) * 100)}%`;\n });\n\n row.appendChild(opacity);\n }\n\n // Style button for regular layers, legend button for Background\n if (this.showStyleEditor) {\n if (layerId === 'Background') {\n const legendButton = this.createBackgroundLegendButton();\n row.appendChild(legendButton);\n } else {\n const styleButton = this.createStyleButton(layerId);\n if (styleButton) {\n row.appendChild(styleButton);\n }\n }\n }\n\n item.appendChild(row);\n\n // Add context menu event listener (skip for Background layer)\n if (this.enableContextMenu && layerId !== 'Background') {\n row.addEventListener('contextmenu', (e) => {\n e.preventDefault();\n e.stopPropagation();\n this.showContextMenu(layerId, e.clientX, e.clientY);\n });\n }\n\n this.panel.appendChild(item);\n }\n\n /**\n * Create a symbol element for a layer\n * @param layerId The layer ID\n * @returns The symbol HTML element, or null if layer not found\n */\n private createLayerSymbol(layerId: string): HTMLElement | null {\n // Check if it's a custom layer first\n const layerState = this.state.layerStates[layerId];\n if (layerState?.isCustomLayer) {\n const symbolType = layerState.customLayerType || 'custom-raster';\n // Use a default color for custom layers\n const color = '#4a90d9';\n const svgMarkup = createLayerSymbolSVG(symbolType, color);\n\n const symbolContainer = document.createElement('span');\n symbolContainer.className = 'layer-control-symbol';\n symbolContainer.innerHTML = svgMarkup;\n symbolContainer.title = `Layer type: ${symbolType}`;\n\n return symbolContainer;\n }\n\n // Fall back to MapLibre layer\n const layer = this.map.getLayer(layerId);\n if (!layer) return null;\n\n const layerType = layer.type;\n const color = getLayerColor(this.map, layerId, layerType);\n const svgMarkup = createLayerSymbolSVG(layerType, color);\n\n const symbolContainer = document.createElement('span');\n symbolContainer.className = 'layer-control-symbol';\n symbolContainer.innerHTML = svgMarkup;\n symbolContainer.title = `Layer type: ${layerType}`;\n\n return symbolContainer;\n }\n\n /**\n * Create a symbol element for a background layer\n * @param layer The layer specification\n * @returns The symbol HTML element\n */\n private createBackgroundLayerSymbol(layer: LayerSpecification): HTMLElement {\n const color = getLayerColorFromSpec(layer);\n const svgMarkup = createLayerSymbolSVG(layer.type, color, { size: 14 });\n\n const symbolContainer = document.createElement('span');\n symbolContainer.className = 'background-legend-layer-symbol';\n symbolContainer.innerHTML = svgMarkup;\n symbolContainer.title = `Layer type: ${layer.type}`;\n\n return symbolContainer;\n }\n\n /**\n * Create a symbol element for the Background layer group\n * Shows a stacked layers icon to represent multiple background layers\n * @returns The symbol HTML element\n */\n private createBackgroundGroupSymbol(): HTMLElement {\n const svgMarkup = createBackgroundGroupSymbolSVG(16);\n\n const symbolContainer = document.createElement('span');\n symbolContainer.className = 'layer-control-symbol';\n symbolContainer.innerHTML = svgMarkup;\n symbolContainer.title = 'Background layers';\n\n return symbolContainer;\n }\n\n /**\n * Toggle layer visibility\n */\n private toggleLayerVisibility(layerId: string, visible: boolean): void {\n // Handle Background layer group\n if (layerId === 'Background') {\n this.toggleBackgroundVisibility(visible);\n return;\n }\n\n // Set flag to prevent checkForNewLayers from running during visibility change\n this.state.isStyleOperationInProgress = true;\n\n // Update local state\n if (this.state.layerStates[layerId]) {\n this.state.layerStates[layerId].visible = visible;\n }\n\n // Try custom layer registry first\n if (this.customLayerRegistry?.setVisibility(layerId, visible)) {\n // Clear flag after a delay for custom layers\n setTimeout(() => {\n this.state.isStyleOperationInProgress = false;\n }, 200);\n return;\n }\n\n // Fallback to native MapLibre layer\n this.map.setLayoutProperty(layerId, 'visibility', visible ? 'visible' : 'none');\n\n // Clear flag after styledata events have settled\n setTimeout(() => {\n this.state.isStyleOperationInProgress = false;\n }, 200);\n }\n\n /**\n * Change layer opacity\n */\n private changeLayerOpacity(layerId: string, opacity: number): void {\n // Handle Background layer group\n if (layerId === 'Background') {\n this.changeBackgroundOpacity(opacity);\n return;\n }\n\n // Set flag to prevent checkForNewLayers from running during opacity change\n this.state.isStyleOperationInProgress = true;\n\n // Update local state\n if (this.state.layerStates[layerId]) {\n this.state.layerStates[layerId].opacity = opacity;\n }\n\n // Try custom layer registry first\n if (this.customLayerRegistry?.setOpacity(layerId, opacity)) {\n // Clear flag after a delay for custom layers\n setTimeout(() => {\n this.state.isStyleOperationInProgress = false;\n }, 200);\n return;\n }\n\n // Fallback to native MapLibre layer\n const layerType = getLayerType(this.map, layerId);\n if (layerType) {\n setLayerOpacity(this.map, layerId, layerType, opacity);\n }\n\n // Clear flag after styledata events have settled\n setTimeout(() => {\n this.state.isStyleOperationInProgress = false;\n }, 200);\n }\n\n /**\n * Check if a layer is a user-added layer (vs basemap layer)\n * Used primarily for the background legend to determine which layers are background\n */\n private isUserAddedLayer(layerId: string): boolean {\n // If this layer is in our state (and not Background), it's user-added\n if (this.state.layerStates[layerId] !== undefined && layerId !== 'Background') {\n return true;\n }\n\n // If we have basemapLayerIds (from basemapStyleUrl), check if the layer is NOT in the basemap\n if (this.basemapLayerIds !== null && this.basemapLayerIds.size > 0) {\n return !this.basemapLayerIds.has(layerId);\n }\n\n // For layers not in our state, check if the layer was added after control initialization\n // or uses a user-added source\n if (this.initialLayerIds !== null && !this.initialLayerIds.has(layerId)) {\n // Layer was added after control - it's user-added\n return true;\n }\n\n // Check source-based heuristics\n const layer = this.map.getLayer(layerId);\n if (layer) {\n const sourceId = (layer as any).source;\n if (sourceId) {\n const userAddedSourceIds = this.detectUserAddedSources();\n return userAddedSourceIds.has(sourceId);\n }\n }\n\n return false;\n }\n\n /**\n * Toggle visibility for all background layers (basemap layers)\n */\n private toggleBackgroundVisibility(visible: boolean): void {\n // Update local state\n if (this.state.layerStates['Background']) {\n this.state.layerStates['Background'].visible = visible;\n }\n\n // Apply to all basemap layers (layers not in layerStates)\n const styleLayers = this.map.getStyle().layers || [];\n styleLayers.forEach(layer => {\n if (!this.isUserAddedLayer(layer.id)) {\n // Update visibility cache\n this.state.backgroundLayerVisibility.set(layer.id, visible);\n this.map.setLayoutProperty(layer.id, 'visibility', visible ? 'visible' : 'none');\n }\n });\n\n // Update legend panel checkboxes if open\n if (this.state.backgroundLegendOpen) {\n const legendPanel = this.panel.querySelector('.layer-control-background-legend');\n if (legendPanel) {\n const checkboxes = legendPanel.querySelectorAll('.background-legend-checkbox') as NodeListOf<HTMLInputElement>;\n checkboxes.forEach(checkbox => {\n checkbox.checked = visible;\n });\n }\n }\n }\n\n /**\n * Change opacity for all background layers (basemap layers)\n */\n private changeBackgroundOpacity(opacity: number): void {\n // Update local state\n if (this.state.layerStates['Background']) {\n this.state.layerStates['Background'].opacity = opacity;\n }\n\n // Apply to all basemap layers (layers not in layerStates)\n const styleLayers = this.map.getStyle().layers || [];\n styleLayers.forEach(styleLayer => {\n if (!this.isUserAddedLayer(styleLayer.id)) {\n const layerType = getLayerType(this.map, styleLayer.id);\n if (layerType) {\n setLayerOpacity(this.map, styleLayer.id, layerType, opacity);\n }\n }\n });\n }\n\n // ===== Background Legend Methods =====\n\n /**\n * Create legend button for Background layer\n */\n private createBackgroundLegendButton(): HTMLButtonElement {\n const button = document.createElement('button');\n button.className = 'layer-control-style-button layer-control-background-legend-button';\n button.innerHTML = '⚙'; // Gear icon (same as style button)\n button.title = 'Show background layer details';\n button.setAttribute('aria-label', 'Show background layer visibility controls');\n button.setAttribute('aria-expanded', String(this.state.backgroundLegendOpen));\n\n button.addEventListener('click', (e) => {\n e.stopPropagation();\n this.toggleBackgroundLegend();\n });\n\n return button;\n }\n\n /**\n * Toggle background legend panel visibility\n */\n private toggleBackgroundLegend(): void {\n if (this.state.backgroundLegendOpen) {\n this.closeBackgroundLegend();\n } else {\n this.openBackgroundLegend();\n }\n }\n\n /**\n * Open background legend panel\n */\n private openBackgroundLegend(): void {\n // Close any open style editor first\n if (this.state.activeStyleEditor) {\n this.closeStyleEditor(this.state.activeStyleEditor);\n }\n\n const itemEl = this.panel.querySelector('[data-layer-id=\"Background\"]');\n if (!itemEl) return;\n\n // Check if panel already exists\n let legendPanel = itemEl.querySelector('.layer-control-background-legend');\n if (legendPanel) {\n // Refresh the list\n const layerList = legendPanel.querySelector('.background-legend-layer-list');\n if (layerList) {\n this.populateBackgroundLayerList(layerList as HTMLElement);\n }\n } else {\n // Create new panel\n legendPanel = this.createBackgroundLegendPanel();\n itemEl.appendChild(legendPanel);\n }\n\n this.state.backgroundLegendOpen = true;\n\n // Update button aria state\n const button = itemEl.querySelector('.layer-control-background-legend-button');\n if (button) {\n button.setAttribute('aria-expanded', 'true');\n button.classList.add('active');\n }\n\n // Scroll into view\n setTimeout(() => {\n legendPanel?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }, 50);\n }\n\n /**\n * Close background legend panel\n */\n private closeBackgroundLegend(): void {\n const itemEl = this.panel.querySelector('[data-layer-id=\"Background\"]');\n if (!itemEl) return;\n\n const legendPanel = itemEl.querySelector('.layer-control-background-legend');\n if (legendPanel) {\n legendPanel.remove();\n }\n\n this.state.backgroundLegendOpen = false;\n\n // Update button aria state\n const button = itemEl.querySelector('.layer-control-background-legend-button');\n if (button) {\n button.setAttribute('aria-expanded', 'false');\n button.classList.remove('active');\n }\n }\n\n /**\n * Create the background legend panel with individual layer controls\n */\n private createBackgroundLegendPanel(): HTMLDivElement {\n const panel = document.createElement('div');\n panel.className = 'layer-control-background-legend';\n\n // Header\n const header = document.createElement('div');\n header.className = 'background-legend-header';\n\n const title = document.createElement('span');\n title.className = 'background-legend-title';\n title.textContent = 'Background Layers';\n\n const closeBtn = document.createElement('button');\n closeBtn.className = 'background-legend-close';\n closeBtn.innerHTML = '×';\n closeBtn.title = 'Close';\n closeBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.closeBackgroundLegend();\n });\n\n header.appendChild(title);\n header.appendChild(closeBtn);\n\n // Quick actions row\n const actionsRow = document.createElement('div');\n actionsRow.className = 'background-legend-actions';\n\n const showAllBtn = document.createElement('button');\n showAllBtn.className = 'background-legend-action-btn';\n showAllBtn.textContent = 'Show All';\n showAllBtn.addEventListener('click', () => this.setAllBackgroundLayersVisibility(true));\n\n const hideAllBtn = document.createElement('button');\n hideAllBtn.className = 'background-legend-action-btn';\n hideAllBtn.textContent = 'Hide All';\n hideAllBtn.addEventListener('click', () => this.setAllBackgroundLayersVisibility(false));\n\n actionsRow.appendChild(showAllBtn);\n actionsRow.appendChild(hideAllBtn);\n\n // Filter row - \"Only rendered\" checkbox\n const filterRow = document.createElement('div');\n filterRow.className = 'background-legend-filter';\n\n const filterCheckbox = document.createElement('input');\n filterCheckbox.type = 'checkbox';\n filterCheckbox.className = 'background-legend-filter-checkbox';\n filterCheckbox.id = 'background-legend-only-rendered';\n filterCheckbox.checked = this.state.onlyRenderedFilter;\n filterCheckbox.addEventListener('change', () => {\n this.state.onlyRenderedFilter = filterCheckbox.checked;\n const layerList = panel.querySelector('.background-legend-layer-list');\n if (layerList) {\n this.populateBackgroundLayerList(layerList as HTMLElement);\n }\n });\n\n const filterLabel = document.createElement('label');\n filterLabel.className = 'background-legend-filter-label';\n filterLabel.htmlFor = 'background-legend-only-rendered';\n filterLabel.textContent = 'Only rendered';\n\n filterRow.appendChild(filterCheckbox);\n filterRow.appendChild(filterLabel);\n\n // Layer list container (scrollable)\n const layerList = document.createElement('div');\n layerList.className = 'background-legend-layer-list';\n\n // Populate with background layers\n this.populateBackgroundLayerList(layerList);\n\n panel.appendChild(header);\n panel.appendChild(actionsRow);\n panel.appendChild(filterRow);\n panel.appendChild(layerList);\n\n return panel;\n }\n\n /**\n * Check if a layer is currently rendered in the map viewport\n */\n private isLayerRendered(layerId: string): boolean {\n try {\n const layer = this.map.getLayer(layerId);\n if (!layer) return false;\n\n // Check if layer is visible first\n const visibility = this.map.getLayoutProperty(layerId, 'visibility');\n if (visibility === 'none') return false;\n\n // For raster layers, check if tiles are loaded\n if (layer.type === 'raster' || layer.type === 'hillshade') {\n // Raster layers are considered rendered if visible\n return true;\n }\n\n // For background layers (solid color), they're always rendered if visible\n if (layer.type === 'background') {\n return true;\n }\n\n // For vector layers, use queryRenderedFeatures to check if any features are visible\n const features = this.map.queryRenderedFeatures({ layers: [layerId] });\n return features.length > 0;\n } catch (error) {\n // If query fails, assume layer is rendered if we can see it\n return true;\n }\n }\n\n /**\n * Populate the background layer list with individual layers\n */\n private populateBackgroundLayerList(container: HTMLElement): void {\n container.innerHTML = ''; // Clear existing\n\n const styleLayers = this.map.getStyle().layers || [];\n\n styleLayers.forEach(layer => {\n if (!this.isUserAddedLayer(layer.id)) {\n // Skip drawn layers if excludeDrawnLayers is enabled\n if (this.excludeDrawnLayers && this.isDrawnLayer(layer.id)) {\n return;\n }\n\n // Skip layers matching user-defined exclusion patterns\n if (this.isExcludedByPattern(layer.id)) {\n return;\n }\n\n // If \"Only rendered\" filter is enabled, skip layers that aren't rendered\n if (this.state.onlyRenderedFilter && !this.isLayerRendered(layer.id)) {\n return;\n }\n\n // This is a background layer\n const layerRow = document.createElement('div');\n layerRow.className = 'background-legend-layer-row';\n layerRow.setAttribute('data-background-layer-id', layer.id);\n\n // Checkbox\n const checkbox = document.createElement('input');\n checkbox.type = 'checkbox';\n checkbox.className = 'background-legend-checkbox';\n\n // Get visibility from map or cache\n const visibility = this.map.getLayoutProperty(layer.id, 'visibility');\n const isVisible = visibility !== 'none';\n checkbox.checked = isVisible;\n\n // Update cache\n this.state.backgroundLayerVisibility.set(layer.id, isVisible);\n\n checkbox.addEventListener('change', () => {\n this.toggleIndividualBackgroundLayer(layer.id, checkbox.checked);\n });\n\n // Layer name\n const name = document.createElement('span');\n name.className = 'background-legend-layer-name';\n name.textContent = this.generateFriendlyName(layer.id);\n name.title = layer.id; // Show full ID on hover\n\n // Layer type indicator\n const typeIndicator = document.createElement('span');\n typeIndicator.className = 'background-legend-layer-type';\n typeIndicator.textContent = layer.type;\n\n layerRow.appendChild(checkbox);\n\n // Add layer symbol (if enabled)\n if (this.showLayerSymbol) {\n const symbol = this.createBackgroundLayerSymbol(layer);\n if (symbol) {\n layerRow.appendChild(symbol);\n }\n }\n\n layerRow.appendChild(name);\n layerRow.appendChild(typeIndicator);\n container.appendChild(layerRow);\n }\n });\n\n // Show message if no background layers\n if (container.children.length === 0) {\n const emptyMsg = document.createElement('p');\n emptyMsg.className = 'background-legend-empty';\n emptyMsg.textContent = this.state.onlyRenderedFilter\n ? 'No rendered layers in current view.'\n : 'No background layers found.';\n container.appendChild(emptyMsg);\n }\n }\n\n /**\n * Toggle visibility of an individual background layer\n */\n private toggleIndividualBackgroundLayer(layerId: string, visible: boolean): void {\n // Update visibility cache\n this.state.backgroundLayerVisibility.set(layerId, visible);\n\n // Apply to map\n this.map.setLayoutProperty(layerId, 'visibility', visible ? 'visible' : 'none');\n\n // Update the main Background checkbox state\n this.updateBackgroundCheckboxState();\n }\n\n /**\n * Set visibility for all background layers\n */\n private setAllBackgroundLayersVisibility(visible: boolean): void {\n const styleLayers = this.map.getStyle().layers || [];\n\n styleLayers.forEach(layer => {\n if (!this.isUserAddedLayer(layer.id)) {\n this.state.backgroundLayerVisibility.set(layer.id, visible);\n this.map.setLayoutProperty(layer.id, 'visibility', visible ? 'visible' : 'none');\n }\n });\n\n // Update checkboxes in the legend panel\n const legendPanel = this.panel.querySelector('.layer-control-background-legend');\n if (legendPanel) {\n const checkboxes = legendPanel.querySelectorAll('.background-legend-checkbox') as NodeListOf<HTMLInputElement>;\n checkboxes.forEach(checkbox => {\n checkbox.checked = visible;\n });\n }\n\n // Update main Background checkbox\n this.updateBackgroundCheckboxState();\n }\n\n /**\n * Update the main Background checkbox based on individual layer states\n */\n private updateBackgroundCheckboxState(): void {\n const styleLayers = this.map.getStyle().layers || [];\n let anyVisible = false;\n let allVisible = true;\n\n styleLayers.forEach(layer => {\n if (!this.isUserAddedLayer(layer.id)) {\n const visible = this.state.backgroundLayerVisibility.get(layer.id);\n if (visible === true) anyVisible = true;\n if (visible === false) allVisible = false;\n }\n });\n\n // Update main checkbox\n const backgroundItem = this.panel.querySelector('[data-layer-id=\"Background\"]');\n if (backgroundItem) {\n const checkbox = backgroundItem.querySelector('.layer-control-checkbox') as HTMLInputElement;\n if (checkbox) {\n checkbox.checked = anyVisible;\n checkbox.indeterminate = anyVisible && !allVisible;\n }\n }\n\n // Update layerState\n if (this.state.layerStates['Background']) {\n this.state.layerStates['Background'].visible = anyVisible;\n }\n }\n\n /**\n * Create style button for a layer\n */\n private createStyleButton(layerId: string): HTMLButtonElement | null {\n // Don't create button for Background layer\n if (layerId === 'Background') {\n return null;\n }\n\n const layerState = this.state.layerStates[layerId];\n const isCustomLayer = layerState?.isCustomLayer === true;\n\n const button = document.createElement('button');\n button.className = 'layer-control-style-button';\n button.innerHTML = '⚙'; // Gear icon\n\n if (isCustomLayer) {\n // Custom layers don't support style editing - show info panel instead\n button.title = 'Layer info (style editing not available)';\n button.setAttribute('aria-label', `Layer info for ${layerId}`);\n } else {\n button.title = 'Edit layer style';\n button.setAttribute('aria-label', `Edit style for ${layerId}`);\n }\n\n button.addEventListener('click', (e) => {\n e.stopPropagation();\n this.toggleStyleEditor(layerId);\n });\n\n return button;\n }\n\n /**\n * Toggle style editor for a layer\n */\n private toggleStyleEditor(layerId: string): void {\n // If this editor is already open, close it\n if (this.state.activeStyleEditor === layerId) {\n this.closeStyleEditor(layerId);\n return;\n }\n\n // Close any other open editor\n if (this.state.activeStyleEditor) {\n this.closeStyleEditor(this.state.activeStyleEditor);\n }\n\n // Open this editor\n this.openStyleEditor(layerId);\n }\n\n /**\n * Open style editor for a layer\n */\n private openStyleEditor(layerId: string): void {\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`);\n if (!itemEl) return;\n\n // Check if this is a custom layer\n const layerState = this.state.layerStates[layerId];\n if (layerState?.isCustomLayer) {\n // Show info message for custom layers\n const editor = this.createCustomLayerInfoPanel(layerId);\n itemEl.appendChild(editor);\n this.styleEditors.set(layerId, editor);\n this.state.activeStyleEditor = layerId;\n\n // Scroll into view\n setTimeout(() => {\n editor.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }, 50);\n return;\n }\n\n // Cache original style if not already cached\n if (!this.state.originalStyles.has(layerId)) {\n const layer = this.map.getLayer(layerId);\n if (layer) {\n cacheOriginalLayerStyle(this.map, layerId, this.state.originalStyles);\n }\n }\n\n // Create style editor UI\n const editor = this.createStyleEditor(layerId);\n if (!editor) return;\n\n itemEl.appendChild(editor);\n this.styleEditors.set(layerId, editor);\n this.state.activeStyleEditor = layerId;\n\n // Scroll editor into view\n setTimeout(() => {\n editor.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }, 50);\n }\n\n /**\n * Create info panel for custom layers (style editing not supported)\n */\n private createCustomLayerInfoPanel(layerId: string): HTMLDivElement {\n const editor = document.createElement('div');\n editor.className = 'layer-control-style-editor layer-control-custom-info';\n\n // Header\n const header = document.createElement('div');\n header.className = 'style-editor-header';\n\n const title = document.createElement('span');\n title.className = 'style-editor-title';\n title.textContent = 'Layer Info';\n\n const closeBtn = document.createElement('button');\n closeBtn.className = 'style-editor-close';\n closeBtn.innerHTML = '×';\n closeBtn.title = 'Close';\n closeBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.closeStyleEditor(layerId);\n });\n\n header.appendChild(title);\n header.appendChild(closeBtn);\n\n // Info content\n const content = document.createElement('div');\n content.className = 'style-editor-controls';\n\n const infoText = document.createElement('p');\n infoText.className = 'layer-control-custom-info-text';\n infoText.textContent = `This is a custom layer. Style editing is not available for this layer type. Use the visibility toggle and opacity slider to control the layer.`;\n\n content.appendChild(infoText);\n\n // Close button\n const actions = document.createElement('div');\n actions.className = 'style-editor-actions';\n\n const closeActionBtn = document.createElement('button');\n closeActionBtn.className = 'style-editor-button style-editor-button-close';\n closeActionBtn.textContent = 'Close';\n closeActionBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.closeStyleEditor(layerId);\n });\n\n actions.appendChild(closeActionBtn);\n\n editor.appendChild(header);\n editor.appendChild(content);\n editor.appendChild(actions);\n\n return editor;\n }\n\n /**\n * Close style editor for a layer\n */\n private closeStyleEditor(layerId: string): void {\n const editor = this.styleEditors.get(layerId);\n if (editor) {\n editor.remove();\n this.styleEditors.delete(layerId);\n }\n\n if (this.state.activeStyleEditor === layerId) {\n this.state.activeStyleEditor = null;\n }\n }\n\n /**\n * Create style editor UI\n */\n private createStyleEditor(layerId: string): HTMLDivElement | null {\n const layer = this.map.getLayer(layerId);\n if (!layer) return null;\n\n const editor = document.createElement('div');\n editor.className = 'layer-control-style-editor';\n\n // Header\n const header = document.createElement('div');\n header.className = 'style-editor-header';\n\n const title = document.createElement('span');\n title.className = 'style-editor-title';\n title.textContent = 'Edit Style';\n\n const closeBtn = document.createElement('button');\n closeBtn.className = 'style-editor-close';\n closeBtn.innerHTML = '×';\n closeBtn.title = 'Close';\n closeBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.closeStyleEditor(layerId);\n });\n\n header.appendChild(title);\n header.appendChild(closeBtn);\n\n // Controls container - populate based on layer type\n const controls = document.createElement('div');\n controls.className = 'style-editor-controls';\n\n const layerType = layer.type;\n this.addStyleControlsForLayerType(controls, layerId, layerType);\n\n // Action buttons\n const actions = document.createElement('div');\n actions.className = 'style-editor-actions';\n\n const resetBtn = document.createElement('button');\n resetBtn.className = 'style-editor-button style-editor-button-reset';\n resetBtn.textContent = 'Reset';\n resetBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.resetLayerStyle(layerId);\n });\n\n const closeActionBtn = document.createElement('button');\n closeActionBtn.className = 'style-editor-button style-editor-button-close';\n closeActionBtn.textContent = 'Close';\n closeActionBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.closeStyleEditor(layerId);\n });\n\n actions.appendChild(resetBtn);\n actions.appendChild(closeActionBtn);\n\n editor.appendChild(header);\n editor.appendChild(controls);\n editor.appendChild(actions);\n\n return editor;\n }\n\n /**\n * Add style controls based on layer type\n */\n private addStyleControlsForLayerType(container: HTMLElement, layerId: string, layerType: string): void {\n switch (layerType) {\n case 'fill':\n this.addFillControls(container, layerId);\n break;\n case 'line':\n this.addLineControls(container, layerId);\n break;\n case 'circle':\n this.addCircleControls(container, layerId);\n break;\n case 'raster':\n this.addRasterControls(container, layerId);\n break;\n case 'symbol':\n this.addSymbolControls(container, layerId);\n break;\n default:\n container.textContent = `Style controls for ${layerType} layers not yet implemented.`;\n }\n }\n\n /**\n * Add controls for fill layers\n */\n private addFillControls(container: HTMLElement, layerId: string): void {\n // Fill Color - try layer definition first, then runtime property\n const style = this.map.getStyle();\n const layer = style.layers?.find(l => l.id === layerId);\n let fillColor: any = undefined;\n\n // First try to get from layer definition\n if (layer && 'paint' in layer && layer.paint && 'fill-color' in layer.paint) {\n fillColor = layer.paint['fill-color'];\n }\n\n // Fallback to runtime property if not in definition\n if (!fillColor) {\n fillColor = this.map.getPaintProperty(layerId, 'fill-color');\n }\n\n this.createColorControl(container, layerId, 'fill-color', 'Fill Color', normalizeColor(fillColor || '#088'));\n\n // Fill Opacity\n const fillOpacity = this.map.getPaintProperty(layerId, 'fill-opacity');\n if (fillOpacity !== undefined && typeof fillOpacity === 'number') {\n this.createSliderControl(container, layerId, 'fill-opacity', 'Fill Opacity', fillOpacity, 0, 1, 0.05);\n }\n\n // Fill Outline Color\n const outlineColor = this.map.getPaintProperty(layerId, 'fill-outline-color');\n if (outlineColor !== undefined) {\n this.createColorControl(container, layerId, 'fill-outline-color', 'Outline Color', normalizeColor(outlineColor));\n }\n }\n\n /**\n * Add controls for line layers\n */\n private addLineControls(container: HTMLElement, layerId: string): void {\n // Line Color - try layer definition first, then runtime property\n const style = this.map.getStyle();\n const layer = style.layers?.find(l => l.id === layerId);\n let lineColor: any = undefined;\n\n // First try to get from layer definition\n if (layer && 'paint' in layer && layer.paint && 'line-color' in layer.paint) {\n lineColor = layer.paint['line-color'];\n }\n\n // Fallback to runtime property if not in definition\n if (!lineColor) {\n lineColor = this.map.getPaintProperty(layerId, 'line-color');\n }\n\n this.createColorControl(container, layerId, 'line-color', 'Line Color', normalizeColor(lineColor || '#000'));\n\n // Line Width\n const lineWidth = this.map.getPaintProperty(layerId, 'line-width');\n this.createSliderControl(container, layerId, 'line-width', 'Line Width', typeof lineWidth === 'number' ? lineWidth : 1, 0, 20, 0.5);\n\n // Line Opacity\n const lineOpacity = this.map.getPaintProperty(layerId, 'line-opacity');\n if (lineOpacity !== undefined && typeof lineOpacity === 'number') {\n this.createSliderControl(container, layerId, 'line-opacity', 'Line Opacity', lineOpacity, 0, 1, 0.05);\n }\n\n // Line Blur\n const lineBlur = this.map.getPaintProperty(layerId, 'line-blur');\n if (lineBlur !== undefined && typeof lineBlur === 'number') {\n this.createSliderControl(container, layerId, 'line-blur', 'Line Blur', lineBlur, 0, 5, 0.1);\n }\n }\n\n /**\n * Add controls for circle layers\n */\n private addCircleControls(container: HTMLElement, layerId: string): void {\n // Circle Color - try layer definition first, then runtime property\n const style = this.map.getStyle();\n const layer = style.layers?.find(l => l.id === layerId);\n let circleColor: any = undefined;\n\n // First try to get from layer definition\n if (layer && 'paint' in layer && layer.paint && 'circle-color' in layer.paint) {\n circleColor = layer.paint['circle-color'];\n }\n\n // Fallback to runtime property if not in definition\n if (!circleColor) {\n circleColor = this.map.getPaintProperty(layerId, 'circle-color');\n }\n\n this.createColorControl(container, layerId, 'circle-color', 'Circle Color', normalizeColor(circleColor || '#000'));\n\n // Circle Radius\n const circleRadius = this.map.getPaintProperty(layerId, 'circle-radius');\n this.createSliderControl(container, layerId, 'circle-radius', 'Radius', typeof circleRadius === 'number' ? circleRadius : 5, 0, 40, 0.5);\n\n // Circle Opacity\n const circleOpacity = this.map.getPaintProperty(layerId, 'circle-opacity');\n if (circleOpacity !== undefined && typeof circleOpacity === 'number') {\n this.createSliderControl(container, layerId, 'circle-opacity', 'Opacity', circleOpacity, 0, 1, 0.05);\n }\n\n // Circle Stroke Color\n const strokeColor = this.map.getPaintProperty(layerId, 'circle-stroke-color');\n if (strokeColor !== undefined) {\n this.createColorControl(container, layerId, 'circle-stroke-color', 'Stroke Color', normalizeColor(strokeColor));\n }\n\n // Circle Stroke Width\n const strokeWidth = this.map.getPaintProperty(layerId, 'circle-stroke-width');\n if (strokeWidth !== undefined && typeof strokeWidth === 'number') {\n this.createSliderControl(container, layerId, 'circle-stroke-width', 'Stroke Width', strokeWidth, 0, 10, 0.1);\n }\n }\n\n /**\n * Add controls for raster layers\n */\n private addRasterControls(container: HTMLElement, layerId: string): void {\n // Raster Opacity\n const rasterOpacity = this.map.getPaintProperty(layerId, 'raster-opacity');\n this.createSliderControl(container, layerId, 'raster-opacity', 'Opacity', typeof rasterOpacity === 'number' ? rasterOpacity : 1, 0, 1, 0.05);\n\n // Raster Brightness Min\n const brightnessMin = this.map.getPaintProperty(layerId, 'raster-brightness-min');\n this.createSliderControl(container, layerId, 'raster-brightness-min', 'Brightness Min', typeof brightnessMin === 'number' ? brightnessMin : 0, -1, 1, 0.05);\n\n // Raster Brightness Max\n const brightnessMax = this.map.getPaintProperty(layerId, 'raster-brightness-max');\n this.createSliderControl(container, layerId, 'raster-brightness-max', 'Brightness Max', typeof brightnessMax === 'number' ? brightnessMax : 1, -1, 1, 0.05);\n\n // Raster Saturation\n const saturation = this.map.getPaintProperty(layerId, 'raster-saturation');\n this.createSliderControl(container, layerId, 'raster-saturation', 'Saturation', typeof saturation === 'number' ? saturation : 0, -1, 1, 0.05);\n\n // Raster Contrast\n const contrast = this.map.getPaintProperty(layerId, 'raster-contrast');\n this.createSliderControl(container, layerId, 'raster-contrast', 'Contrast', typeof contrast === 'number' ? contrast : 0, -1, 1, 0.05);\n\n // Raster Hue Rotate\n const hueRotate = this.map.getPaintProperty(layerId, 'raster-hue-rotate');\n this.createSliderControl(container, layerId, 'raster-hue-rotate', 'Hue Rotate', typeof hueRotate === 'number' ? hueRotate : 0, 0, 350, 5);\n }\n\n /**\n * Add controls for symbol layers\n */\n private addSymbolControls(container: HTMLElement, layerId: string): void {\n // Text Color\n const textColor = this.map.getPaintProperty(layerId, 'text-color');\n if (textColor !== undefined) {\n this.createColorControl(container, layerId, 'text-color', 'Text Color', normalizeColor(textColor));\n }\n\n // Text Opacity\n const textOpacity = this.map.getPaintProperty(layerId, 'text-opacity');\n if (textOpacity !== undefined && typeof textOpacity === 'number') {\n this.createSliderControl(container, layerId, 'text-opacity', 'Text Opacity', textOpacity, 0, 1, 0.05);\n }\n\n // Icon Opacity\n const iconOpacity = this.map.getPaintProperty(layerId, 'icon-opacity');\n if (iconOpacity !== undefined && typeof iconOpacity === 'number') {\n this.createSliderControl(container, layerId, 'icon-opacity', 'Icon Opacity', iconOpacity, 0, 1, 0.05);\n }\n }\n\n /**\n * Create a color control\n */\n private createColorControl(\n container: HTMLElement,\n layerId: string,\n property: string,\n label: string,\n initialValue: string\n ): void {\n const controlGroup = document.createElement('div');\n controlGroup.className = 'style-control-group';\n\n const labelEl = document.createElement('label');\n labelEl.className = 'style-control-label';\n labelEl.textContent = label;\n\n const inputWrapper = document.createElement('div');\n inputWrapper.className = 'style-control-color-group';\n\n const colorInput = document.createElement('input');\n colorInput.type = 'color';\n colorInput.className = 'style-control-color-picker';\n colorInput.value = initialValue;\n colorInput.dataset.property = property;\n\n const hexDisplay = document.createElement('input');\n hexDisplay.type = 'text';\n hexDisplay.className = 'style-control-color-value';\n hexDisplay.value = initialValue;\n hexDisplay.readOnly = true;\n\n colorInput.addEventListener('input', () => {\n const color = colorInput.value;\n hexDisplay.value = color;\n this.map.setPaintProperty(layerId, property, color);\n });\n\n inputWrapper.appendChild(colorInput);\n inputWrapper.appendChild(hexDisplay);\n\n controlGroup.appendChild(labelEl);\n controlGroup.appendChild(inputWrapper);\n\n container.appendChild(controlGroup);\n }\n\n /**\n * Create a slider control\n */\n private createSliderControl(\n container: HTMLElement,\n layerId: string,\n property: string,\n label: string,\n initialValue: number,\n min: number,\n max: number,\n step: number\n ): void {\n const controlGroup = document.createElement('div');\n controlGroup.className = 'style-control-group';\n\n const labelEl = document.createElement('label');\n labelEl.className = 'style-control-label';\n labelEl.textContent = label;\n\n const inputWrapper = document.createElement('div');\n inputWrapper.className = 'style-control-input-wrapper';\n\n const slider = document.createElement('input');\n slider.type = 'range';\n slider.className = 'style-control-slider';\n slider.min = String(min);\n slider.max = String(max);\n slider.step = String(step);\n slider.value = String(initialValue);\n slider.dataset.property = property;\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'style-control-value';\n valueDisplay.textContent = formatNumericValue(initialValue, step);\n\n slider.addEventListener('input', () => {\n const value = parseFloat(slider.value);\n valueDisplay.textContent = formatNumericValue(value, step);\n this.map.setPaintProperty(layerId, property, value);\n });\n\n inputWrapper.appendChild(slider);\n inputWrapper.appendChild(valueDisplay);\n\n controlGroup.appendChild(labelEl);\n controlGroup.appendChild(inputWrapper);\n\n container.appendChild(controlGroup);\n }\n\n /**\n * Reset layer style to original\n */\n private resetLayerStyle(layerId: string): void {\n const originalStyle = this.state.originalStyles.get(layerId);\n if (!originalStyle) return;\n\n // Restore original paint properties\n restoreOriginalStyle(this.map, layerId, this.state.originalStyles);\n\n // Update UI controls to reflect the reset values\n const editor = this.styleEditors.get(layerId);\n if (editor) {\n // Update all slider controls\n const sliders = editor.querySelectorAll('.style-control-slider') as NodeListOf<HTMLInputElement>;\n sliders.forEach(slider => {\n const property = slider.dataset.property;\n if (property) {\n const value = this.map.getPaintProperty(layerId, property);\n if (value !== undefined && typeof value === 'number') {\n slider.value = String(value);\n // Update value display\n const valueDisplay = slider.parentElement?.querySelector('.style-control-value');\n if (valueDisplay) {\n const step = parseFloat(slider.step);\n valueDisplay.textContent = formatNumericValue(value, step);\n }\n }\n }\n });\n\n // Update all color controls\n const colorPickers = editor.querySelectorAll('.style-control-color-picker') as NodeListOf<HTMLInputElement>;\n colorPickers.forEach(picker => {\n const property = picker.dataset.property;\n if (property) {\n const value = this.map.getPaintProperty(layerId, property);\n if (value !== undefined) {\n const hexColor = normalizeColor(value);\n picker.value = hexColor;\n // Update hex display\n const hexDisplay = picker.parentElement?.querySelector('.style-control-color-value');\n if (hexDisplay) {\n hexDisplay.textContent = hexColor;\n }\n }\n }\n });\n }\n }\n\n /**\n * Update layer states from map (sync UI with map)\n */\n private updateLayerStatesFromMap(): void {\n if (this.state.userInteractingWithSlider) {\n return; // Don't update while user is dragging\n }\n\n Object.keys(this.state.layerStates).forEach(layerId => {\n try {\n // Skip custom layers - they manage their own state via adapters\n if (this.state.layerStates[layerId]?.isCustomLayer) {\n return;\n }\n\n // Skip Background layer group\n if (layerId === 'Background') {\n return;\n }\n\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n // Check visibility\n const visibility = this.map.getLayoutProperty(layerId, 'visibility');\n const isVisible = visibility !== 'none';\n\n // Get opacity\n const layerType = layer.type;\n const opacity = getLayerOpacity(this.map, layerId, layerType);\n\n // Update local state\n if (this.state.layerStates[layerId]) {\n this.state.layerStates[layerId].visible = isVisible;\n this.state.layerStates[layerId].opacity = opacity;\n }\n\n // Update UI\n this.updateUIForLayer(layerId, isVisible, opacity);\n } catch (error) {\n console.warn(`Failed to update state for layer ${layerId}:`, error);\n }\n });\n }\n\n /**\n * Update UI elements for a specific layer\n */\n private updateUIForLayer(layerId: string, visible: boolean, opacity: number): void {\n const layerItems = this.panel.querySelectorAll('.layer-control-item');\n\n layerItems.forEach(item => {\n if ((item as HTMLElement).dataset.layerId === layerId) {\n const checkbox = item.querySelector('.layer-control-checkbox') as HTMLInputElement;\n const opacitySlider = item.querySelector('.layer-control-opacity') as HTMLInputElement;\n\n if (checkbox) {\n checkbox.checked = visible;\n }\n\n if (opacitySlider) {\n opacitySlider.value = String(opacity);\n opacitySlider.title = `Opacity: ${Math.round(opacity * 100)}%`;\n }\n }\n });\n }\n\n /**\n * Check for new layers and add them to the control, remove deleted layers\n */\n private checkForNewLayers(): void {\n // Skip checking for new layers during style operations to prevent race conditions\n // that could incorrectly delete custom layers\n if (this.state.isStyleOperationInProgress) {\n return;\n }\n\n try {\n const style = this.map.getStyle();\n if (!style || !style.layers) {\n return;\n }\n\n const currentMapLayerIds = new Set(style.layers.map(layer => layer.id));\n\n // Check if we're in auto-detect mode (no specific layers were specified)\n const isAutoDetectMode = this.targetLayers.length === 0 ||\n (this.targetLayers.length === 1 && this.targetLayers[0] === 'Background') ||\n this.targetLayers.every(id => id === 'Background' || this.state.layerStates[id]);\n\n // Find new layers that aren't in our state yet\n const newLayers: string[] = [];\n\n // Detection priority for NEW layers (added after control):\n // 1. basemapLayerIds (from basemapStyleUrl) - most reliable\n // 2. initialLayerIds - layer NOT in initialLayerIds means it was added after control\n // 3. Source-based heuristics - fallback\n const useBasemapStyleDetection = this.basemapLayerIds !== null && this.basemapLayerIds.size > 0;\n const useInitialLayerDetection = !useBasemapStyleDetection && this.initialLayerIds !== null && this.initialLayerIds.size > 0;\n\n currentMapLayerIds.forEach(layerId => {\n if (layerId !== 'Background' && !this.state.layerStates[layerId]) {\n const layer = this.map.getLayer(layerId);\n if (layer) {\n // Always skip layers that were present when control was initialized\n // These are background/basemap layers and should stay grouped under \"Background\"\n if (this.initialLayerIds !== null && this.initialLayerIds.has(layerId)) {\n // Layer was in initial set - it's a background layer, skip it\n return;\n }\n\n // In auto-detect mode, apply additional filtering\n if (isAutoDetectMode) {\n // Skip drawn layers if excludeDrawnLayers is enabled\n if (this.excludeDrawnLayers && this.isDrawnLayer(layerId)) {\n return;\n }\n\n // Skip layers matching user-defined exclusion patterns\n if (this.isExcludedByPattern(layerId)) {\n return;\n }\n\n // Skip layers that are not user-added (i.e., background/basemap layers)\n if (!this.isUserAddedLayer(layerId)) {\n return;\n }\n\n if (useBasemapStyleDetection) {\n // Use basemap style layer IDs - if layer is in basemap, skip it\n if (this.basemapLayerIds!.has(layerId)) {\n return;\n }\n } else if (useInitialLayerDetection) {\n // Layer NOT in initialLayerIds means it was added AFTER control\n // These are definitely user-added layers and should be included\n if (this.initialLayerIds!.has(layerId)) {\n // Layer was in initial set - check source-based heuristics\n const userAddedSourceIds = this.detectUserAddedSources();\n const sourceId = (layer as any).source;\n if (!sourceId || !userAddedSourceIds.has(sourceId)) {\n return;\n }\n }\n // Layer NOT in initialLayerIds - it's new, include it\n } else {\n // Fall back to source-based heuristics\n const userAddedSourceIds = this.detectUserAddedSources();\n const sourceId = (layer as any).source;\n if (!sourceId || !userAddedSourceIds.has(sourceId)) {\n return;\n }\n }\n }\n newLayers.push(layerId);\n }\n }\n });\n\n // Find removed layers that are still in our state\n // Skip custom layers - they have their own removal mechanism via the adapter\n const removedLayers: string[] = [];\n Object.keys(this.state.layerStates).forEach(layerId => {\n const state = this.state.layerStates[layerId];\n // Skip Background, custom layers, and layers still in the map\n if (layerId !== 'Background' && !state.isCustomLayer && !currentMapLayerIds.has(layerId)) {\n removedLayers.push(layerId);\n }\n });\n\n // Remove deleted layers from UI and state\n if (removedLayers.length > 0) {\n removedLayers.forEach(layerId => {\n // Remove from state\n delete this.state.layerStates[layerId];\n\n // Remove from UI\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`);\n if (itemEl) {\n itemEl.remove();\n }\n\n // Clean up style editor if open\n if (this.state.activeStyleEditor === layerId) {\n this.state.activeStyleEditor = null;\n }\n this.styleEditors.delete(layerId);\n });\n }\n\n // Add UI for new layers\n if (newLayers.length > 0) {\n newLayers.forEach(layerId => {\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n // Get layer type and opacity\n const layerType = layer.type;\n const opacity = getLayerOpacity(this.map, layerId, layerType);\n const visibility = this.map.getLayoutProperty(layerId, 'visibility');\n const isVisible = visibility !== 'none';\n\n // Add to state\n this.state.layerStates[layerId] = {\n visible: isVisible,\n opacity: opacity,\n name: this.generateFriendlyName(layerId),\n };\n\n // Add to UI\n this.addLayerItem(layerId, this.state.layerStates[layerId]);\n });\n }\n\n // Check for new/removed custom layers\n if (this.customLayerRegistry) {\n const customLayerIds = this.customLayerRegistry.getAllLayerIds();\n\n // Find new custom layers\n customLayerIds.forEach(layerId => {\n if (!this.state.layerStates[layerId]) {\n const customState = this.customLayerRegistry!.getLayerState(layerId);\n if (customState) {\n this.state.layerStates[layerId] = {\n visible: customState.visible,\n opacity: customState.opacity,\n name: customState.name,\n isCustomLayer: true,\n customLayerType: this.customLayerRegistry!.getSymbolType(layerId) || undefined,\n };\n this.addLayerItem(layerId, this.state.layerStates[layerId]);\n }\n }\n });\n\n // Find removed custom layers\n Object.keys(this.state.layerStates).forEach(layerId => {\n const state = this.state.layerStates[layerId];\n if (state.isCustomLayer && !customLayerIds.includes(layerId)) {\n // Remove from state\n delete this.state.layerStates[layerId];\n\n // Remove from UI\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`);\n if (itemEl) {\n itemEl.remove();\n }\n\n // Clean up style editor if open\n if (this.state.activeStyleEditor === layerId) {\n this.state.activeStyleEditor = null;\n }\n this.styleEditors.delete(layerId);\n }\n });\n }\n } catch (error) {\n console.warn('Failed to check for new layers:', error);\n }\n }\n\n /**\n * Register a custom layer adapter dynamically.\n * This allows adding adapters after the LayerControl has been initialized.\n * @param adapter The custom layer adapter to register\n */\n registerCustomAdapter(adapter: CustomLayerAdapter): void {\n // Create registry if it doesn't exist\n if (!this.customLayerRegistry) {\n this.customLayerRegistry = new CustomLayerRegistry();\n // Subscribe to registry changes\n this.customLayerUnsubscribe = this.customLayerRegistry.onChange(() => {\n this.checkForNewLayers();\n });\n }\n\n // Register the adapter\n this.customLayerRegistry.register(adapter);\n\n // Rebuild layer items to include the new adapter's layers\n if (this.panel) {\n this.checkForNewLayers();\n }\n }\n\n // ===== Context Menu Methods =====\n\n /**\n * Create context menu element\n */\n private createContextMenu(): HTMLDivElement {\n const menu = document.createElement('div');\n menu.className = 'layer-control-context-menu';\n menu.style.display = 'none';\n\n // Rename\n const renameItem = this.createContextMenuItem('Rename', '✏️', () => {\n if (this.state.contextMenu.targetLayerId) {\n this.startRenaming(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n });\n\n // Zoom to layer\n const zoomItem = this.createContextMenuItem('Zoom to Layer', '🔍', () => {\n if (this.state.contextMenu.targetLayerId) {\n this.zoomToLayer(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n });\n\n // Separator\n const sep1 = document.createElement('div');\n sep1.className = 'context-menu-separator';\n\n // Move up\n const moveUpItem = this.createContextMenuItem('Move Up', '↑', () => {\n if (this.state.contextMenu.targetLayerId) {\n this.moveLayerUp(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n });\n\n // Move to top\n const moveTopItem = this.createContextMenuItem('Move to Top', '⤒', () => {\n if (this.state.contextMenu.targetLayerId) {\n this.moveLayerToTop(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n });\n\n // Move down\n const moveDownItem = this.createContextMenuItem('Move Down', '↓', () => {\n if (this.state.contextMenu.targetLayerId) {\n this.moveLayerDown(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n });\n\n // Move to bottom\n const moveBottomItem = this.createContextMenuItem('Move to Bottom', '⤓', () => {\n if (this.state.contextMenu.targetLayerId) {\n this.moveLayerToBottom(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n });\n\n // Separator\n const sep2 = document.createElement('div');\n sep2.className = 'context-menu-separator';\n\n // Remove layer\n const removeItem = this.createContextMenuItem('Remove Layer', '🗑️', () => {\n if (this.state.contextMenu.targetLayerId) {\n this.removeLayer(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n }, true);\n\n menu.appendChild(renameItem);\n menu.appendChild(zoomItem);\n menu.appendChild(sep1);\n menu.appendChild(moveUpItem);\n menu.appendChild(moveTopItem);\n menu.appendChild(moveDownItem);\n menu.appendChild(moveBottomItem);\n menu.appendChild(sep2);\n menu.appendChild(removeItem);\n\n return menu;\n }\n\n /**\n * Create a context menu item\n */\n private createContextMenuItem(\n label: string,\n icon: string,\n onClick: () => void,\n isDanger = false\n ): HTMLDivElement {\n const item = document.createElement('div');\n item.className = 'context-menu-item' + (isDanger ? ' context-menu-item-danger' : '');\n\n const iconEl = document.createElement('span');\n iconEl.className = 'context-menu-item-icon';\n iconEl.textContent = icon;\n\n const labelEl = document.createElement('span');\n labelEl.className = 'context-menu-item-label';\n labelEl.textContent = label;\n\n item.appendChild(iconEl);\n item.appendChild(labelEl);\n\n item.addEventListener('click', (e) => {\n e.stopPropagation();\n onClick();\n });\n\n return item;\n }\n\n /**\n * Show context menu at position\n */\n private showContextMenu(layerId: string, x: number, y: number): void {\n if (!this.contextMenuEl) return;\n\n // Update state\n this.state.contextMenu = {\n visible: true,\n targetLayerId: layerId,\n x,\n y,\n };\n\n // Position the menu relative to the map container\n const mapRect = this.mapContainer.getBoundingClientRect();\n let menuX = x - mapRect.left;\n let menuY = y - mapRect.top;\n\n // Show menu to get dimensions\n this.contextMenuEl.style.display = 'block';\n\n // Adjust if menu would go off screen\n const menuRect = this.contextMenuEl.getBoundingClientRect();\n if (menuX + menuRect.width > mapRect.width) {\n menuX = mapRect.width - menuRect.width - 5;\n }\n if (menuY + menuRect.height > mapRect.height) {\n menuY = mapRect.height - menuRect.height - 5;\n }\n\n this.contextMenuEl.style.left = `${menuX}px`;\n this.contextMenuEl.style.top = `${menuY}px`;\n }\n\n /**\n * Hide context menu\n */\n private hideContextMenu(): void {\n if (!this.contextMenuEl) return;\n\n this.state.contextMenu = {\n visible: false,\n targetLayerId: null,\n x: 0,\n y: 0,\n };\n\n this.contextMenuEl.style.display = 'none';\n }\n\n /**\n * Start renaming a layer\n */\n private startRenaming(layerId: string): void {\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`);\n if (!itemEl) return;\n\n const nameEl = itemEl.querySelector('.layer-control-name');\n if (!nameEl) return;\n\n this.state.renamingLayerId = layerId;\n\n const currentName = this.state.customLayerNames.get(layerId) ||\n this.state.layerStates[layerId]?.name ||\n layerId;\n\n // Replace name span with input\n const input = document.createElement('input');\n input.type = 'text';\n input.className = 'layer-control-name-input';\n input.value = currentName;\n\n const finishRename = () => {\n const newName = input.value.trim() || currentName;\n const oldName = currentName;\n\n if (newName !== oldName) {\n this.state.customLayerNames.set(layerId, newName);\n if (this.state.layerStates[layerId]) {\n this.state.layerStates[layerId].name = newName;\n }\n this.onLayerRename?.(layerId, oldName, newName);\n }\n\n // Restore name span\n const newNameEl = document.createElement('span');\n newNameEl.className = 'layer-control-name';\n newNameEl.textContent = newName;\n newNameEl.title = newName;\n input.replaceWith(newNameEl);\n\n this.state.renamingLayerId = null;\n };\n\n input.addEventListener('blur', finishRename);\n input.addEventListener('keydown', (e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n finishRename();\n } else if (e.key === 'Escape') {\n e.preventDefault();\n // Restore original name\n const newNameEl = document.createElement('span');\n newNameEl.className = 'layer-control-name';\n newNameEl.textContent = currentName;\n newNameEl.title = currentName;\n input.replaceWith(newNameEl);\n this.state.renamingLayerId = null;\n }\n });\n\n nameEl.replaceWith(input);\n input.focus();\n input.select();\n }\n\n /**\n * Zoom to a layer's bounds\n */\n private zoomToLayer(layerId: string): void {\n // Check if it's a custom layer with getBounds support\n const layerState = this.state.layerStates[layerId];\n if (layerState?.isCustomLayer && this.customLayerRegistry) {\n const bounds = this.customLayerRegistry.getBounds(layerId);\n if (bounds) {\n this.map.fitBounds(bounds as [number, number, number, number], { padding: 50 });\n return;\n }\n }\n\n // For native MapLibre layers, try to get bounds from features\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n try {\n // First try querySourceFeatures for all features\n const sourceId = (layer as any).source;\n let features = sourceId ? this.map.querySourceFeatures(sourceId) : [];\n\n // If no source features, try rendered features\n if (features.length === 0) {\n features = this.map.queryRenderedFeatures({ layers: [layerId] });\n }\n\n if (features.length === 0) return;\n\n // Calculate bounds\n let minLng = Infinity, minLat = Infinity, maxLng = -Infinity, maxLat = -Infinity;\n\n features.forEach(feature => {\n if (!feature.geometry) return;\n\n const processCoords = (coords: any) => {\n if (typeof coords[0] === 'number') {\n const [lng, lat] = coords;\n minLng = Math.min(minLng, lng);\n minLat = Math.min(minLat, lat);\n maxLng = Math.max(maxLng, lng);\n maxLat = Math.max(maxLat, lat);\n } else {\n coords.forEach(processCoords);\n }\n };\n\n if (feature.geometry.type === 'Point') {\n processCoords((feature.geometry as any).coordinates);\n } else if (feature.geometry.type === 'LineString' || feature.geometry.type === 'MultiPoint') {\n (feature.geometry as any).coordinates.forEach(processCoords);\n } else if (feature.geometry.type === 'Polygon' || feature.geometry.type === 'MultiLineString') {\n (feature.geometry as any).coordinates.forEach((ring: any) => ring.forEach(processCoords));\n } else if (feature.geometry.type === 'MultiPolygon') {\n (feature.geometry as any).coordinates.forEach((polygon: any) =>\n polygon.forEach((ring: any) => ring.forEach(processCoords))\n );\n }\n });\n\n if (minLng !== Infinity && minLat !== Infinity && maxLng !== -Infinity && maxLat !== -Infinity) {\n this.map.fitBounds([[minLng, minLat], [maxLng, maxLat]], { padding: 50 });\n }\n } catch (error) {\n console.warn(`Failed to zoom to layer ${layerId}:`, error);\n }\n }\n\n /**\n * Get user layer IDs in current map order (top to bottom in UI = high z-index to low)\n * Includes both MapLibre layers and custom layers managed by adapters.\n */\n private getUserLayerIdsInMapOrder(): string[] {\n const style = this.map.getStyle();\n if (!style?.layers) return [];\n\n // Get map layers in their actual order (low index = rendered first/bottom)\n const mapLayerIds = style.layers.map(l => l.id);\n\n // Filter to only user layers that are in our state\n const userLayerIds = Object.keys(this.state.layerStates).filter(id => id !== 'Background');\n\n // Separate MapLibre layers and custom layers\n const mapLibreLayers = userLayerIds.filter(id => mapLayerIds.includes(id));\n const customLayers = userLayerIds.filter(id =>\n this.state.layerStates[id]?.isCustomLayer && !mapLayerIds.includes(id)\n );\n\n // Sort MapLibre layers by map order (reversed: high index = top in UI)\n const sortedMapLibreLayers = mapLibreLayers\n .sort((a, b) => mapLayerIds.indexOf(b) - mapLayerIds.indexOf(a));\n\n // Custom layers are placed at the top (rendered last/on top)\n // Maintain their relative order from the state\n return [...customLayers, ...sortedMapLibreLayers];\n }\n\n /**\n * Check if a layer is a MapLibre layer (not a custom layer)\n */\n private isMapLibreLayer(layerId: string): boolean {\n return this.map.getLayer(layerId) !== undefined;\n }\n\n /**\n * Find the next MapLibre layer ID in a direction from a given index\n * @param layerIds Array of layer IDs\n * @param startIndex Index to start searching from\n * @param direction 1 for forward (toward bottom), -1 for backward (toward top)\n * @returns MapLibre layer ID or undefined if not found\n */\n private findNextMapLibreLayer(layerIds: string[], startIndex: number, direction: 1 | -1): string | undefined {\n for (let i = startIndex; direction === 1 ? i < layerIds.length : i >= 0; i += direction) {\n if (this.isMapLibreLayer(layerIds[i])) {\n return layerIds[i];\n }\n }\n return undefined;\n }\n\n /**\n * Move a layer up in UI (higher rendering order = move to higher z-index)\n */\n private moveLayerUp(layerId: string): void {\n const layerIds = this.getUserLayerIdsInMapOrder();\n const index = layerIds.indexOf(layerId);\n if (index <= 0) return; // Already at top or not found\n\n // Check if this is a custom layer\n const isCustom = this.state.layerStates[layerId]?.isCustomLayer;\n\n if (!isCustom && this.isMapLibreLayer(layerId)) {\n // For MapLibre layers, we need to move them in the map\n // UI: [0]=top, [1], [2], ... [n]=bottom\n // Map array: bottom to top (low index = low z-index)\n // moveLayer(id, beforeId) moves id to render BELOW beforeId\n\n try {\n // Find the MapLibre layer to move before (2 positions above if exists)\n // If moving to top, use undefined as beforeId\n const targetBeforeId = index >= 2\n ? this.findNextMapLibreLayer(layerIds, index - 2, -1)\n : undefined;\n this.map.moveLayer(layerId, targetBeforeId);\n } catch (e) {\n // Ignore errors\n }\n }\n\n // For custom layers, just update the internal order\n // Swap positions in the state\n const newLayerStates: { [key: string]: LayerState } = {};\n const orderedIds = [...layerIds];\n [orderedIds[index], orderedIds[index - 1]] = [orderedIds[index - 1], orderedIds[index]];\n\n // Add Background first if it exists\n if (this.state.layerStates['Background']) {\n newLayerStates['Background'] = this.state.layerStates['Background'];\n }\n orderedIds.forEach(id => {\n if (this.state.layerStates[id]) {\n newLayerStates[id] = this.state.layerStates[id];\n }\n });\n this.state.layerStates = newLayerStates;\n\n // Rebuild UI\n this.buildLayerItems();\n this.onLayerReorder?.(this.getUserLayerIdsInMapOrder());\n }\n\n /**\n * Move a layer to the top (highest rendering order)\n */\n private moveLayerToTop(layerId: string): void {\n const layerIds = this.getUserLayerIdsInMapOrder();\n const index = layerIds.indexOf(layerId);\n if (index <= 0) return; // Already at top or not found\n\n // Check if this is a custom layer\n const isCustom = this.state.layerStates[layerId]?.isCustomLayer;\n\n if (!isCustom && this.isMapLibreLayer(layerId)) {\n // Move in MapLibre - no beforeId means move to top (highest z-index)\n try {\n this.map.moveLayer(layerId);\n } catch (e) {\n // Ignore errors\n }\n }\n\n // Update internal order - move to front\n const newLayerStates: { [key: string]: LayerState } = {};\n const orderedIds = [...layerIds];\n orderedIds.splice(index, 1);\n orderedIds.unshift(layerId);\n\n // Add Background first if it exists\n if (this.state.layerStates['Background']) {\n newLayerStates['Background'] = this.state.layerStates['Background'];\n }\n orderedIds.forEach(id => {\n if (this.state.layerStates[id]) {\n newLayerStates[id] = this.state.layerStates[id];\n }\n });\n this.state.layerStates = newLayerStates;\n\n // Rebuild UI\n this.buildLayerItems();\n this.onLayerReorder?.(this.getUserLayerIdsInMapOrder());\n }\n\n /**\n * Move a layer down in UI (lower rendering order = move to lower z-index)\n */\n private moveLayerDown(layerId: string): void {\n const layerIds = this.getUserLayerIdsInMapOrder();\n const index = layerIds.indexOf(layerId);\n if (index < 0 || index >= layerIds.length - 1) return; // Already at bottom or not found\n\n // Check if this is a custom layer\n const isCustom = this.state.layerStates[layerId]?.isCustomLayer;\n\n if (!isCustom && this.isMapLibreLayer(layerId)) {\n // The layer below in UI is at index + 1, which has lower z-index in map\n // To move our layer below it, we call moveLayer(layerId, belowLayerId)\n // This puts layerId just below belowLayerId in rendering order\n // Find the next MapLibre layer below\n const belowLayerId = this.findNextMapLibreLayer(layerIds, index + 1, 1);\n\n if (belowLayerId) {\n try {\n this.map.moveLayer(layerId, belowLayerId);\n } catch (e) {\n // Ignore errors\n }\n }\n }\n\n // Update internal order - swap positions\n const newLayerStates: { [key: string]: LayerState } = {};\n const orderedIds = [...layerIds];\n [orderedIds[index], orderedIds[index + 1]] = [orderedIds[index + 1], orderedIds[index]];\n\n // Add Background first if it exists\n if (this.state.layerStates['Background']) {\n newLayerStates['Background'] = this.state.layerStates['Background'];\n }\n orderedIds.forEach(id => {\n if (this.state.layerStates[id]) {\n newLayerStates[id] = this.state.layerStates[id];\n }\n });\n this.state.layerStates = newLayerStates;\n\n // Rebuild UI\n this.buildLayerItems();\n this.onLayerReorder?.(this.getUserLayerIdsInMapOrder());\n }\n\n /**\n * Move a layer to the bottom (lowest rendering order among user layers)\n */\n private moveLayerToBottom(layerId: string): void {\n const layerIds = this.getUserLayerIdsInMapOrder();\n if (layerIds.length <= 1) return;\n\n const index = layerIds.indexOf(layerId);\n if (index < 0 || index === layerIds.length - 1) return; // Not found or already at bottom\n\n // Check if this is a custom layer\n const isCustom = this.state.layerStates[layerId]?.isCustomLayer;\n\n if (!isCustom && this.isMapLibreLayer(layerId)) {\n // The bottom layer in UI has the lowest z-index among user layers\n // Find the bottom-most MapLibre layer\n const bottomLayerId = this.findNextMapLibreLayer(layerIds, layerIds.length - 1, -1);\n\n if (bottomLayerId && bottomLayerId !== layerId) {\n try {\n // Move this layer to be just below the current bottom layer\n this.map.moveLayer(layerId, bottomLayerId);\n } catch (e) {\n // Ignore errors\n }\n }\n }\n\n // Update internal order - move to end\n const newLayerStates: { [key: string]: LayerState } = {};\n const orderedIds = [...layerIds];\n orderedIds.splice(index, 1);\n orderedIds.push(layerId);\n\n // Add Background first if it exists\n if (this.state.layerStates['Background']) {\n newLayerStates['Background'] = this.state.layerStates['Background'];\n }\n orderedIds.forEach(id => {\n if (this.state.layerStates[id]) {\n newLayerStates[id] = this.state.layerStates[id];\n }\n });\n this.state.layerStates = newLayerStates;\n\n // Rebuild UI\n this.buildLayerItems();\n this.onLayerReorder?.(this.getUserLayerIdsInMapOrder());\n }\n\n /**\n * Remove a layer from the map\n */\n private removeLayer(layerId: string): void {\n const layerState = this.state.layerStates[layerId];\n\n // Check if it's a custom layer\n if (layerState?.isCustomLayer && this.customLayerRegistry) {\n this.customLayerRegistry.removeLayer(layerId);\n } else {\n // Remove native MapLibre layer\n try {\n const layer = this.map.getLayer(layerId);\n if (layer) {\n const sourceId = (layer as any).source;\n this.map.removeLayer(layerId);\n\n // Check if source is still used by other layers\n if (sourceId) {\n const style = this.map.getStyle();\n const sourceStillUsed = style?.layers?.some(l => (l as any).source === sourceId);\n if (!sourceStillUsed) {\n try {\n this.map.removeSource(sourceId);\n } catch (e) {\n // Source might not exist or be in use\n }\n }\n }\n }\n } catch (error) {\n console.warn(`Failed to remove layer ${layerId}:`, error);\n }\n }\n\n // Remove from state\n delete this.state.layerStates[layerId];\n this.state.customLayerNames.delete(layerId);\n\n // Remove from UI\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`);\n if (itemEl) {\n itemEl.remove();\n }\n\n // Call callback\n this.onLayerRemove?.(layerId);\n }\n\n // ===== Drag and Drop Methods =====\n\n /**\n * Create drag handle element\n */\n private createDragHandle(layerId: string): HTMLDivElement {\n const handle = document.createElement('div');\n handle.className = 'layer-control-drag-handle';\n handle.innerHTML = `<svg viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <circle cx=\"5\" cy=\"3\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"3\" r=\"1.5\"/>\n <circle cx=\"5\" cy=\"8\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"8\" r=\"1.5\"/>\n <circle cx=\"5\" cy=\"13\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"13\" r=\"1.5\"/>\n </svg>`;\n handle.title = 'Drag to reorder';\n\n // Pointer events for dragging\n handle.addEventListener('pointerdown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n this.startDrag(layerId, e);\n });\n\n return handle;\n }\n\n /**\n * Create a disabled drag handle for alignment (used for Background layer)\n */\n private createDisabledDragHandle(): HTMLDivElement {\n const handle = document.createElement('div');\n handle.className = 'layer-control-drag-handle layer-control-drag-handle-disabled';\n handle.innerHTML = `<svg viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <circle cx=\"5\" cy=\"3\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"3\" r=\"1.5\"/>\n <circle cx=\"5\" cy=\"8\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"8\" r=\"1.5\"/>\n <circle cx=\"5\" cy=\"13\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"13\" r=\"1.5\"/>\n </svg>`;\n return handle;\n }\n\n /**\n * Start dragging a layer\n */\n private startDrag(layerId: string, e: PointerEvent): void {\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`) as HTMLElement;\n if (!itemEl) return;\n\n // Get item rect before any modifications\n const rect = itemEl.getBoundingClientRect();\n\n // Set up drag state\n this.state.drag = {\n active: true,\n layerId,\n startY: e.clientY,\n currentY: e.clientY,\n placeholder: null,\n draggedElement: null,\n };\n\n // Add dragging class to panel\n this.panel.classList.add('dragging-active');\n\n // Hide original first (before creating clone to avoid visual jump)\n itemEl.classList.add('dragging');\n\n // Create placeholder at original position\n const placeholder = document.createElement('div');\n placeholder.className = 'layer-control-drop-placeholder';\n placeholder.style.height = `${rect.height}px`;\n itemEl.parentNode?.insertBefore(placeholder, itemEl);\n this.state.drag.placeholder = placeholder;\n\n // Create floating clone\n const clone = itemEl.cloneNode(true) as HTMLElement;\n clone.classList.remove('dragging');\n clone.className = 'layer-control-item layer-control-item-dragging';\n clone.style.width = `${rect.width}px`;\n clone.style.left = `${rect.left}px`;\n clone.style.top = `${rect.top}px`;\n document.body.appendChild(clone);\n this.state.drag.draggedElement = clone;\n\n // Set up move and end handlers on document\n const onMove = (moveE: PointerEvent) => this.onDragMove(moveE);\n const onEnd = (endE: PointerEvent) => {\n document.removeEventListener('pointermove', onMove);\n document.removeEventListener('pointerup', onEnd);\n document.removeEventListener('pointercancel', onEnd);\n this.endDrag(endE);\n };\n\n document.addEventListener('pointermove', onMove);\n document.addEventListener('pointerup', onEnd);\n document.addEventListener('pointercancel', onEnd);\n }\n\n /**\n * Handle drag move\n */\n private onDragMove(e: PointerEvent): void {\n if (!this.state.drag.active || !this.state.drag.draggedElement) return;\n\n const placeholder = this.state.drag.placeholder;\n if (!placeholder) return;\n\n // Move the floating element\n const deltaY = e.clientY - this.state.drag.startY;\n const clone = this.state.drag.draggedElement;\n const currentTop = parseFloat(clone.style.top) || 0;\n clone.style.top = `${currentTop + deltaY}px`;\n this.state.drag.startY = e.clientY;\n this.state.drag.currentY = e.clientY;\n\n // Get all layer items (excluding the one being dragged and Background)\n const items = Array.from(this.panel.querySelectorAll('.layer-control-item:not(.dragging)'))\n .filter(item => (item as HTMLElement).dataset.layerId !== 'Background') as HTMLElement[];\n\n // Find which item we're hovering over\n for (const item of items) {\n const itemRect = item.getBoundingClientRect();\n\n // Check if cursor is within this item's vertical bounds\n if (e.clientY >= itemRect.top && e.clientY <= itemRect.bottom) {\n const itemMiddle = itemRect.top + itemRect.height / 2;\n\n if (e.clientY < itemMiddle) {\n // Insert placeholder before this item (if not already there)\n if (placeholder.nextSibling !== item) {\n item.parentNode?.insertBefore(placeholder, item);\n }\n } else {\n // Insert placeholder after this item (if not already there)\n if (placeholder.previousSibling !== item) {\n item.parentNode?.insertBefore(placeholder, item.nextSibling);\n }\n }\n break;\n }\n }\n }\n\n /**\n * End dragging\n */\n private endDrag(_e: PointerEvent): void {\n if (!this.state.drag.active) return;\n\n const layerId = this.state.drag.layerId;\n const placeholder = this.state.drag.placeholder;\n\n // Get the original item\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`) as HTMLElement;\n\n if (itemEl && placeholder) {\n // Move item to placeholder position\n placeholder.parentNode?.insertBefore(itemEl, placeholder);\n itemEl.classList.remove('dragging');\n }\n\n // Clean up\n this.cleanupDragState();\n\n // Update map layer order based on UI order\n this.applyUIOrderToMap();\n }\n\n /**\n * Clean up drag state\n */\n private cleanupDragState(): void {\n // Remove floating element\n if (this.state.drag.draggedElement) {\n this.state.drag.draggedElement.remove();\n }\n\n // Remove placeholder\n if (this.state.drag.placeholder) {\n this.state.drag.placeholder.remove();\n }\n\n // Remove dragging class from panel\n this.panel.classList.remove('dragging-active');\n\n // Remove dragging class from any items\n this.panel.querySelectorAll('.layer-control-item.dragging').forEach(el => {\n el.classList.remove('dragging');\n });\n\n // Reset drag state\n this.state.drag = {\n active: false,\n layerId: null,\n startY: 0,\n currentY: 0,\n placeholder: null,\n draggedElement: null,\n };\n }\n\n /**\n * Apply UI order to map layers\n */\n private applyUIOrderToMap(): void {\n // Set flag to prevent checkForNewLayers from running during reordering\n // This prevents custom layers from being incorrectly deleted due to race conditions\n this.state.isStyleOperationInProgress = true;\n\n // Get layer items in current UI order\n const items = this.panel.querySelectorAll('.layer-control-item');\n const uiLayerIds: string[] = [];\n\n items.forEach(item => {\n const layerId = (item as HTMLElement).dataset.layerId;\n if (layerId && layerId !== 'Background') {\n uiLayerIds.push(layerId);\n }\n });\n\n // UI shows top layer first, but we need to move layers in reverse order\n // to maintain the correct stacking\n const reversedIds = [...uiLayerIds].reverse();\n\n // Build a set of MapLibre layer IDs for quick lookup\n const style = this.map.getStyle();\n const mapLibreLayerIds = new Set(style?.layers?.map(l => l.id) || []);\n\n // Move each layer to its correct position\n for (let i = 0; i < reversedIds.length; i++) {\n const layerId = reversedIds[i];\n\n // Check if layer exists in MapLibre (skip custom layers)\n if (!mapLibreLayerIds.has(layerId)) {\n continue;\n }\n\n // Find the next MapLibre layer to use as beforeId\n // Skip any custom layers that might be between this layer and the next\n let beforeId: string | undefined = undefined;\n for (let j = i - 1; j >= 0; j--) {\n if (mapLibreLayerIds.has(reversedIds[j])) {\n beforeId = reversedIds[j];\n break;\n }\n }\n\n try {\n this.map.moveLayer(layerId, beforeId);\n } catch (e) {\n // Ignore errors\n }\n }\n\n // Call callback\n this.onLayerReorder?.(uiLayerIds);\n\n // Clear flag after styledata events have settled\n // The 200ms delay accounts for the 100ms timeout in the styledata event handler\n setTimeout(() => {\n this.state.isStyleOperationInProgress = false;\n }, 200);\n }\n}\n"],"names":["opacity","clamp","color","svgMarkup","symbolContainer","layerList","editor","_a"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/lib/core/CustomLayerRegistry.ts","../src/lib/utils/layerUtils.ts","../src/lib/utils/styleCache.ts","../src/lib/utils/colorUtils.ts","../src/lib/utils/formatters.ts","../src/lib/utils/symbolUtils.ts","../src/lib/core/LayerControl.ts"],"sourcesContent":["import type { CustomLayerAdapter, LayerState } from './types';\n\n/**\n * Registry for managing custom layer adapters.\n * Routes layer operations to the appropriate adapter based on layer ID.\n */\nexport class CustomLayerRegistry {\n private adapters: Map<string, CustomLayerAdapter> = new Map();\n private changeListeners: Array<(event: 'add' | 'remove', layerId: string) => void> = [];\n private unsubscribers: Map<string, () => void> = new Map();\n\n /**\n * Register a custom layer adapter.\n * @param adapter The adapter to register\n */\n register(adapter: CustomLayerAdapter): void {\n this.adapters.set(adapter.type, adapter);\n\n // Subscribe to adapter's layer changes if supported\n if (adapter.onLayerChange) {\n const unsubscribe = adapter.onLayerChange((event, layerId) => {\n this.notifyChange(event, layerId);\n });\n this.unsubscribers.set(adapter.type, unsubscribe);\n }\n }\n\n /**\n * Unregister an adapter by type.\n * @param type The adapter type to unregister\n */\n unregister(type: string): void {\n // Clean up the subscription for this adapter\n const unsubscribe = this.unsubscribers.get(type);\n if (unsubscribe) {\n unsubscribe();\n this.unsubscribers.delete(type);\n }\n this.adapters.delete(type);\n }\n\n /**\n * Get all custom layer IDs across all adapters.\n * @returns Array of layer IDs\n */\n getAllLayerIds(): string[] {\n const ids: string[] = [];\n this.adapters.forEach(adapter => {\n ids.push(...adapter.getLayerIds());\n });\n return ids;\n }\n\n /**\n * Check if a layer ID is managed by any adapter.\n * @param layerId The layer ID to check\n * @returns true if the layer is managed by an adapter\n */\n hasLayer(layerId: string): boolean {\n for (const adapter of this.adapters.values()) {\n if (adapter.getLayerIds().includes(layerId)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Get the adapter responsible for a specific layer.\n * @param layerId The layer ID\n * @returns The adapter or null if not found\n */\n getAdapterForLayer(layerId: string): CustomLayerAdapter | null {\n for (const adapter of this.adapters.values()) {\n if (adapter.getLayerIds().includes(layerId)) {\n return adapter;\n }\n }\n return null;\n }\n\n /**\n * Get the state of a custom layer.\n * @param layerId The layer ID\n * @returns The layer state or null if not found\n */\n getLayerState(layerId: string): LayerState | null {\n const adapter = this.getAdapterForLayer(layerId);\n return adapter ? adapter.getLayerState(layerId) : null;\n }\n\n /**\n * Set visibility of a custom layer.\n * @param layerId The layer ID\n * @param visible Whether the layer should be visible\n * @returns true if the operation was handled by an adapter\n */\n setVisibility(layerId: string, visible: boolean): boolean {\n const adapter = this.getAdapterForLayer(layerId);\n if (adapter) {\n adapter.setVisibility(layerId, visible);\n return true;\n }\n return false;\n }\n\n /**\n * Set opacity of a custom layer.\n * @param layerId The layer ID\n * @param opacity The opacity value (0-1)\n * @returns true if the operation was handled by an adapter\n */\n setOpacity(layerId: string, opacity: number): boolean {\n const adapter = this.getAdapterForLayer(layerId);\n if (adapter) {\n adapter.setOpacity(layerId, opacity);\n return true;\n }\n return false;\n }\n\n /**\n * Get the symbol type for a custom layer (for UI display).\n * @param layerId The layer ID\n * @returns The symbol type or null if not available\n */\n getSymbolType(layerId: string): string | null {\n const adapter = this.getAdapterForLayer(layerId);\n if (adapter && adapter.getSymbolType) {\n return adapter.getSymbolType(layerId);\n }\n return null;\n }\n\n /**\n * Get the bounds of a custom layer (for zoom-to-layer).\n * @param layerId The layer ID\n * @returns The bounds [west, south, east, north] or null if not available\n */\n getBounds(layerId: string): [number, number, number, number] | null {\n const adapter = this.getAdapterForLayer(layerId);\n if (adapter && adapter.getBounds) {\n return adapter.getBounds(layerId);\n }\n return null;\n }\n\n /**\n * Remove a custom layer through its adapter.\n * @param layerId The layer ID to remove\n * @returns true if the operation was handled by an adapter\n */\n removeLayer(layerId: string): boolean {\n const adapter = this.getAdapterForLayer(layerId);\n if (adapter && adapter.removeLayer) {\n adapter.removeLayer(layerId);\n return true;\n }\n return false;\n }\n\n /**\n * Subscribe to layer changes across all adapters.\n * @param callback Function called when layers are added or removed\n * @returns Unsubscribe function\n */\n onChange(callback: (event: 'add' | 'remove', layerId: string) => void): () => void {\n this.changeListeners.push(callback);\n return () => {\n const idx = this.changeListeners.indexOf(callback);\n if (idx >= 0) {\n this.changeListeners.splice(idx, 1);\n }\n };\n }\n\n private notifyChange(event: 'add' | 'remove', layerId: string): void {\n this.changeListeners.forEach(cb => cb(event, layerId));\n }\n\n /**\n * Clean up all subscriptions and adapters.\n */\n destroy(): void {\n this.unsubscribers.forEach(unsub => unsub());\n this.unsubscribers.clear();\n this.adapters.clear();\n this.changeListeners = [];\n }\n}\n","import type { Map as MapLibreMap } from 'maplibre-gl';\nimport type { StyleableLayerType } from '../core/types';\n\n/**\n * Get the opacity property name for a given layer type\n * Supports all MapLibre layer types: fill, line, symbol, circle, heatmap,\n * fill-extrusion, raster, hillshade, color-relief, background\n * @param layerType MapLibre layer type\n * @returns Opacity property name(s), or null if the layer type doesn't support opacity\n */\nexport function getOpacityProperty(layerType: string): string | string[] | null {\n switch (layerType) {\n case 'fill':\n return 'fill-opacity';\n case 'line':\n return 'line-opacity';\n case 'circle':\n return 'circle-opacity';\n case 'symbol':\n // Symbol layers have both icon and text opacity\n return ['icon-opacity', 'text-opacity'];\n case 'raster':\n return 'raster-opacity';\n case 'background':\n return 'background-opacity';\n case 'heatmap':\n return 'heatmap-opacity';\n case 'fill-extrusion':\n return 'fill-extrusion-opacity';\n case 'hillshade':\n // Hillshade uses exaggeration for intensity, not opacity\n return 'hillshade-exaggeration';\n case 'color-relief':\n // Color-relief doesn't have a standard opacity property\n return null;\n default:\n // For custom layer types, try the standard pattern\n return `${layerType}-opacity`;\n }\n}\n\n/**\n * Get the current opacity value for a layer\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @param layerType Layer type\n * @returns Current opacity value (0-1), or 1.0 if the layer type doesn't support opacity\n */\nexport function getLayerOpacity(\n map: MapLibreMap,\n layerId: string,\n layerType: string\n): number {\n const opacityProp = getOpacityProperty(layerType);\n\n // Layer type doesn't support opacity\n if (opacityProp === null) {\n return 1.0;\n }\n\n if (Array.isArray(opacityProp)) {\n // For symbol layers, use icon-opacity as the primary value\n const opacity = map.getPaintProperty(layerId, opacityProp[0]);\n return (opacity !== undefined && opacity !== null) ? opacity as number : 1.0;\n }\n\n const opacity = map.getPaintProperty(layerId, opacityProp);\n return (opacity !== undefined && opacity !== null) ? opacity as number : 1.0;\n}\n\n/**\n * Set the opacity for a layer\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @param layerType Layer type\n * @param opacity Opacity value (0-1)\n */\nexport function setLayerOpacity(\n map: MapLibreMap,\n layerId: string,\n layerType: string,\n opacity: number\n): void {\n const opacityProp = getOpacityProperty(layerType);\n\n // Layer type doesn't support opacity\n if (opacityProp === null) {\n return;\n }\n\n if (Array.isArray(opacityProp)) {\n // For symbol layers, set both icon and text opacity\n opacityProp.forEach((prop) => {\n map.setPaintProperty(layerId, prop, opacity);\n });\n } else {\n map.setPaintProperty(layerId, opacityProp, opacity);\n }\n}\n\n/**\n * Check if a layer type supports style editing\n * @param layerType Layer type\n * @returns True if the layer type supports style editing\n */\nexport function isStyleableLayerType(layerType: string): layerType is StyleableLayerType {\n return [\n 'fill',\n 'line',\n 'circle',\n 'symbol',\n 'raster',\n 'heatmap',\n 'fill-extrusion',\n 'hillshade',\n ].includes(layerType);\n}\n\n/**\n * Get layer type from map\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @returns Layer type or null if layer not found\n */\nexport function getLayerType(map: MapLibreMap, layerId: string): string | null {\n try {\n const layer = map.getLayer(layerId);\n return layer ? layer.type : null;\n } catch (error) {\n console.warn(`Failed to get layer type for ${layerId}:`, error);\n return null;\n }\n}\n","import type { Map as MapLibreMap } from 'maplibre-gl';\nimport type { OriginalStyle } from '../core/types';\n\n/**\n * Deep clone a paint value (handles complex MapLibre expressions)\n * @param value Paint value to clone\n * @returns Cloned value\n */\nexport function clonePaintValue(value: any): any {\n if (Array.isArray(value)) {\n return value.map((item) => clonePaintValue(item));\n }\n if (value && typeof value === 'object') {\n try {\n return JSON.parse(JSON.stringify(value));\n } catch (error) {\n return value;\n }\n }\n return value;\n}\n\n/**\n * Cache the original paint properties for a layer\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @param originalStyles Map to store original styles\n */\nexport function cacheOriginalLayerStyle(\n map: MapLibreMap,\n layerId: string,\n originalStyles: Map<string, OriginalStyle>\n): void {\n if (originalStyles.has(layerId)) {\n return; // Already cached\n }\n\n try {\n const layer = map.getLayer(layerId);\n if (!layer) {\n return;\n }\n\n const paint: Record<string, any> = {};\n const style = map.getStyle();\n const layerDef = style.layers?.find(l => l.id === layerId);\n\n // For raster layers, handle all properties with defaults\n if (layer.type === 'raster') {\n // Default values from MapLibre GL spec\n const rasterDefaults: Record<string, number> = {\n 'raster-opacity': 1,\n 'raster-brightness-min': 0,\n 'raster-brightness-max': 1,\n 'raster-saturation': 0,\n 'raster-contrast': 0,\n 'raster-hue-rotate': 0\n };\n\n // Start with defaults\n Object.assign(paint, rasterDefaults);\n\n // Override with values from layer definition\n if (layerDef && 'paint' in layerDef && layerDef.paint) {\n Object.entries(layerDef.paint).forEach(([prop, value]) => {\n if (prop.startsWith('raster-')) {\n paint[prop] = clonePaintValue(value);\n }\n });\n }\n } else {\n // For non-raster layers, just get values from the layer definition\n if (layerDef && 'paint' in layerDef && layerDef.paint) {\n Object.entries(layerDef.paint).forEach(([prop, value]) => {\n paint[prop] = clonePaintValue(value);\n });\n }\n }\n\n originalStyles.set(layerId, { paint });\n } catch (error) {\n console.warn(`Failed to cache original style for ${layerId}:`, error);\n }\n}\n\n/**\n * Get the current value of a paint property\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @param property Property name\n * @param fallback Fallback value if property is not set\n * @returns Current property value\n */\nexport function getCurrentPaintValue(\n map: MapLibreMap,\n layerId: string,\n property: string,\n fallback?: any\n): any {\n try {\n const value = map.getPaintProperty(layerId, property);\n return value !== undefined ? value : fallback;\n } catch (error) {\n return fallback;\n }\n}\n\n/**\n * Restore original paint properties for a layer\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @param originalStyles Map of original styles\n * @returns Object with restored properties\n */\nexport function restoreOriginalStyle(\n map: MapLibreMap,\n layerId: string,\n originalStyles: Map<string, OriginalStyle>\n): Record<string, any> {\n const original = originalStyles.get(layerId);\n if (!original) {\n return {};\n }\n\n const applied: Record<string, any> = {};\n\n Object.entries(original.paint).forEach(([property, value]) => {\n try {\n const restoredValue = clonePaintValue(value);\n map.setPaintProperty(layerId, property, restoredValue);\n applied[property] = restoredValue;\n } catch (error) {\n console.warn(`Failed to restore ${property} for ${layerId}:`, error);\n }\n });\n\n return applied;\n}\n","/**\n * Convert RGB values to hex color string\n * @param r Red component (0-255)\n * @param g Green component (0-255)\n * @param b Blue component (0-255)\n * @returns Hex color string (e.g., '#ff0000')\n */\nexport function rgbToHex(r: number, g: number, b: number): string {\n const clamp = (v: number) => Math.max(0, Math.min(255, Math.round(v)));\n const toHex = (v: number) => {\n const hex = clamp(v).toString(16);\n return hex.length === 1 ? `0${hex}` : hex;\n };\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\n}\n\n/**\n * Normalize a color value to hex format\n * Handles hex strings, RGB strings, and RGB arrays\n * @param value Color value in various formats\n * @returns Normalized hex color string (always 6 digits)\n */\nexport function normalizeColor(value: any): string {\n if (typeof value === 'string') {\n // Already hex format\n if (value.startsWith('#')) {\n // Expand shorthand hex (#RGB to #RRGGBB)\n if (value.length === 4) {\n const r = value[1];\n const g = value[2];\n const b = value[3];\n return `#${r}${r}${g}${g}${b}${b}`;\n }\n return value;\n }\n\n // RGB string format: 'rgb(51, 136, 255)'\n if (value.startsWith('rgb')) {\n const match = value.match(/\\d+/g);\n if (match && match.length >= 3) {\n const [r, g, b] = match.map((num) => parseInt(num, 10));\n return rgbToHex(r, g, b);\n }\n }\n } else if (Array.isArray(value) && value.length >= 3) {\n // RGB array format: [51, 136, 255]\n return rgbToHex(value[0], value[1], value[2]);\n }\n\n // Fallback color (MapLibre default blue)\n return '#3388ff';\n}\n","/**\n * Format a numeric value based on the step size\n * @param value Numeric value to format\n * @param step Step size (determines decimal places)\n * @returns Formatted string\n */\nexport function formatNumericValue(value: number, step: number): string {\n let decimals = 0;\n\n if (step && Number(step) !== 1) {\n const stepNumber = Number(step);\n if (stepNumber > 0 && stepNumber < 1) {\n decimals = Math.min(4, Math.ceil(Math.abs(Math.log10(stepNumber))));\n }\n }\n\n return value.toFixed(decimals);\n}\n\n/**\n * Clamp a numeric value between min and max\n * @param value Value to clamp\n * @param min Minimum value\n * @param max Maximum value\n * @returns Clamped value\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n","import type { Map as MapLibreMap, LayerSpecification } from 'maplibre-gl';\nimport { normalizeColor, rgbToHex } from './colorUtils';\n\n/**\n * Map of layer types to their primary color property\n */\nconst COLOR_PROPERTY_MAP: Record<string, string[]> = {\n fill: ['fill-color', 'fill-outline-color'],\n line: ['line-color'],\n circle: ['circle-color', 'circle-stroke-color'],\n symbol: ['icon-color', 'text-color'],\n background: ['background-color'],\n heatmap: ['heatmap-color'],\n 'fill-extrusion': ['fill-extrusion-color'],\n};\n\n/**\n * Extract the first color value from a MapLibre expression\n * Handles expressions like ['case', ...], ['match', ...], ['interpolate', ...]\n * @param expression The MapLibre expression to extract color from\n * @returns The first color found, or null\n */\nfunction extractColorFromExpression(expression: any[]): string | null {\n if (!Array.isArray(expression) || expression.length === 0) return null;\n\n // Recursively search for color values\n for (const item of expression) {\n if (typeof item === 'string') {\n // Check if it's a color string\n if (\n item.startsWith('#') ||\n item.startsWith('rgb') ||\n item.startsWith('hsl')\n ) {\n return normalizeColor(item);\n }\n } else if (Array.isArray(item)) {\n const result = extractColorFromExpression(item);\n if (result) return result;\n }\n }\n return null;\n}\n\n/**\n * Get the primary color from a layer's paint properties\n * @param map The MapLibre map instance\n * @param layerId The layer ID\n * @param layerType The layer type\n * @returns The normalized hex color, or null if not found\n */\nexport function getLayerColor(\n map: MapLibreMap,\n layerId: string,\n layerType: string\n): string | null {\n const propertyNames = COLOR_PROPERTY_MAP[layerType];\n if (!propertyNames) return null;\n\n // Try each property in order\n for (const propertyName of propertyNames) {\n // First try runtime property (may have been changed)\n try {\n const runtimeColor = map.getPaintProperty(layerId, propertyName);\n if (runtimeColor) {\n if (typeof runtimeColor === 'string') {\n return normalizeColor(runtimeColor);\n }\n if (Array.isArray(runtimeColor)) {\n // Handle expressions\n const extracted = extractColorFromExpression(runtimeColor);\n if (extracted) return extracted;\n }\n }\n } catch {\n // Property doesn't exist, continue\n }\n\n // Try from layer definition\n const style = map.getStyle();\n const layer = style?.layers?.find(\n (l: LayerSpecification) => l.id === layerId\n );\n if (layer && 'paint' in layer && layer.paint) {\n const paintColor = (layer.paint as Record<string, any>)[propertyName];\n if (paintColor) {\n if (typeof paintColor === 'string') {\n return normalizeColor(paintColor);\n }\n if (Array.isArray(paintColor)) {\n const extracted = extractColorFromExpression(paintColor);\n if (extracted) return extracted;\n }\n }\n }\n }\n\n return null;\n}\n\n/**\n * Get the primary color directly from a layer specification\n * @param layer The layer specification\n * @returns The normalized hex color, or null if not found\n */\nexport function getLayerColorFromSpec(layer: LayerSpecification): string | null {\n const propertyNames = COLOR_PROPERTY_MAP[layer.type];\n if (!propertyNames) return null;\n\n for (const propertyName of propertyNames) {\n if ('paint' in layer && layer.paint) {\n const paintColor = (layer.paint as Record<string, any>)[propertyName];\n if (paintColor) {\n if (typeof paintColor === 'string') {\n return normalizeColor(paintColor);\n }\n if (Array.isArray(paintColor)) {\n const extracted = extractColorFromExpression(paintColor);\n if (extracted) return extracted;\n }\n }\n }\n }\n\n return null;\n}\n\n/**\n * Darken a hex color by a given amount\n * @param hexColor The hex color to darken (e.g., '#ff0000')\n * @param amount Amount to darken (0-1, where 1 is fully black)\n * @returns The darkened hex color\n */\nexport function darkenColor(hexColor: string, amount: number): string {\n // Normalize to 6-digit hex\n let hex = hexColor.replace('#', '');\n if (hex.length === 3) {\n hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];\n }\n\n const r = Math.max(\n 0,\n parseInt(hex.slice(0, 2), 16) - Math.round(255 * amount)\n );\n const g = Math.max(\n 0,\n parseInt(hex.slice(2, 4), 16) - Math.round(255 * amount)\n );\n const b = Math.max(\n 0,\n parseInt(hex.slice(4, 6), 16) - Math.round(255 * amount)\n );\n return rgbToHex(r, g, b);\n}\n\n// SVG Symbol Templates\n\n/**\n * Create a fill symbol (filled rectangle)\n */\nfunction createFillSymbol(size: number, color: string): string {\n const padding = 2;\n const borderColor = darkenColor(color, 0.3);\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"1\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a line symbol (horizontal line)\n */\nfunction createLineSymbol(\n size: number,\n color: string,\n strokeWidth: number = 2\n): string {\n const y = size / 2;\n const padding = 2;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <line x1=\"${padding}\" y1=\"${y}\" x2=\"${size - padding}\" y2=\"${y}\"\n stroke=\"${color}\" stroke-width=\"${strokeWidth}\" stroke-linecap=\"round\"/>\n </svg>`;\n}\n\n/**\n * Create a circle symbol (filled circle)\n */\nfunction createCircleSymbol(size: number, color: string): string {\n const cx = size / 2;\n const cy = size / 2;\n const r = size / 2 - 3;\n const borderColor = darkenColor(color, 0.3);\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"${cx}\" cy=\"${cy}\" r=\"${r}\" fill=\"${color}\"\n stroke=\"${borderColor}\" stroke-width=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a marker/pin symbol for symbol layers\n */\nfunction createMarkerSymbol(size: number, color: string): string {\n const borderColor = darkenColor(color, 0.3);\n // Simple pin/marker shape\n const cx = size / 2;\n const pinWidth = size * 0.5;\n const pinHeight = size * 0.7;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M${cx} ${size - 2}\n L${cx - pinWidth / 2} ${size - pinHeight}\n A${pinWidth / 2} ${pinWidth / 2} 0 1 1 ${cx + pinWidth / 2} ${size - pinHeight}\n Z\"\n fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"1\"/>\n <circle cx=\"${cx}\" cy=\"${size - pinHeight - pinWidth / 4}\" r=\"${pinWidth / 5}\" fill=\"white\"/>\n </svg>`;\n}\n\n/**\n * Create a raster symbol (gradient pattern)\n */\nfunction createRasterSymbol(size: number): string {\n const padding = 2;\n const id = `rasterGrad_${Math.random().toString(36).slice(2, 9)}`;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"${id}\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stop-color=\"#e0e0e0\"/>\n <stop offset=\"50%\" stop-color=\"#808080\"/>\n <stop offset=\"100%\" stop-color=\"#404040\"/>\n </linearGradient>\n </defs>\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"url(#${id})\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a background symbol (rectangle with inner indicator)\n */\nfunction createBackgroundSymbol(size: number, color: string): string {\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"1\" y=\"1\" width=\"${size - 2}\" height=\"${size - 2}\" fill=\"${color}\" rx=\"2\"/>\n <rect x=\"3\" y=\"3\" width=\"${size - 6}\" height=\"${size - 6}\" fill=\"none\"\n stroke=\"white\" stroke-width=\"1\" stroke-opacity=\"0.5\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a heatmap symbol (orange-red gradient)\n */\nfunction createHeatmapSymbol(size: number): string {\n const padding = 2;\n const id = `heatmapGrad_${Math.random().toString(36).slice(2, 9)}`;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <radialGradient id=\"${id}\" cx=\"50%\" cy=\"50%\" r=\"50%\">\n <stop offset=\"0%\" stop-color=\"#ffff00\"/>\n <stop offset=\"50%\" stop-color=\"#ff8800\"/>\n <stop offset=\"100%\" stop-color=\"#ff0000\"/>\n </radialGradient>\n </defs>\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"url(#${id})\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a hillshade symbol (gray gradient)\n */\nfunction createHillshadeSymbol(size: number): string {\n const padding = 2;\n const id = `hillshadeGrad_${Math.random().toString(36).slice(2, 9)}`;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"${id}\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stop-color=\"#ffffff\"/>\n <stop offset=\"100%\" stop-color=\"#666666\"/>\n </linearGradient>\n </defs>\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"url(#${id})\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a fill-extrusion symbol (3D-ish rectangle)\n */\nfunction createFillExtrusionSymbol(size: number, color: string): string {\n const borderColor = darkenColor(color, 0.3);\n const topColor = color;\n const sideColor = darkenColor(color, 0.2);\n const depth = 3;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <polygon points=\"${2 + depth},2 ${size - 2},2 ${size - 2},${size - 2 - depth} ${size - 2 - depth},${size - 2} 2,${size - 2} 2,${2 + depth}\"\n fill=\"${topColor}\" stroke=\"${borderColor}\" stroke-width=\"1\"/>\n <polygon points=\"2,${2 + depth} ${2 + depth},2 ${2 + depth},${size - 2 - depth} 2,${size - 2}\"\n fill=\"${sideColor}\" stroke=\"${borderColor}\" stroke-width=\"0.5\"/>\n <polygon points=\"${2 + depth},${size - 2 - depth} ${size - 2},${size - 2 - depth} ${size - 2 - depth},${size - 2} 2,${size - 2}\"\n fill=\"${sideColor}\" stroke=\"${borderColor}\" stroke-width=\"0.5\"/>\n </svg>`;\n}\n\n/**\n * Create a default symbol (simple square)\n */\nfunction createDefaultSymbol(size: number, color: string): string {\n const padding = 2;\n const borderColor = darkenColor(color, 0.3);\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a COG (Cloud Optimized GeoTIFF) symbol\n * Grid pattern representing raster tiles\n */\nfunction createCOGSymbol(size: number, color: string): string {\n const padding = 2;\n const borderColor = darkenColor(color, 0.3);\n const cellSize = (size - padding * 2) / 2;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${cellSize}\" height=\"${cellSize}\" fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"0.5\"/>\n <rect x=\"${padding + cellSize}\" y=\"${padding}\" width=\"${cellSize}\" height=\"${cellSize}\" fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.8\"/>\n <rect x=\"${padding}\" y=\"${padding + cellSize}\" width=\"${cellSize}\" height=\"${cellSize}\" fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.6\"/>\n <rect x=\"${padding + cellSize}\" y=\"${padding + cellSize}\" width=\"${cellSize}\" height=\"${cellSize}\" fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.4\"/>\n </svg>`;\n}\n\n/**\n * Create a Zarr symbol\n * Layered grid pattern representing multidimensional data\n */\nfunction createZarrSymbol(size: number, color: string): string {\n const padding = 2;\n const borderColor = darkenColor(color, 0.3);\n const innerSize = size - padding * 2;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"${padding + 2}\" y=\"${padding}\" width=\"${innerSize - 2}\" height=\"${innerSize - 2}\" fill=\"${darkenColor(color, 0.2)}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" rx=\"1\"/>\n <rect x=\"${padding + 1}\" y=\"${padding + 1}\" width=\"${innerSize - 2}\" height=\"${innerSize - 2}\" fill=\"${darkenColor(color, 0.1)}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" rx=\"1\"/>\n <rect x=\"${padding}\" y=\"${padding + 2}\" width=\"${innerSize - 2}\" height=\"${innerSize - 2}\" fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" rx=\"1\"/>\n <line x1=\"${padding + 3}\" y1=\"${padding + 5}\" x2=\"${padding + innerSize - 5}\" y2=\"${padding + 5}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.5\"/>\n <line x1=\"${padding + 3}\" y1=\"${padding + 8}\" x2=\"${padding + innerSize - 5}\" y2=\"${padding + 8}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.5\"/>\n </svg>`;\n}\n\n/**\n * Create a generic custom raster symbol\n * Gradient grid representing custom raster layers\n */\nfunction createCustomRasterSymbol(size: number, color: string): string {\n const padding = 2;\n const borderColor = darkenColor(color, 0.3);\n const id = `customRasterGrad_${Math.random().toString(36).slice(2, 9)}`;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"${id}\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stop-color=\"${color}\"/>\n <stop offset=\"100%\" stop-color=\"${darkenColor(color, 0.4)}\"/>\n </linearGradient>\n </defs>\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"url(#${id})\" stroke=\"${borderColor}\" stroke-width=\"1\" rx=\"1\"/>\n <line x1=\"${size / 2}\" y1=\"${padding}\" x2=\"${size / 2}\" y2=\"${size - padding}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.3\"/>\n <line x1=\"${padding}\" y1=\"${size / 2}\" x2=\"${size - padding}\" y2=\"${size / 2}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.3\"/>\n </svg>`;\n}\n\n/**\n * Create a stacked layers symbol for background layer groups\n * Shows multiple overlapping rectangles to represent multiple layers\n */\nfunction createStackedLayersSymbol(size: number): string {\n const colors = ['#a8d4a8', '#8ec4e8', '#d4c4a8'];\n const borderColor = '#666666';\n // Three stacked rectangles offset diagonally\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"4\" y=\"1\" width=\"${size - 6}\" height=\"${size - 6}\" fill=\"${colors[2]}\" stroke=\"${borderColor}\" stroke-width=\"0.75\" rx=\"1\"/>\n <rect x=\"2\" y=\"3\" width=\"${size - 6}\" height=\"${size - 6}\" fill=\"${colors[1]}\" stroke=\"${borderColor}\" stroke-width=\"0.75\" rx=\"1\"/>\n <rect x=\"0\" y=\"5\" width=\"${size - 6}\" height=\"${size - 6}\" fill=\"${colors[0]}\" stroke=\"${borderColor}\" stroke-width=\"0.75\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Symbol generation options\n */\nexport interface SymbolOptions {\n /** Symbol size in pixels (default: 16) */\n size?: number;\n /** Stroke width for line symbols (default: 2) */\n strokeWidth?: number;\n}\n\n/**\n * Create an SVG symbol for a layer type\n * @param layerType The MapLibre layer type\n * @param color The primary color (hex format), or null for default\n * @param options Optional configuration\n * @returns SVG markup string\n */\nexport function createLayerSymbolSVG(\n layerType: string,\n color: string | null,\n options: SymbolOptions = {}\n): string {\n const size = options.size || 16;\n const strokeWidth = options.strokeWidth || 2;\n const fillColor = color || '#888888'; // Fallback gray\n\n switch (layerType) {\n case 'fill':\n return createFillSymbol(size, fillColor);\n case 'line':\n return createLineSymbol(size, fillColor, strokeWidth);\n case 'circle':\n return createCircleSymbol(size, fillColor);\n case 'symbol':\n return createMarkerSymbol(size, fillColor);\n case 'raster':\n return createRasterSymbol(size);\n case 'background':\n return createBackgroundSymbol(size, fillColor);\n case 'heatmap':\n return createHeatmapSymbol(size);\n case 'hillshade':\n return createHillshadeSymbol(size);\n case 'fill-extrusion':\n return createFillExtrusionSymbol(size, fillColor);\n case 'background-group':\n return createStackedLayersSymbol(size);\n case 'cog':\n return createCOGSymbol(size, fillColor);\n case 'zarr':\n return createZarrSymbol(size, fillColor);\n case 'custom-raster':\n return createCustomRasterSymbol(size, fillColor);\n default:\n return createDefaultSymbol(size, fillColor);\n }\n}\n\n/**\n * Create an SVG symbol for the Background layer group\n * @param size Symbol size in pixels (default: 16)\n * @returns SVG markup string\n */\nexport function createBackgroundGroupSymbolSVG(size: number = 16): string {\n return createStackedLayersSymbol(size);\n}\n","import type { IControl, Map as MapLibreMap, LayerSpecification } from 'maplibre-gl';\nimport type {\n LayerControlOptions,\n LayerState,\n OriginalStyle,\n InternalControlState,\n CustomLayerAdapter,\n} from './types';\nimport { CustomLayerRegistry } from './CustomLayerRegistry';\nimport { getLayerType, getLayerOpacity, setLayerOpacity } from '../utils/layerUtils';\nimport { cacheOriginalLayerStyle, restoreOriginalStyle } from '../utils/styleCache';\nimport { normalizeColor } from '../utils/colorUtils';\nimport { formatNumericValue } from '../utils/formatters';\nimport {\n getLayerColor,\n getLayerColorFromSpec,\n createLayerSymbolSVG,\n createBackgroundGroupSymbolSVG,\n} from '../utils/symbolUtils';\n\n/**\n * LayerControl - A comprehensive layer control for MapLibre GL\n * Provides visibility toggle, opacity control, and advanced style editing\n */\nexport class LayerControl implements IControl {\n private map!: MapLibreMap;\n private mapContainer!: HTMLElement;\n private container!: HTMLDivElement;\n private button!: HTMLButtonElement;\n private panel!: HTMLDivElement;\n\n // Panel positioning\n private resizeHandler: (() => void) | null = null;\n private mapResizeHandler: (() => void) | null = null;\n\n // State management\n private state: InternalControlState;\n private targetLayers: string[];\n private styleEditors: Map<string, HTMLElement>;\n private initialSourceIds: Set<string> | null = null;\n private initialLayerIds: Set<string> | null = null;\n\n // Panel width management\n private minPanelWidth: number;\n private maxPanelWidth: number;\n private maxPanelHeight: number;\n private showStyleEditor: boolean;\n private showOpacitySlider: boolean;\n private showLayerSymbol: boolean;\n private excludeDrawnLayers: boolean;\n private excludeLayerPatterns: RegExp[];\n private customLayerRegistry: CustomLayerRegistry | null = null;\n private customLayerUnsubscribe: (() => void) | null = null;\n private basemapStyleUrl: string | null = null;\n private basemapLayerIds: Set<string> | null = null;\n private widthSliderEl: HTMLElement | null = null;\n private widthThumbEl: HTMLElement | null = null;\n private widthValueEl: HTMLElement | null = null;\n private isWidthSliderActive = false;\n private widthDragRectWidth: number | null = null;\n private widthDragStartX: number | null = null;\n private widthDragStartWidth: number | null = null;\n private widthFrame: number | null = null;\n\n // Context menu and drag-drop\n private contextMenuEl: HTMLDivElement | null = null;\n private enableContextMenu: boolean;\n private enableDragAndDrop: boolean;\n private onLayerRename?: (layerId: string, oldName: string, newName: string) => void;\n private onLayerReorder?: (layerOrder: string[]) => void;\n private onLayerRemove?: (layerId: string) => void;\n\n constructor(options: LayerControlOptions = {}) {\n this.minPanelWidth = options.panelMinWidth || 240;\n this.maxPanelWidth = options.panelMaxWidth || 420;\n this.maxPanelHeight = options.panelMaxHeight || 600;\n this.showStyleEditor = options.showStyleEditor !== false;\n this.showOpacitySlider = options.showOpacitySlider !== false;\n this.showLayerSymbol = options.showLayerSymbol !== false;\n this.excludeDrawnLayers = options.excludeDrawnLayers !== false;\n this.excludeLayerPatterns = this.wildcardPatternsToRegex(options.excludeLayers || []);\n\n // Context menu and drag-drop options\n this.enableContextMenu = options.enableContextMenu !== false;\n this.enableDragAndDrop = options.enableDragAndDrop !== false;\n this.onLayerRename = options.onLayerRename;\n this.onLayerReorder = options.onLayerReorder;\n this.onLayerRemove = options.onLayerRemove;\n\n this.state = {\n collapsed: options.collapsed !== false,\n panelWidth: options.panelWidth || 350,\n activeStyleEditor: null,\n layerStates: options.layerStates || {},\n originalStyles: new Map<string, OriginalStyle>(),\n userInteractingWithSlider: false,\n backgroundLegendOpen: false,\n backgroundLayerVisibility: new Map<string, boolean>(),\n onlyRenderedFilter: false,\n contextMenu: {\n visible: false,\n targetLayerId: null,\n x: 0,\n y: 0,\n },\n renamingLayerId: null,\n customLayerNames: new Map<string, string>(),\n drag: {\n active: false,\n layerId: null,\n startY: 0,\n currentY: 0,\n placeholder: null,\n draggedElement: null,\n },\n isStyleOperationInProgress: false,\n };\n\n this.targetLayers = options.layers || Object.keys(this.state.layerStates);\n this.styleEditors = new Map<string, HTMLElement>();\n\n // Initialize custom layer registry if adapters are provided\n if (options.customLayerAdapters && options.customLayerAdapters.length > 0) {\n this.customLayerRegistry = new CustomLayerRegistry();\n options.customLayerAdapters.forEach(adapter => {\n this.customLayerRegistry!.register(adapter);\n });\n }\n\n // Store basemap style URL for reliable layer detection\n this.basemapStyleUrl = options.basemapStyleUrl || null;\n }\n\n /**\n * Called when the control is added to the map\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this.map = map;\n this.mapContainer = map.getContainer();\n\n // Capture initial source IDs and layer IDs (basemap) before auto-detecting layers\n // Sources and layers added after this point are considered user-added\n const style = this.map.getStyle();\n if (style && style.sources) {\n this.initialSourceIds = new Set(Object.keys(style.sources));\n } else {\n this.initialSourceIds = new Set();\n }\n\n // Capture initial layer IDs - any layer added after this is user-added\n if (style && style.layers) {\n this.initialLayerIds = new Set(style.layers.map(layer => layer.id));\n } else {\n this.initialLayerIds = new Set();\n }\n\n this.container = this.createContainer();\n this.button = this.createToggleButton();\n this.panel = this.createPanel();\n\n this.container.appendChild(this.button);\n // Append panel to map container for independent positioning (avoids overlap with other controls)\n this.mapContainer.appendChild(this.panel);\n\n // Create context menu element (appended to map container)\n if (this.enableContextMenu) {\n this.contextMenuEl = this.createContextMenu();\n this.mapContainer.appendChild(this.contextMenuEl);\n }\n\n // Now that panel is attached, update width display\n this.updateWidthDisplay();\n\n // Setup event listeners\n this.setupEventListeners();\n\n // If basemapStyleUrl is provided, fetch it first for reliable layer detection\n if (this.basemapStyleUrl && !this.basemapLayerIds) {\n this.fetchBasemapStyle().then(() => {\n // Auto-detect layers after basemap style is fetched\n if (Object.keys(this.state.layerStates).length === 0) {\n this.autoDetectLayers();\n }\n // Build layer items\n this.buildLayerItems();\n }).catch(error => {\n console.warn('Failed to fetch basemap style, falling back to heuristic detection:', error);\n // Fall back to heuristic detection\n if (Object.keys(this.state.layerStates).length === 0) {\n this.autoDetectLayers();\n }\n this.buildLayerItems();\n });\n } else {\n // Auto-detect layers using source-based heuristics\n if (Object.keys(this.state.layerStates).length === 0) {\n this.autoDetectLayers();\n }\n // Build layer items\n this.buildLayerItems();\n }\n\n // If panel starts expanded, update position after control is added to DOM\n if (!this.state.collapsed) {\n // Use requestAnimationFrame to wait until container is in DOM and positioned\n requestAnimationFrame(() => {\n this.updatePanelPosition();\n });\n }\n\n return this.container;\n }\n\n /**\n * Fetch the basemap style JSON and extract layer IDs.\n * This provides reliable distinction between basemap and user-added layers.\n */\n private async fetchBasemapStyle(): Promise<void> {\n if (!this.basemapStyleUrl) return;\n\n try {\n const response = await fetch(this.basemapStyleUrl);\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n const styleJson = await response.json();\n\n // Extract layer IDs from the basemap style\n if (styleJson && Array.isArray(styleJson.layers)) {\n this.basemapLayerIds = new Set(\n styleJson.layers.map((layer: { id: string }) => layer.id)\n );\n } else {\n this.basemapLayerIds = new Set();\n }\n } catch (error) {\n console.warn('Failed to fetch basemap style from URL:', this.basemapStyleUrl, error);\n throw error;\n }\n }\n\n /**\n * Called when the control is removed from the map\n */\n onRemove(): void {\n // Clean up custom layer registry subscription\n if (this.customLayerUnsubscribe) {\n this.customLayerUnsubscribe();\n this.customLayerUnsubscribe = null;\n }\n if (this.customLayerRegistry) {\n this.customLayerRegistry.destroy();\n this.customLayerRegistry = null;\n }\n\n // Remove resize event listeners\n if (this.resizeHandler) {\n window.removeEventListener('resize', this.resizeHandler);\n this.resizeHandler = null;\n }\n if (this.mapResizeHandler) {\n this.map.off('resize', this.mapResizeHandler);\n this.mapResizeHandler = null;\n }\n\n // Clean up context menu\n if (this.contextMenuEl) {\n this.contextMenuEl.parentNode?.removeChild(this.contextMenuEl);\n this.contextMenuEl = null;\n }\n\n // Clean up any active drag state\n this.cleanupDragState();\n\n // Remove panel from map container\n this.panel.parentNode?.removeChild(this.panel);\n\n // Remove button container from control stack\n this.container.parentNode?.removeChild(this.container);\n }\n\n /**\n * Auto-detect layers from the map and populate layerStates\n */\n private autoDetectLayers(): void {\n const style = this.map.getStyle();\n if (!style || !style.layers) {\n return;\n }\n\n // Get all layer IDs from the map\n const allLayerIds = style.layers.map(layer => layer.id);\n\n if (this.targetLayers.length === 0) {\n // No layers specified - auto-detect user-added layers vs background layers\n const userAddedLayers: string[] = [];\n const backgroundLayerIds: string[] = [];\n\n // Detection priority for INITIAL detection:\n // 1. basemapLayerIds (from basemapStyleUrl) - most reliable\n // 2. Source-based heuristics - works for layers added before OR after control\n // Note: initialLayerIds is NOT used here because it would incorrectly classify\n // user layers added BEFORE the control as basemap layers\n const useBasemapStyleDetection = this.basemapLayerIds !== null && this.basemapLayerIds.size > 0;\n\n // Identify which sources are user-added (for source-based heuristic detection)\n const userAddedSourceIds = useBasemapStyleDetection\n ? new Set<string>()\n : this.detectUserAddedSources();\n\n allLayerIds.forEach(layerId => {\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n // Skip drawn layers if excludeDrawnLayers is enabled\n if (this.excludeDrawnLayers && this.isDrawnLayer(layerId)) {\n backgroundLayerIds.push(layerId);\n return;\n }\n\n // Skip layers matching user-defined exclusion patterns\n if (this.isExcludedByPattern(layerId)) {\n backgroundLayerIds.push(layerId);\n return;\n }\n\n if (useBasemapStyleDetection) {\n // Use basemap style layer IDs for reliable detection\n if (this.basemapLayerIds!.has(layerId)) {\n // This layer is from the basemap style\n backgroundLayerIds.push(layerId);\n } else {\n // This layer is not in the basemap style - it's user-added\n userAddedLayers.push(layerId);\n }\n } else {\n // Use source-based heuristics\n // Check if this layer uses a user-added source\n const sourceId = (layer as any).source;\n if (sourceId && userAddedSourceIds.has(sourceId)) {\n userAddedLayers.push(layerId);\n } else {\n // Layer uses a basemap source or has no source (like background color layer)\n backgroundLayerIds.push(layerId);\n }\n }\n });\n\n // Add Background entry if there are background layers\n if (backgroundLayerIds.length > 0) {\n this.state.layerStates['Background'] = {\n visible: true,\n opacity: 1.0,\n name: 'Background'\n };\n }\n\n // Add entries for auto-detected user layers\n userAddedLayers.forEach(layerId => {\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n const visibility = this.map.getLayoutProperty(layerId, 'visibility');\n const isVisible = visibility !== 'none';\n const layerType = layer.type;\n const opacity = getLayerOpacity(this.map, layerId, layerType);\n const friendlyName = this.generateFriendlyName(layerId);\n\n this.state.layerStates[layerId] = {\n visible: isVisible,\n opacity: opacity,\n name: friendlyName\n };\n });\n } else {\n // Specific layers requested - separate into user layers + Background\n const userLayers: string[] = [];\n const basemapLayers: string[] = [];\n\n allLayerIds.forEach(layerId => {\n // Skip layers matching user-defined exclusion patterns\n if (this.isExcludedByPattern(layerId)) {\n basemapLayers.push(layerId);\n return;\n }\n\n if (this.targetLayers.includes(layerId)) {\n userLayers.push(layerId);\n } else {\n basemapLayers.push(layerId);\n }\n });\n\n // Add Background entry if there are basemap layers\n if (basemapLayers.length > 0) {\n this.state.layerStates['Background'] = {\n visible: true,\n opacity: 1.0,\n name: 'Background'\n };\n }\n\n // Add entries for user-specified layers\n userLayers.forEach(layerId => {\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n // Get visibility\n const visibility = this.map.getLayoutProperty(layerId, 'visibility');\n const isVisible = visibility !== 'none';\n\n // Get opacity\n const layerType = layer.type;\n const opacity = getLayerOpacity(this.map, layerId, layerType);\n\n // Generate friendly name from layer ID\n const friendlyName = this.generateFriendlyName(layerId);\n\n this.state.layerStates[layerId] = {\n visible: isVisible,\n opacity: opacity,\n name: friendlyName\n };\n });\n }\n\n // Detect custom layers from registry\n if (this.customLayerRegistry) {\n const customLayerIds = this.customLayerRegistry.getAllLayerIds();\n customLayerIds.forEach(layerId => {\n // Skip if already in state\n if (this.state.layerStates[layerId]) return;\n\n const customState = this.customLayerRegistry!.getLayerState(layerId);\n if (customState) {\n this.state.layerStates[layerId] = {\n visible: customState.visible,\n opacity: customState.opacity,\n name: customState.name,\n isCustomLayer: true,\n customLayerType: this.customLayerRegistry!.getSymbolType(layerId) || undefined,\n };\n }\n });\n }\n\n // Update targetLayers to include detected layers\n this.targetLayers = Object.keys(this.state.layerStates);\n }\n\n /**\n * Detect which sources are user-added (not from the basemap style)\n * User-added sources are identified by:\n * - Sources that were NOT present when the control was first added\n * - Additionally for sources added later:\n * - GeoJSON sources with inline data objects (not URL strings)\n * - Image, video, canvas sources\n * - Raster, raster-dem, vector sources from non-basemap tile providers\n */\n private detectUserAddedSources(): Set<string> {\n const userAddedSources = new Set<string>();\n const style = this.map.getStyle();\n if (!style || !style.sources) return userAddedSources;\n\n // First, detect the basemap's domain from sprite/glyphs URLs\n const basemapDomains = new Set<string>();\n\n // Known basemap providers\n const knownBasemapProviders = [\n 'demotiles.maplibre.org',\n 'api.maptiler.com',\n 'tiles.stadiamaps.com',\n 'api.mapbox.com',\n 'basemaps.cartocdn.com',\n 'tiles.mapbox.com',\n 'a.basemaps.cartocdn.com',\n 'b.basemaps.cartocdn.com',\n 'c.basemaps.cartocdn.com',\n 'd.basemaps.cartocdn.com',\n 'tiles.arcgis.com',\n 'server.arcgisonline.com',\n 'services.arcgisonline.com',\n ];\n\n // Detect domains from sprite/glyphs URLs (these are likely basemap domains)\n const spriteUrl = style.sprite as string | undefined;\n if (spriteUrl && typeof spriteUrl === 'string') {\n try {\n const url = new URL(spriteUrl);\n basemapDomains.add(url.hostname);\n } catch { /* ignore */ }\n }\n if (style.glyphs) {\n try {\n const url = new URL(style.glyphs.replace('{fontstack}', 'x').replace('{range}', 'x'));\n basemapDomains.add(url.hostname);\n } catch { /* ignore */ }\n }\n\n // Check each source\n for (const [sourceId, source] of Object.entries(style.sources)) {\n // If we have a snapshot of initial sources, use that as the primary check\n // Sources that existed when the control was added are basemap sources\n if (this.initialSourceIds && this.initialSourceIds.has(sourceId)) {\n // This source was present in the initial style, it's a basemap source\n continue;\n }\n\n const src = source as any;\n const sourceType = src.type;\n\n // Image, video, and canvas sources are always user-added\n if (sourceType === 'image' || sourceType === 'video' || sourceType === 'canvas') {\n userAddedSources.add(sourceId);\n continue;\n }\n\n // GeoJSON sources with inline data objects are user-added (if added after initial load)\n if (sourceType === 'geojson') {\n if (src.data && typeof src.data === 'object') {\n userAddedSources.add(sourceId);\n } else if (src.data && typeof src.data === 'string') {\n // GeoJSON with URL - check if it's from a basemap domain\n try {\n const url = new URL(src.data);\n const isBasemap = knownBasemapProviders.some(p => url.hostname.includes(p)) ||\n basemapDomains.has(url.hostname);\n if (!isBasemap) {\n userAddedSources.add(sourceId);\n }\n } catch {\n // Relative URL or invalid - assume user-added\n userAddedSources.add(sourceId);\n }\n }\n continue;\n }\n\n // Check tile URLs for raster, raster-dem, and vector sources\n if (sourceType === 'raster' || sourceType === 'raster-dem' || sourceType === 'vector') {\n const tileUrl = src.url || (src.tiles && src.tiles[0]) || '';\n if (tileUrl) {\n try {\n const url = new URL(tileUrl.replace(/{[^}]+}/g, '0'));\n const hostname = url.hostname;\n\n // Check if this is a known basemap provider\n const isKnownBasemap = knownBasemapProviders.some(provider =>\n hostname === provider || hostname.endsWith('.' + provider)\n );\n\n // Check if this matches detected basemap domains\n const matchesBasemapDomain = basemapDomains.has(hostname);\n\n // If not a basemap source, it's user-added\n if (!isKnownBasemap && !matchesBasemapDomain) {\n userAddedSources.add(sourceId);\n }\n } catch {\n // If URL parsing fails, assume it could be user-added\n userAddedSources.add(sourceId);\n }\n }\n }\n }\n\n return userAddedSources;\n }\n\n /**\n * Generate a friendly display name from a layer ID\n */\n private generateFriendlyName(layerId: string): string {\n // Remove common prefixes\n let name = layerId.replace(/^(layer[-_]?|gl[-_]?)/, '');\n\n // Replace dashes and underscores with spaces\n name = name.replace(/[-_]/g, ' ');\n\n // Capitalize first letter of each word\n name = name.replace(/\\b\\w/g, char => char.toUpperCase());\n\n return name || layerId; // Fallback to original if empty\n }\n\n /**\n * Check if a layer ID belongs to a drawing library (Geoman, Mapbox GL Draw, etc.)\n * @param layerId The layer ID to check\n * @returns true if the layer is from a drawing library\n */\n private isDrawnLayer(layerId: string): boolean {\n const drawnLayerPatterns = [\n /^gm[-_\\s]/i, // Geoman (gm-main-*, gm_*, Gm Temporary...)\n /^gl-draw[-_]/i, // Mapbox GL Draw\n /^mapbox-gl-draw[-_]/i, // Mapbox GL Draw alternative\n /^terra-draw[-_]/i, // Terra Draw\n /^maplibre-gl-draw[-_]/i, // MapLibre GL Draw\n /^draw[-_]layer/i, // Generic draw layers\n ];\n\n return drawnLayerPatterns.some(pattern => pattern.test(layerId));\n }\n\n /**\n * Convert wildcard patterns (e.g., '*-temp-*', 'debug-*') to RegExp objects\n */\n private wildcardPatternsToRegex(patterns: string[]): RegExp[] {\n return patterns.map(pattern => {\n // Escape special regex characters except *\n const escaped = pattern.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&');\n // Convert * to .* for wildcard matching\n const regexStr = escaped.replace(/\\*/g, '.*');\n return new RegExp(`^${regexStr}$`, 'i');\n });\n }\n\n /**\n * Check if a layer matches any of the user-defined exclusion patterns\n */\n private isExcludedByPattern(layerId: string): boolean {\n return this.excludeLayerPatterns.some(pattern => pattern.test(layerId));\n }\n\n /**\n * Create the main container element\n */\n private createContainer(): HTMLDivElement {\n const container = document.createElement('div');\n container.className = 'maplibregl-ctrl maplibregl-ctrl-group maplibregl-ctrl-layer-control';\n return container;\n }\n\n /**\n * Create the toggle button\n */\n private createToggleButton(): HTMLButtonElement {\n const button = document.createElement('button');\n button.type = 'button';\n button.title = 'Layer Control';\n button.setAttribute('aria-label', 'Layer Control');\n\n // Create layers icon (SVG)\n const icon = document.createElement('span');\n icon.className = 'layer-control-icon';\n icon.innerHTML =\n '<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\" ' +\n 'fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">' +\n '<polygon points=\"12 3 3 8.25 12 13.5 21 8.25 12 3\"></polygon>' +\n '<polyline points=\"3 12.75 12 18 21 12.75\"></polyline>' +\n '<polyline points=\"3 17.25 12 22 21 17.25\"></polyline>' +\n '</svg>';\n\n button.appendChild(icon);\n return button;\n }\n\n /**\n * Create the panel element\n */\n private createPanel(): HTMLDivElement {\n const panel = document.createElement('div');\n panel.className = 'layer-control-panel';\n\n // Set initial width and max height directly on the element\n panel.style.width = `${this.state.panelWidth}px`;\n panel.style.maxHeight = `${this.maxPanelHeight}px`;\n\n if (!this.state.collapsed) {\n panel.classList.add('expanded');\n }\n\n // Add header\n const header = this.createPanelHeader();\n panel.appendChild(header);\n\n // Add action buttons (Show All / Hide All)\n const actionButtons = this.createActionButtons();\n panel.appendChild(actionButtons);\n\n return panel;\n }\n\n /**\n * Detect which corner the control is positioned in\n * @returns The position: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'\n */\n private getControlPosition(): 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' {\n const parent = this.container.parentElement;\n if (!parent) return 'top-right'; // Default\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 'top-right'; // Default\n }\n\n /**\n * Update the panel position based on button location and control corner\n * Positions the panel next to the button, expanding in the appropriate direction\n */\n private updatePanelPosition(): void {\n if (!this.button || !this.panel || !this.mapContainer) return;\n\n const buttonRect = this.button.getBoundingClientRect();\n const mapRect = this.mapContainer.getBoundingClientRect();\n const position = this.getControlPosition();\n\n // Calculate button position relative to map container\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\n const panelGap = 5; // Gap between button and panel\n\n // Reset all positioning\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 // Panel expands down and to the right\n this.panel.style.top = `${buttonTop + buttonRect.height + panelGap}px`;\n this.panel.style.left = `${buttonLeft}px`;\n break;\n\n case 'top-right':\n // Panel expands down and to the left\n this.panel.style.top = `${buttonTop + buttonRect.height + panelGap}px`;\n this.panel.style.right = `${buttonRight}px`;\n break;\n\n case 'bottom-left':\n // Panel expands up and to the right\n this.panel.style.bottom = `${buttonBottom + buttonRect.height + panelGap}px`;\n this.panel.style.left = `${buttonLeft}px`;\n break;\n\n case 'bottom-right':\n // Panel expands up and to the left\n this.panel.style.bottom = `${buttonBottom + buttonRect.height + panelGap}px`;\n this.panel.style.right = `${buttonRight}px`;\n break;\n }\n }\n\n /**\n * Create action buttons for Show All / Hide All\n */\n private createActionButtons(): HTMLElement {\n const container = document.createElement('div');\n container.className = 'layer-control-actions';\n\n const showAllBtn = document.createElement('button');\n showAllBtn.type = 'button';\n showAllBtn.className = 'layer-control-action-btn';\n showAllBtn.textContent = 'Show All';\n showAllBtn.title = 'Show all layers';\n showAllBtn.addEventListener('click', () => this.setAllLayersVisibility(true));\n\n const hideAllBtn = document.createElement('button');\n hideAllBtn.type = 'button';\n hideAllBtn.className = 'layer-control-action-btn';\n hideAllBtn.textContent = 'Hide All';\n hideAllBtn.title = 'Hide all layers';\n hideAllBtn.addEventListener('click', () => this.setAllLayersVisibility(false));\n\n container.appendChild(showAllBtn);\n container.appendChild(hideAllBtn);\n\n return container;\n }\n\n /**\n * Set visibility of all layers\n */\n private setAllLayersVisibility(visible: boolean): void {\n Object.keys(this.state.layerStates).forEach(layerId => {\n // Use toggleLayerVisibility which handles both native and custom layers\n this.toggleLayerVisibility(layerId, visible);\n\n // Update checkbox in UI\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`);\n if (itemEl) {\n const checkbox = itemEl.querySelector('.layer-control-checkbox') as HTMLInputElement;\n if (checkbox) {\n checkbox.checked = visible;\n checkbox.indeterminate = false;\n }\n }\n });\n }\n\n /**\n * Create the panel header with title and width control\n */\n private createPanelHeader(): HTMLElement {\n const header = document.createElement('div');\n header.className = 'layer-control-panel-header';\n\n const title = document.createElement('span');\n title.className = 'layer-control-panel-title';\n title.textContent = 'Layers';\n header.appendChild(title);\n\n // Add width control\n const widthControl = this.createWidthControl();\n header.appendChild(widthControl);\n\n return header;\n }\n\n /**\n * Create the width control slider\n */\n private createWidthControl(): HTMLElement {\n const widthControl = document.createElement('label');\n widthControl.className = 'layer-control-width-control';\n widthControl.title = 'Adjust layer panel width';\n\n const widthLabel = document.createElement('span');\n widthLabel.textContent = 'Width';\n widthControl.appendChild(widthLabel);\n\n const widthSlider = document.createElement('div');\n widthSlider.className = 'layer-control-width-slider';\n widthSlider.setAttribute('role', 'slider');\n widthSlider.setAttribute('aria-valuemin', String(this.minPanelWidth));\n widthSlider.setAttribute('aria-valuemax', String(this.maxPanelWidth));\n widthSlider.setAttribute('aria-valuenow', String(this.state.panelWidth));\n widthSlider.setAttribute('aria-valuestep', '10');\n widthSlider.setAttribute('aria-label', 'Layer panel width');\n widthSlider.tabIndex = 0;\n\n const widthTrack = document.createElement('div');\n widthTrack.className = 'layer-control-width-track';\n const widthThumb = document.createElement('div');\n widthThumb.className = 'layer-control-width-thumb';\n\n widthSlider.appendChild(widthTrack);\n widthSlider.appendChild(widthThumb);\n\n this.widthSliderEl = widthSlider;\n this.widthThumbEl = widthThumb;\n\n // Add width value display\n const widthValue = document.createElement('span');\n widthValue.className = 'layer-control-width-value';\n this.widthValueEl = widthValue;\n\n widthControl.appendChild(widthSlider);\n widthControl.appendChild(widthValue);\n\n this.updateWidthDisplay();\n this.setupWidthSliderEvents(widthSlider);\n\n return widthControl;\n }\n\n /**\n * Setup event listeners for width slider\n */\n private setupWidthSliderEvents(widthSlider: HTMLElement): void {\n // Pointer events for dragging\n widthSlider.addEventListener('pointerdown', (event) => {\n event.preventDefault();\n const rect = widthSlider.getBoundingClientRect();\n this.widthDragRectWidth = rect.width || 1;\n this.widthDragStartX = event.clientX;\n this.widthDragStartWidth = this.state.panelWidth;\n this.isWidthSliderActive = true;\n widthSlider.setPointerCapture(event.pointerId);\n this.updateWidthFromPointer(event, true);\n });\n\n widthSlider.addEventListener('pointermove', (event) => {\n if (!this.isWidthSliderActive) return;\n this.updateWidthFromPointer(event);\n });\n\n const endPointerDrag = (event: PointerEvent) => {\n if (!this.isWidthSliderActive) return;\n if (event.pointerId !== undefined) {\n try {\n widthSlider.releasePointerCapture(event.pointerId);\n } catch (error) {\n // Ignore release errors\n }\n }\n this.isWidthSliderActive = false;\n this.widthDragRectWidth = null;\n this.widthDragStartX = null;\n this.widthDragStartWidth = null;\n this.updateWidthDisplay();\n };\n\n widthSlider.addEventListener('pointerup', endPointerDrag);\n widthSlider.addEventListener('pointercancel', endPointerDrag);\n widthSlider.addEventListener('lostpointercapture', endPointerDrag);\n\n // Keyboard navigation\n widthSlider.addEventListener('keydown', (event) => {\n let handled = true;\n const step = event.shiftKey ? 20 : 10;\n\n switch (event.key) {\n case 'ArrowLeft':\n case 'ArrowDown':\n this.applyPanelWidth(this.state.panelWidth - step, true);\n break;\n case 'ArrowRight':\n case 'ArrowUp':\n this.applyPanelWidth(this.state.panelWidth + step, true);\n break;\n case 'Home':\n this.applyPanelWidth(this.minPanelWidth, true);\n break;\n case 'End':\n this.applyPanelWidth(this.maxPanelWidth, true);\n break;\n case 'PageUp':\n this.applyPanelWidth(this.state.panelWidth + 50, true);\n break;\n case 'PageDown':\n this.applyPanelWidth(this.state.panelWidth - 50, true);\n break;\n default:\n handled = false;\n }\n\n if (handled) {\n event.preventDefault();\n this.updateWidthDisplay();\n }\n });\n }\n\n /**\n * Update panel width from pointer event\n */\n private updateWidthFromPointer(event: PointerEvent, resetBaseline = false): void {\n if (!this.widthSliderEl) return;\n\n const sliderWidth = this.widthDragRectWidth || this.widthSliderEl.getBoundingClientRect().width || 1;\n const widthRange = this.maxPanelWidth - this.minPanelWidth;\n\n let width: number;\n if (resetBaseline) {\n const rect = this.widthSliderEl.getBoundingClientRect();\n const relative = rect.width > 0 ? (event.clientX - rect.left) / rect.width : 0;\n const clampedRatio = Math.min(1, Math.max(0, relative));\n width = this.minPanelWidth + clampedRatio * widthRange;\n this.widthDragStartWidth = width;\n this.widthDragStartX = event.clientX;\n } else {\n const delta = event.clientX - (this.widthDragStartX || event.clientX);\n width = (this.widthDragStartWidth || this.state.panelWidth) + (delta / sliderWidth) * widthRange;\n }\n\n this.applyPanelWidth(width, this.isWidthSliderActive);\n }\n\n /**\n * Apply panel width (clamped to min/max)\n */\n private applyPanelWidth(width: number, immediate = false): void {\n const clamped = Math.round(Math.min(this.maxPanelWidth, Math.max(this.minPanelWidth, width)));\n\n const applyWidth = () => {\n this.state.panelWidth = clamped;\n const px = `${clamped}px`;\n this.panel.style.width = px;\n this.updateWidthDisplay();\n };\n\n if (immediate) {\n applyWidth();\n return;\n }\n\n if (this.widthFrame) {\n cancelAnimationFrame(this.widthFrame);\n }\n this.widthFrame = requestAnimationFrame(() => {\n applyWidth();\n this.widthFrame = null;\n });\n }\n\n /**\n * Update width display (value label and thumb position)\n */\n private updateWidthDisplay(): void {\n if (this.widthValueEl) {\n this.widthValueEl.textContent = `${this.state.panelWidth}px`;\n }\n if (this.widthSliderEl) {\n this.widthSliderEl.setAttribute('aria-valuenow', String(this.state.panelWidth));\n const ratio = (this.state.panelWidth - this.minPanelWidth) / (this.maxPanelWidth - this.minPanelWidth || 1);\n if (this.widthThumbEl) {\n const sliderWidth = this.widthSliderEl.clientWidth;\n // If element not yet rendered, defer the update\n if (sliderWidth === 0) {\n requestAnimationFrame(() => this.updateWidthDisplay());\n return;\n }\n const thumbWidth = this.widthThumbEl.offsetWidth || 14;\n const padding = 16;\n const available = Math.max(0, sliderWidth - padding - thumbWidth);\n const clampedRatio = Math.min(1, Math.max(0, ratio));\n const leftPx = 8 + available * clampedRatio;\n this.widthThumbEl.style.left = `${leftPx}px`;\n }\n }\n }\n\n /**\n * Setup main event listeners\n */\n private setupEventListeners(): void {\n // Toggle button click\n this.button.addEventListener('click', () => this.toggle());\n\n // Click outside to close panel and context menu\n document.addEventListener('click', (e) => {\n const target = e.target as Node;\n\n // Close context menu if clicking outside of it\n if (this.contextMenuEl && this.state.contextMenu.visible) {\n if (!this.contextMenuEl.contains(target)) {\n this.hideContextMenu();\n }\n }\n\n // Close panel if clicking outside\n if (!this.container.contains(target) && !this.panel.contains(target)) {\n this.collapse();\n }\n });\n\n // Update panel position on window resize\n this.resizeHandler = () => {\n if (!this.state.collapsed) {\n this.updatePanelPosition();\n }\n };\n window.addEventListener('resize', this.resizeHandler);\n\n // Update panel position on map resize (e.g., sidebar toggle)\n this.mapResizeHandler = () => {\n if (!this.state.collapsed) {\n this.updatePanelPosition();\n }\n };\n this.map.on('resize', this.mapResizeHandler);\n\n // Listen for map layer changes\n this.setupLayerChangeListeners();\n }\n\n /**\n * Setup listeners for map layer changes\n */\n private setupLayerChangeListeners(): void {\n this.map.on('styledata', () => {\n setTimeout(() => {\n this.updateLayerStatesFromMap();\n this.checkForNewLayers();\n }, 100);\n });\n\n this.map.on('data', (e) => {\n if (e.sourceDataType === 'content') {\n setTimeout(() => {\n this.updateLayerStatesFromMap();\n this.checkForNewLayers();\n }, 100);\n }\n });\n\n this.map.on('sourcedata', (e) => {\n if (e.sourceDataType === 'metadata') {\n setTimeout(() => {\n this.checkForNewLayers();\n }, 150);\n }\n });\n\n // Subscribe to custom layer registry changes\n if (this.customLayerRegistry) {\n this.customLayerUnsubscribe = this.customLayerRegistry.onChange(() => {\n setTimeout(() => this.checkForNewLayers(), 100);\n });\n }\n }\n\n /**\n * Toggle panel expanded/collapsed state\n */\n private toggle(): void {\n if (this.state.collapsed) {\n this.expand();\n } else {\n this.collapse();\n }\n }\n\n /**\n * Expand the panel\n */\n private expand(): void {\n this.state.collapsed = false;\n this.panel.classList.add('expanded');\n this.updatePanelPosition();\n }\n\n /**\n * Collapse the panel\n */\n private collapse(): void {\n this.state.collapsed = true;\n this.panel.classList.remove('expanded');\n }\n\n /**\n * Build layer items (called initially and when layers change)\n */\n private buildLayerItems(): void {\n // Clear existing items\n const existingItems = this.panel.querySelectorAll('.layer-control-item');\n existingItems.forEach(item => item.remove());\n this.styleEditors.clear();\n\n // Add items for all layers in our state\n Object.entries(this.state.layerStates).forEach(([layerId, state]) => {\n if (this.targetLayers.length === 0 || this.targetLayers.includes(layerId)) {\n this.addLayerItem(layerId, state);\n }\n });\n }\n\n /**\n * Add a single layer item to the panel\n */\n private addLayerItem(layerId: string, state: LayerState): void {\n const item = document.createElement('div');\n item.className = 'layer-control-item';\n item.setAttribute('data-layer-id', layerId);\n\n const row = document.createElement('div');\n row.className = 'layer-control-row';\n\n // Add drag handle (disabled for Background layer for alignment)\n if (this.enableDragAndDrop) {\n if (layerId === 'Background') {\n const disabledHandle = this.createDisabledDragHandle();\n row.appendChild(disabledHandle);\n } else {\n const dragHandle = this.createDragHandle(layerId);\n row.appendChild(dragHandle);\n }\n }\n\n // Visibility checkbox\n const checkbox = document.createElement('input');\n checkbox.type = 'checkbox';\n checkbox.className = 'layer-control-checkbox';\n checkbox.checked = state.visible;\n checkbox.addEventListener('change', () => {\n this.toggleLayerVisibility(layerId, checkbox.checked);\n });\n\n // Layer name - use custom name if set\n const displayName = this.state.customLayerNames.get(layerId) || state.name || layerId;\n const name = document.createElement('span');\n name.className = 'layer-control-name';\n name.textContent = displayName;\n name.title = displayName;\n\n row.appendChild(checkbox);\n\n // Add layer symbol (if enabled)\n if (this.showLayerSymbol) {\n if (layerId === 'Background') {\n // Special stacked layers symbol for background group\n const symbol = this.createBackgroundGroupSymbol();\n row.appendChild(symbol);\n } else {\n const symbol = this.createLayerSymbol(layerId);\n if (symbol) {\n row.appendChild(symbol);\n }\n }\n }\n\n row.appendChild(name);\n\n // Opacity slider (conditionally shown)\n if (this.showOpacitySlider) {\n const opacity = document.createElement('input');\n opacity.type = 'range';\n opacity.className = 'layer-control-opacity';\n opacity.min = '0';\n opacity.max = '1';\n opacity.step = '0.01';\n opacity.value = String(state.opacity);\n opacity.title = `Opacity: ${Math.round(state.opacity * 100)}%`;\n\n // Handle slider interaction tracking\n opacity.addEventListener('mousedown', () => {\n this.state.userInteractingWithSlider = true;\n });\n opacity.addEventListener('mouseup', () => {\n this.state.userInteractingWithSlider = false;\n });\n\n opacity.addEventListener('input', () => {\n this.changeLayerOpacity(layerId, parseFloat(opacity.value));\n opacity.title = `Opacity: ${Math.round(parseFloat(opacity.value) * 100)}%`;\n });\n\n row.appendChild(opacity);\n }\n\n // Style button for regular layers, legend button for Background\n if (this.showStyleEditor) {\n if (layerId === 'Background') {\n const legendButton = this.createBackgroundLegendButton();\n row.appendChild(legendButton);\n } else {\n const styleButton = this.createStyleButton(layerId);\n if (styleButton) {\n row.appendChild(styleButton);\n }\n }\n }\n\n item.appendChild(row);\n\n // Add context menu event listener (skip for Background layer)\n if (this.enableContextMenu && layerId !== 'Background') {\n row.addEventListener('contextmenu', (e) => {\n e.preventDefault();\n e.stopPropagation();\n this.showContextMenu(layerId, e.clientX, e.clientY);\n });\n }\n\n this.panel.appendChild(item);\n }\n\n /**\n * Create a symbol element for a layer\n * @param layerId The layer ID\n * @returns The symbol HTML element, or null if layer not found\n */\n private createLayerSymbol(layerId: string): HTMLElement | null {\n // Check if it's a custom layer first\n const layerState = this.state.layerStates[layerId];\n if (layerState?.isCustomLayer) {\n const symbolType = layerState.customLayerType || 'custom-raster';\n // Use a default color for custom layers\n const color = '#4a90d9';\n const svgMarkup = createLayerSymbolSVG(symbolType, color);\n\n const symbolContainer = document.createElement('span');\n symbolContainer.className = 'layer-control-symbol';\n symbolContainer.innerHTML = svgMarkup;\n symbolContainer.title = `Layer type: ${symbolType}`;\n\n return symbolContainer;\n }\n\n // Fall back to MapLibre layer\n const layer = this.map.getLayer(layerId);\n if (!layer) return null;\n\n const layerType = layer.type;\n const color = getLayerColor(this.map, layerId, layerType);\n const svgMarkup = createLayerSymbolSVG(layerType, color);\n\n const symbolContainer = document.createElement('span');\n symbolContainer.className = 'layer-control-symbol';\n symbolContainer.innerHTML = svgMarkup;\n symbolContainer.title = `Layer type: ${layerType}`;\n\n return symbolContainer;\n }\n\n /**\n * Create a symbol element for a background layer\n * @param layer The layer specification\n * @returns The symbol HTML element\n */\n private createBackgroundLayerSymbol(layer: LayerSpecification): HTMLElement {\n const color = getLayerColorFromSpec(layer);\n const svgMarkup = createLayerSymbolSVG(layer.type, color, { size: 14 });\n\n const symbolContainer = document.createElement('span');\n symbolContainer.className = 'background-legend-layer-symbol';\n symbolContainer.innerHTML = svgMarkup;\n symbolContainer.title = `Layer type: ${layer.type}`;\n\n return symbolContainer;\n }\n\n /**\n * Create a symbol element for the Background layer group\n * Shows a stacked layers icon to represent multiple background layers\n * @returns The symbol HTML element\n */\n private createBackgroundGroupSymbol(): HTMLElement {\n const svgMarkup = createBackgroundGroupSymbolSVG(16);\n\n const symbolContainer = document.createElement('span');\n symbolContainer.className = 'layer-control-symbol';\n symbolContainer.innerHTML = svgMarkup;\n symbolContainer.title = 'Background layers';\n\n return symbolContainer;\n }\n\n /**\n * Toggle layer visibility\n */\n private toggleLayerVisibility(layerId: string, visible: boolean): void {\n // Handle Background layer group\n if (layerId === 'Background') {\n this.toggleBackgroundVisibility(visible);\n return;\n }\n\n // Set flag to prevent checkForNewLayers from running during visibility change\n this.state.isStyleOperationInProgress = true;\n\n // Update local state\n if (this.state.layerStates[layerId]) {\n this.state.layerStates[layerId].visible = visible;\n }\n\n // Try custom layer registry first\n if (this.customLayerRegistry?.setVisibility(layerId, visible)) {\n // Clear flag after a delay for custom layers\n setTimeout(() => {\n this.state.isStyleOperationInProgress = false;\n }, 200);\n return;\n }\n\n // Fallback to native MapLibre layer\n this.map.setLayoutProperty(layerId, 'visibility', visible ? 'visible' : 'none');\n\n // Clear flag after styledata events have settled\n setTimeout(() => {\n this.state.isStyleOperationInProgress = false;\n }, 200);\n }\n\n /**\n * Change layer opacity\n */\n private changeLayerOpacity(layerId: string, opacity: number): void {\n // Handle Background layer group\n if (layerId === 'Background') {\n this.changeBackgroundOpacity(opacity);\n return;\n }\n\n // Set flag to prevent checkForNewLayers from running during opacity change\n this.state.isStyleOperationInProgress = true;\n\n // Update local state\n if (this.state.layerStates[layerId]) {\n this.state.layerStates[layerId].opacity = opacity;\n }\n\n // Try custom layer registry first\n if (this.customLayerRegistry?.setOpacity(layerId, opacity)) {\n // Clear flag after a delay for custom layers\n setTimeout(() => {\n this.state.isStyleOperationInProgress = false;\n }, 200);\n return;\n }\n\n // Fallback to native MapLibre layer\n const layerType = getLayerType(this.map, layerId);\n if (layerType) {\n setLayerOpacity(this.map, layerId, layerType, opacity);\n }\n\n // Clear flag after styledata events have settled\n setTimeout(() => {\n this.state.isStyleOperationInProgress = false;\n }, 200);\n }\n\n /**\n * Check if a layer is a user-added layer (vs basemap layer)\n * Used primarily for the background legend to determine which layers are background\n */\n private isUserAddedLayer(layerId: string): boolean {\n // If this layer is in our state (and not Background), it's user-added\n if (this.state.layerStates[layerId] !== undefined && layerId !== 'Background') {\n return true;\n }\n\n // If we have basemapLayerIds (from basemapStyleUrl), check if the layer is NOT in the basemap\n if (this.basemapLayerIds !== null && this.basemapLayerIds.size > 0) {\n return !this.basemapLayerIds.has(layerId);\n }\n\n // For layers not in our state, check if the layer was added after control initialization\n // or uses a user-added source\n if (this.initialLayerIds !== null && !this.initialLayerIds.has(layerId)) {\n // Layer was added after control - it's user-added\n return true;\n }\n\n // Check source-based heuristics\n const layer = this.map.getLayer(layerId);\n if (layer) {\n const sourceId = (layer as any).source;\n if (sourceId) {\n const userAddedSourceIds = this.detectUserAddedSources();\n return userAddedSourceIds.has(sourceId);\n }\n }\n\n return false;\n }\n\n /**\n * Toggle visibility for all background layers (basemap layers)\n */\n private toggleBackgroundVisibility(visible: boolean): void {\n // Update local state\n if (this.state.layerStates['Background']) {\n this.state.layerStates['Background'].visible = visible;\n }\n\n // Apply to all basemap layers (layers not in layerStates)\n const styleLayers = this.map.getStyle().layers || [];\n styleLayers.forEach(layer => {\n if (!this.isUserAddedLayer(layer.id)) {\n // Update visibility cache\n this.state.backgroundLayerVisibility.set(layer.id, visible);\n this.map.setLayoutProperty(layer.id, 'visibility', visible ? 'visible' : 'none');\n }\n });\n\n // Update legend panel checkboxes if open\n if (this.state.backgroundLegendOpen) {\n const legendPanel = this.panel.querySelector('.layer-control-background-legend');\n if (legendPanel) {\n const checkboxes = legendPanel.querySelectorAll('.background-legend-checkbox') as NodeListOf<HTMLInputElement>;\n checkboxes.forEach(checkbox => {\n checkbox.checked = visible;\n });\n }\n }\n }\n\n /**\n * Change opacity for all background layers (basemap layers)\n */\n private changeBackgroundOpacity(opacity: number): void {\n // Update local state\n if (this.state.layerStates['Background']) {\n this.state.layerStates['Background'].opacity = opacity;\n }\n\n // Apply to all basemap layers (layers not in layerStates)\n const styleLayers = this.map.getStyle().layers || [];\n styleLayers.forEach(styleLayer => {\n if (!this.isUserAddedLayer(styleLayer.id)) {\n const layerType = getLayerType(this.map, styleLayer.id);\n if (layerType) {\n setLayerOpacity(this.map, styleLayer.id, layerType, opacity);\n }\n }\n });\n }\n\n // ===== Background Legend Methods =====\n\n /**\n * Create legend button for Background layer\n */\n private createBackgroundLegendButton(): HTMLButtonElement {\n const button = document.createElement('button');\n button.className = 'layer-control-style-button layer-control-background-legend-button';\n button.innerHTML = '⚙'; // Gear icon (same as style button)\n button.title = 'Show background layer details';\n button.setAttribute('aria-label', 'Show background layer visibility controls');\n button.setAttribute('aria-expanded', String(this.state.backgroundLegendOpen));\n\n button.addEventListener('click', (e) => {\n e.stopPropagation();\n this.toggleBackgroundLegend();\n });\n\n return button;\n }\n\n /**\n * Toggle background legend panel visibility\n */\n private toggleBackgroundLegend(): void {\n if (this.state.backgroundLegendOpen) {\n this.closeBackgroundLegend();\n } else {\n this.openBackgroundLegend();\n }\n }\n\n /**\n * Open background legend panel\n */\n private openBackgroundLegend(): void {\n // Close any open style editor first\n if (this.state.activeStyleEditor) {\n this.closeStyleEditor(this.state.activeStyleEditor);\n }\n\n const itemEl = this.panel.querySelector('[data-layer-id=\"Background\"]');\n if (!itemEl) return;\n\n // Check if panel already exists\n let legendPanel = itemEl.querySelector('.layer-control-background-legend');\n if (legendPanel) {\n // Refresh the list\n const layerList = legendPanel.querySelector('.background-legend-layer-list');\n if (layerList) {\n this.populateBackgroundLayerList(layerList as HTMLElement);\n }\n } else {\n // Create new panel\n legendPanel = this.createBackgroundLegendPanel();\n itemEl.appendChild(legendPanel);\n }\n\n this.state.backgroundLegendOpen = true;\n\n // Update button aria state\n const button = itemEl.querySelector('.layer-control-background-legend-button');\n if (button) {\n button.setAttribute('aria-expanded', 'true');\n button.classList.add('active');\n }\n\n // Scroll into view\n setTimeout(() => {\n legendPanel?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }, 50);\n }\n\n /**\n * Close background legend panel\n */\n private closeBackgroundLegend(): void {\n const itemEl = this.panel.querySelector('[data-layer-id=\"Background\"]');\n if (!itemEl) return;\n\n const legendPanel = itemEl.querySelector('.layer-control-background-legend');\n if (legendPanel) {\n legendPanel.remove();\n }\n\n this.state.backgroundLegendOpen = false;\n\n // Update button aria state\n const button = itemEl.querySelector('.layer-control-background-legend-button');\n if (button) {\n button.setAttribute('aria-expanded', 'false');\n button.classList.remove('active');\n }\n }\n\n /**\n * Create the background legend panel with individual layer controls\n */\n private createBackgroundLegendPanel(): HTMLDivElement {\n const panel = document.createElement('div');\n panel.className = 'layer-control-background-legend';\n\n // Header\n const header = document.createElement('div');\n header.className = 'background-legend-header';\n\n const title = document.createElement('span');\n title.className = 'background-legend-title';\n title.textContent = 'Background Layers';\n\n const closeBtn = document.createElement('button');\n closeBtn.className = 'background-legend-close';\n closeBtn.innerHTML = '×';\n closeBtn.title = 'Close';\n closeBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.closeBackgroundLegend();\n });\n\n header.appendChild(title);\n header.appendChild(closeBtn);\n\n // Quick actions row\n const actionsRow = document.createElement('div');\n actionsRow.className = 'background-legend-actions';\n\n const showAllBtn = document.createElement('button');\n showAllBtn.className = 'background-legend-action-btn';\n showAllBtn.textContent = 'Show All';\n showAllBtn.addEventListener('click', () => this.setAllBackgroundLayersVisibility(true));\n\n const hideAllBtn = document.createElement('button');\n hideAllBtn.className = 'background-legend-action-btn';\n hideAllBtn.textContent = 'Hide All';\n hideAllBtn.addEventListener('click', () => this.setAllBackgroundLayersVisibility(false));\n\n actionsRow.appendChild(showAllBtn);\n actionsRow.appendChild(hideAllBtn);\n\n // Filter row - \"Only rendered\" checkbox\n const filterRow = document.createElement('div');\n filterRow.className = 'background-legend-filter';\n\n const filterCheckbox = document.createElement('input');\n filterCheckbox.type = 'checkbox';\n filterCheckbox.className = 'background-legend-filter-checkbox';\n filterCheckbox.id = 'background-legend-only-rendered';\n filterCheckbox.checked = this.state.onlyRenderedFilter;\n filterCheckbox.addEventListener('change', () => {\n this.state.onlyRenderedFilter = filterCheckbox.checked;\n const layerList = panel.querySelector('.background-legend-layer-list');\n if (layerList) {\n this.populateBackgroundLayerList(layerList as HTMLElement);\n }\n });\n\n const filterLabel = document.createElement('label');\n filterLabel.className = 'background-legend-filter-label';\n filterLabel.htmlFor = 'background-legend-only-rendered';\n filterLabel.textContent = 'Only rendered';\n\n filterRow.appendChild(filterCheckbox);\n filterRow.appendChild(filterLabel);\n\n // Layer list container (scrollable)\n const layerList = document.createElement('div');\n layerList.className = 'background-legend-layer-list';\n\n // Populate with background layers\n this.populateBackgroundLayerList(layerList);\n\n panel.appendChild(header);\n panel.appendChild(actionsRow);\n panel.appendChild(filterRow);\n panel.appendChild(layerList);\n\n return panel;\n }\n\n /**\n * Check if a layer is currently rendered in the map viewport\n */\n private isLayerRendered(layerId: string): boolean {\n try {\n const layer = this.map.getLayer(layerId);\n if (!layer) return false;\n\n // Check if layer is visible first\n const visibility = this.map.getLayoutProperty(layerId, 'visibility');\n if (visibility === 'none') return false;\n\n // For raster layers, check if tiles are loaded\n if (layer.type === 'raster' || layer.type === 'hillshade') {\n // Raster layers are considered rendered if visible\n return true;\n }\n\n // For background layers (solid color), they're always rendered if visible\n if (layer.type === 'background') {\n return true;\n }\n\n // For vector layers, use queryRenderedFeatures to check if any features are visible\n const features = this.map.queryRenderedFeatures({ layers: [layerId] });\n return features.length > 0;\n } catch (error) {\n // If query fails, assume layer is rendered if we can see it\n return true;\n }\n }\n\n /**\n * Populate the background layer list with individual layers\n */\n private populateBackgroundLayerList(container: HTMLElement): void {\n container.innerHTML = ''; // Clear existing\n\n const styleLayers = this.map.getStyle().layers || [];\n\n styleLayers.forEach(layer => {\n if (!this.isUserAddedLayer(layer.id)) {\n // Skip drawn layers if excludeDrawnLayers is enabled\n if (this.excludeDrawnLayers && this.isDrawnLayer(layer.id)) {\n return;\n }\n\n // Skip layers matching user-defined exclusion patterns\n if (this.isExcludedByPattern(layer.id)) {\n return;\n }\n\n // If \"Only rendered\" filter is enabled, skip layers that aren't rendered\n if (this.state.onlyRenderedFilter && !this.isLayerRendered(layer.id)) {\n return;\n }\n\n // This is a background layer\n const layerRow = document.createElement('div');\n layerRow.className = 'background-legend-layer-row';\n layerRow.setAttribute('data-background-layer-id', layer.id);\n\n // Checkbox\n const checkbox = document.createElement('input');\n checkbox.type = 'checkbox';\n checkbox.className = 'background-legend-checkbox';\n\n // Get visibility from map or cache\n const visibility = this.map.getLayoutProperty(layer.id, 'visibility');\n const isVisible = visibility !== 'none';\n checkbox.checked = isVisible;\n\n // Update cache\n this.state.backgroundLayerVisibility.set(layer.id, isVisible);\n\n checkbox.addEventListener('change', () => {\n this.toggleIndividualBackgroundLayer(layer.id, checkbox.checked);\n });\n\n // Layer name\n const name = document.createElement('span');\n name.className = 'background-legend-layer-name';\n name.textContent = this.generateFriendlyName(layer.id);\n name.title = layer.id; // Show full ID on hover\n\n // Layer type indicator\n const typeIndicator = document.createElement('span');\n typeIndicator.className = 'background-legend-layer-type';\n typeIndicator.textContent = layer.type;\n\n layerRow.appendChild(checkbox);\n\n // Add layer symbol (if enabled)\n if (this.showLayerSymbol) {\n const symbol = this.createBackgroundLayerSymbol(layer);\n if (symbol) {\n layerRow.appendChild(symbol);\n }\n }\n\n layerRow.appendChild(name);\n layerRow.appendChild(typeIndicator);\n container.appendChild(layerRow);\n }\n });\n\n // Show message if no background layers\n if (container.children.length === 0) {\n const emptyMsg = document.createElement('p');\n emptyMsg.className = 'background-legend-empty';\n emptyMsg.textContent = this.state.onlyRenderedFilter\n ? 'No rendered layers in current view.'\n : 'No background layers found.';\n container.appendChild(emptyMsg);\n }\n }\n\n /**\n * Toggle visibility of an individual background layer\n */\n private toggleIndividualBackgroundLayer(layerId: string, visible: boolean): void {\n // Update visibility cache\n this.state.backgroundLayerVisibility.set(layerId, visible);\n\n // Apply to map\n this.map.setLayoutProperty(layerId, 'visibility', visible ? 'visible' : 'none');\n\n // Update the main Background checkbox state\n this.updateBackgroundCheckboxState();\n }\n\n /**\n * Set visibility for all background layers\n */\n private setAllBackgroundLayersVisibility(visible: boolean): void {\n const styleLayers = this.map.getStyle().layers || [];\n\n styleLayers.forEach(layer => {\n if (!this.isUserAddedLayer(layer.id)) {\n this.state.backgroundLayerVisibility.set(layer.id, visible);\n this.map.setLayoutProperty(layer.id, 'visibility', visible ? 'visible' : 'none');\n }\n });\n\n // Update checkboxes in the legend panel\n const legendPanel = this.panel.querySelector('.layer-control-background-legend');\n if (legendPanel) {\n const checkboxes = legendPanel.querySelectorAll('.background-legend-checkbox') as NodeListOf<HTMLInputElement>;\n checkboxes.forEach(checkbox => {\n checkbox.checked = visible;\n });\n }\n\n // Update main Background checkbox\n this.updateBackgroundCheckboxState();\n }\n\n /**\n * Update the main Background checkbox based on individual layer states\n */\n private updateBackgroundCheckboxState(): void {\n const styleLayers = this.map.getStyle().layers || [];\n let anyVisible = false;\n let allVisible = true;\n\n styleLayers.forEach(layer => {\n if (!this.isUserAddedLayer(layer.id)) {\n const visible = this.state.backgroundLayerVisibility.get(layer.id);\n if (visible === true) anyVisible = true;\n if (visible === false) allVisible = false;\n }\n });\n\n // Update main checkbox\n const backgroundItem = this.panel.querySelector('[data-layer-id=\"Background\"]');\n if (backgroundItem) {\n const checkbox = backgroundItem.querySelector('.layer-control-checkbox') as HTMLInputElement;\n if (checkbox) {\n checkbox.checked = anyVisible;\n checkbox.indeterminate = anyVisible && !allVisible;\n }\n }\n\n // Update layerState\n if (this.state.layerStates['Background']) {\n this.state.layerStates['Background'].visible = anyVisible;\n }\n }\n\n /**\n * Create style button for a layer\n */\n private createStyleButton(layerId: string): HTMLButtonElement | null {\n // Don't create button for Background layer\n if (layerId === 'Background') {\n return null;\n }\n\n const layerState = this.state.layerStates[layerId];\n const isCustomLayer = layerState?.isCustomLayer === true;\n\n const button = document.createElement('button');\n button.className = 'layer-control-style-button';\n button.innerHTML = '⚙'; // Gear icon\n\n if (isCustomLayer) {\n // Custom layers don't support style editing - show info panel instead\n button.title = 'Layer info (style editing not available)';\n button.setAttribute('aria-label', `Layer info for ${layerId}`);\n } else {\n button.title = 'Edit layer style';\n button.setAttribute('aria-label', `Edit style for ${layerId}`);\n }\n\n button.addEventListener('click', (e) => {\n e.stopPropagation();\n this.toggleStyleEditor(layerId);\n });\n\n return button;\n }\n\n /**\n * Toggle style editor for a layer\n */\n private toggleStyleEditor(layerId: string): void {\n // If this editor is already open, close it\n if (this.state.activeStyleEditor === layerId) {\n this.closeStyleEditor(layerId);\n return;\n }\n\n // Close any other open editor\n if (this.state.activeStyleEditor) {\n this.closeStyleEditor(this.state.activeStyleEditor);\n }\n\n // Open this editor\n this.openStyleEditor(layerId);\n }\n\n /**\n * Open style editor for a layer\n */\n private openStyleEditor(layerId: string): void {\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`);\n if (!itemEl) return;\n\n // Check if this is a custom layer\n const layerState = this.state.layerStates[layerId];\n if (layerState?.isCustomLayer) {\n // Show info message for custom layers\n const editor = this.createCustomLayerInfoPanel(layerId);\n itemEl.appendChild(editor);\n this.styleEditors.set(layerId, editor);\n this.state.activeStyleEditor = layerId;\n\n // Scroll into view\n setTimeout(() => {\n editor.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }, 50);\n return;\n }\n\n // Cache original style if not already cached\n if (!this.state.originalStyles.has(layerId)) {\n const layer = this.map.getLayer(layerId);\n if (layer) {\n cacheOriginalLayerStyle(this.map, layerId, this.state.originalStyles);\n }\n }\n\n // Create style editor UI\n const editor = this.createStyleEditor(layerId);\n if (!editor) return;\n\n itemEl.appendChild(editor);\n this.styleEditors.set(layerId, editor);\n this.state.activeStyleEditor = layerId;\n\n // Scroll editor into view\n setTimeout(() => {\n editor.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }, 50);\n }\n\n /**\n * Create info panel for custom layers (style editing not supported)\n */\n private createCustomLayerInfoPanel(layerId: string): HTMLDivElement {\n const editor = document.createElement('div');\n editor.className = 'layer-control-style-editor layer-control-custom-info';\n\n // Header\n const header = document.createElement('div');\n header.className = 'style-editor-header';\n\n const title = document.createElement('span');\n title.className = 'style-editor-title';\n title.textContent = 'Layer Info';\n\n const closeBtn = document.createElement('button');\n closeBtn.className = 'style-editor-close';\n closeBtn.innerHTML = '×';\n closeBtn.title = 'Close';\n closeBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.closeStyleEditor(layerId);\n });\n\n header.appendChild(title);\n header.appendChild(closeBtn);\n\n // Info content\n const content = document.createElement('div');\n content.className = 'style-editor-controls';\n\n const infoText = document.createElement('p');\n infoText.className = 'layer-control-custom-info-text';\n infoText.textContent = `This is a custom layer. Style editing is not available for this layer type. Use the visibility toggle and opacity slider to control the layer.`;\n\n content.appendChild(infoText);\n\n // Close button\n const actions = document.createElement('div');\n actions.className = 'style-editor-actions';\n\n const closeActionBtn = document.createElement('button');\n closeActionBtn.className = 'style-editor-button style-editor-button-close';\n closeActionBtn.textContent = 'Close';\n closeActionBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.closeStyleEditor(layerId);\n });\n\n actions.appendChild(closeActionBtn);\n\n editor.appendChild(header);\n editor.appendChild(content);\n editor.appendChild(actions);\n\n return editor;\n }\n\n /**\n * Close style editor for a layer\n */\n private closeStyleEditor(layerId: string): void {\n const editor = this.styleEditors.get(layerId);\n if (editor) {\n editor.remove();\n this.styleEditors.delete(layerId);\n }\n\n if (this.state.activeStyleEditor === layerId) {\n this.state.activeStyleEditor = null;\n }\n }\n\n /**\n * Create style editor UI\n */\n private createStyleEditor(layerId: string): HTMLDivElement | null {\n const layer = this.map.getLayer(layerId);\n if (!layer) return null;\n\n const editor = document.createElement('div');\n editor.className = 'layer-control-style-editor';\n\n // Header\n const header = document.createElement('div');\n header.className = 'style-editor-header';\n\n const title = document.createElement('span');\n title.className = 'style-editor-title';\n title.textContent = 'Edit Style';\n\n const closeBtn = document.createElement('button');\n closeBtn.className = 'style-editor-close';\n closeBtn.innerHTML = '×';\n closeBtn.title = 'Close';\n closeBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.closeStyleEditor(layerId);\n });\n\n header.appendChild(title);\n header.appendChild(closeBtn);\n\n // Controls container - populate based on layer type\n const controls = document.createElement('div');\n controls.className = 'style-editor-controls';\n\n const layerType = layer.type;\n this.addStyleControlsForLayerType(controls, layerId, layerType);\n\n // Action buttons\n const actions = document.createElement('div');\n actions.className = 'style-editor-actions';\n\n const resetBtn = document.createElement('button');\n resetBtn.className = 'style-editor-button style-editor-button-reset';\n resetBtn.textContent = 'Reset';\n resetBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.resetLayerStyle(layerId);\n });\n\n const removeBtn = document.createElement('button');\n removeBtn.className = 'style-editor-button style-editor-button-remove';\n removeBtn.textContent = 'Remove';\n removeBtn.title = 'Remove layer from map';\n removeBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n if (confirm('Are you sure you want to remove this layer?')) {\n this.closeStyleEditor(layerId);\n this.removeLayer(layerId);\n }\n });\n\n const closeActionBtn = document.createElement('button');\n closeActionBtn.className = 'style-editor-button style-editor-button-close';\n closeActionBtn.textContent = 'Close';\n closeActionBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.closeStyleEditor(layerId);\n });\n\n actions.appendChild(resetBtn);\n actions.appendChild(removeBtn);\n actions.appendChild(closeActionBtn);\n\n editor.appendChild(header);\n editor.appendChild(controls);\n editor.appendChild(actions);\n\n return editor;\n }\n\n /**\n * Add style controls based on layer type\n */\n private addStyleControlsForLayerType(container: HTMLElement, layerId: string, layerType: string): void {\n switch (layerType) {\n case 'fill':\n this.addFillControls(container, layerId);\n break;\n case 'line':\n this.addLineControls(container, layerId);\n break;\n case 'circle':\n this.addCircleControls(container, layerId);\n break;\n case 'raster':\n this.addRasterControls(container, layerId);\n break;\n case 'symbol':\n this.addSymbolControls(container, layerId);\n break;\n default:\n container.textContent = `Style controls for ${layerType} layers not yet implemented.`;\n }\n }\n\n /**\n * Add controls for fill layers\n */\n private addFillControls(container: HTMLElement, layerId: string): void {\n // Fill Color - try layer definition first, then runtime property\n const style = this.map.getStyle();\n const layer = style.layers?.find(l => l.id === layerId);\n let fillColor: any = undefined;\n\n // First try to get from layer definition\n if (layer && 'paint' in layer && layer.paint && 'fill-color' in layer.paint) {\n fillColor = layer.paint['fill-color'];\n }\n\n // Fallback to runtime property if not in definition\n if (!fillColor) {\n fillColor = this.map.getPaintProperty(layerId, 'fill-color');\n }\n\n this.createColorControl(container, layerId, 'fill-color', 'Fill Color', normalizeColor(fillColor || '#088'));\n\n // Fill Opacity\n const fillOpacity = this.map.getPaintProperty(layerId, 'fill-opacity');\n if (fillOpacity !== undefined && typeof fillOpacity === 'number') {\n this.createSliderControl(container, layerId, 'fill-opacity', 'Fill Opacity', fillOpacity, 0, 1, 0.05);\n }\n\n // Fill Outline Color\n const outlineColor = this.map.getPaintProperty(layerId, 'fill-outline-color');\n if (outlineColor !== undefined) {\n this.createColorControl(container, layerId, 'fill-outline-color', 'Outline Color', normalizeColor(outlineColor));\n }\n }\n\n /**\n * Add controls for line layers\n */\n private addLineControls(container: HTMLElement, layerId: string): void {\n // Line Color - try layer definition first, then runtime property\n const style = this.map.getStyle();\n const layer = style.layers?.find(l => l.id === layerId);\n let lineColor: any = undefined;\n\n // First try to get from layer definition\n if (layer && 'paint' in layer && layer.paint && 'line-color' in layer.paint) {\n lineColor = layer.paint['line-color'];\n }\n\n // Fallback to runtime property if not in definition\n if (!lineColor) {\n lineColor = this.map.getPaintProperty(layerId, 'line-color');\n }\n\n this.createColorControl(container, layerId, 'line-color', 'Line Color', normalizeColor(lineColor || '#000'));\n\n // Line Width\n const lineWidth = this.map.getPaintProperty(layerId, 'line-width');\n this.createSliderControl(container, layerId, 'line-width', 'Line Width', typeof lineWidth === 'number' ? lineWidth : 1, 0, 20, 0.5);\n\n // Line Opacity\n const lineOpacity = this.map.getPaintProperty(layerId, 'line-opacity');\n if (lineOpacity !== undefined && typeof lineOpacity === 'number') {\n this.createSliderControl(container, layerId, 'line-opacity', 'Line Opacity', lineOpacity, 0, 1, 0.05);\n }\n\n // Line Blur\n const lineBlur = this.map.getPaintProperty(layerId, 'line-blur');\n if (lineBlur !== undefined && typeof lineBlur === 'number') {\n this.createSliderControl(container, layerId, 'line-blur', 'Line Blur', lineBlur, 0, 5, 0.1);\n }\n }\n\n /**\n * Add controls for circle layers\n */\n private addCircleControls(container: HTMLElement, layerId: string): void {\n // Circle Color - try layer definition first, then runtime property\n const style = this.map.getStyle();\n const layer = style.layers?.find(l => l.id === layerId);\n let circleColor: any = undefined;\n\n // First try to get from layer definition\n if (layer && 'paint' in layer && layer.paint && 'circle-color' in layer.paint) {\n circleColor = layer.paint['circle-color'];\n }\n\n // Fallback to runtime property if not in definition\n if (!circleColor) {\n circleColor = this.map.getPaintProperty(layerId, 'circle-color');\n }\n\n this.createColorControl(container, layerId, 'circle-color', 'Circle Color', normalizeColor(circleColor || '#000'));\n\n // Circle Radius\n const circleRadius = this.map.getPaintProperty(layerId, 'circle-radius');\n this.createSliderControl(container, layerId, 'circle-radius', 'Radius', typeof circleRadius === 'number' ? circleRadius : 5, 0, 40, 0.5);\n\n // Circle Opacity\n const circleOpacity = this.map.getPaintProperty(layerId, 'circle-opacity');\n if (circleOpacity !== undefined && typeof circleOpacity === 'number') {\n this.createSliderControl(container, layerId, 'circle-opacity', 'Opacity', circleOpacity, 0, 1, 0.05);\n }\n\n // Circle Stroke Color\n const strokeColor = this.map.getPaintProperty(layerId, 'circle-stroke-color');\n if (strokeColor !== undefined) {\n this.createColorControl(container, layerId, 'circle-stroke-color', 'Stroke Color', normalizeColor(strokeColor));\n }\n\n // Circle Stroke Width\n const strokeWidth = this.map.getPaintProperty(layerId, 'circle-stroke-width');\n if (strokeWidth !== undefined && typeof strokeWidth === 'number') {\n this.createSliderControl(container, layerId, 'circle-stroke-width', 'Stroke Width', strokeWidth, 0, 10, 0.1);\n }\n }\n\n /**\n * Add controls for raster layers\n */\n private addRasterControls(container: HTMLElement, layerId: string): void {\n // Raster Opacity\n const rasterOpacity = this.map.getPaintProperty(layerId, 'raster-opacity');\n this.createSliderControl(container, layerId, 'raster-opacity', 'Opacity', typeof rasterOpacity === 'number' ? rasterOpacity : 1, 0, 1, 0.05);\n\n // Raster Brightness Min\n const brightnessMin = this.map.getPaintProperty(layerId, 'raster-brightness-min');\n this.createSliderControl(container, layerId, 'raster-brightness-min', 'Brightness Min', typeof brightnessMin === 'number' ? brightnessMin : 0, -1, 1, 0.05);\n\n // Raster Brightness Max\n const brightnessMax = this.map.getPaintProperty(layerId, 'raster-brightness-max');\n this.createSliderControl(container, layerId, 'raster-brightness-max', 'Brightness Max', typeof brightnessMax === 'number' ? brightnessMax : 1, -1, 1, 0.05);\n\n // Raster Saturation\n const saturation = this.map.getPaintProperty(layerId, 'raster-saturation');\n this.createSliderControl(container, layerId, 'raster-saturation', 'Saturation', typeof saturation === 'number' ? saturation : 0, -1, 1, 0.05);\n\n // Raster Contrast\n const contrast = this.map.getPaintProperty(layerId, 'raster-contrast');\n this.createSliderControl(container, layerId, 'raster-contrast', 'Contrast', typeof contrast === 'number' ? contrast : 0, -1, 1, 0.05);\n\n // Raster Hue Rotate\n const hueRotate = this.map.getPaintProperty(layerId, 'raster-hue-rotate');\n this.createSliderControl(container, layerId, 'raster-hue-rotate', 'Hue Rotate', typeof hueRotate === 'number' ? hueRotate : 0, 0, 350, 5);\n }\n\n /**\n * Add controls for symbol layers\n */\n private addSymbolControls(container: HTMLElement, layerId: string): void {\n // Text Color\n const textColor = this.map.getPaintProperty(layerId, 'text-color');\n if (textColor !== undefined) {\n this.createColorControl(container, layerId, 'text-color', 'Text Color', normalizeColor(textColor));\n }\n\n // Text Opacity\n const textOpacity = this.map.getPaintProperty(layerId, 'text-opacity');\n if (textOpacity !== undefined && typeof textOpacity === 'number') {\n this.createSliderControl(container, layerId, 'text-opacity', 'Text Opacity', textOpacity, 0, 1, 0.05);\n }\n\n // Icon Opacity\n const iconOpacity = this.map.getPaintProperty(layerId, 'icon-opacity');\n if (iconOpacity !== undefined && typeof iconOpacity === 'number') {\n this.createSliderControl(container, layerId, 'icon-opacity', 'Icon Opacity', iconOpacity, 0, 1, 0.05);\n }\n }\n\n /**\n * Create a color control\n */\n private createColorControl(\n container: HTMLElement,\n layerId: string,\n property: string,\n label: string,\n initialValue: string\n ): void {\n const controlGroup = document.createElement('div');\n controlGroup.className = 'style-control-group';\n\n const labelEl = document.createElement('label');\n labelEl.className = 'style-control-label';\n labelEl.textContent = label;\n\n const inputWrapper = document.createElement('div');\n inputWrapper.className = 'style-control-color-group';\n\n const colorInput = document.createElement('input');\n colorInput.type = 'color';\n colorInput.className = 'style-control-color-picker';\n colorInput.value = initialValue;\n colorInput.dataset.property = property;\n\n const hexDisplay = document.createElement('input');\n hexDisplay.type = 'text';\n hexDisplay.className = 'style-control-color-value';\n hexDisplay.value = initialValue;\n hexDisplay.readOnly = true;\n\n colorInput.addEventListener('input', () => {\n const color = colorInput.value;\n hexDisplay.value = color;\n this.map.setPaintProperty(layerId, property, color);\n });\n\n inputWrapper.appendChild(colorInput);\n inputWrapper.appendChild(hexDisplay);\n\n controlGroup.appendChild(labelEl);\n controlGroup.appendChild(inputWrapper);\n\n container.appendChild(controlGroup);\n }\n\n /**\n * Create a slider control\n */\n private createSliderControl(\n container: HTMLElement,\n layerId: string,\n property: string,\n label: string,\n initialValue: number,\n min: number,\n max: number,\n step: number\n ): void {\n const controlGroup = document.createElement('div');\n controlGroup.className = 'style-control-group';\n\n const labelEl = document.createElement('label');\n labelEl.className = 'style-control-label';\n labelEl.textContent = label;\n\n const inputWrapper = document.createElement('div');\n inputWrapper.className = 'style-control-input-wrapper';\n\n const slider = document.createElement('input');\n slider.type = 'range';\n slider.className = 'style-control-slider';\n slider.min = String(min);\n slider.max = String(max);\n slider.step = String(step);\n slider.value = String(initialValue);\n slider.dataset.property = property;\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'style-control-value';\n valueDisplay.textContent = formatNumericValue(initialValue, step);\n\n slider.addEventListener('input', () => {\n const value = parseFloat(slider.value);\n valueDisplay.textContent = formatNumericValue(value, step);\n this.map.setPaintProperty(layerId, property, value);\n });\n\n inputWrapper.appendChild(slider);\n inputWrapper.appendChild(valueDisplay);\n\n controlGroup.appendChild(labelEl);\n controlGroup.appendChild(inputWrapper);\n\n container.appendChild(controlGroup);\n }\n\n /**\n * Reset layer style to original\n */\n private resetLayerStyle(layerId: string): void {\n const originalStyle = this.state.originalStyles.get(layerId);\n if (!originalStyle) return;\n\n // Restore original paint properties\n restoreOriginalStyle(this.map, layerId, this.state.originalStyles);\n\n // Update UI controls to reflect the reset values\n const editor = this.styleEditors.get(layerId);\n if (editor) {\n // Update all slider controls\n const sliders = editor.querySelectorAll('.style-control-slider') as NodeListOf<HTMLInputElement>;\n sliders.forEach(slider => {\n const property = slider.dataset.property;\n if (property) {\n const value = this.map.getPaintProperty(layerId, property);\n if (value !== undefined && typeof value === 'number') {\n slider.value = String(value);\n // Update value display\n const valueDisplay = slider.parentElement?.querySelector('.style-control-value');\n if (valueDisplay) {\n const step = parseFloat(slider.step);\n valueDisplay.textContent = formatNumericValue(value, step);\n }\n }\n }\n });\n\n // Update all color controls\n const colorPickers = editor.querySelectorAll('.style-control-color-picker') as NodeListOf<HTMLInputElement>;\n colorPickers.forEach(picker => {\n const property = picker.dataset.property;\n if (property) {\n const value = this.map.getPaintProperty(layerId, property);\n if (value !== undefined) {\n const hexColor = normalizeColor(value);\n picker.value = hexColor;\n // Update hex display\n const hexDisplay = picker.parentElement?.querySelector('.style-control-color-value');\n if (hexDisplay) {\n hexDisplay.textContent = hexColor;\n }\n }\n }\n });\n }\n }\n\n /**\n * Update layer states from map (sync UI with map)\n */\n private updateLayerStatesFromMap(): void {\n if (this.state.userInteractingWithSlider) {\n return; // Don't update while user is dragging\n }\n\n Object.keys(this.state.layerStates).forEach(layerId => {\n try {\n // Skip custom layers - they manage their own state via adapters\n if (this.state.layerStates[layerId]?.isCustomLayer) {\n return;\n }\n\n // Skip Background layer group\n if (layerId === 'Background') {\n return;\n }\n\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n // Check visibility\n const visibility = this.map.getLayoutProperty(layerId, 'visibility');\n const isVisible = visibility !== 'none';\n\n // Get opacity\n const layerType = layer.type;\n const opacity = getLayerOpacity(this.map, layerId, layerType);\n\n // Update local state\n if (this.state.layerStates[layerId]) {\n this.state.layerStates[layerId].visible = isVisible;\n this.state.layerStates[layerId].opacity = opacity;\n }\n\n // Update UI\n this.updateUIForLayer(layerId, isVisible, opacity);\n } catch (error) {\n console.warn(`Failed to update state for layer ${layerId}:`, error);\n }\n });\n }\n\n /**\n * Update UI elements for a specific layer\n */\n private updateUIForLayer(layerId: string, visible: boolean, opacity: number): void {\n const layerItems = this.panel.querySelectorAll('.layer-control-item');\n\n layerItems.forEach(item => {\n if ((item as HTMLElement).dataset.layerId === layerId) {\n const checkbox = item.querySelector('.layer-control-checkbox') as HTMLInputElement;\n const opacitySlider = item.querySelector('.layer-control-opacity') as HTMLInputElement;\n\n if (checkbox) {\n checkbox.checked = visible;\n }\n\n if (opacitySlider) {\n opacitySlider.value = String(opacity);\n opacitySlider.title = `Opacity: ${Math.round(opacity * 100)}%`;\n }\n }\n });\n }\n\n /**\n * Check for new layers and add them to the control, remove deleted layers\n */\n private checkForNewLayers(): void {\n // Skip checking for new layers during style operations to prevent race conditions\n // that could incorrectly delete custom layers\n if (this.state.isStyleOperationInProgress) {\n return;\n }\n\n try {\n const style = this.map.getStyle();\n if (!style || !style.layers) {\n return;\n }\n\n const currentMapLayerIds = new Set(style.layers.map(layer => layer.id));\n\n // Check if we're in auto-detect mode (no specific layers were specified)\n const isAutoDetectMode = this.targetLayers.length === 0 ||\n (this.targetLayers.length === 1 && this.targetLayers[0] === 'Background') ||\n this.targetLayers.every(id => id === 'Background' || this.state.layerStates[id]);\n\n // Find new layers that aren't in our state yet\n const newLayers: string[] = [];\n\n // Detection priority for NEW layers (added after control):\n // 1. basemapLayerIds (from basemapStyleUrl) - most reliable\n // 2. initialLayerIds - layer NOT in initialLayerIds means it was added after control\n // 3. Source-based heuristics - fallback\n const useBasemapStyleDetection = this.basemapLayerIds !== null && this.basemapLayerIds.size > 0;\n const useInitialLayerDetection = !useBasemapStyleDetection && this.initialLayerIds !== null && this.initialLayerIds.size > 0;\n\n currentMapLayerIds.forEach(layerId => {\n if (layerId !== 'Background' && !this.state.layerStates[layerId]) {\n const layer = this.map.getLayer(layerId);\n if (layer) {\n // Always skip layers that were present when control was initialized\n // These are background/basemap layers and should stay grouped under \"Background\"\n if (this.initialLayerIds !== null && this.initialLayerIds.has(layerId)) {\n // Layer was in initial set - it's a background layer, skip it\n return;\n }\n\n // In auto-detect mode, apply additional filtering\n if (isAutoDetectMode) {\n // Skip drawn layers if excludeDrawnLayers is enabled\n if (this.excludeDrawnLayers && this.isDrawnLayer(layerId)) {\n return;\n }\n\n // Skip layers matching user-defined exclusion patterns\n if (this.isExcludedByPattern(layerId)) {\n return;\n }\n\n // Skip layers that are not user-added (i.e., background/basemap layers)\n if (!this.isUserAddedLayer(layerId)) {\n return;\n }\n\n if (useBasemapStyleDetection) {\n // Use basemap style layer IDs - if layer is in basemap, skip it\n if (this.basemapLayerIds!.has(layerId)) {\n return;\n }\n } else if (useInitialLayerDetection) {\n // Layer NOT in initialLayerIds means it was added AFTER control\n // These are definitely user-added layers and should be included\n if (this.initialLayerIds!.has(layerId)) {\n // Layer was in initial set - check source-based heuristics\n const userAddedSourceIds = this.detectUserAddedSources();\n const sourceId = (layer as any).source;\n if (!sourceId || !userAddedSourceIds.has(sourceId)) {\n return;\n }\n }\n // Layer NOT in initialLayerIds - it's new, include it\n } else {\n // Fall back to source-based heuristics\n const userAddedSourceIds = this.detectUserAddedSources();\n const sourceId = (layer as any).source;\n if (!sourceId || !userAddedSourceIds.has(sourceId)) {\n return;\n }\n }\n }\n newLayers.push(layerId);\n }\n }\n });\n\n // Find removed layers that are still in our state\n // Skip custom layers - they have their own removal mechanism via the adapter\n const removedLayers: string[] = [];\n Object.keys(this.state.layerStates).forEach(layerId => {\n const state = this.state.layerStates[layerId];\n // Skip Background, custom layers, and layers still in the map\n if (layerId !== 'Background' && !state.isCustomLayer && !currentMapLayerIds.has(layerId)) {\n removedLayers.push(layerId);\n }\n });\n\n // Remove deleted layers from UI and state\n if (removedLayers.length > 0) {\n removedLayers.forEach(layerId => {\n // Remove from state\n delete this.state.layerStates[layerId];\n\n // Remove from UI\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`);\n if (itemEl) {\n itemEl.remove();\n }\n\n // Clean up style editor if open\n if (this.state.activeStyleEditor === layerId) {\n this.state.activeStyleEditor = null;\n }\n this.styleEditors.delete(layerId);\n });\n }\n\n // Add UI for new layers\n if (newLayers.length > 0) {\n newLayers.forEach(layerId => {\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n // Get layer type and opacity\n const layerType = layer.type;\n const opacity = getLayerOpacity(this.map, layerId, layerType);\n const visibility = this.map.getLayoutProperty(layerId, 'visibility');\n const isVisible = visibility !== 'none';\n\n // Add to state\n this.state.layerStates[layerId] = {\n visible: isVisible,\n opacity: opacity,\n name: this.generateFriendlyName(layerId),\n };\n\n // Add to UI\n this.addLayerItem(layerId, this.state.layerStates[layerId]);\n });\n }\n\n // Check for new/removed custom layers\n if (this.customLayerRegistry) {\n const customLayerIds = this.customLayerRegistry.getAllLayerIds();\n\n // Find new custom layers\n customLayerIds.forEach(layerId => {\n if (!this.state.layerStates[layerId]) {\n const customState = this.customLayerRegistry!.getLayerState(layerId);\n if (customState) {\n this.state.layerStates[layerId] = {\n visible: customState.visible,\n opacity: customState.opacity,\n name: customState.name,\n isCustomLayer: true,\n customLayerType: this.customLayerRegistry!.getSymbolType(layerId) || undefined,\n };\n this.addLayerItem(layerId, this.state.layerStates[layerId]);\n }\n }\n });\n\n // Find removed custom layers\n Object.keys(this.state.layerStates).forEach(layerId => {\n const state = this.state.layerStates[layerId];\n if (state.isCustomLayer && !customLayerIds.includes(layerId)) {\n // Remove from state\n delete this.state.layerStates[layerId];\n\n // Remove from UI\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`);\n if (itemEl) {\n itemEl.remove();\n }\n\n // Clean up style editor if open\n if (this.state.activeStyleEditor === layerId) {\n this.state.activeStyleEditor = null;\n }\n this.styleEditors.delete(layerId);\n }\n });\n }\n } catch (error) {\n console.warn('Failed to check for new layers:', error);\n }\n }\n\n /**\n * Register a custom layer adapter dynamically.\n * This allows adding adapters after the LayerControl has been initialized.\n * @param adapter The custom layer adapter to register\n */\n registerCustomAdapter(adapter: CustomLayerAdapter): void {\n // Create registry if it doesn't exist\n if (!this.customLayerRegistry) {\n this.customLayerRegistry = new CustomLayerRegistry();\n // Subscribe to registry changes\n this.customLayerUnsubscribe = this.customLayerRegistry.onChange(() => {\n this.checkForNewLayers();\n });\n }\n\n // Register the adapter\n this.customLayerRegistry.register(adapter);\n\n // Rebuild layer items to include the new adapter's layers\n if (this.panel) {\n this.checkForNewLayers();\n }\n }\n\n // ===== Context Menu Methods =====\n\n /**\n * Create context menu element\n */\n private createContextMenu(): HTMLDivElement {\n const menu = document.createElement('div');\n menu.className = 'layer-control-context-menu';\n menu.style.display = 'none';\n\n // Rename\n const renameItem = this.createContextMenuItem('Rename', '✏️', () => {\n if (this.state.contextMenu.targetLayerId) {\n this.startRenaming(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n });\n\n // Zoom to layer\n const zoomItem = this.createContextMenuItem('Zoom to Layer', '🔍', () => {\n if (this.state.contextMenu.targetLayerId) {\n this.zoomToLayer(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n });\n\n // Separator\n const sep1 = document.createElement('div');\n sep1.className = 'context-menu-separator';\n\n // Move up\n const moveUpItem = this.createContextMenuItem('Move Up', '↑', () => {\n if (this.state.contextMenu.targetLayerId) {\n this.moveLayerUp(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n });\n\n // Move to top\n const moveTopItem = this.createContextMenuItem('Move to Top', '⤒', () => {\n if (this.state.contextMenu.targetLayerId) {\n this.moveLayerToTop(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n });\n\n // Move down\n const moveDownItem = this.createContextMenuItem('Move Down', '↓', () => {\n if (this.state.contextMenu.targetLayerId) {\n this.moveLayerDown(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n });\n\n // Move to bottom\n const moveBottomItem = this.createContextMenuItem('Move to Bottom', '⤓', () => {\n if (this.state.contextMenu.targetLayerId) {\n this.moveLayerToBottom(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n });\n\n // Separator\n const sep2 = document.createElement('div');\n sep2.className = 'context-menu-separator';\n\n // Remove layer\n const removeItem = this.createContextMenuItem('Remove Layer', '🗑️', () => {\n if (this.state.contextMenu.targetLayerId) {\n this.removeLayer(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n }, true);\n\n menu.appendChild(renameItem);\n menu.appendChild(zoomItem);\n menu.appendChild(sep1);\n menu.appendChild(moveUpItem);\n menu.appendChild(moveTopItem);\n menu.appendChild(moveDownItem);\n menu.appendChild(moveBottomItem);\n menu.appendChild(sep2);\n menu.appendChild(removeItem);\n\n return menu;\n }\n\n /**\n * Create a context menu item\n */\n private createContextMenuItem(\n label: string,\n icon: string,\n onClick: () => void,\n isDanger = false\n ): HTMLDivElement {\n const item = document.createElement('div');\n item.className = 'context-menu-item' + (isDanger ? ' context-menu-item-danger' : '');\n\n const iconEl = document.createElement('span');\n iconEl.className = 'context-menu-item-icon';\n iconEl.textContent = icon;\n\n const labelEl = document.createElement('span');\n labelEl.className = 'context-menu-item-label';\n labelEl.textContent = label;\n\n item.appendChild(iconEl);\n item.appendChild(labelEl);\n\n item.addEventListener('click', (e) => {\n e.stopPropagation();\n onClick();\n });\n\n return item;\n }\n\n /**\n * Show context menu at position\n */\n private showContextMenu(layerId: string, x: number, y: number): void {\n if (!this.contextMenuEl) return;\n\n // Update state\n this.state.contextMenu = {\n visible: true,\n targetLayerId: layerId,\n x,\n y,\n };\n\n // Position the menu relative to the map container\n const mapRect = this.mapContainer.getBoundingClientRect();\n let menuX = x - mapRect.left;\n let menuY = y - mapRect.top;\n\n // Show menu to get dimensions\n this.contextMenuEl.style.display = 'block';\n\n // Adjust if menu would go off screen\n const menuRect = this.contextMenuEl.getBoundingClientRect();\n if (menuX + menuRect.width > mapRect.width) {\n menuX = mapRect.width - menuRect.width - 5;\n }\n if (menuY + menuRect.height > mapRect.height) {\n menuY = mapRect.height - menuRect.height - 5;\n }\n\n this.contextMenuEl.style.left = `${menuX}px`;\n this.contextMenuEl.style.top = `${menuY}px`;\n }\n\n /**\n * Hide context menu\n */\n private hideContextMenu(): void {\n if (!this.contextMenuEl) return;\n\n this.state.contextMenu = {\n visible: false,\n targetLayerId: null,\n x: 0,\n y: 0,\n };\n\n this.contextMenuEl.style.display = 'none';\n }\n\n /**\n * Start renaming a layer\n */\n private startRenaming(layerId: string): void {\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`);\n if (!itemEl) return;\n\n const nameEl = itemEl.querySelector('.layer-control-name');\n if (!nameEl) return;\n\n this.state.renamingLayerId = layerId;\n\n const currentName = this.state.customLayerNames.get(layerId) ||\n this.state.layerStates[layerId]?.name ||\n layerId;\n\n // Replace name span with input\n const input = document.createElement('input');\n input.type = 'text';\n input.className = 'layer-control-name-input';\n input.value = currentName;\n\n const finishRename = () => {\n const newName = input.value.trim() || currentName;\n const oldName = currentName;\n\n if (newName !== oldName) {\n this.state.customLayerNames.set(layerId, newName);\n if (this.state.layerStates[layerId]) {\n this.state.layerStates[layerId].name = newName;\n }\n this.onLayerRename?.(layerId, oldName, newName);\n }\n\n // Restore name span\n const newNameEl = document.createElement('span');\n newNameEl.className = 'layer-control-name';\n newNameEl.textContent = newName;\n newNameEl.title = newName;\n input.replaceWith(newNameEl);\n\n this.state.renamingLayerId = null;\n };\n\n input.addEventListener('blur', finishRename);\n input.addEventListener('keydown', (e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n finishRename();\n } else if (e.key === 'Escape') {\n e.preventDefault();\n // Restore original name\n const newNameEl = document.createElement('span');\n newNameEl.className = 'layer-control-name';\n newNameEl.textContent = currentName;\n newNameEl.title = currentName;\n input.replaceWith(newNameEl);\n this.state.renamingLayerId = null;\n }\n });\n\n nameEl.replaceWith(input);\n input.focus();\n input.select();\n }\n\n /**\n * Zoom to a layer's bounds\n */\n private zoomToLayer(layerId: string): void {\n // Check if it's a custom layer with getBounds support\n const layerState = this.state.layerStates[layerId];\n if (layerState?.isCustomLayer && this.customLayerRegistry) {\n const bounds = this.customLayerRegistry.getBounds(layerId);\n if (bounds) {\n this.map.fitBounds(bounds as [number, number, number, number], { padding: 50 });\n return;\n }\n }\n\n // For native MapLibre layers, try to get bounds from features\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n try {\n // First try querySourceFeatures for all features\n const sourceId = (layer as any).source;\n let features = sourceId ? this.map.querySourceFeatures(sourceId) : [];\n\n // If no source features, try rendered features\n if (features.length === 0) {\n features = this.map.queryRenderedFeatures({ layers: [layerId] });\n }\n\n if (features.length === 0) return;\n\n // Calculate bounds\n let minLng = Infinity, minLat = Infinity, maxLng = -Infinity, maxLat = -Infinity;\n\n features.forEach(feature => {\n if (!feature.geometry) return;\n\n const processCoords = (coords: any) => {\n if (typeof coords[0] === 'number') {\n const [lng, lat] = coords;\n minLng = Math.min(minLng, lng);\n minLat = Math.min(minLat, lat);\n maxLng = Math.max(maxLng, lng);\n maxLat = Math.max(maxLat, lat);\n } else {\n coords.forEach(processCoords);\n }\n };\n\n if (feature.geometry.type === 'Point') {\n processCoords((feature.geometry as any).coordinates);\n } else if (feature.geometry.type === 'LineString' || feature.geometry.type === 'MultiPoint') {\n (feature.geometry as any).coordinates.forEach(processCoords);\n } else if (feature.geometry.type === 'Polygon' || feature.geometry.type === 'MultiLineString') {\n (feature.geometry as any).coordinates.forEach((ring: any) => ring.forEach(processCoords));\n } else if (feature.geometry.type === 'MultiPolygon') {\n (feature.geometry as any).coordinates.forEach((polygon: any) =>\n polygon.forEach((ring: any) => ring.forEach(processCoords))\n );\n }\n });\n\n if (minLng !== Infinity && minLat !== Infinity && maxLng !== -Infinity && maxLat !== -Infinity) {\n this.map.fitBounds([[minLng, minLat], [maxLng, maxLat]], { padding: 50 });\n }\n } catch (error) {\n console.warn(`Failed to zoom to layer ${layerId}:`, error);\n }\n }\n\n /**\n * Get user layer IDs in current map order (top to bottom in UI = high z-index to low)\n * Includes both MapLibre layers and custom layers managed by adapters.\n */\n private getUserLayerIdsInMapOrder(): string[] {\n const style = this.map.getStyle();\n if (!style?.layers) return [];\n\n // Get map layers in their actual order (low index = rendered first/bottom)\n const mapLayerIds = style.layers.map(l => l.id);\n\n // Filter to only user layers that are in our state\n const userLayerIds = Object.keys(this.state.layerStates).filter(id => id !== 'Background');\n\n // Separate MapLibre layers and custom layers\n const mapLibreLayers = userLayerIds.filter(id => mapLayerIds.includes(id));\n const customLayers = userLayerIds.filter(id =>\n this.state.layerStates[id]?.isCustomLayer && !mapLayerIds.includes(id)\n );\n\n // Sort MapLibre layers by map order (reversed: high index = top in UI)\n const sortedMapLibreLayers = mapLibreLayers\n .sort((a, b) => mapLayerIds.indexOf(b) - mapLayerIds.indexOf(a));\n\n // Custom layers are placed at the top (rendered last/on top)\n // Maintain their relative order from the state\n return [...customLayers, ...sortedMapLibreLayers];\n }\n\n /**\n * Check if a layer is a MapLibre layer (not a custom layer)\n */\n private isMapLibreLayer(layerId: string): boolean {\n return this.map.getLayer(layerId) !== undefined;\n }\n\n /**\n * Find the next MapLibre layer ID in a direction from a given index\n * @param layerIds Array of layer IDs\n * @param startIndex Index to start searching from\n * @param direction 1 for forward (toward bottom), -1 for backward (toward top)\n * @returns MapLibre layer ID or undefined if not found\n */\n private findNextMapLibreLayer(layerIds: string[], startIndex: number, direction: 1 | -1): string | undefined {\n for (let i = startIndex; direction === 1 ? i < layerIds.length : i >= 0; i += direction) {\n if (this.isMapLibreLayer(layerIds[i])) {\n return layerIds[i];\n }\n }\n return undefined;\n }\n\n /**\n * Move a layer up in UI (higher rendering order = move to higher z-index)\n */\n private moveLayerUp(layerId: string): void {\n const layerIds = this.getUserLayerIdsInMapOrder();\n const index = layerIds.indexOf(layerId);\n if (index <= 0) return; // Already at top or not found\n\n // Check if this is a custom layer\n const isCustom = this.state.layerStates[layerId]?.isCustomLayer;\n\n if (!isCustom && this.isMapLibreLayer(layerId)) {\n // For MapLibre layers, we need to move them in the map\n // UI: [0]=top, [1], [2], ... [n]=bottom\n // Map array: bottom to top (low index = low z-index)\n // moveLayer(id, beforeId) moves id to render BELOW beforeId\n\n try {\n // Find the MapLibre layer to move before (2 positions above if exists)\n // If moving to top, use undefined as beforeId\n const targetBeforeId = index >= 2\n ? this.findNextMapLibreLayer(layerIds, index - 2, -1)\n : undefined;\n this.map.moveLayer(layerId, targetBeforeId);\n } catch (e) {\n // Ignore errors\n }\n }\n\n // For custom layers, just update the internal order\n // Swap positions in the state\n const newLayerStates: { [key: string]: LayerState } = {};\n const orderedIds = [...layerIds];\n [orderedIds[index], orderedIds[index - 1]] = [orderedIds[index - 1], orderedIds[index]];\n\n // Add Background first if it exists\n if (this.state.layerStates['Background']) {\n newLayerStates['Background'] = this.state.layerStates['Background'];\n }\n orderedIds.forEach(id => {\n if (this.state.layerStates[id]) {\n newLayerStates[id] = this.state.layerStates[id];\n }\n });\n this.state.layerStates = newLayerStates;\n\n // Rebuild UI\n this.buildLayerItems();\n this.onLayerReorder?.(this.getUserLayerIdsInMapOrder());\n }\n\n /**\n * Move a layer to the top (highest rendering order)\n */\n private moveLayerToTop(layerId: string): void {\n const layerIds = this.getUserLayerIdsInMapOrder();\n const index = layerIds.indexOf(layerId);\n if (index <= 0) return; // Already at top or not found\n\n // Check if this is a custom layer\n const isCustom = this.state.layerStates[layerId]?.isCustomLayer;\n\n if (!isCustom && this.isMapLibreLayer(layerId)) {\n // Move in MapLibre - no beforeId means move to top (highest z-index)\n try {\n this.map.moveLayer(layerId);\n } catch (e) {\n // Ignore errors\n }\n }\n\n // Update internal order - move to front\n const newLayerStates: { [key: string]: LayerState } = {};\n const orderedIds = [...layerIds];\n orderedIds.splice(index, 1);\n orderedIds.unshift(layerId);\n\n // Add Background first if it exists\n if (this.state.layerStates['Background']) {\n newLayerStates['Background'] = this.state.layerStates['Background'];\n }\n orderedIds.forEach(id => {\n if (this.state.layerStates[id]) {\n newLayerStates[id] = this.state.layerStates[id];\n }\n });\n this.state.layerStates = newLayerStates;\n\n // Rebuild UI\n this.buildLayerItems();\n this.onLayerReorder?.(this.getUserLayerIdsInMapOrder());\n }\n\n /**\n * Move a layer down in UI (lower rendering order = move to lower z-index)\n */\n private moveLayerDown(layerId: string): void {\n const layerIds = this.getUserLayerIdsInMapOrder();\n const index = layerIds.indexOf(layerId);\n if (index < 0 || index >= layerIds.length - 1) return; // Already at bottom or not found\n\n // Check if this is a custom layer\n const isCustom = this.state.layerStates[layerId]?.isCustomLayer;\n\n if (!isCustom && this.isMapLibreLayer(layerId)) {\n // The layer below in UI is at index + 1, which has lower z-index in map\n // To move our layer below it, we call moveLayer(layerId, belowLayerId)\n // This puts layerId just below belowLayerId in rendering order\n // Find the next MapLibre layer below\n const belowLayerId = this.findNextMapLibreLayer(layerIds, index + 1, 1);\n\n if (belowLayerId) {\n try {\n this.map.moveLayer(layerId, belowLayerId);\n } catch (e) {\n // Ignore errors\n }\n }\n }\n\n // Update internal order - swap positions\n const newLayerStates: { [key: string]: LayerState } = {};\n const orderedIds = [...layerIds];\n [orderedIds[index], orderedIds[index + 1]] = [orderedIds[index + 1], orderedIds[index]];\n\n // Add Background first if it exists\n if (this.state.layerStates['Background']) {\n newLayerStates['Background'] = this.state.layerStates['Background'];\n }\n orderedIds.forEach(id => {\n if (this.state.layerStates[id]) {\n newLayerStates[id] = this.state.layerStates[id];\n }\n });\n this.state.layerStates = newLayerStates;\n\n // Rebuild UI\n this.buildLayerItems();\n this.onLayerReorder?.(this.getUserLayerIdsInMapOrder());\n }\n\n /**\n * Move a layer to the bottom (lowest rendering order among user layers)\n */\n private moveLayerToBottom(layerId: string): void {\n const layerIds = this.getUserLayerIdsInMapOrder();\n if (layerIds.length <= 1) return;\n\n const index = layerIds.indexOf(layerId);\n if (index < 0 || index === layerIds.length - 1) return; // Not found or already at bottom\n\n // Check if this is a custom layer\n const isCustom = this.state.layerStates[layerId]?.isCustomLayer;\n\n if (!isCustom && this.isMapLibreLayer(layerId)) {\n // The bottom layer in UI has the lowest z-index among user layers\n // Find the bottom-most MapLibre layer\n const bottomLayerId = this.findNextMapLibreLayer(layerIds, layerIds.length - 1, -1);\n\n if (bottomLayerId && bottomLayerId !== layerId) {\n try {\n // Move this layer to be just below the current bottom layer\n this.map.moveLayer(layerId, bottomLayerId);\n } catch (e) {\n // Ignore errors\n }\n }\n }\n\n // Update internal order - move to end\n const newLayerStates: { [key: string]: LayerState } = {};\n const orderedIds = [...layerIds];\n orderedIds.splice(index, 1);\n orderedIds.push(layerId);\n\n // Add Background first if it exists\n if (this.state.layerStates['Background']) {\n newLayerStates['Background'] = this.state.layerStates['Background'];\n }\n orderedIds.forEach(id => {\n if (this.state.layerStates[id]) {\n newLayerStates[id] = this.state.layerStates[id];\n }\n });\n this.state.layerStates = newLayerStates;\n\n // Rebuild UI\n this.buildLayerItems();\n this.onLayerReorder?.(this.getUserLayerIdsInMapOrder());\n }\n\n /**\n * Remove a layer from the map\n */\n private removeLayer(layerId: string): void {\n const layerState = this.state.layerStates[layerId];\n\n // Check if it's a custom layer\n if (layerState?.isCustomLayer && this.customLayerRegistry) {\n this.customLayerRegistry.removeLayer(layerId);\n } else {\n // Remove native MapLibre layer\n try {\n const layer = this.map.getLayer(layerId);\n if (layer) {\n const sourceId = (layer as any).source;\n this.map.removeLayer(layerId);\n\n // Check if source is still used by other layers\n if (sourceId) {\n const style = this.map.getStyle();\n const sourceStillUsed = style?.layers?.some(l => (l as any).source === sourceId);\n if (!sourceStillUsed) {\n try {\n this.map.removeSource(sourceId);\n } catch (e) {\n // Source might not exist or be in use\n }\n }\n }\n }\n } catch (error) {\n console.warn(`Failed to remove layer ${layerId}:`, error);\n }\n }\n\n // Remove from state\n delete this.state.layerStates[layerId];\n this.state.customLayerNames.delete(layerId);\n\n // Remove from UI\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`);\n if (itemEl) {\n itemEl.remove();\n }\n\n // Call callback\n this.onLayerRemove?.(layerId);\n }\n\n // ===== Drag and Drop Methods =====\n\n /**\n * Create drag handle element\n */\n private createDragHandle(layerId: string): HTMLDivElement {\n const handle = document.createElement('div');\n handle.className = 'layer-control-drag-handle';\n handle.innerHTML = `<svg viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <circle cx=\"5\" cy=\"3\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"3\" r=\"1.5\"/>\n <circle cx=\"5\" cy=\"8\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"8\" r=\"1.5\"/>\n <circle cx=\"5\" cy=\"13\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"13\" r=\"1.5\"/>\n </svg>`;\n handle.title = 'Drag to reorder';\n\n // Pointer events for dragging\n handle.addEventListener('pointerdown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n this.startDrag(layerId, e);\n });\n\n return handle;\n }\n\n /**\n * Create a disabled drag handle for alignment (used for Background layer)\n */\n private createDisabledDragHandle(): HTMLDivElement {\n const handle = document.createElement('div');\n handle.className = 'layer-control-drag-handle layer-control-drag-handle-disabled';\n handle.innerHTML = `<svg viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <circle cx=\"5\" cy=\"3\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"3\" r=\"1.5\"/>\n <circle cx=\"5\" cy=\"8\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"8\" r=\"1.5\"/>\n <circle cx=\"5\" cy=\"13\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"13\" r=\"1.5\"/>\n </svg>`;\n return handle;\n }\n\n /**\n * Start dragging a layer\n */\n private startDrag(layerId: string, e: PointerEvent): void {\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`) as HTMLElement;\n if (!itemEl) return;\n\n // Get item rect before any modifications\n const rect = itemEl.getBoundingClientRect();\n\n // Set up drag state\n this.state.drag = {\n active: true,\n layerId,\n startY: e.clientY,\n currentY: e.clientY,\n placeholder: null,\n draggedElement: null,\n };\n\n // Add dragging class to panel\n this.panel.classList.add('dragging-active');\n\n // Hide original first (before creating clone to avoid visual jump)\n itemEl.classList.add('dragging');\n\n // Create placeholder at original position\n const placeholder = document.createElement('div');\n placeholder.className = 'layer-control-drop-placeholder';\n placeholder.style.height = `${rect.height}px`;\n itemEl.parentNode?.insertBefore(placeholder, itemEl);\n this.state.drag.placeholder = placeholder;\n\n // Create floating clone\n const clone = itemEl.cloneNode(true) as HTMLElement;\n clone.classList.remove('dragging');\n clone.className = 'layer-control-item layer-control-item-dragging';\n clone.style.width = `${rect.width}px`;\n clone.style.left = `${rect.left}px`;\n clone.style.top = `${rect.top}px`;\n document.body.appendChild(clone);\n this.state.drag.draggedElement = clone;\n\n // Set up move and end handlers on document\n const onMove = (moveE: PointerEvent) => this.onDragMove(moveE);\n const onEnd = (endE: PointerEvent) => {\n document.removeEventListener('pointermove', onMove);\n document.removeEventListener('pointerup', onEnd);\n document.removeEventListener('pointercancel', onEnd);\n this.endDrag(endE);\n };\n\n document.addEventListener('pointermove', onMove);\n document.addEventListener('pointerup', onEnd);\n document.addEventListener('pointercancel', onEnd);\n }\n\n /**\n * Handle drag move\n */\n private onDragMove(e: PointerEvent): void {\n if (!this.state.drag.active || !this.state.drag.draggedElement) return;\n\n const placeholder = this.state.drag.placeholder;\n if (!placeholder) return;\n\n // Move the floating element\n const deltaY = e.clientY - this.state.drag.startY;\n const clone = this.state.drag.draggedElement;\n const currentTop = parseFloat(clone.style.top) || 0;\n clone.style.top = `${currentTop + deltaY}px`;\n this.state.drag.startY = e.clientY;\n this.state.drag.currentY = e.clientY;\n\n // Get all layer items (excluding the one being dragged and Background)\n const items = Array.from(this.panel.querySelectorAll('.layer-control-item:not(.dragging)'))\n .filter(item => (item as HTMLElement).dataset.layerId !== 'Background') as HTMLElement[];\n\n // Find which item we're hovering over\n for (const item of items) {\n const itemRect = item.getBoundingClientRect();\n\n // Check if cursor is within this item's vertical bounds\n if (e.clientY >= itemRect.top && e.clientY <= itemRect.bottom) {\n const itemMiddle = itemRect.top + itemRect.height / 2;\n\n if (e.clientY < itemMiddle) {\n // Insert placeholder before this item (if not already there)\n if (placeholder.nextSibling !== item) {\n item.parentNode?.insertBefore(placeholder, item);\n }\n } else {\n // Insert placeholder after this item (if not already there)\n if (placeholder.previousSibling !== item) {\n item.parentNode?.insertBefore(placeholder, item.nextSibling);\n }\n }\n break;\n }\n }\n }\n\n /**\n * End dragging\n */\n private endDrag(_e: PointerEvent): void {\n if (!this.state.drag.active) return;\n\n const layerId = this.state.drag.layerId;\n const placeholder = this.state.drag.placeholder;\n\n // Get the original item\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`) as HTMLElement;\n\n if (itemEl && placeholder) {\n // Move item to placeholder position\n placeholder.parentNode?.insertBefore(itemEl, placeholder);\n itemEl.classList.remove('dragging');\n }\n\n // Clean up\n this.cleanupDragState();\n\n // Update map layer order based on UI order\n this.applyUIOrderToMap();\n }\n\n /**\n * Clean up drag state\n */\n private cleanupDragState(): void {\n // Remove floating element\n if (this.state.drag.draggedElement) {\n this.state.drag.draggedElement.remove();\n }\n\n // Remove placeholder\n if (this.state.drag.placeholder) {\n this.state.drag.placeholder.remove();\n }\n\n // Remove dragging class from panel\n this.panel.classList.remove('dragging-active');\n\n // Remove dragging class from any items\n this.panel.querySelectorAll('.layer-control-item.dragging').forEach(el => {\n el.classList.remove('dragging');\n });\n\n // Reset drag state\n this.state.drag = {\n active: false,\n layerId: null,\n startY: 0,\n currentY: 0,\n placeholder: null,\n draggedElement: null,\n };\n }\n\n /**\n * Apply UI order to map layers\n */\n private applyUIOrderToMap(): void {\n // Set flag to prevent checkForNewLayers from running during reordering\n // This prevents custom layers from being incorrectly deleted due to race conditions\n this.state.isStyleOperationInProgress = true;\n\n // Get layer items in current UI order\n const items = this.panel.querySelectorAll('.layer-control-item');\n const uiLayerIds: string[] = [];\n\n items.forEach(item => {\n const layerId = (item as HTMLElement).dataset.layerId;\n if (layerId && layerId !== 'Background') {\n uiLayerIds.push(layerId);\n }\n });\n\n // UI shows top layer first, but we need to move layers in reverse order\n // to maintain the correct stacking\n const reversedIds = [...uiLayerIds].reverse();\n\n // Build a set of MapLibre layer IDs for quick lookup\n const style = this.map.getStyle();\n const mapLibreLayerIds = new Set(style?.layers?.map(l => l.id) || []);\n\n // Move each layer to its correct position\n for (let i = 0; i < reversedIds.length; i++) {\n const layerId = reversedIds[i];\n\n // Check if layer exists in MapLibre (skip custom layers)\n if (!mapLibreLayerIds.has(layerId)) {\n continue;\n }\n\n // Find the next MapLibre layer to use as beforeId\n // Skip any custom layers that might be between this layer and the next\n let beforeId: string | undefined = undefined;\n for (let j = i - 1; j >= 0; j--) {\n if (mapLibreLayerIds.has(reversedIds[j])) {\n beforeId = reversedIds[j];\n break;\n }\n }\n\n try {\n this.map.moveLayer(layerId, beforeId);\n } catch (e) {\n // Ignore errors\n }\n }\n\n // Call callback\n this.onLayerReorder?.(uiLayerIds);\n\n // Clear flag after styledata events have settled\n // The 200ms delay accounts for the 100ms timeout in the styledata event handler\n setTimeout(() => {\n this.state.isStyleOperationInProgress = false;\n }, 200);\n }\n}\n"],"names":["opacity","clamp","color","svgMarkup","symbolContainer","layerList","editor","_a"],"mappings":"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"}
|