@geoql/v-maplibre 1.10.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -15
- package/dist/arc-B_fAMcpz.js +2 -0
- package/dist/arc-B_fAMcpz.js.map +1 -0
- package/dist/{arrow-4ecDVUFv.js → arrow-B87Hvf8z.js} +1 -1
- package/dist/{arrow-4ecDVUFv.js.map → arrow-B87Hvf8z.js.map} +1 -1
- package/dist/bitmap-C_yi2tt7.js +2 -0
- package/dist/bitmap-C_yi2tt7.js.map +1 -0
- package/dist/cog-Cksxp4kb.js +2 -0
- package/dist/cog-Cksxp4kb.js.map +1 -0
- package/dist/column-CN436hkx.js +2 -0
- package/dist/column-CN436hkx.js.map +1 -0
- package/dist/contour-DJbs8Kf4.js +2 -0
- package/dist/contour-DJbs8Kf4.js.map +1 -0
- package/dist/deckgl.d.ts +47 -0
- package/dist/deckgl.js +2 -0
- package/dist/deckgl.js.map +1 -0
- package/dist/generic-B-YSsfL2.js +2 -0
- package/dist/generic-B-YSsfL2.js.map +1 -0
- package/dist/geoarrow-path-4ompjoL_.js +2 -0
- package/dist/{geoarrow-path-CV0aOugP.js.map → geoarrow-path-4ompjoL_.js.map} +1 -1
- package/dist/geoarrow-polygon-DUlcZwlA.js +2 -0
- package/dist/{geoarrow-polygon-BjfqZpaf.js.map → geoarrow-polygon-DUlcZwlA.js.map} +1 -1
- package/dist/geoarrow-scatterplot-Cd2DK-iz.js +2 -0
- package/dist/{geoarrow-scatterplot-DxkqOIWR.js.map → geoarrow-scatterplot-Cd2DK-iz.js.map} +1 -1
- package/dist/geoarrow-solid-polygon-q14Ff9j9.js +2 -0
- package/dist/{geoarrow-solid-polygon-LGavbdMg.js.map → geoarrow-solid-polygon-q14Ff9j9.js.map} +1 -1
- package/dist/geoarrow-text-DHvTakUd.js +2 -0
- package/dist/{geoarrow-text-8HY70yYe.js.map → geoarrow-text-DHvTakUd.js.map} +1 -1
- package/dist/geoarrow-trips-CwRSQdMU.js +2 -0
- package/dist/{geoarrow-trips-Bqc-_N6F.js.map → geoarrow-trips-CwRSQdMU.js.map} +1 -1
- package/dist/geohash-DfnNENva.js +2 -0
- package/dist/geohash-DfnNENva.js.map +1 -0
- package/dist/geojson-BRWVICwI.js +2 -0
- package/dist/geojson-BRWVICwI.js.map +1 -0
- package/dist/geotiff.d.ts +50 -0
- package/dist/geotiff.js +2 -0
- package/dist/geotiff.js.map +1 -0
- package/dist/great-circle-Da5XIa2p.js +2 -0
- package/dist/great-circle-Da5XIa2p.js.map +1 -0
- package/dist/grid-DKP8clpW.js +2 -0
- package/dist/grid-DKP8clpW.js.map +1 -0
- package/dist/grid-cell-CZ41kY8K.js +2 -0
- package/dist/grid-cell-CZ41kY8K.js.map +1 -0
- package/dist/h3-cluster-Cco_QCbU.js +2 -0
- package/dist/h3-cluster-Cco_QCbU.js.map +1 -0
- package/dist/h3-hexagon-BqvZfU5b.js +2 -0
- package/dist/h3-hexagon-BqvZfU5b.js.map +1 -0
- package/dist/heatmap-Bq7-L0jp.js +2 -0
- package/dist/heatmap-Bq7-L0jp.js.map +1 -0
- package/dist/hexagon-T0vesB_G.js +2 -0
- package/dist/hexagon-T0vesB_G.js.map +1 -0
- package/dist/icon-Bwm2m8b4.js +2 -0
- package/dist/icon-Bwm2m8b4.js.map +1 -0
- package/dist/index-2D1oVTKr.d.ts +37 -0
- package/dist/index.d.ts +121 -491
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lidar.d.ts +232 -0
- package/dist/lidar.js +2 -0
- package/dist/lidar.js.map +1 -0
- package/dist/line-2EN6ukkf.js +2 -0
- package/dist/line-2EN6ukkf.js.map +1 -0
- package/dist/mosaic-DUwBxfGg.js +43 -0
- package/dist/mosaic-DUwBxfGg.js.map +1 -0
- package/dist/multi-cog-B2kVLX90.js +2 -0
- package/dist/multi-cog-B2kVLX90.js.map +1 -0
- package/dist/mvt-q6iXzmEF.js +2 -0
- package/dist/mvt-q6iXzmEF.js.map +1 -0
- package/dist/path-CKCx5_Gi.js +2 -0
- package/dist/path-CKCx5_Gi.js.map +1 -0
- package/dist/point-cloud-C9zJxZDT.js +2 -0
- package/dist/point-cloud-C9zJxZDT.js.map +1 -0
- package/dist/polygon-DRpsvg1W.js +2 -0
- package/dist/polygon-DRpsvg1W.js.map +1 -0
- package/dist/quadkey-DfoG2hLL.js +2 -0
- package/dist/quadkey-DfoG2hLL.js.map +1 -0
- package/dist/s2-DlEDAkpJ.js +2 -0
- package/dist/s2-DlEDAkpJ.js.map +1 -0
- package/dist/scatterplot-B9zXE6Jf.js +2 -0
- package/dist/scatterplot-B9zXE6Jf.js.map +1 -0
- package/dist/scenegraph-BVXLw8Cw.js +2 -0
- package/dist/scenegraph-BVXLw8Cw.js.map +1 -0
- package/dist/screen-grid-Dgj0QdEI.js +2 -0
- package/dist/screen-grid-Dgj0QdEI.js.map +1 -0
- package/dist/simple-mesh-ypHRymUD.js +2 -0
- package/dist/simple-mesh-ypHRymUD.js.map +1 -0
- package/dist/solid-polygon-DyWHVxEO.js +2 -0
- package/dist/solid-polygon-DyWHVxEO.js.map +1 -0
- package/dist/starfield-Djc5vy6K.js +2 -0
- package/dist/starfield-Djc5vy6K.js.map +1 -0
- package/dist/starfield.d.ts +7 -0
- package/dist/starfield.js +2 -0
- package/dist/starfield.js.map +1 -0
- package/dist/symbols-DXKzIgbY.js +2 -0
- package/dist/symbols-DXKzIgbY.js.map +1 -0
- package/dist/terrain-D3LKaDfn.js +2 -0
- package/dist/terrain-D3LKaDfn.js.map +1 -0
- package/dist/text-C6lF4GFS.js +2 -0
- package/dist/text-C6lF4GFS.js.map +1 -0
- package/dist/tile-3d-DHzr5_s2.js +2 -0
- package/dist/tile-3d-DHzr5_s2.js.map +1 -0
- package/dist/tile-DqpbfgRL.js +2 -0
- package/dist/tile-DqpbfgRL.js.map +1 -0
- package/dist/trips-CchyX_8N.js +2 -0
- package/dist/trips-CchyX_8N.js.map +1 -0
- package/dist/useDeckOverlay-GlkH_rvP.js +2 -0
- package/dist/useDeckOverlay-GlkH_rvP.js.map +1 -0
- package/dist/useDeckOverlay-JoRzVQ7g.d.ts +43 -0
- package/dist/v-maplibre.css +2 -2
- package/dist/wind-particle-Rs67QBQ9.js +2 -0
- package/dist/wind-particle-Rs67QBQ9.js.map +1 -0
- package/dist/wind.d.ts +9 -0
- package/dist/wind.js +2 -0
- package/dist/wind.js.map +1 -0
- package/dist/wms-KlHzzqd3.js +2 -0
- package/dist/wms-KlHzzqd3.js.map +1 -0
- package/dist/zarr-Czf44Tqd.js +2 -0
- package/dist/zarr-Czf44Tqd.js.map +1 -0
- package/package.json +36 -16
- package/dist/arc-sQuzag_9.js +0 -2
- package/dist/arc-sQuzag_9.js.map +0 -1
- package/dist/bitmap-C9wTsmdA.js +0 -2
- package/dist/bitmap-C9wTsmdA.js.map +0 -1
- package/dist/cog-BC2mhbA-.js +0 -2
- package/dist/cog-BC2mhbA-.js.map +0 -1
- package/dist/column-Dai69vdE.js +0 -2
- package/dist/column-Dai69vdE.js.map +0 -1
- package/dist/contour-BVSFeMXQ.js +0 -2
- package/dist/contour-BVSFeMXQ.js.map +0 -1
- package/dist/generic-DLtJwFOg.js +0 -2
- package/dist/generic-DLtJwFOg.js.map +0 -1
- package/dist/geoarrow-path-CV0aOugP.js +0 -2
- package/dist/geoarrow-polygon-BjfqZpaf.js +0 -2
- package/dist/geoarrow-scatterplot-DxkqOIWR.js +0 -2
- package/dist/geoarrow-solid-polygon-LGavbdMg.js +0 -2
- package/dist/geoarrow-text-8HY70yYe.js +0 -2
- package/dist/geoarrow-trips-Bqc-_N6F.js +0 -2
- package/dist/geohash-Bq6Va31-.js +0 -2
- package/dist/geohash-Bq6Va31-.js.map +0 -1
- package/dist/geojson-DmmblQfq.js +0 -2
- package/dist/geojson-DmmblQfq.js.map +0 -1
- package/dist/great-circle-B3wrKr2V.js +0 -2
- package/dist/great-circle-B3wrKr2V.js.map +0 -1
- package/dist/grid-cell-CTiUtStS.js +0 -2
- package/dist/grid-cell-CTiUtStS.js.map +0 -1
- package/dist/grid-d5GMfgA7.js +0 -2
- package/dist/grid-d5GMfgA7.js.map +0 -1
- package/dist/h3-cluster-BqU_KkMN.js +0 -2
- package/dist/h3-cluster-BqU_KkMN.js.map +0 -1
- package/dist/h3-hexagon-E-7rMATA.js +0 -2
- package/dist/h3-hexagon-E-7rMATA.js.map +0 -1
- package/dist/heatmap-CToABGhe.js +0 -2
- package/dist/heatmap-CToABGhe.js.map +0 -1
- package/dist/hexagon-B7QFHPOG.js +0 -2
- package/dist/hexagon-B7QFHPOG.js.map +0 -1
- package/dist/icon-dGkYJha7.js +0 -2
- package/dist/icon-dGkYJha7.js.map +0 -1
- package/dist/line-BqRkZ9qg.js +0 -2
- package/dist/line-BqRkZ9qg.js.map +0 -1
- package/dist/mosaic-BdOpB_UM.js +0 -43
- package/dist/mosaic-BdOpB_UM.js.map +0 -1
- package/dist/multi-cog-RzUpiduc.js +0 -2
- package/dist/multi-cog-RzUpiduc.js.map +0 -1
- package/dist/mvt-DKjRIMv0.js +0 -2
- package/dist/mvt-DKjRIMv0.js.map +0 -1
- package/dist/path-QpGANcDO.js +0 -2
- package/dist/path-QpGANcDO.js.map +0 -1
- package/dist/point-cloud-CwNI1kj4.js +0 -2
- package/dist/point-cloud-CwNI1kj4.js.map +0 -1
- package/dist/polygon-CnEkEdCz.js +0 -2
- package/dist/polygon-CnEkEdCz.js.map +0 -1
- package/dist/quadkey-DqvKjWw3.js +0 -2
- package/dist/quadkey-DqvKjWw3.js.map +0 -1
- package/dist/s2-BHisRsYi.js +0 -2
- package/dist/s2-BHisRsYi.js.map +0 -1
- package/dist/scatterplot-DtFjVt95.js +0 -2
- package/dist/scatterplot-DtFjVt95.js.map +0 -1
- package/dist/scenegraph-DfsmFuLy.js +0 -2
- package/dist/scenegraph-DfsmFuLy.js.map +0 -1
- package/dist/screen-grid-C-Ge9TH9.js +0 -2
- package/dist/screen-grid-C-Ge9TH9.js.map +0 -1
- package/dist/simple-mesh-CwDv4_8p.js +0 -2
- package/dist/simple-mesh-CwDv4_8p.js.map +0 -1
- package/dist/solid-polygon-DS3vtguq.js +0 -2
- package/dist/solid-polygon-DS3vtguq.js.map +0 -1
- package/dist/starfield-DnXurhKv.js +0 -2
- package/dist/starfield-DnXurhKv.js.map +0 -1
- package/dist/symbols-CVfar3bo.js +0 -2
- package/dist/symbols-CVfar3bo.js.map +0 -1
- package/dist/terrain-Vnqb4j1R.js +0 -2
- package/dist/terrain-Vnqb4j1R.js.map +0 -1
- package/dist/text-BuHw5Jdf.js +0 -2
- package/dist/text-BuHw5Jdf.js.map +0 -1
- package/dist/tile-3d-CAbU8BnN.js +0 -2
- package/dist/tile-3d-CAbU8BnN.js.map +0 -1
- package/dist/tile-B03s67tw.js +0 -2
- package/dist/tile-B03s67tw.js.map +0 -1
- package/dist/trips-Cy2yQXp7.js +0 -2
- package/dist/trips-Cy2yQXp7.js.map +0 -1
- package/dist/wind-particle-C1OQmbu7.js +0 -2
- package/dist/wind-particle-C1OQmbu7.js.map +0 -1
- package/dist/wms-toc-Os2F.js +0 -2
- package/dist/wms-toc-Os2F.js.map +0 -1
- package/dist/zarr-CGUO8nTA.js +0 -2
- package/dist/zarr-CGUO8nTA.js.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["$slots","VMap"],"sources":["../src/controls/attribution/VControlAttribution.vue","../src/controls/fullscreen/VControlFullscreen.vue","../src/controls/geolocate/events.ts","../src/controls/geolocate/VControlGeolocate.vue","../src/controls/navigation/VControlNavigation.vue","../src/controls/scale/VControlScale.vue","../src/controls/lidar/events.ts","../src/controls/lidar/VControlLidar.vue","../src/controls/_shared/useMapControl.ts","../src/controls/layer/VControlLayer.vue","../src/controls/layer/VControlLayerGroup.vue","../src/controls/legend/VControlLegend.vue","../src/layers/maplibre/canvas/VLayerMaplibreCanvas.vue","../src/layers/maplibre/geojson/VLayerMaplibreGeojson.vue","../src/layers/maplibre/image/VLayerMaplibreImage.vue","../src/layers/maplibre/raster/VLayerMaplibreRaster.vue","../src/constants/events/layer.ts","../src/constants/events/map.ts","../src/constants/events/marker.ts","../src/constants/events/popup.ts","../src/layers/maplibre/vector/VLayerMaplibreVector.vue","../src/layers/maplibre/video/VLayerMaplibreVideo.vue","../src/layers/maplibre/pmtile/VLayerMaplibrePmtile.vue","../src/layers/maplibre/custom/cluster/VLayerMaplibreCluster.vue","../src/layers/maplibre/custom/route/VLayerMaplibreRoute.vue","../src/layers/maplibre/custom/isochrone/VLayerMaplibreIsochrone.vue","../src/layers/deckgl/index.ts","../src/layers/index.ts","../src/map/VMap.vue","../src/popups/VPopup.vue","../src/markers/VMarker.vue","../src/index.ts"],"sourcesContent":["<script setup lang=\"ts\">\n import { AttributionControl } from 'maplibre-gl';\n import { onMounted, useSlots } from 'vue';\n import { MapKey, injectStrict } from '../../utils';\n import type { AttributionControlOptions, ControlPosition } from './types';\n\n const defaultOptions: AttributionControlOptions = {\n compact: false,\n customAttribution: undefined,\n };\n\n const props = withDefaults(\n defineProps<{\n options?: AttributionControlOptions;\n position?: ControlPosition;\n }>(),\n {\n options: undefined,\n position: 'bottom-right',\n },\n );\n\n const slots = useSlots();\n\n const map = injectStrict(MapKey);\n\n onMounted(() => {\n addControl();\n });\n\n const addControl = (): void => {\n let options = defaultOptions;\n if (props.options) {\n options = {\n ...props.options,\n };\n }\n if (slots && slots.default?.()) {\n options.customAttribution = slots.default()[0]!\n .children as unknown as string;\n }\n const control = new AttributionControl(options);\n map.value!.addControl(control, props.position);\n };\n</script>\n\n<template>\n <slot></slot>\n</template>\n","<script setup lang=\"ts\">\n import { FullscreenControl } from 'maplibre-gl';\n import { onMounted } from 'vue';\n import { MapKey, injectStrict } from '../../utils';\n import type { ControlPosition, FullscreenControlOptions } from './types';\n\n const defaultOptions: FullscreenControlOptions = {\n container: undefined,\n };\n\n const props = withDefaults(\n defineProps<{\n options?: FullscreenControlOptions;\n position?: ControlPosition;\n }>(),\n {\n options: undefined,\n position: 'top-left',\n },\n );\n\n const map = injectStrict(MapKey);\n\n onMounted(() => {\n addControl();\n });\n\n const addControl = (): void => {\n const control = new FullscreenControl(props.options || defaultOptions);\n map.value!.addControl(control, props.position);\n };\n</script>\n","export const geolocateControlEvents: string[] = [\n 'geolocate',\n 'error',\n 'outofmaxbounds',\n 'trackuserlocationstart',\n 'trackuserlocationend',\n];\n","<script setup lang=\"ts\">\n import { GeolocateControl } from 'maplibre-gl';\n import { onMounted } from 'vue';\n import { MapKey, injectStrict } from '../../utils';\n import { geolocateControlEvents as events } from './events';\n import type { ControlPosition, GeolocateControlOptions } from './types';\n\n const defaultOptions: GeolocateControlOptions = {\n fitBoundsOptions: {\n linear: false,\n offset: [0, 0],\n maxZoom: 22,\n },\n positionOptions: {\n enableHighAccuracy: true,\n maximumAge: 0,\n timeout: 6000,\n },\n trackUserLocation: true,\n showAccuracyCircle: true,\n showUserLocation: true,\n };\n\n const props = withDefaults(\n defineProps<{\n options?: GeolocateControlOptions;\n position?: ControlPosition;\n }>(),\n {\n options: undefined,\n position: 'top-left',\n },\n );\n\n const emit = defineEmits(events);\n\n const map = injectStrict(MapKey);\n\n onMounted(() => {\n addControl();\n });\n\n const addControl = (): void => {\n const control = new GeolocateControl(props.options || defaultOptions);\n map.value!.addControl(control, props.position);\n events.forEach((event: string) => {\n control.on(event, () => {\n emit(event);\n });\n });\n };\n</script>\n","<script setup lang=\"ts\">\n import { NavigationControl } from 'maplibre-gl';\n import { onMounted, inject } from 'vue';\n import { MapKey } from '../../utils';\n import type { ControlPosition, NavigationOptions } from './types';\n\n const defaultOptions: NavigationOptions = {\n showCompass: true,\n showZoom: true,\n visualizePitch: true,\n };\n\n const props = withDefaults(\n defineProps<{\n options?: NavigationOptions;\n position?: ControlPosition;\n }>(),\n {\n options: undefined,\n position: 'top-left',\n },\n );\n\n const map = inject(MapKey);\n\n onMounted(() => {\n addControl();\n });\n\n const addControl = (): void => {\n const control = new NavigationControl(props.options || defaultOptions);\n map!.value!.addControl(control, props.position);\n };\n</script>\n","<script setup lang=\"ts\">\n import { onMounted, inject } from 'vue';\n import { ScaleControl } from 'maplibre-gl';\n import { MapKey } from '../../utils';\n import type { ControlPosition, ScaleControlOptions } from './types';\n\n const defaultOptions: ScaleControlOptions = {\n maxWidth: 100,\n unit: 'metric',\n };\n\n const props = withDefaults(\n defineProps<{\n options?: ScaleControlOptions;\n position?: ControlPosition;\n }>(),\n {\n options: undefined,\n position: 'bottom-left',\n },\n );\n\n const map = inject(MapKey);\n\n onMounted(() => {\n addControl();\n });\n\n const addControl = (): void => {\n const control = new ScaleControl(props.options || defaultOptions);\n map?.value!.addControl(control, props.position);\n };\n</script>\n\n<template>\n <slot></slot>\n</template>\n","export const lidarControlEvents: string[] = [\n 'load',\n 'loadstart',\n 'loaderror',\n 'unload',\n 'statechange',\n 'stylechange',\n 'collapse',\n 'expand',\n 'streamingstart',\n 'streamingstop',\n 'streamingprogress',\n 'budgetreached',\n];\n","<script setup lang=\"ts\">\n /**\n * COPC / LAZ point-cloud viewer control with streaming + colormap controls.\n *\n * @requires `maplibre-gl-lidar`\n *\n * Install with:\n * `pnpm add maplibre-gl-lidar`\n */\n import { onMounted, onUnmounted, ref } from 'vue';\n import { MapKey, injectStrict, requirePeer } from '../../utils';\n import { lidarControlEvents as events } from './events';\n import type {\n ControlPosition,\n LidarControlOptions,\n ColorScheme,\n ColormapName,\n ColorRangeConfig,\n PointCloudInfo,\n StreamingLoaderOptions,\n CopcLoadingMode,\n } from './types';\n\n const defaultOptions: LidarControlOptions = {\n collapsed: true,\n pointSize: 2,\n colorScheme: 'elevation',\n pickable: false,\n autoZoom: true,\n };\n\n const props = withDefaults(\n defineProps<{\n options?: LidarControlOptions;\n position?: ControlPosition;\n defaultUrl?: string;\n }>(),\n {\n options: undefined,\n position: 'top-right',\n defaultUrl: undefined,\n },\n );\n\n const emit = defineEmits(events);\n\n const map = injectStrict(MapKey);\n\n interface LidarControlInstance {\n on: (event: string, handler: (data?: unknown) => void) => void;\n off: (event: string, handler: (data?: unknown) => void) => void;\n loadPointCloud: (\n source: string | File | ArrayBuffer,\n options?: { loadingMode?: CopcLoadingMode },\n ) => Promise<PointCloudInfo>;\n loadPointCloudStreaming: (\n source: string | File | ArrayBuffer,\n options?: StreamingLoaderOptions,\n ) => Promise<PointCloudInfo>;\n loadPointCloudEptStreaming: (\n eptUrl: string,\n options?: StreamingLoaderOptions,\n ) => Promise<PointCloudInfo>;\n unloadPointCloud: (id?: string) => void;\n flyToPointCloud: (id?: string) => void;\n setPointSize: (size: number) => void;\n setOpacity: (opacity: number) => void;\n setColorScheme: (scheme: ColorScheme) => void;\n setColormap: (colormap: ColormapName) => void;\n getColormap: () => ColormapName;\n setColorRange: (config: ColorRangeConfig) => void;\n getColorRange: () => ColorRangeConfig;\n setUsePercentile: (use: boolean) => void;\n getUsePercentile: () => boolean;\n setPickable: (pickable: boolean) => void;\n setElevationRange: (min: number, max: number) => void;\n clearElevationRange: () => void;\n setPointBudget: (budget: number) => void;\n setZOffset: (offset: number) => void;\n setZOffsetEnabled: (enabled: boolean) => void;\n getZOffset: () => number;\n setTerrain: (enabled: boolean) => void;\n getTerrain: () => boolean;\n setPickInfoFields: (fields?: string[]) => void;\n getPickInfoFields: () => string[] | undefined;\n setClassificationVisibility: (code: number, visible: boolean) => void;\n showAllClassifications: () => void;\n hideAllClassifications: () => void;\n getHiddenClassifications: () => number[];\n getAvailableClassifications: () => number[];\n toggle: () => void;\n expand: () => void;\n collapse: () => void;\n getState: () => unknown;\n getPointClouds: () => PointCloudInfo[];\n stopStreaming: (id?: string) => void;\n isStreaming: (id?: string) => boolean;\n getStreamingProgress: () => unknown;\n getMap: () => unknown;\n getPanelElement: () => HTMLElement | null;\n }\n\n const control = ref<LidarControlInstance | null>(null);\n\n onMounted(async () => {\n await addControl();\n });\n\n onUnmounted(() => {\n if (control.value && map.value) {\n map.value.removeControl(control.value as unknown as maplibregl.IControl);\n control.value = null;\n }\n });\n\n const addControl = async (): Promise<void> => {\n const { LidarControl } = await requirePeer(\n 'maplibre-gl-lidar',\n () => import('maplibre-gl-lidar'),\n );\n\n control.value = new LidarControl(\n props.options || defaultOptions,\n ) as unknown as LidarControlInstance;\n\n map.value!.addControl(\n control.value as unknown as maplibregl.IControl,\n props.position,\n );\n\n events.forEach((event: string) => {\n control.value!.on(event, (data?: unknown) => {\n emit(event, data);\n });\n });\n\n if (props.defaultUrl) {\n control.value.loadPointCloud(props.defaultUrl);\n }\n };\n\n defineExpose({\n loadPointCloud: (\n source: string | File | ArrayBuffer,\n options?: { loadingMode?: CopcLoadingMode },\n ) => control.value?.loadPointCloud(source, options),\n loadPointCloudStreaming: (\n source: string | File | ArrayBuffer,\n options?: StreamingLoaderOptions,\n ) => control.value?.loadPointCloudStreaming(source, options),\n loadPointCloudEptStreaming: (\n eptUrl: string,\n options?: StreamingLoaderOptions,\n ) => control.value?.loadPointCloudEptStreaming(eptUrl, options),\n unloadPointCloud: (id?: string) => control.value?.unloadPointCloud(id),\n flyToPointCloud: (id?: string) => control.value?.flyToPointCloud(id),\n setPointSize: (size: number) => control.value?.setPointSize(size),\n setColorScheme: (scheme: ColorScheme) =>\n control.value?.setColorScheme(scheme),\n setColormap: (colormap: ColormapName) =>\n control.value?.setColormap(colormap),\n getColormap: () => control.value?.getColormap(),\n setColorRange: (config: ColorRangeConfig) =>\n control.value?.setColorRange(config),\n getColorRange: () => control.value?.getColorRange(),\n setOpacity: (opacity: number) => control.value?.setOpacity(opacity),\n setPickable: (pickable: boolean) => control.value?.setPickable(pickable),\n setUsePercentile: (use: boolean) => control.value?.setUsePercentile(use),\n getUsePercentile: () => control.value?.getUsePercentile(),\n setElevationRange: (min: number, max: number) =>\n control.value?.setElevationRange(min, max),\n clearElevationRange: () => control.value?.clearElevationRange(),\n setPointBudget: (budget: number) => control.value?.setPointBudget(budget),\n setZOffset: (offset: number) => control.value?.setZOffset(offset),\n setZOffsetEnabled: (enabled: boolean) =>\n control.value?.setZOffsetEnabled(enabled),\n getZOffset: () => control.value?.getZOffset(),\n setTerrain: (enabled: boolean) => control.value?.setTerrain(enabled),\n getTerrain: () => control.value?.getTerrain(),\n setPickInfoFields: (fields?: string[]) =>\n control.value?.setPickInfoFields(fields),\n getPickInfoFields: () => control.value?.getPickInfoFields(),\n setClassificationVisibility: (code: number, visible: boolean) =>\n control.value?.setClassificationVisibility(code, visible),\n showAllClassifications: () => control.value?.showAllClassifications(),\n hideAllClassifications: () => control.value?.hideAllClassifications(),\n getHiddenClassifications: () => control.value?.getHiddenClassifications(),\n getAvailableClassifications: () =>\n control.value?.getAvailableClassifications(),\n toggle: () => control.value?.toggle(),\n expand: () => control.value?.expand(),\n collapse: () => control.value?.collapse(),\n getState: () => control.value?.getState(),\n getPointClouds: () => control.value?.getPointClouds(),\n stopStreaming: (id?: string) => control.value?.stopStreaming(id),\n isStreaming: (id?: string) => control.value?.isStreaming(id),\n getStreamingProgress: () => control.value?.getStreamingProgress(),\n getMap: () => control.value?.getMap(),\n getPanelElement: () => control.value?.getPanelElement(),\n getControl: () => control.value,\n });\n</script>\n","import {\n onMounted,\n onUnmounted,\n onUpdated,\n type Ref,\n type ShallowRef,\n} from 'vue';\nimport type { Map, IControl, ControlPosition } from 'maplibre-gl';\n\n/**\n * Register a Vue component as a MapLibre IControl for proper control stacking.\n *\n * @param map - Ref to the MapLibre map instance\n * @param containerRef - Ref to the component's root HTMLElement\n * @param position - Control position ('top-left' | 'top-right' | 'bottom-left' | 'bottom-right')\n */\nexport function useMapControl(\n map: ShallowRef<Map | null> | Ref<Map | null>,\n containerRef: Ref<HTMLElement | null>,\n position: ControlPosition,\n): void {\n let control: IControl | null = null;\n let isAdded = false;\n\n /**\n * Re-add the maplibregl-ctrl class if Vue's :class reconciliation removed it.\n * Vue overwrites the class attribute when dynamic :class bindings update,\n * which drops imperatively-added classes like maplibregl-ctrl.\n */\n const ensureControlClass = () => {\n if (\n isAdded &&\n containerRef.value &&\n !containerRef.value.classList.contains('maplibregl-ctrl')\n ) {\n containerRef.value.classList.add('maplibregl-ctrl');\n }\n };\n\n onMounted(() => {\n if (!map.value || !containerRef.value) return;\n\n control = {\n onAdd: (): HTMLElement => {\n containerRef.value?.classList.add('maplibregl-ctrl');\n return containerRef.value!;\n },\n onRemove: (): void => {},\n };\n\n map.value.addControl(control, position);\n isAdded = true;\n });\n\n onUpdated(() => {\n ensureControlClass();\n });\n\n onUnmounted(() => {\n if (map.value && control) {\n try {\n map.value.removeControl(control);\n } catch {\n // Control may already be removed if map was destroyed\n }\n }\n });\n}\n","<script setup lang=\"ts\">\n import { ref, watch, inject, onMounted } from 'vue';\n import { MapKey, injectStrict } from '../../utils';\n import { DeckLayersKey } from '../../layers/deckgl/_shared/useDeckOverlay';\n import { useMapControl } from '../_shared';\n import type { ControlPosition, LayerType } from './types';\n\n const props = withDefaults(\n defineProps<{\n layerId: string;\n position?: ControlPosition;\n visible?: boolean;\n opacity?: number;\n title?: string;\n layerType?: LayerType;\n }>(),\n {\n position: 'top-right',\n visible: true,\n opacity: 1,\n title: 'Layer Control',\n layerType: undefined,\n },\n );\n\n const emit = defineEmits<{\n 'visibility-change': [visible: boolean];\n 'opacity-change': [opacity: number];\n 'update:visible': [visible: boolean];\n 'update:opacity': [opacity: number];\n }>();\n\n const map = injectStrict(MapKey);\n const deckLayers = inject(DeckLayersKey, null);\n const containerRef = ref<HTMLElement | null>(null);\n const isVisible = ref(props.visible);\n const currentOpacity = ref(props.opacity);\n\n useMapControl(map, containerRef, props.position);\n\n // Function to detect layer type (called fresh each time, not cached)\n const getLayerType = (): LayerType | null => {\n if (props.layerType) return props.layerType;\n if (!map.value) return null;\n const maplibreLayer = map.value.getLayer(props.layerId);\n if (maplibreLayer) return 'maplibre';\n if (deckLayers) {\n const layers = deckLayers.getLayers();\n const deckLayer = (layers as Array<{ id: string }>).find(\n (l) => l.id === props.layerId,\n );\n if (deckLayer) return 'deckgl';\n }\n return null;\n };\n\n const getOpacityProperty = (): string | null => {\n if (!map.value || getLayerType() !== 'maplibre') return null;\n\n const layer = map.value.getLayer(props.layerId);\n if (!layer) return null;\n\n switch (layer.type) {\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 return 'icon-opacity';\n default:\n return null;\n }\n };\n\n const updateVisibility = (visible: boolean) => {\n const layerType = getLayerType();\n\n if (layerType === 'maplibre') {\n if (!map.value) return;\n const layer = map.value.getLayer(props.layerId);\n if (!layer) {\n console.warn(`MapLibre layer not found: ${props.layerId}`);\n return;\n }\n map.value.setLayoutProperty(\n props.layerId,\n 'visibility',\n visible ? 'visible' : 'none',\n );\n } else if (layerType === 'deckgl') {\n if (!deckLayers) {\n console.warn(\n `deck.gl overlay not available for layer: ${props.layerId}`,\n );\n return;\n }\n const layers = deckLayers.getLayers();\n const existingLayer = (\n layers as Array<{ id: string; clone?: (props: object) => unknown }>\n ).find((l) => l.id === props.layerId);\n if (!existingLayer) {\n console.warn(`deck.gl layer not found: ${props.layerId}`);\n return;\n }\n if (typeof existingLayer.clone === 'function') {\n const updatedLayer = existingLayer.clone({ visible });\n deckLayers.updateLayer(props.layerId, updatedLayer);\n }\n } else {\n console.warn(`Layer not found in MapLibre or deck.gl: ${props.layerId}`);\n return;\n }\n\n emit('visibility-change', visible);\n emit('update:visible', visible);\n };\n\n const updateOpacity = (opacity: number) => {\n const layerType = getLayerType();\n\n if (layerType === 'maplibre') {\n const opacityProp = getOpacityProperty();\n if (!map.value || !opacityProp) return;\n const layer = map.value.getLayer(props.layerId);\n if (!layer) {\n console.warn(`MapLibre layer not found: ${props.layerId}`);\n return;\n }\n map.value.setPaintProperty(props.layerId, opacityProp, opacity);\n } else if (layerType === 'deckgl') {\n if (!deckLayers) {\n console.warn(\n `deck.gl overlay not available for layer: ${props.layerId}`,\n );\n return;\n }\n const layers = deckLayers.getLayers();\n const existingLayer = (\n layers as Array<{ id: string; clone?: (props: object) => unknown }>\n ).find((l) => l.id === props.layerId);\n if (!existingLayer) {\n console.warn(`deck.gl layer not found: ${props.layerId}`);\n return;\n }\n if (typeof existingLayer.clone === 'function') {\n const updatedLayer = existingLayer.clone({ opacity });\n deckLayers.updateLayer(props.layerId, updatedLayer);\n }\n } else {\n console.warn(`Layer not found in MapLibre or deck.gl: ${props.layerId}`);\n return;\n }\n\n emit('opacity-change', opacity);\n emit('update:opacity', opacity);\n };\n\n const toggleVisibility = () => {\n isVisible.value = !isVisible.value;\n };\n\n const handleOpacityInput = (event: Event) => {\n const target = event.target as HTMLInputElement;\n currentOpacity.value = Number(target.value) / 100;\n };\n\n watch(isVisible, (newValue) => {\n updateVisibility(newValue);\n });\n\n watch(currentOpacity, (newValue) => {\n updateOpacity(newValue);\n });\n\n watch(\n () => props.visible,\n (newValue) => {\n isVisible.value = newValue;\n },\n );\n\n watch(\n () => props.opacity,\n (newValue) => {\n currentOpacity.value = newValue;\n },\n );\n\n // Wait for layer to be available, then apply initial settings\n onMounted(() => {\n let applied = false;\n\n const checkAndApply = () => {\n if (applied) return true;\n // Use function directly to get fresh result (not cached computed)\n const layerType = getLayerType();\n if (layerType) {\n applied = true;\n updateVisibility(isVisible.value);\n updateOpacity(currentOpacity.value);\n return true;\n }\n return false;\n };\n\n // Try immediately\n if (checkAndApply()) return;\n\n // If layer not found, retry with increasing intervals\n // Total wait: ~10 seconds (enough for data fetching)\n const delays = [100, 200, 300, 500, 500, 1000, 1000, 1000, 2000, 3000];\n let index = 0;\n\n const retry = () => {\n if (checkAndApply() || index >= delays.length) return;\n setTimeout(() => {\n index++;\n retry();\n }, delays[index]);\n };\n\n retry();\n });\n</script>\n\n<template>\n <div ref=\"containerRef\" class=\"v-layer-control\">\n <div class=\"v-layer-control-header\">\n <span class=\"v-layer-control-title\">{{ title }}</span>\n <button\n type=\"button\"\n class=\"v-layer-control-toggle\"\n :class=\"{ 'is-hidden': !isVisible }\"\n :aria-pressed=\"isVisible\"\n :title=\"isVisible ? 'Hide layer' : 'Show layer'\"\n @click=\"toggleVisibility\"\n >\n <svg\n v-if=\"isVisible\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n >\n <path\n d=\"M8 3C4.5 3 1.5 5.5 0.5 8C1.5 10.5 4.5 13 8 13C11.5 13 14.5 10.5 15.5 8C14.5 5.5 11.5 3 8 3Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <circle\n cx=\"8\"\n cy=\"8\"\n r=\"2.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n />\n </svg>\n <svg v-else width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path\n d=\"M2 2L14 14M6.5 6.5C5.9 7.1 5.5 7.9 5.5 8.8C5.5 10.4 6.9 11.5 8 11.5C8.9 11.5 9.7 11.1 10.3 10.5M8 3C4.5 3 1.5 5.5 0.5 8C1 9.2 1.8 10.3 2.8 11.2M13.2 11.2C14.2 10.3 15 9.2 15.5 8C14.5 5.5 11.5 3 8 3\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n\n <div class=\"v-layer-control-slider-row\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"100\"\n :value=\"Math.round(currentOpacity * 100)\"\n class=\"v-layer-control-slider\"\n :disabled=\"!isVisible\"\n @input=\"handleOpacityInput\"\n />\n <span class=\"v-layer-control-value\"\n >{{ Math.round(currentOpacity * 100) }}%</span\n >\n </div>\n\n <slot></slot>\n </div>\n</template>\n\n<style>\n .v-layer-control {\n min-width: 140px;\n max-width: 280px;\n margin: 10px;\n background: var(--color-card, #fff);\n border-radius: var(--radius, 0.5rem);\n border: 1px solid var(--color-border, #e5e7eb);\n box-shadow:\n 0 1px 3px 0 rgb(0 0 0 / 0.1),\n 0 1px 2px -1px rgb(0 0 0 / 0.1);\n font-family:\n ui-sans-serif,\n system-ui,\n -apple-system,\n sans-serif;\n font-size: 12px;\n overflow: hidden;\n padding: 8px 10px;\n /* Required: MapLibre control containers have pointer-events:none */\n pointer-events: auto;\n }\n\n .v-layer-control-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n margin-bottom: 8px;\n }\n\n .v-layer-control-title {\n font-weight: 500;\n font-size: 11px;\n color: var(--color-card-foreground, #111827);\n line-height: 1.2;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n min-width: 0;\n }\n\n .v-layer-control-toggle {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n padding: 0;\n border: none;\n border-radius: calc(var(--radius, 0.5rem) - 2px);\n background: transparent;\n color: var(--color-foreground, #374151);\n cursor: pointer;\n transition:\n background 0.15s ease,\n color 0.15s ease;\n flex-shrink: 0;\n }\n\n .v-layer-control-toggle svg {\n width: 14px;\n height: 14px;\n }\n\n .v-layer-control-toggle:hover {\n background: var(--color-accent, #f3f4f6);\n }\n\n .v-layer-control-toggle.is-hidden {\n color: var(--color-muted-foreground, #9ca3af);\n }\n\n .v-layer-control-toggle:focus {\n outline: none;\n }\n\n .v-layer-control-toggle:focus-visible {\n outline: 2px solid var(--color-primary, #3b82f6);\n outline-offset: -2px;\n }\n\n .v-layer-control-slider-row {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .v-layer-control-slider {\n flex: 1;\n height: 3px;\n border-radius: 2px;\n background: var(--color-secondary, #e5e7eb);\n cursor: pointer;\n -webkit-appearance: none;\n appearance: none;\n }\n\n .v-layer-control-slider:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n }\n\n .v-layer-control-value {\n font-size: 10px;\n font-weight: 500;\n color: var(--color-muted-foreground, #6b7280);\n font-variant-numeric: tabular-nums;\n min-width: 28px;\n text-align: right;\n }\n\n .v-layer-control-slider::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background: var(--color-primary, #3b82f6);\n cursor: pointer;\n border: 2px solid #fff;\n box-shadow: 0 1px 3px rgb(0 0 0 / 0.2);\n }\n\n .v-layer-control-slider::-moz-range-thumb {\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background: var(--color-primary, #3b82f6);\n cursor: pointer;\n border: 2px solid #fff;\n box-shadow: 0 1px 3px rgb(0 0 0 / 0.2);\n }\n\n .v-layer-control-slider:disabled::-webkit-slider-thumb {\n cursor: not-allowed;\n }\n\n .v-layer-control-slider:disabled::-moz-range-thumb {\n cursor: not-allowed;\n }\n\n .v-layer-control-slider:focus {\n outline: none;\n }\n\n .v-layer-control-slider:focus::-webkit-slider-thumb {\n box-shadow: 0 0 0 3px\n color-mix(in srgb, var(--color-primary, #3b82f6) 20%, transparent);\n }\n</style>\n","<script setup lang=\"ts\">\n import { ref, watch, inject, onMounted } from 'vue';\n import { MapKey, injectStrict } from '../../utils';\n import { DeckLayersKey } from '../../layers/deckgl/_shared/useDeckOverlay';\n import { useMapControl } from '../_shared';\n import type { ControlPosition, LayerType } from './types';\n\n export interface LayerConfig {\n id: string;\n title: string;\n visible?: boolean;\n opacity?: number;\n type?: LayerType;\n }\n\n const props = withDefaults(\n defineProps<{\n layers: LayerConfig[];\n position?: ControlPosition;\n title?: string;\n collapsible?: boolean;\n collapsed?: boolean;\n }>(),\n {\n position: 'top-right',\n title: 'Layers',\n collapsible: true,\n collapsed: false,\n },\n );\n\n const emit = defineEmits<{\n 'visibility-change': [data: { layerId: string; visible: boolean }];\n 'opacity-change': [data: { layerId: string; opacity: number }];\n 'update:layers': [layers: LayerConfig[]];\n }>();\n\n const map = injectStrict(MapKey);\n const deckLayers = inject(DeckLayersKey, null);\n const containerRef = ref<HTMLElement | null>(null);\n const isCollapsed = ref(props.collapsed);\n\n const layerStates = ref<Map<string, { visible: boolean; opacity: number }>>(\n new Map(),\n );\n\n useMapControl(map, containerRef, props.position);\n\n const initLayerStates = () => {\n for (const layer of props.layers) {\n layerStates.value.set(layer.id, {\n visible: layer.visible ?? true,\n opacity: layer.opacity ?? 1,\n });\n }\n };\n\n const getLayerType = (\n layerId: string,\n configType?: LayerType,\n ): LayerType | null => {\n if (configType) return configType;\n if (!map.value) return null;\n\n const maplibreLayer = map.value.getLayer(layerId);\n if (maplibreLayer) return 'maplibre';\n\n if (deckLayers) {\n const layers = deckLayers.getLayers();\n const deckLayer = (layers as Array<{ id: string }>).find(\n (l) => l.id === layerId,\n );\n if (deckLayer) return 'deckgl';\n }\n return null;\n };\n\n const getOpacityProperty = (layerId: string): string | null => {\n if (!map.value) return null;\n const layer = map.value.getLayer(layerId);\n if (!layer) return null;\n\n const layerType = layer.type;\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 return 'icon-opacity';\n case 'raster':\n return 'raster-opacity';\n default:\n return null;\n }\n };\n\n const updateVisibility = (\n layerId: string,\n visible: boolean,\n configType?: LayerType,\n ) => {\n const layerType = getLayerType(layerId, configType);\n\n if (layerType === 'maplibre') {\n if (!map.value) return;\n const layer = map.value.getLayer(layerId);\n if (!layer) {\n console.warn(\n `[VControlLayerGroup] MapLibre layer not found: ${layerId}`,\n );\n return;\n }\n map.value.setLayoutProperty(\n layerId,\n 'visibility',\n visible ? 'visible' : 'none',\n );\n } else if (layerType === 'deckgl') {\n if (!deckLayers) {\n console.warn(\n `[VControlLayerGroup] deck.gl overlay not available for layer: ${layerId}`,\n );\n return;\n }\n const layers = deckLayers.getLayers();\n const existingLayer = (\n layers as Array<{ id: string; clone?: (props: object) => unknown }>\n ).find((l) => l.id === layerId);\n if (!existingLayer) {\n console.warn(\n `[VControlLayerGroup] deck.gl layer not found: ${layerId}`,\n );\n return;\n }\n if (typeof existingLayer.clone === 'function') {\n const updatedLayer = existingLayer.clone({ visible });\n deckLayers.updateLayer(layerId, updatedLayer);\n }\n } else {\n console.warn(`[VControlLayerGroup] Layer not found: ${layerId}`);\n return;\n }\n\n emit('visibility-change', { layerId, visible });\n };\n\n const updateOpacity = (\n layerId: string,\n opacity: number,\n configType?: LayerType,\n ) => {\n const layerType = getLayerType(layerId, configType);\n\n if (layerType === 'maplibre') {\n const opacityProp = getOpacityProperty(layerId);\n if (!map.value || !opacityProp) return;\n const layer = map.value.getLayer(layerId);\n if (!layer) {\n console.warn(\n `[VControlLayerGroup] MapLibre layer not found: ${layerId}`,\n );\n return;\n }\n map.value.setPaintProperty(layerId, opacityProp, opacity);\n } else if (layerType === 'deckgl') {\n if (!deckLayers) {\n console.warn(\n `[VControlLayerGroup] deck.gl overlay not available for layer: ${layerId}`,\n );\n return;\n }\n const layers = deckLayers.getLayers();\n const existingLayer = (\n layers as Array<{ id: string; clone?: (props: object) => unknown }>\n ).find((l) => l.id === layerId);\n if (!existingLayer) {\n console.warn(\n `[VControlLayerGroup] deck.gl layer not found: ${layerId}`,\n );\n return;\n }\n if (typeof existingLayer.clone === 'function') {\n const updatedLayer = existingLayer.clone({ opacity });\n deckLayers.updateLayer(layerId, updatedLayer);\n }\n } else {\n console.warn(`[VControlLayerGroup] Layer not found: ${layerId}`);\n return;\n }\n\n emit('opacity-change', { layerId, opacity });\n };\n\n const toggleVisibility = (layer: LayerConfig) => {\n const state = layerStates.value.get(layer.id);\n if (!state) return;\n\n const newVisible = !state.visible;\n state.visible = newVisible;\n updateVisibility(layer.id, newVisible, layer.type);\n };\n\n const handleOpacityInput = (layer: LayerConfig, event: Event) => {\n const target = event.target as HTMLInputElement;\n const opacity = Number(target.value) / 100;\n\n const state = layerStates.value.get(layer.id);\n if (!state) return;\n\n state.opacity = opacity;\n updateOpacity(layer.id, opacity, layer.type);\n };\n\n const getState = (layerId: string) => {\n return layerStates.value.get(layerId) ?? { visible: true, opacity: 1 };\n };\n\n const toggleCollapse = () => {\n if (props.collapsible) {\n isCollapsed.value = !isCollapsed.value;\n }\n };\n\n watch(\n () => props.layers,\n () => {\n initLayerStates();\n },\n { deep: true },\n );\n\n watch(\n () => props.collapsed,\n (newValue) => {\n isCollapsed.value = newValue;\n },\n );\n\n onMounted(() => {\n initLayerStates();\n // Apply initial states\n for (const layer of props.layers) {\n const state = getState(layer.id);\n updateVisibility(layer.id, state.visible, layer.type);\n updateOpacity(layer.id, state.opacity, layer.type);\n }\n });\n</script>\n\n<template>\n <div\n ref=\"containerRef\"\n class=\"v-layer-group maplibregl-ctrl\"\n :class=\"{ 'is-collapsed': isCollapsed }\"\n >\n <button\n v-if=\"collapsible\"\n type=\"button\"\n class=\"v-layer-group-header\"\n @click=\"toggleCollapse\"\n >\n <span class=\"v-layer-group-title\">{{ title }}</span>\n <svg\n class=\"v-layer-group-chevron\"\n :class=\"{ 'is-collapsed': isCollapsed }\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n >\n <path\n d=\"M3 5L7 9L11 5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n <div v-else class=\"v-layer-group-header is-static\">\n <span class=\"v-layer-group-title\">{{ title }}</span>\n </div>\n\n <div v-if=\"!isCollapsed\" class=\"v-layer-group-content\">\n <div v-for=\"layer in layers\" :key=\"layer.id\" class=\"v-layer-group-item\">\n <div class=\"v-layer-group-item-header\">\n <span class=\"v-layer-group-item-title\">{{ layer.title }}</span>\n <button\n type=\"button\"\n class=\"v-layer-group-toggle\"\n :class=\"{ 'is-hidden': !getState(layer.id).visible }\"\n :aria-pressed=\"getState(layer.id).visible\"\n :title=\"getState(layer.id).visible ? 'Hide layer' : 'Show layer'\"\n @click=\"toggleVisibility(layer)\"\n >\n <svg\n v-if=\"getState(layer.id).visible\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n >\n <path\n d=\"M8 3C4.5 3 1.5 5.5 0.5 8C1.5 10.5 4.5 13 8 13C11.5 13 14.5 10.5 15.5 8C14.5 5.5 11.5 3 8 3Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <circle\n cx=\"8\"\n cy=\"8\"\n r=\"2.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n />\n </svg>\n <svg v-else width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path\n d=\"M2 2L14 14M6.5 6.5C5.9 7.1 5.5 7.9 5.5 8.8C5.5 10.4 6.9 11.5 8 11.5C8.9 11.5 9.7 11.1 10.3 10.5M8 3C4.5 3 1.5 5.5 0.5 8C1 9.2 1.8 10.3 2.8 11.2M13.2 11.2C14.2 10.3 15 9.2 15.5 8C14.5 5.5 11.5 3 8 3\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n <div class=\"v-layer-group-slider-row\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"100\"\n :value=\"Math.round(getState(layer.id).opacity * 100)\"\n class=\"v-layer-group-slider\"\n :disabled=\"!getState(layer.id).visible\"\n @input=\"handleOpacityInput(layer, $event)\"\n />\n <span class=\"v-layer-group-value\"\n >{{ Math.round(getState(layer.id).opacity * 100) }}%</span\n >\n </div>\n </div>\n </div>\n\n <slot></slot>\n </div>\n</template>\n\n<style>\n .v-layer-group {\n min-width: 140px;\n max-width: 280px;\n margin: 10px;\n background: var(--color-card, #fff);\n border-radius: var(--radius, 0.5rem);\n border: 1px solid var(--color-border, #e5e7eb);\n box-shadow:\n 0 1px 3px 0 rgb(0 0 0 / 0.1),\n 0 1px 2px -1px rgb(0 0 0 / 0.1);\n font-family:\n ui-sans-serif,\n system-ui,\n -apple-system,\n sans-serif;\n font-size: 12px;\n overflow: hidden;\n /* Required: MapLibre control containers have pointer-events:none */\n pointer-events: auto;\n }\n\n .v-layer-group-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n width: 100%;\n min-height: 36px;\n padding: 8px 10px;\n border: none;\n border-bottom: 1px solid var(--color-border, #e5e7eb);\n background: transparent;\n cursor: pointer;\n text-align: left;\n line-height: 1;\n touch-action: manipulation;\n -webkit-tap-highlight-color: transparent;\n }\n\n .v-layer-group-header.is-static {\n cursor: default;\n }\n\n .v-layer-group-header:not(.is-static):hover {\n background: var(--color-accent, #f3f4f6);\n }\n\n .v-layer-group-header:focus {\n outline: none;\n }\n\n .v-layer-group-header:focus-visible {\n outline: 2px solid var(--color-primary, #3b82f6);\n outline-offset: -2px;\n }\n\n .v-layer-group.is-collapsed .v-layer-group-header {\n border-bottom: none;\n }\n\n .v-layer-group-title {\n font-weight: 500;\n font-size: 11px;\n color: var(--color-card-foreground, #111827);\n line-height: 1.2;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n min-width: 0;\n }\n\n .v-layer-group-chevron {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n color: var(--color-muted-foreground, #6b7280);\n transition: transform 0.15s ease;\n flex-shrink: 0;\n }\n\n .v-layer-group-chevron.is-collapsed {\n transform: rotate(-90deg);\n }\n\n .v-layer-group-content {\n display: flex;\n flex-direction: column;\n }\n\n .v-layer-group-item {\n padding: 6px 10px 8px;\n border-bottom: 1px solid var(--color-border, #e5e7eb);\n }\n\n .v-layer-group-item:last-child {\n border-bottom: none;\n }\n\n .v-layer-group-item-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n margin-bottom: 6px;\n }\n\n .v-layer-group-item-title {\n font-weight: 500;\n font-size: 11px;\n color: var(--color-foreground, #374151);\n line-height: 1.2;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n min-width: 0;\n }\n\n .v-layer-group-toggle {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n padding: 0;\n border: none;\n border-radius: calc(var(--radius, 0.5rem) - 2px);\n background: transparent;\n color: var(--color-foreground, #374151);\n cursor: pointer;\n transition:\n background 0.15s ease,\n color 0.15s ease;\n flex-shrink: 0;\n }\n\n .v-layer-group-toggle svg {\n width: 14px;\n height: 14px;\n }\n\n .v-layer-group-toggle:hover {\n background: var(--color-accent, #f3f4f6);\n }\n\n .v-layer-group-toggle.is-hidden {\n color: var(--color-muted-foreground, #9ca3af);\n }\n\n .v-layer-group-slider-row {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .v-layer-group-slider {\n flex: 1;\n height: 3px;\n border-radius: 2px;\n background: var(--color-secondary, #e5e7eb);\n cursor: pointer;\n -webkit-appearance: none;\n appearance: none;\n }\n\n .v-layer-group-slider:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n }\n\n .v-layer-group-slider::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: var(--color-primary, #3b82f6);\n cursor: pointer;\n border: 2px solid #fff;\n box-shadow: 0 1px 3px rgb(0 0 0 / 0.2);\n }\n\n .v-layer-group-slider::-moz-range-thumb {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: var(--color-primary, #3b82f6);\n cursor: pointer;\n border: 2px solid #fff;\n box-shadow: 0 1px 3px rgb(0 0 0 / 0.2);\n }\n\n .v-layer-group-slider:disabled::-webkit-slider-thumb {\n cursor: not-allowed;\n }\n\n .v-layer-group-slider:disabled::-moz-range-thumb {\n cursor: not-allowed;\n }\n\n .v-layer-group-slider:focus {\n outline: none;\n }\n\n .v-layer-group-slider:focus::-webkit-slider-thumb {\n box-shadow: 0 0 0 3px\n color-mix(in srgb, var(--color-primary, #3b82f6) 20%, transparent);\n }\n\n .v-layer-group-value {\n font-size: 10px;\n font-weight: 500;\n color: var(--color-muted-foreground, #6b7280);\n font-variant-numeric: tabular-nums;\n min-width: 28px;\n text-align: right;\n }\n</style>\n","<script setup lang=\"ts\">\n import { ref, watch, computed, inject, onMounted } from 'vue';\n import { MapKey, injectStrict } from '../../utils';\n import { DeckLayersKey } from '../../layers/deckgl/_shared/useDeckOverlay';\n import { useMapControl } from '../_shared';\n import type {\n ControlPosition,\n LegendType,\n CategoryLegendItem,\n GradientLegendItem,\n SizeLegendItem,\n TableLegendItem,\n LegendItem,\n FilterState,\n ExpressionValue,\n DeckLayerWithExtensions,\n } from './types';\n\n const props = withDefaults(\n defineProps<{\n layerIds: string[];\n type?: LegendType;\n items?: LegendItem[];\n position?: ControlPosition;\n property?: string;\n autoGenerate?: boolean;\n title?: string;\n collapsed?: boolean;\n interactive?: boolean;\n }>(),\n {\n type: 'category',\n position: 'top-right',\n autoGenerate: false,\n title: 'Legend',\n collapsed: false,\n interactive: true,\n },\n );\n\n const emit = defineEmits<{\n 'item-click': [data: { item: LegendItem; index: number; visible: boolean }];\n 'filter-change': [data: { filter: FilterState; layerIds: string[] }];\n 'update:filter': [filter: FilterState];\n }>();\n\n const map = injectStrict(MapKey);\n const deckLayers = inject(DeckLayersKey, null);\n const containerRef = ref<HTMLElement | null>(null);\n const isCollapsed = ref(props.collapsed);\n const categoryItemVisibility = ref<Map<string | number, boolean>>(new Map());\n const generatedItems = ref<LegendItem[]>([]);\n\n useMapControl(map, containerRef, props.position);\n\n const parseMatchExpression = (\n expression: ExpressionValue[],\n ): CategoryLegendItem[] => {\n const items: CategoryLegendItem[] = [];\n const defaultColor = expression[expression.length - 1] as string;\n\n for (let i = 2; i < expression.length - 1; i += 2) {\n const value = expression[i];\n const color = expression[i + 1] as string;\n\n if (Array.isArray(value)) {\n for (const v of value) {\n items.push({\n value: v as string | number,\n label: String(v),\n color,\n visible: true,\n });\n }\n } else {\n items.push({\n value: value as string | number,\n label: String(value),\n color,\n visible: true,\n });\n }\n }\n\n if (items.length > 0 && defaultColor && typeof defaultColor === 'string') {\n items.push({\n value: '__default__',\n label: 'Other',\n color: defaultColor,\n visible: true,\n });\n }\n\n return items;\n };\n\n const parseStepExpression = (\n expression: ExpressionValue[],\n ): GradientLegendItem | null => {\n const colors: string[] = [];\n const stops: number[] = [];\n\n const defaultColor = expression[2] as string;\n colors.push(defaultColor);\n\n for (let i = 3; i < expression.length; i += 2) {\n const stop = expression[i] as number;\n const color = expression[i + 1] as string;\n stops.push(stop);\n colors.push(color);\n }\n\n if (stops.length === 0) return null;\n\n return {\n min: stops[0],\n max: stops[stops.length - 1],\n colors,\n stops,\n };\n };\n\n const parseInterpolateExpression = (\n expression: ExpressionValue[],\n ): GradientLegendItem | null => {\n const colors: string[] = [];\n const stops: number[] = [];\n\n const startIndex = expression[1] && Array.isArray(expression[1]) ? 3 : 3;\n\n for (let i = startIndex; i < expression.length; i += 2) {\n const stop = expression[i] as number;\n const color = expression[i + 1] as string;\n stops.push(stop);\n colors.push(color);\n }\n\n if (stops.length < 2) return null;\n\n return {\n min: stops[0],\n max: stops[stops.length - 1],\n colors,\n stops,\n };\n };\n\n const generateLegendFromPaint = (): LegendItem[] => {\n if (!props.autoGenerate || !props.property || !map.value) return [];\n\n const layerId = props.layerIds[0];\n if (!layerId) return [];\n\n const layer = map.value.getLayer(layerId);\n if (!layer) {\n console.warn(`[VControlLegend] Layer not found: ${layerId}`);\n return [];\n }\n\n const paintValue = map.value.getPaintProperty(layerId, props.property);\n if (!paintValue || !Array.isArray(paintValue)) {\n console.warn(\n `[VControlLegend] Paint property \"${props.property}\" not found or not an expression`,\n );\n return [];\n }\n\n const expressionType = paintValue[0];\n\n if (expressionType === 'match') {\n return parseMatchExpression(paintValue as ExpressionValue[]);\n }\n\n if (expressionType === 'step') {\n const gradient = parseStepExpression(paintValue as ExpressionValue[]);\n return gradient ? [gradient] : [];\n }\n\n if (\n expressionType === 'interpolate' ||\n expressionType === 'interpolate-hcl' ||\n expressionType === 'interpolate-lab'\n ) {\n const gradient = parseInterpolateExpression(\n paintValue as ExpressionValue[],\n );\n return gradient ? [gradient] : [];\n }\n\n console.warn(\n `[VControlLegend] Unsupported expression type: ${expressionType}`,\n );\n return [];\n };\n\n const effectiveItems = computed((): LegendItem[] => {\n if (props.items && props.items.length > 0) {\n return props.items;\n }\n return generatedItems.value;\n });\n\n const categoryItems = computed(() => {\n if (props.type !== 'category') return [];\n return effectiveItems.value.filter(\n (item): item is CategoryLegendItem =>\n 'value' in item && 'color' in item && 'label' in item,\n );\n });\n\n const gradientItem = computed(() => {\n if (props.type !== 'gradient') return null;\n const items = effectiveItems.value;\n if (items.length === 0) return null;\n const first = items[0];\n if ('min' in first && 'max' in first && 'colors' in first) {\n return first as GradientLegendItem;\n }\n return null;\n });\n\n const sizeItems = computed(() => {\n if (props.type !== 'size') return [];\n return effectiveItems.value.filter(\n (item): item is SizeLegendItem => 'size' in item && 'value' in item,\n );\n });\n\n const tableItems = computed((): TableLegendItem[] => {\n if (props.type !== 'table') return [];\n return effectiveItems.value\n .filter(\n (item): item is TableLegendItem =>\n 'label' in item &&\n 'color' in item &&\n 'value' in item &&\n !('size' in item) &&\n !('visible' in item),\n )\n .sort((a, b) => b.value - a.value);\n });\n\n const formatTableValue = (item: TableLegendItem): string => {\n if (item.formattedValue) return item.formattedValue;\n return `${item.value}${item.unit ?? ''}`;\n };\n\n const filterState = computed((): FilterState => {\n const visibleValues = Array.from(categoryItemVisibility.value.entries())\n .filter(([, visible]) => visible)\n .map(([value]) => value);\n return { visibleValues };\n });\n\n const gradientStyle = computed(() => {\n if (!gradientItem.value) return '';\n const colorStops = gradientItem.value.colors.join(', ');\n return `linear-gradient(to right, ${colorStops})`;\n });\n\n const initVisibility = () => {\n if (props.type === 'category') {\n for (const item of categoryItems.value) {\n categoryItemVisibility.value.set(item.value, item.visible ?? true);\n }\n }\n };\n\n const applyFilterToMapLibreLayers = () => {\n if (!map.value || !props.property || props.type !== 'category') return;\n\n const visibleValues = filterState.value.visibleValues.filter(\n (v) => v !== '__default__',\n );\n const allValues = categoryItems.value\n .map((item) => item.value)\n .filter((v) => v !== '__default__');\n const allVisible = visibleValues.length === allValues.length;\n\n for (const layerId of props.layerIds) {\n const layer = map.value.getLayer(layerId);\n if (!layer) continue;\n\n if (allVisible) {\n map.value.setFilter(layerId, null);\n } else if (visibleValues.length === 0) {\n map.value.setFilter(layerId, ['==', ['get', '_never_match_'], true]);\n } else {\n const paintValue = map.value.getPaintProperty(layerId, props.property);\n if (!paintValue || !Array.isArray(paintValue)) continue;\n\n const inputExpr = paintValue[1];\n let propertyName: string | null = null;\n\n if (Array.isArray(inputExpr) && inputExpr[0] === 'get') {\n propertyName = inputExpr[1] as string;\n }\n\n if (propertyName) {\n map.value.setFilter(layerId, [\n 'in',\n ['get', propertyName],\n ['literal', visibleValues],\n ]);\n }\n }\n }\n };\n\n const applyFilterToDeckglLayers = () => {\n if (!deckLayers || props.type !== 'category') return;\n\n const visibleValues = filterState.value.visibleValues.filter(\n (v) => v !== '__default__',\n );\n const allValues = categoryItems.value\n .map((item) => item.value)\n .filter((v) => v !== '__default__');\n const allVisible = visibleValues.length === allValues.length;\n\n const layers = deckLayers.getLayers() as DeckLayerWithExtensions[];\n\n for (const layerId of props.layerIds) {\n if (map.value?.getLayer(layerId)) continue;\n\n const deckLayer = layers.find((l) => l.id === layerId);\n if (!deckLayer) continue;\n\n const hasDataFilterExtension = deckLayer.props?.extensions?.some(\n (ext) => ext?.constructor?.name === 'DataFilterExtension',\n );\n\n if (!hasDataFilterExtension) {\n console.warn(\n `[VControlLegend] deck.gl layer \"${layerId}\" requires DataFilterExtension for filtering. ` +\n 'Add DataFilterExtension to layer extensions and configure getFilterValue accessor.',\n );\n continue;\n }\n\n if (typeof deckLayer.clone !== 'function') continue;\n\n if (allVisible) {\n const updatedLayer = deckLayer.clone({\n filterRange: [-Infinity, Infinity],\n });\n deckLayers.updateLayer(layerId, updatedLayer);\n } else if (visibleValues.length === 0) {\n const updatedLayer = deckLayer.clone({\n filterRange: [Infinity, Infinity],\n });\n deckLayers.updateLayer(layerId, updatedLayer);\n } else {\n const valueIndices = visibleValues\n .map((v) => categoryItems.value.findIndex((item) => item.value === v))\n .filter((i) => i >= 0);\n\n if (valueIndices.length > 0) {\n const minIndex = Math.min(...valueIndices);\n const maxIndex = Math.max(...valueIndices);\n const updatedLayer = deckLayer.clone({\n filterRange: [minIndex - 0.5, maxIndex + 0.5],\n });\n deckLayers.updateLayer(layerId, updatedLayer);\n }\n }\n }\n };\n\n const toggleItem = (item: CategoryLegendItem, index: number) => {\n if (!props.interactive) return;\n\n const currentVisible = categoryItemVisibility.value.get(item.value) ?? true;\n const newVisible = !currentVisible;\n categoryItemVisibility.value.set(item.value, newVisible);\n\n applyFilterToMapLibreLayers();\n applyFilterToDeckglLayers();\n\n emit('item-click', { item, index, visible: newVisible });\n emit('filter-change', {\n filter: filterState.value,\n layerIds: props.layerIds,\n });\n emit('update:filter', filterState.value);\n };\n\n const isItemVisible = (item: CategoryLegendItem) => {\n return categoryItemVisibility.value.get(item.value) ?? true;\n };\n\n const toggleCollapse = () => {\n isCollapsed.value = !isCollapsed.value;\n };\n\n watch(\n () => props.items,\n () => {\n initVisibility();\n },\n { deep: true },\n );\n\n watch(\n () => props.collapsed,\n (newValue) => {\n isCollapsed.value = newValue;\n },\n );\n\n onMounted(() => {\n if (props.autoGenerate) {\n generatedItems.value = generateLegendFromPaint();\n }\n initVisibility();\n });\n</script>\n\n<template>\n <div\n ref=\"containerRef\"\n class=\"v-legend-control\"\n :class=\"{ 'is-collapsed': isCollapsed }\"\n >\n <button\n type=\"button\"\n class=\"v-legend-control-header\"\n @click=\"toggleCollapse\"\n >\n <span class=\"v-legend-control-title\">{{ title }}</span>\n <svg\n class=\"v-legend-control-chevron\"\n :class=\"{ 'is-collapsed': isCollapsed }\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n >\n <path\n d=\"M3 5L7 9L11 5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n\n <div v-if=\"!isCollapsed\" class=\"v-legend-control-content\">\n <template v-if=\"type === 'category'\">\n <button\n v-for=\"(item, index) in categoryItems\"\n :key=\"item.value\"\n type=\"button\"\n class=\"v-legend-control-item\"\n :class=\"{\n 'is-interactive': interactive,\n 'is-hidden': !isItemVisible(item),\n }\"\n :disabled=\"!interactive\"\n @click=\"toggleItem(item, index)\"\n >\n <span\n class=\"v-legend-control-swatch\"\n :style=\"{ backgroundColor: item.color }\"\n ></span>\n <span class=\"v-legend-control-label\">{{ item.label }}</span>\n <span v-if=\"item.count !== undefined\" class=\"v-legend-control-count\">\n {{ item.count }}\n </span>\n </button>\n </template>\n\n <template v-else-if=\"type === 'gradient' && gradientItem\">\n <div\n class=\"v-legend-control-gradient\"\n :style=\"{ background: gradientStyle }\"\n ></div>\n <div class=\"v-legend-control-gradient-labels\">\n <span>{{ gradientItem.minLabel ?? gradientItem.min }}</span>\n <span>{{ gradientItem.maxLabel ?? gradientItem.max }}</span>\n </div>\n </template>\n\n <template v-else-if=\"type === 'size'\">\n <div\n v-for=\"item in sizeItems\"\n :key=\"item.value\"\n class=\"v-legend-control-size-item\"\n >\n <div class=\"v-legend-control-size-circle-wrap\">\n <div\n class=\"v-legend-control-size-circle\"\n :style=\"{\n width: `${Math.min(item.size, 20)}px`,\n height: `${Math.min(item.size, 20)}px`,\n }\"\n ></div>\n </div>\n <span class=\"v-legend-control-label\">{{ item.label }}</span>\n </div>\n </template>\n\n <template v-else-if=\"type === 'table'\">\n <div class=\"v-legend-control-table\">\n <div\n v-for=\"item in tableItems\"\n :key=\"item.label\"\n class=\"v-legend-control-table-row\"\n :title=\"item.description\"\n >\n <span\n class=\"v-legend-control-swatch\"\n :style=\"{ backgroundColor: item.color }\"\n ></span>\n <span class=\"v-legend-control-table-label\">{{ item.label }}</span>\n <span class=\"v-legend-control-table-value\">\n {{ formatTableValue(item) }}\n </span>\n </div>\n </div>\n </template>\n </div>\n\n <slot></slot>\n </div>\n</template>\n\n<style>\n .v-legend-control {\n min-width: 140px;\n max-width: 200px;\n margin: 10px;\n background: var(--color-card, #fff);\n border-radius: var(--radius, 0.5rem);\n border: 1px solid var(--color-border, #e5e7eb);\n box-shadow:\n 0 1px 3px 0 rgb(0 0 0 / 0.1),\n 0 1px 2px -1px rgb(0 0 0 / 0.1);\n font-family:\n ui-sans-serif,\n system-ui,\n -apple-system,\n sans-serif;\n font-size: 12px;\n overflow: hidden;\n /* Required: MapLibre control containers have pointer-events:none */\n pointer-events: auto;\n }\n\n .v-legend-control-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n width: 100%;\n min-height: 44px;\n padding: 8px 10px;\n border: none;\n border-bottom: 1px solid var(--color-border, #e5e7eb);\n background: transparent;\n cursor: pointer;\n text-align: left;\n line-height: 1;\n touch-action: manipulation;\n -webkit-tap-highlight-color: transparent;\n }\n\n .v-legend-control.is-collapsed .v-legend-control-header {\n border-bottom: none;\n }\n\n .v-legend-control-header:hover {\n background: var(--color-accent, #f3f4f6);\n }\n\n .v-legend-control-title {\n font-weight: 500;\n font-size: 13px;\n color: var(--color-card-foreground, #111827);\n line-height: 1;\n }\n\n .v-legend-control-chevron {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n color: var(--color-muted-foreground, #6b7280);\n transition: transform 0.15s ease;\n flex-shrink: 0;\n }\n\n .v-legend-control-chevron.is-collapsed {\n transform: rotate(-90deg);\n }\n\n .v-legend-control-content {\n padding: 6px;\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n\n .v-legend-control-item {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 6px 8px;\n border: none;\n border-radius: calc(var(--radius, 0.5rem) - 4px);\n background: transparent;\n text-align: left;\n transition:\n background 0.1s ease,\n opacity 0.1s ease;\n }\n\n .v-legend-control-item.is-interactive {\n cursor: pointer;\n }\n\n .v-legend-control-item.is-interactive:hover {\n background: var(--color-accent, #f3f4f6);\n }\n\n .v-legend-control-item.is-hidden {\n opacity: 0.4;\n }\n\n .v-legend-control-item.is-hidden .v-legend-control-label {\n text-decoration: line-through;\n }\n\n .v-legend-control-item:disabled {\n cursor: default;\n }\n\n .v-legend-control-swatch {\n width: 12px;\n height: 12px;\n border-radius: 3px;\n flex-shrink: 0;\n box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.1);\n }\n\n .v-legend-control-label {\n flex: 1;\n font-size: 11px;\n font-weight: 500;\n color: var(--color-foreground, #374151);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .v-legend-control-count {\n font-size: 10px;\n font-weight: 500;\n color: var(--color-muted-foreground, #6b7280);\n background: var(--color-secondary, #f3f4f6);\n padding: 1px 5px;\n border-radius: 8px;\n }\n\n .v-legend-control-gradient {\n height: 12px;\n border-radius: 3px;\n margin: 6px 8px 4px;\n }\n\n .v-legend-control-gradient-labels {\n display: flex;\n justify-content: space-between;\n padding: 0 8px 6px;\n font-size: 10px;\n font-weight: 500;\n color: var(--color-muted-foreground, #6b7280);\n }\n\n .v-legend-control-size-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 8px;\n }\n\n .v-legend-control-size-circle-wrap {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n }\n\n .v-legend-control-size-circle {\n border-radius: 50%;\n background: var(--color-primary, #3b82f6);\n box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.1);\n }\n\n .v-legend-control-table {\n max-height: 300px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 1px;\n }\n\n .v-legend-control-table-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 8px;\n border-radius: calc(var(--radius, 0.5rem) - 4px);\n }\n\n .v-legend-control-table-row:hover {\n background: var(--color-accent, #f3f4f6);\n }\n\n .v-legend-control-table-label {\n flex: 1;\n font-size: 11px;\n font-weight: 500;\n color: var(--color-foreground, #374151);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .v-legend-control-table-value {\n font-size: 10px;\n font-weight: 600;\n color: var(--color-muted-foreground, #6b7280);\n white-space: nowrap;\n font-variant-numeric: tabular-nums;\n }\n\n .v-legend-control:has(.v-legend-control-table) {\n max-width: 280px;\n }\n</style>\n","<script setup lang=\"ts\">\n import type {\n CanvasSourceSpecification,\n LayerSpecification,\n Map,\n } from 'maplibre-gl';\n import type { Ref } from 'vue';\n import { onMounted, onBeforeUnmount, ref, watch } from 'vue';\n import { injectStrict, MapKey } from '../../../utils';\n\n const props = withDefaults(\n defineProps<{\n source: CanvasSourceSpecification;\n layer: LayerSpecification;\n sourceId?: string;\n layerId?: string;\n before?: string;\n }>(),\n {\n sourceId: 'maplibre.gl-canvas-source',\n layerId: 'maplibre.gl-canvas-layer',\n before: '',\n },\n );\n\n const map = injectStrict(MapKey);\n const loaded: Ref<boolean> = ref(false);\n\n // Helper function to safely get map instance\n const getMapInstance = (): Map | null => {\n return map.value || null;\n };\n\n // Setup functions\n const setupMap = (mapInstance: Map) => {\n if (!mapInstance) return;\n\n mapInstance.on('style.load', () => {\n const styleTimeout = () => {\n if (!mapInstance.isStyleLoaded()) {\n loaded.value = false;\n setTimeout(styleTimeout, 200);\n } else {\n loaded.value = true;\n }\n };\n styleTimeout();\n });\n };\n\n const addLayer = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if (!mapInstance.getSource(props.sourceId)) {\n mapInstance.addSource(props.sourceId, props.source);\n }\n if (!mapInstance.getLayer(props.layerId)) {\n const layerSpec = {\n ...props.layer,\n id: props.layerId,\n source: props.sourceId,\n } as LayerSpecification;\n mapInstance.addLayer(layerSpec, props.before);\n }\n } catch (error) {\n console.error('Error adding Canvas layer:', error);\n }\n };\n\n const updateSource = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n // For canvas sources, we need to remove and re-add both source and layer\n if (mapInstance.getLayer(props.layerId)) {\n mapInstance.removeLayer(props.layerId);\n }\n if (mapInstance.getSource(props.sourceId)) {\n mapInstance.removeSource(props.sourceId);\n }\n\n mapInstance.addSource(props.sourceId, props.source);\n const layerSpec = {\n ...props.layer,\n id: props.layerId,\n source: props.sourceId,\n } as LayerSpecification;\n mapInstance.addLayer(layerSpec, props.before);\n } catch (error) {\n console.error('Error updating Canvas source:', error);\n }\n };\n\n const updateLayer = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if (mapInstance.getLayer(props.layerId)) {\n Object.entries(props.layer.paint || {}).forEach(([key, value]) => {\n mapInstance.setPaintProperty(props.layerId, key, value);\n });\n Object.entries(props.layer.layout || {}).forEach(([key, value]) => {\n mapInstance.setLayoutProperty(props.layerId, key, value);\n });\n }\n } catch (error) {\n console.error('Error updating Canvas layer:', error);\n }\n };\n\n // Watchers\n watch(() => props.source, updateSource, { deep: true });\n watch(() => props.layer, updateLayer, { deep: true });\n\n // Watch for map instance changes\n watch(\n map,\n (newMap) => {\n if (newMap) {\n setupMap(newMap);\n }\n },\n { immediate: true },\n );\n\n // Watch loaded state\n watch(loaded, (value) => {\n if (value) {\n addLayer();\n }\n });\n\n // Lifecycle hooks\n onMounted(() => {\n const mapInstance = getMapInstance();\n if (mapInstance?.isStyleLoaded()) {\n addLayer();\n }\n });\n\n onBeforeUnmount(() => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if (mapInstance.getLayer(props.layerId)) {\n mapInstance.removeLayer(props.layerId);\n }\n if (mapInstance.getSource(props.sourceId)) {\n mapInstance.removeSource(props.sourceId);\n }\n } catch (error) {\n console.error('Error cleaning up Canvas layer:', error);\n }\n });\n</script>\n\n<template>\n <slot></slot>\n</template>\n","<!-- web/app/lib/v-mapbox/layers/maplibre/geojson/VLayerMaplibreGeojson.vue -->\n<script setup lang=\"ts\">\n import type { Ref } from 'vue';\n import { onMounted, onBeforeUnmount, ref, watch, nextTick } from 'vue';\n import type {\n GeoJSONSource,\n GeoJSONSourceSpecification,\n LayerSpecification,\n Map,\n MapLayerMouseEvent,\n } from 'maplibre-gl';\n import { injectStrict, MapKey } from '../../../utils';\n\n interface LayerClick {\n features: GeoJSON.Feature[];\n coordinates: {\n lng: number;\n lat: number;\n };\n }\n\n interface Props {\n sourceId: string;\n layerId: string;\n source: GeoJSONSourceSpecification;\n layer: LayerSpecification;\n before?: string;\n }\n\n const props = withDefaults(defineProps<Props>(), {\n sourceId: 'maplibre-gl-geojson-source',\n layerId: 'maplibre-gl-geojson-layer',\n before: '',\n });\n\n const emit = defineEmits<{\n 'on-click': [event: LayerClick];\n }>();\n\n const map = injectStrict(MapKey);\n const loaded: Ref<boolean> = ref(false);\n\n // Helper to check if data is valid GeoJSON with features\n const hasValidData = (\n data: string | GeoJSON.GeoJSON | undefined,\n ): boolean => {\n if (!data || typeof data === 'string') return false;\n if (data && typeof data === 'object' && 'type' in data) {\n if (data.type === 'FeatureCollection' && 'features' in data) {\n return data.features.length > 0;\n }\n // Also valid for single Feature or Geometry\n return (\n data.type === 'Feature' ||\n data.type === 'Point' ||\n data.type === 'LineString' ||\n data.type === 'Polygon' ||\n data.type === 'MultiPoint' ||\n data.type === 'MultiLineString' ||\n data.type === 'MultiPolygon'\n );\n }\n return false;\n };\n\n // Helper function to safely get map instance\n const getMapInstance = (): Map | null => {\n const instance = map.value || null;\n return instance;\n };\n\n // Setup functions\n const setupMap = (mapInstance: Map) => {\n if (!mapInstance) {\n return;\n }\n\n mapInstance.on('style.load', () => {\n const styleTimeout = () => {\n if (!mapInstance.isStyleLoaded()) {\n loaded.value = false;\n setTimeout(styleTimeout, 200);\n } else {\n loaded.value = true;\n }\n };\n styleTimeout();\n });\n };\n\n const addLayer = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance || !mapInstance.isStyleLoaded()) {\n return;\n }\n\n // For clustering support, wait for valid data before adding source/layer\n if (!hasValidData(props.source.data)) {\n console.log(\n `[${props.layerId}] Waiting for valid data before adding layer`,\n );\n return;\n }\n\n try {\n // Only add source if it doesn't exist\n if (!mapInstance.getSource(props.sourceId)) {\n mapInstance.addSource(props.sourceId, props.source);\n }\n\n // Only add layer if it doesn't exist\n if (!mapInstance.getLayer(props.layerId)) {\n const layerSpec = {\n ...props.layer,\n id: props.layerId,\n source: props.sourceId,\n } as LayerSpecification;\n\n mapInstance.addLayer(layerSpec, props.before);\n }\n } catch (error) {\n console.error('Error adding GeoJSON layer:', error);\n }\n };\n\n const updateSource = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n const source = mapInstance.getSource(props.sourceId) as\n | GeoJSONSource\n | undefined;\n\n if (source && 'setData' in source) {\n // CRITICAL FIX: Only update data if source doesn't have clustering\n // or if this is the first/primary layer for this source\n const existingLayers = mapInstance\n .getStyle()\n .layers.filter(\n (l) =>\n l.type !== 'background' &&\n 'source' in l &&\n l.source === props.sourceId,\n );\n\n // Only update data if this is the first layer using this source\n // This prevents breaking clustering when multiple layers share a source\n if (\n existingLayers.length === 0 ||\n existingLayers[0]?.id === props.layerId\n ) {\n source.setData(props.source.data);\n }\n } else if (!source) {\n // If source doesn't exist, try to add the layer\n addLayer();\n }\n } catch (error) {\n console.error('Error updating GeoJSON source:', error);\n }\n };\n\n const updateLayer = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if (mapInstance.getLayer(props.layerId)) {\n // Update paint properties\n Object.entries(props.layer.paint || {}).forEach(([key, value]) => {\n mapInstance.setPaintProperty(props.layerId, key, value);\n });\n // Update layout properties\n Object.entries(props.layer.layout || {}).forEach(([key, value]) => {\n mapInstance.setLayoutProperty(props.layerId, key, value);\n });\n } else {\n // If layer doesn't exist, try to add it\n addLayer();\n }\n } catch (error) {\n console.error('Error updating GeoJSON layer:', error);\n }\n };\n\n const setupLayerEvents = (mapInstance: Map) => {\n if (!mapInstance) {\n return;\n }\n\n try {\n // Add click handler for the specific layer\n mapInstance.on('click', props.layerId, (e: MapLayerMouseEvent) => {\n if (e.features && e.features.length > 0) {\n emit('on-click', {\n features: e.features,\n coordinates: e.lngLat,\n });\n }\n });\n\n // Add hover effect to verify interactivity\n mapInstance.on('mouseenter', props.layerId, () => {\n mapInstance.getCanvas().style.cursor = 'pointer';\n });\n\n mapInstance.on('mouseleave', props.layerId, () => {\n mapInstance.getCanvas().style.cursor = '';\n });\n } catch (error) {\n console.error('Error in setupLayerEvents:', error);\n }\n };\n\n // Track if layer has been initialized to prevent duplicate setup\n const initialized = ref(false);\n\n // Initialize layer - single entry point to prevent race conditions\n const initializeLayer = async () => {\n if (initialized.value) return;\n\n const mapInstance = getMapInstance();\n if (!mapInstance || !mapInstance.isStyleLoaded()) return;\n if (!hasValidData(props.source.data)) return;\n\n // Use nextTick to ensure Vue has finished setup\n await nextTick();\n\n // Double-check conditions after nextTick\n if (initialized.value) return;\n if (!mapInstance.isStyleLoaded()) return;\n\n addLayer();\n setupLayerEvents(mapInstance);\n initialized.value = true;\n };\n\n // Watch loaded state - MUST be defined BEFORE watch(map) to catch immediate changes\n watch(loaded, (value) => {\n if (value) {\n initializeLayer();\n }\n });\n\n // Watch for map instance changes\n watch(\n map,\n (newMap) => {\n if (newMap) {\n setupMap(newMap);\n // Check if style is already loaded\n if (newMap.isStyleLoaded()) {\n loaded.value = true;\n // Also try to initialize directly in case watch(loaded) already fired\n initializeLayer();\n }\n }\n },\n { immediate: true },\n );\n\n // Watchers for updates after initialization\n watch(\n () => props.source,\n (newSource, oldSource) => {\n // Wait for valid data before doing anything\n if (!hasValidData(newSource?.data)) {\n return;\n }\n\n // Only update if the data actually changed\n if (JSON.stringify(newSource.data) !== JSON.stringify(oldSource?.data)) {\n const mapInstance = getMapInstance();\n if (mapInstance?.isStyleLoaded()) {\n // If source doesn't exist yet, add the whole layer\n if (!mapInstance.getSource(props.sourceId)) {\n addLayer();\n if (!initialized.value) {\n setupLayerEvents(mapInstance);\n initialized.value = true;\n }\n } else {\n // Source exists, just update data\n updateSource();\n }\n }\n }\n },\n { deep: true },\n );\n\n watch(() => props.layer, updateLayer, { deep: true });\n\n // Watch for visibility changes\n watch(\n () => props.layer.layout?.visibility,\n (newVisibility) => {\n const mapInstance = getMapInstance();\n if (!mapInstance || !mapInstance.isStyleLoaded()) return;\n\n const hasLayer = mapInstance.getLayer(props.layerId);\n\n if (!hasLayer && newVisibility === 'visible') {\n // Add layer if it doesn't exist and should be visible\n if (hasValidData(props.source.data)) {\n addLayer();\n }\n } else if (hasLayer) {\n // Update visibility of existing layer\n try {\n mapInstance.setLayoutProperty(\n props.layerId,\n 'visibility',\n newVisibility,\n );\n } catch (error) {\n console.error(\n `Error updating visibility for ${props.layerId}:`,\n error,\n );\n }\n }\n },\n { immediate: true },\n );\n\n // Lifecycle hooks\n onMounted(() => {\n // Use nextTick to ensure all watchers are set up\n nextTick(() => {\n initializeLayer();\n });\n });\n\n onBeforeUnmount(() => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n // Remove layer\n if (mapInstance.getLayer(props.layerId)) {\n mapInstance.removeLayer(props.layerId);\n }\n\n // Only remove source if no other layers are using it\n const layersUsingSource = mapInstance\n .getStyle()\n .layers.filter(\n (l) =>\n l.type !== 'background' &&\n 'source' in l &&\n l.source === props.sourceId,\n );\n\n if (\n layersUsingSource.length === 0 &&\n mapInstance.getSource(props.sourceId)\n ) {\n mapInstance.removeSource(props.sourceId);\n }\n } catch (error) {\n console.error('Error cleaning up GeoJSON layer:', error);\n }\n });\n</script>\n\n<template>\n <slot></slot>\n</template>\n","<script setup lang=\"ts\">\n import type {\n LayerSpecification as AnyLayer,\n ImageSourceSpecification as ImageSourceRaw,\n ImageSource,\n Map,\n } from 'maplibre-gl';\n import type { PropType, Ref } from 'vue';\n import { onMounted, onBeforeUnmount, ref, watch } from 'vue';\n import { injectStrict, MapKey } from '../../../utils';\n\n const props = defineProps({\n sourceId: {\n type: String,\n default: 'maplibre.gl-image-source',\n required: true,\n },\n layerId: {\n type: String,\n default: 'maplibre.gl-image-layer',\n required: true,\n },\n source: {\n type: Object as PropType<ImageSourceRaw>,\n required: true,\n },\n layer: {\n type: Object as PropType<AnyLayer>,\n default: () => ({}),\n required: true,\n },\n before: {\n type: String,\n default: '',\n required: false,\n },\n });\n\n const map = injectStrict(MapKey);\n const loaded: Ref<boolean> = ref(false);\n\n // Helper function to safely get map instance\n const getMapInstance = (): Map | null => {\n return map.value || null;\n };\n\n // Setup functions\n const setupMap = (mapInstance: Map) => {\n if (!mapInstance) return;\n\n mapInstance.on('style.load', () => {\n const styleTimeout = () => {\n if (!mapInstance.isStyleLoaded()) {\n loaded.value = false;\n setTimeout(styleTimeout, 200);\n } else {\n loaded.value = true;\n }\n };\n styleTimeout();\n });\n };\n\n const addLayer = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if (!mapInstance.getSource(props.sourceId)) {\n mapInstance.addSource(props.sourceId, props.source);\n }\n if (!mapInstance.getLayer(props.layerId)) {\n const layerSpec = {\n ...props.layer,\n id: props.layerId,\n source: props.sourceId,\n } as AnyLayer;\n mapInstance.addLayer(layerSpec, props.before);\n }\n } catch (error) {\n console.error('Error adding Image layer:', error);\n }\n };\n\n const updateSource = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n const source = mapInstance.getSource(props.sourceId) as ImageSource;\n if (source) {\n // For image sources, we need to update coordinates and url\n if (source.updateImage) {\n source.updateImage({\n url: props.source.url,\n coordinates: props.source.coordinates,\n });\n } else {\n // If updateImage is not available, remove and re-add the source and layer\n if (mapInstance.getLayer(props.layerId)) {\n mapInstance.removeLayer(props.layerId);\n }\n if (mapInstance.getSource(props.sourceId)) {\n mapInstance.removeSource(props.sourceId);\n }\n\n mapInstance.addSource(props.sourceId, props.source);\n const layerSpec = {\n ...props.layer,\n id: props.layerId,\n source: props.sourceId,\n } as AnyLayer;\n mapInstance.addLayer(layerSpec, props.before);\n }\n }\n } catch (error) {\n console.error('Error updating Image source:', error);\n }\n };\n\n const updateLayer = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if (mapInstance.getLayer(props.layerId)) {\n Object.entries(props.layer.paint || {}).forEach(([key, value]) => {\n mapInstance.setPaintProperty(props.layerId, key, value);\n });\n Object.entries(props.layer.layout || {}).forEach(([key, value]) => {\n mapInstance.setLayoutProperty(props.layerId, key, value);\n });\n }\n } catch (error) {\n console.error('Error updating Image layer:', error);\n }\n };\n\n // Watchers\n watch(() => props.source, updateSource, { deep: true });\n watch(() => props.layer, updateLayer, { deep: true });\n\n // Watch for map instance changes\n watch(\n map,\n (newMap) => {\n if (newMap) {\n setupMap(newMap);\n }\n },\n { immediate: true },\n );\n\n // Watch loaded state\n watch(loaded, (value) => {\n if (value) {\n addLayer();\n }\n });\n\n // Lifecycle hooks\n onMounted(() => {\n const mapInstance = getMapInstance();\n if (mapInstance?.isStyleLoaded()) {\n addLayer();\n }\n });\n\n onBeforeUnmount(() => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if (mapInstance.getLayer(props.layerId)) {\n mapInstance.removeLayer(props.layerId);\n }\n if (mapInstance.getSource(props.sourceId)) {\n mapInstance.removeSource(props.sourceId);\n }\n } catch (error) {\n console.error('Error cleaning up Image layer:', error);\n }\n });\n</script>\n\n<template>\n <slot></slot>\n</template>\n","<script setup lang=\"ts\">\n import type {\n RasterSourceSpecification,\n RasterLayerSpecification,\n Map,\n } from 'maplibre-gl';\n import type { Ref } from 'vue';\n import { onMounted, ref, watch } from 'vue';\n import { injectStrict, MapKey } from '../../../utils';\n\n const props = defineProps<{\n sourceId: string;\n source: RasterSourceSpecification;\n layerId: string;\n layer: RasterLayerSpecification;\n before?: string;\n }>();\n\n const map = injectStrict(MapKey);\n const loaded: Ref<boolean> = ref(false);\n\n const getMapInstance = (): Map | null => {\n return map.value || null;\n };\n\n const setupMap = (mapInstance: Map) => {\n if (!mapInstance) return;\n\n mapInstance.on('style.load', () => {\n const styleTimeout = () => {\n if (!mapInstance.isStyleLoaded()) {\n loaded.value = false;\n setTimeout(styleTimeout, 200);\n } else {\n loaded.value = true;\n }\n };\n styleTimeout();\n });\n };\n\n const addLayer = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if (!mapInstance.getSource(props.sourceId)) {\n mapInstance.addSource(props.sourceId, props.source);\n }\n if (!mapInstance.getLayer(props.layerId)) {\n // Always add with proper ordering\n mapInstance.addLayer(props.layer, props.before);\n\n // Set initial visibility\n if (props.layer.layout?.visibility) {\n mapInstance.setLayoutProperty(\n props.layerId,\n 'visibility',\n props.layer.layout.visibility,\n );\n }\n }\n } catch (error) {\n console.error(`[${props.layerId}] Error setting up layer:`, error);\n }\n };\n\n const updateSource = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n // Store the current beforeId since we'll need to reuse it\n const beforeId = props.before;\n\n if (mapInstance.getLayer(props.layerId)) {\n mapInstance.removeLayer(props.layerId);\n }\n mapInstance.removeSource(props.sourceId);\n\n mapInstance.addSource(props.sourceId, props.source);\n const layerSpec = {\n ...props.layer,\n id: props.layerId,\n type: 'raster',\n source: props.sourceId,\n } as RasterLayerSpecification;\n\n // Explicitly check if the beforeId layer exists before adding\n if (beforeId && mapInstance.getLayer(beforeId)) {\n mapInstance.addLayer(layerSpec, beforeId);\n } else {\n mapInstance.addLayer(layerSpec);\n }\n } catch (error) {\n console.error('Error updating Raster source:', error);\n }\n };\n\n const updateLayer = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if (mapInstance.getLayer(props.layerId)) {\n // Update paint properties\n const paint = props.layer.paint || {};\n Object.entries(paint).forEach(([key, value]) => {\n mapInstance.setPaintProperty(props.layerId, key, value);\n });\n\n // Update layout properties\n const layout = props.layer.layout || {};\n Object.entries(layout).forEach(([key, value]) => {\n mapInstance.setLayoutProperty(props.layerId, key, value);\n });\n }\n } catch (error) {\n console.error('Error updating Raster layer:', error);\n }\n };\n\n // Watchers\n watch(\n () => props.source.tiles?.[0], // Usually raster sources have a single tile URL\n (newTileUrl, oldTileUrl) => {\n if (newTileUrl !== oldTileUrl) {\n updateSource();\n }\n },\n );\n watch(() => props.layer, updateLayer, { deep: true });\n watch(\n map,\n (newMap) => {\n if (newMap) {\n setupMap(newMap);\n }\n },\n { immediate: true },\n );\n watch(loaded, (value) => {\n if (value) {\n addLayer();\n }\n });\n watch(\n () => props.layer.layout?.visibility,\n (newVisibility) => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n const hasLayer = mapInstance.getLayer(props.layerId);\n\n if (!hasLayer) {\n // Add layer with proper ordering\n try {\n mapInstance.addLayer(props.layer, props.before);\n } catch (error) {\n console.error(`[${props.layerId}] Error adding layer:`, error);\n }\n } else {\n try {\n // Update visibility\n mapInstance.setLayoutProperty(\n props.layerId,\n 'visibility',\n newVisibility,\n );\n\n // If becoming visible, ensure proper layer ordering\n if (newVisibility === 'visible' && props.before) {\n mapInstance.moveLayer(props.layerId, props.before);\n }\n } catch (error) {\n console.error(`[${props.layerId}] Error updating visibility:`, error);\n }\n }\n },\n { immediate: true },\n );\n watch(\n () => props.before,\n (newBefore) => {\n const mapInstance = getMapInstance();\n if (!mapInstance || !mapInstance.getLayer(props.layerId)) return;\n\n // Only move layer if it's visible\n if (props.layer.layout?.visibility === 'visible') {\n try {\n console.log(`[${props.layerId}] Moving layer before:`, newBefore);\n mapInstance.moveLayer(props.layerId, newBefore);\n } catch (error) {\n console.error(`[${props.layerId}] Error moving layer:`, error);\n }\n }\n },\n );\n\n // Also add logging for source and layer setup\n onMounted(() => {\n const mapInstance = getMapInstance();\n if (!mapInstance) {\n return;\n }\n try {\n addLayer();\n } catch (error) {\n console.error(`[${props.layerId}] Error setting up layer:`, error);\n }\n });\n</script>\n\n<template>\n <slot></slot>\n</template>\n","import type { MapLayerEventType } from 'maplibre-gl';\n\nexport const mapLayerEvents: Array<keyof MapLayerEventType> = [\n 'click',\n 'dblclick',\n 'mousedown',\n 'mouseup',\n 'mousemove',\n 'mouseenter',\n 'mouseleave',\n 'mouseover',\n 'mouseout',\n 'contextmenu',\n 'touchstart',\n 'touchend',\n 'touchcancel',\n];\n","import type { MapEventType } from 'maplibre-gl';\n\nexport const mapEvents: Array<keyof MapEventType> = [\n 'error',\n 'load',\n 'idle',\n 'remove',\n 'render',\n 'resize',\n 'webglcontextlost',\n 'webglcontextrestored',\n 'dataloading',\n 'data',\n 'tiledataloading',\n 'sourcedataloading',\n 'styledataloading',\n 'sourcedata',\n 'styledata',\n 'boxzoomcancel',\n 'boxzoomstart',\n 'boxzoomend',\n 'touchcancel',\n 'touchmove',\n 'touchend',\n 'touchstart',\n 'click',\n 'contextmenu',\n 'dblclick',\n 'mousemove',\n 'mouseup',\n 'mousedown',\n 'mouseout',\n 'mouseover',\n 'movestart',\n 'move',\n 'moveend',\n 'zoomstart',\n 'zoom',\n 'zoomend',\n 'rotatestart',\n 'rotate',\n 'rotateend',\n 'dragstart',\n 'drag',\n 'dragend',\n 'pitchstart',\n 'pitch',\n 'pitchend',\n 'wheel',\n];\n","export const markerMapEvents = ['dragstart', 'drag', 'dragend'];\nexport const markerDOMEvents = ['click', 'mouseenter', 'mouseleave'];\n","export const popupEvents = ['open', 'close'] as Array<'open' | 'close'>;\n","<script setup lang=\"ts\">\n import type { Ref } from 'vue';\n import { onMounted, ref, watch } from 'vue';\n import type {\n Map,\n VectorSourceSpecification,\n LayerSpecification,\n } from 'maplibre-gl';\n import { mapLayerEvents } from '../../../constants/events';\n import { injectStrict, MapKey } from '../../../utils';\n\n const props = defineProps<{\n sourceId: string;\n source: VectorSourceSpecification;\n layerId: string;\n layer: LayerSpecification;\n before?: string;\n }>();\n const emit = defineEmits([...mapLayerEvents]);\n\n const map = injectStrict(MapKey);\n const loaded: Ref<boolean> = ref(false);\n\n // Helper function to safely get map instance\n const getMapInstance = (): Map | null => {\n return map.value || null;\n };\n\n // Setup functions\n const setupMap = (mapInstance: Map) => {\n if (!mapInstance) return;\n\n mapInstance.on('style.load', () => {\n const styleTimeout = () => {\n if (!mapInstance.isStyleLoaded()) {\n loaded.value = false;\n setTimeout(styleTimeout, 200);\n } else {\n loaded.value = true;\n }\n };\n styleTimeout();\n });\n };\n const addLayer = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if (!mapInstance.getSource(props.sourceId)) {\n mapInstance.addSource(props.sourceId, props.source);\n }\n if (!mapInstance.getLayer(props.layerId)) {\n // Always get a fresh beforeId when adding a layer\n if (props.layer.layout?.visibility === 'visible') {\n mapInstance.addLayer(props.layer, props.before);\n } else {\n // For hidden layers, just add them without worrying about order\n mapInstance.addLayer(props.layer);\n }\n }\n } catch (error) {\n console.error(`[${props.layerId}] Error setting up layer:`, error);\n }\n };\n const updateSource = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n const existingSource = mapInstance.getSource(props.sourceId);\n // Only update source if it has actually changed\n if (\n existingSource &&\n JSON.stringify(existingSource.serialize()) !==\n JSON.stringify(props.source)\n ) {\n if (mapInstance.getLayer(props.layerId)) {\n mapInstance.removeLayer(props.layerId);\n }\n mapInstance.removeSource(props.sourceId);\n mapInstance.addSource(props.sourceId, props.source);\n const layerSpec = {\n ...props.layer,\n id: props.layerId,\n source: props.sourceId,\n } as LayerSpecification;\n mapInstance.addLayer(layerSpec, props.before);\n }\n } catch (error) {\n console.error('Error updating vector source:', error);\n }\n };\n const updateLayer = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if (mapInstance.getLayer(props.layerId)) {\n // Get current paint and layout properties\n const currentLayer = mapInstance.getLayer(props.layerId);\n const currentPaint = (currentLayer?.paint || {}) as Record<\n string,\n unknown\n >;\n const currentLayout = (currentLayer?.layout || {}) as Record<\n string,\n unknown\n >;\n\n // Only update properties that have changed\n Object.entries(props.layer.paint || {}).forEach(([key, value]) => {\n if (JSON.stringify(currentPaint[key]) !== JSON.stringify(value)) {\n mapInstance.setPaintProperty(props.layerId, key, value);\n }\n });\n\n Object.entries(props.layer.layout || {}).forEach(([key, value]) => {\n if (JSON.stringify(currentLayout[key]) !== JSON.stringify(value)) {\n mapInstance.setLayoutProperty(props.layerId, key, value);\n }\n });\n }\n } catch (error) {\n console.error('Error updating vector layer:', error);\n }\n };\n const setupLayerEvents = (mapInstance: Map) => {\n if (!mapInstance) return;\n\n try {\n mapLayerEvents.forEach((eventName) => {\n mapInstance.on(eventName, props.layerId, (e) => {\n if (eventName === 'mousemove') {\n mapInstance.getCanvas().style.cursor = 'pointer';\n }\n if (eventName === 'mouseleave') {\n mapInstance.getCanvas().style.cursor = '';\n }\n emit(eventName, e);\n });\n });\n } catch (error) {\n console.error('Error setting up layer events:', error);\n }\n };\n\n // Watchers\n watch(\n map,\n (newMap, oldMap) => {\n if (newMap && newMap !== oldMap) {\n setupMap(newMap);\n }\n },\n { immediate: true },\n );\n watch(loaded, (value) => {\n if (value) {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n addLayer();\n setupLayerEvents(mapInstance);\n }\n });\n watch(\n () => JSON.stringify(props.source.tiles),\n (newTiles, oldTiles) => {\n if (newTiles !== oldTiles) {\n updateSource();\n }\n },\n );\n watch(\n () => ({\n paint: props.layer.paint,\n // Watch layout changes but exclude visibility since it's handled separately\n layout: props.layer.layout\n ? { ...props.layer.layout, visibility: undefined }\n : undefined,\n }),\n (newValue, oldValue) => {\n if (JSON.stringify(newValue) !== JSON.stringify(oldValue)) {\n updateLayer();\n }\n },\n { deep: true },\n );\n watch(\n () => props.layer.layout?.visibility,\n (newVisibility) => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n const hasLayer = mapInstance.getLayer(props.layerId);\n\n if (!hasLayer) {\n // Add layer if it doesn't exist\n try {\n if (!mapInstance.getSource(props.sourceId)) {\n mapInstance.addSource(props.sourceId, props.source);\n }\n mapInstance.addLayer(props.layer, props.before);\n } catch (error) {\n console.error(`[${props.layerId}] Error adding layer:`, error);\n }\n } else {\n try {\n // Update visibility\n mapInstance.setLayoutProperty(\n props.layerId,\n 'visibility',\n newVisibility,\n );\n\n // If becoming visible, ensure proper layer order\n if (newVisibility === 'visible' && props.before) {\n // Small timeout to ensure target layer is ready\n setTimeout(() => {\n mapInstance.moveLayer(props.layerId, props.before);\n }, 0);\n }\n } catch (error) {\n console.error(`[${props.layerId}] Error updating visibility:`, error);\n }\n }\n },\n { immediate: true },\n );\n watch(\n () => props.before,\n (newBefore) => {\n const mapInstance = getMapInstance();\n if (!mapInstance || !mapInstance.getLayer(props.layerId)) return;\n\n // Only move visible layers\n if (props.layer.layout?.visibility === 'visible') {\n try {\n mapInstance.moveLayer(props.layerId, newBefore);\n } catch (error) {\n console.error(\n `Error reordering vector layer ${props.layerId}:`,\n error,\n );\n }\n }\n },\n );\n watch(\n () => props.layer.layout?.visibility,\n (newVisibility) => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n const hasLayer = mapInstance.getLayer(props.layerId);\n\n if (!hasLayer) {\n // Only add layer if it doesn't exist\n try {\n if (!mapInstance.getSource(props.sourceId)) {\n mapInstance.addSource(props.sourceId, props.source);\n }\n mapInstance.addLayer(props.layer, props.before);\n } catch (error) {\n console.error(`[${props.layerId}] Error adding layer:`, error);\n }\n } else {\n // Just update visibility if layer exists\n try {\n mapInstance.setLayoutProperty(\n props.layerId,\n 'visibility',\n newVisibility,\n );\n } catch (error) {\n console.error(`[${props.layerId}] Error updating visibility:`, error);\n }\n }\n },\n { immediate: true },\n );\n onMounted(() => {\n const mapInstance = getMapInstance();\n if (!mapInstance) {\n return;\n }\n try {\n addLayer();\n } catch (error) {\n console.error(`[${props.layerId}] Error setting up layer:`, error);\n }\n });\n</script>\n\n<template>\n <slot></slot>\n</template>\n","<script setup lang=\"ts\">\n import type {\n LayerSpecification as AnyLayer,\n VideoSourceSpecification,\n VideoSource,\n Map,\n } from 'maplibre-gl';\n import type { PropType, Ref } from 'vue';\n import { onMounted, onBeforeUnmount, ref, watch } from 'vue';\n import { injectStrict, MapKey } from '../../../utils';\n\n const props = defineProps({\n sourceId: {\n type: String,\n default: 'maplibre.gl-video-source',\n required: true,\n },\n layerId: {\n type: String,\n default: 'maplibre.gl-video-layer',\n required: true,\n },\n source: {\n type: Object as PropType<VideoSourceSpecification>,\n required: true,\n },\n layer: {\n type: Object as PropType<AnyLayer>,\n default: () => ({}),\n required: true,\n },\n before: {\n type: String,\n default: '',\n required: false,\n },\n });\n\n const map = injectStrict(MapKey);\n const loaded: Ref<boolean> = ref(false);\n\n // Helper function to safely get map instance\n const getMapInstance = (): Map | null => {\n return map.value || null;\n };\n\n // Setup functions\n const setupMap = (mapInstance: Map) => {\n if (!mapInstance) return;\n\n mapInstance.on('style.load', () => {\n const styleTimeout = () => {\n if (!mapInstance.isStyleLoaded()) {\n loaded.value = false;\n setTimeout(styleTimeout, 200);\n } else {\n loaded.value = true;\n }\n };\n styleTimeout();\n });\n };\n\n const addLayer = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if (!mapInstance.getSource(props.sourceId)) {\n mapInstance.addSource(props.sourceId, props.source);\n }\n if (!mapInstance.getLayer(props.layerId)) {\n const layerSpec = {\n ...props.layer,\n id: props.layerId,\n source: props.sourceId,\n } as AnyLayer;\n mapInstance.addLayer(layerSpec, props.before);\n }\n } catch (error) {\n console.error('Error adding Video layer:', error);\n }\n };\n\n const updateSource = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n const source = mapInstance.getSource(props.sourceId) as VideoSource;\n if (source) {\n // For video sources, we need to remove and re-add since there's no direct update method\n if (mapInstance.getLayer(props.layerId)) {\n mapInstance.removeLayer(props.layerId);\n }\n if (mapInstance.getSource(props.sourceId)) {\n mapInstance.removeSource(props.sourceId);\n }\n\n mapInstance.addSource(props.sourceId, props.source);\n const layerSpec = {\n ...props.layer,\n id: props.layerId,\n source: props.sourceId,\n } as AnyLayer;\n mapInstance.addLayer(layerSpec, props.before);\n\n // Additional video-specific operations if needed\n if (source.getVideo) {\n const videoElement = source.getVideo();\n if (videoElement) {\n // Handle video element updates if needed\n videoElement.play().catch((error) => {\n console.error('Error playing video:', error);\n });\n }\n }\n }\n } catch (error) {\n console.error('Error updating Video source:', error);\n }\n };\n\n const updateLayer = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if (mapInstance.getLayer(props.layerId)) {\n Object.entries(props.layer.paint || {}).forEach(([key, value]) => {\n mapInstance.setPaintProperty(props.layerId, key, value);\n });\n Object.entries(props.layer.layout || {}).forEach(([key, value]) => {\n mapInstance.setLayoutProperty(props.layerId, key, value);\n });\n }\n } catch (error) {\n console.error('Error updating Video layer:', error);\n }\n };\n\n // Watchers\n watch(() => props.source, updateSource, { deep: true });\n watch(() => props.layer, updateLayer, { deep: true });\n\n // Watch for map instance changes\n watch(\n map,\n (newMap) => {\n if (newMap) {\n setupMap(newMap);\n }\n },\n { immediate: true },\n );\n\n // Watch loaded state\n watch(loaded, (value) => {\n if (value) {\n addLayer();\n }\n });\n\n // Lifecycle hooks\n onMounted(() => {\n const mapInstance = getMapInstance();\n if (mapInstance?.isStyleLoaded()) {\n addLayer();\n }\n });\n\n onBeforeUnmount(() => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n const source = mapInstance.getSource(props.sourceId) as VideoSource;\n if (source?.getVideo) {\n const videoElement = source.getVideo();\n if (videoElement) {\n // Stop and cleanup video if needed\n videoElement.pause();\n videoElement.remove();\n }\n }\n\n if (mapInstance.getLayer(props.layerId)) {\n mapInstance.removeLayer(props.layerId);\n }\n if (mapInstance.getSource(props.sourceId)) {\n mapInstance.removeSource(props.sourceId);\n }\n } catch (error) {\n console.error('Error cleaning up Video layer:', error);\n }\n });\n</script>\n\n<template>\n <slot></slot>\n</template>\n","<script setup lang=\"ts\">\n import { PMTiles } from 'pmtiles';\n import { inject, onMounted, ref } from 'vue';\n import type { PropType } from 'vue';\n import type {\n RasterLayerSpecification,\n RasterSourceSpecification,\n } from 'maplibre-gl';\n import VLayerMaplibreRaster from '../raster/VLayerMaplibreRaster.vue';\n import { PMTileProtocolKey } from '../../../utils/symbols';\n\n const props = defineProps({\n sourceId: {\n type: String,\n default: 'maplibre.gl-pmtile-source',\n required: true,\n },\n layerId: {\n type: String,\n default: 'maplibre.gl-pmtile-layer',\n required: true,\n },\n url: {\n type: String,\n required: true,\n },\n layer: {\n type: Object as PropType<RasterLayerSpecification>,\n default: () => ({}),\n required: true,\n },\n before: {\n type: String,\n default: '',\n required: false,\n },\n });\n\n const protocol = inject(PMTileProtocolKey);\n if (!protocol) {\n throw new Error('Protocol not provided');\n }\n\n const source = ref<RasterSourceSpecification>({\n type: 'raster',\n url: `pmtiles://${props.url}`,\n tileSize: 512,\n volatile: true,\n });\n onMounted(async () => {\n const p = new PMTiles(props.url);\n protocol.add(p);\n // Optional: You could fetch the header here if you need metadata\n // const header = await p.getHeader();\n });\n</script>\n\n<template>\n <VLayerMaplibreRaster\n :source-id=\"sourceId\"\n :layer-id=\"layerId\"\n :source=\"source\"\n :layer=\"{\n ...layer,\n type: 'raster',\n }\"\n :before=\"before\"\n ></VLayerMaplibreRaster>\n</template>\n","<!-- web/app/lib/v-mapbox/layers/maplibre/cluster/VLayerMaplibreCluster.vue -->\n<script setup lang=\"ts\">\n import type { Ref } from 'vue';\n import { onMounted, onBeforeUnmount, ref, watch, computed } from 'vue';\n import type {\n GeoJSONSource,\n GeoJSONSourceSpecification,\n CircleLayerSpecification,\n SymbolLayerSpecification,\n Map,\n MapLayerMouseEvent,\n DataDrivenPropertyValueSpecification,\n } from 'maplibre-gl';\n import { injectStrict, MapKey } from '../../../../utils';\n\n interface LayerClick {\n features: GeoJSON.Feature[];\n coordinates: {\n lng: number;\n lat: number;\n };\n }\n\n interface Props {\n sourceId: string;\n baseLayerId: string;\n source: GeoJSONSourceSpecification;\n visibility?: boolean;\n clusterPaint?: {\n colors?: string[];\n radii?: number[];\n breakpoints?: number[];\n };\n unclusteredPaint?: {\n color?: DataDrivenPropertyValueSpecification<string>;\n radius?: number;\n };\n textPaint?: {\n color?: string;\n font?: string[];\n size?: number;\n };\n }\n\n const props = withDefaults(defineProps<Props>(), {\n sourceId: 'cluster-source',\n baseLayerId: 'cluster',\n visibility: true,\n clusterPaint: () => ({\n colors: ['#51bbd6', '#f1f075', '#f28cb1'],\n radii: [20, 30, 40],\n breakpoints: [100, 750],\n }),\n unclusteredPaint: () => ({\n color: '#51bbd6',\n radius: 6,\n }),\n textPaint: () => ({\n color: '#ffffff',\n font: ['DIN Offc Pro Medium', 'Arial Unicode MS Bold'],\n size: 12,\n }),\n });\n\n const emit = defineEmits<{\n 'cluster-click': [event: LayerClick];\n 'point-click': [event: LayerClick];\n }>();\n\n const map = injectStrict(MapKey);\n const loaded: Ref<boolean> = ref(false);\n\n // Layer IDs\n const clustersLayerId = computed(() => `${props.baseLayerId}-clusters`);\n const clusterCountLayerId = computed(\n () => `${props.baseLayerId}-cluster-count`,\n );\n const unclusteredLayerId = computed(\n () => `${props.baseLayerId}-unclustered-point`,\n );\n\n // Helper function to safely get map instance\n const getMapInstance = (): Map | null => {\n return map.value || null;\n };\n\n // Helper to check if data is valid GeoJSON with features\n const hasValidData = (data: string | GeoJSON.GeoJSON): boolean => {\n if (typeof data === 'string') return false;\n if (data && typeof data === 'object' && 'type' in data) {\n if (data.type === 'FeatureCollection' && 'features' in data) {\n return data.features.length > 0;\n }\n }\n return false;\n };\n\n // Add all cluster-related layers at once\n const addClusterLayers = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance || !mapInstance.isStyleLoaded()) {\n return;\n }\n\n try {\n // 1. Add source if it doesn't exist\n if (!mapInstance.getSource(props.sourceId)) {\n console.log(`Adding clustered source: ${props.sourceId}`);\n mapInstance.addSource(props.sourceId, {\n ...props.source,\n cluster: true,\n clusterMaxZoom: 14,\n clusterRadius: 50,\n });\n } else {\n // If source exists, update its data\n const source = mapInstance.getSource(props.sourceId) as GeoJSONSource;\n if (source && 'setData' in source) {\n source.setData(props.source.data);\n }\n }\n\n // 2. Add clusters layer\n if (!mapInstance.getLayer(clustersLayerId.value)) {\n console.log(`Adding clusters layer: ${clustersLayerId.value}`);\n mapInstance.addLayer({\n id: clustersLayerId.value,\n type: 'circle',\n source: props.sourceId,\n filter: ['has', 'point_count'],\n paint: {\n 'circle-color': [\n 'step',\n ['get', 'point_count'],\n props.clusterPaint.colors![0]!,\n props.clusterPaint.breakpoints![0]!,\n props.clusterPaint.colors![1]!,\n props.clusterPaint.breakpoints![1]!,\n props.clusterPaint.colors![2]!,\n ],\n 'circle-radius': [\n 'step',\n ['get', 'point_count'],\n props.clusterPaint.radii![0]!,\n props.clusterPaint.breakpoints![0]!,\n props.clusterPaint.radii![1]!,\n props.clusterPaint.breakpoints![1]!,\n props.clusterPaint.radii![2]!,\n ],\n 'circle-stroke-width': 2,\n 'circle-stroke-color': '#ffffff',\n 'circle-opacity': 0.9,\n },\n layout: {\n visibility: props.visibility ? 'visible' : 'none',\n },\n } as CircleLayerSpecification);\n }\n\n // 3. Add cluster count text layer\n if (!mapInstance.getLayer(clusterCountLayerId.value)) {\n console.log(`Adding cluster count layer: ${clusterCountLayerId.value}`);\n mapInstance.addLayer({\n id: clusterCountLayerId.value,\n type: 'symbol',\n source: props.sourceId,\n filter: ['has', 'point_count'],\n layout: {\n 'text-field': '{point_count_abbreviated}',\n 'text-font': props.textPaint.font!,\n 'text-size': props.textPaint.size!,\n visibility: props.visibility ? 'visible' : 'none',\n },\n paint: {\n 'text-color': props.textPaint.color!,\n },\n } as SymbolLayerSpecification);\n }\n\n // 4. Add unclustered points layer\n if (!mapInstance.getLayer(unclusteredLayerId.value)) {\n console.log(\n `Adding unclustered points layer: ${unclusteredLayerId.value}`,\n );\n mapInstance.addLayer({\n id: unclusteredLayerId.value,\n type: 'circle',\n source: props.sourceId,\n filter: ['!', ['has', 'point_count']],\n paint: {\n 'circle-color': props.unclusteredPaint.color!,\n 'circle-radius': props.unclusteredPaint.radius!,\n 'circle-stroke-width': 2,\n 'circle-stroke-color': '#ffffff',\n 'circle-opacity': 0.95,\n },\n layout: {\n visibility: props.visibility ? 'visible' : 'none',\n },\n } as CircleLayerSpecification);\n }\n\n console.log(`All cluster layers added for ${props.baseLayerId}`);\n\n // Setup click handlers after layers are added\n setupLayerEvents(mapInstance);\n } catch (error) {\n console.error('Error adding cluster layers:', error);\n }\n };\n\n // Update source data\n const updateSource = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n const source = mapInstance.getSource(props.sourceId) as\n | GeoJSONSource\n | undefined;\n if (source && 'setData' in source) {\n console.log(`Updating source ${props.sourceId} with data`);\n source.setData(props.source.data);\n\n // After updating data, ensure all layers are properly added\n // This fixes the issue where layers might not render correctly with initial empty data\n setTimeout(() => {\n // Re-add layers if they're missing (this won't duplicate them)\n addClusterLayers();\n }, 100);\n } else if (!source) {\n // Source doesn't exist, add all layers\n addClusterLayers();\n }\n } catch (error) {\n console.error('Error updating source:', error);\n }\n };\n\n // Update visibility for all layers\n const updateVisibility = (visible: boolean): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n const visibility = visible ? 'visible' : 'none';\n\n [\n clustersLayerId.value,\n clusterCountLayerId.value,\n unclusteredLayerId.value,\n ].forEach((layerId) => {\n if (mapInstance.getLayer(layerId)) {\n mapInstance.setLayoutProperty(layerId, 'visibility', visibility);\n }\n });\n };\n\n // Setup click handlers for layers\n const setupLayerEvents = (mapInstance: Map) => {\n if (!mapInstance) return;\n\n try {\n // Click handler for clusters\n mapInstance.on(\n 'click',\n clustersLayerId.value,\n (e: MapLayerMouseEvent) => {\n if (e.features && e.features.length > 0) {\n emit('cluster-click', {\n features: e.features,\n coordinates: e.lngLat,\n });\n }\n },\n );\n\n // Click handler for individual points\n mapInstance.on(\n 'click',\n unclusteredLayerId.value,\n (e: MapLayerMouseEvent) => {\n if (e.features && e.features.length > 0) {\n emit('point-click', {\n features: e.features,\n coordinates: e.lngLat,\n });\n }\n },\n );\n\n // Add hover effects\n [clustersLayerId.value, unclusteredLayerId.value].forEach((layerId) => {\n mapInstance.on('mouseenter', layerId, () => {\n mapInstance.getCanvas().style.cursor = 'pointer';\n });\n\n mapInstance.on('mouseleave', layerId, () => {\n mapInstance.getCanvas().style.cursor = '';\n });\n });\n } catch (error) {\n console.error('Error setting up layer events:', error);\n }\n };\n\n // Setup map\n const setupMap = (mapInstance: Map) => {\n if (!mapInstance) return;\n\n mapInstance.on('style.load', () => {\n const checkStyleLoaded = () => {\n if (!mapInstance.isStyleLoaded()) {\n loaded.value = false;\n setTimeout(checkStyleLoaded, 200);\n } else {\n loaded.value = true;\n // Only add layers if we have data\n if (hasValidData(props.source.data)) {\n addClusterLayers();\n }\n }\n };\n checkStyleLoaded();\n });\n\n // If style is already loaded\n if (mapInstance.isStyleLoaded()) {\n loaded.value = true;\n // Only add layers if we have data\n if (hasValidData(props.source.data)) {\n addClusterLayers();\n }\n }\n };\n\n // Watchers\n watch(\n () => props.source.data,\n (newData) => {\n // Only proceed if we have actual data\n if (hasValidData(newData)) {\n const mapInstance = getMapInstance();\n if (mapInstance?.isStyleLoaded()) {\n // First time with data - add all layers\n if (!mapInstance.getSource(props.sourceId)) {\n addClusterLayers();\n } else {\n // Source exists, just update data\n updateSource();\n }\n }\n }\n },\n { deep: true, immediate: true },\n );\n\n watch(() => props.visibility, updateVisibility);\n\n watch(\n map,\n (newMap) => {\n if (newMap) {\n setupMap(newMap);\n }\n },\n { immediate: true },\n );\n\n // Lifecycle\n onMounted(() => {\n const mapInstance = getMapInstance();\n // Only add layers if map is ready AND we have data\n if (mapInstance?.isStyleLoaded() && hasValidData(props.source.data)) {\n addClusterLayers();\n }\n });\n\n onBeforeUnmount(() => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n // Remove click handlers\n [clustersLayerId.value, unclusteredLayerId.value].forEach((layerId) => {\n mapInstance.off('click', layerId, () => {});\n mapInstance.off('mouseenter', layerId, () => {});\n mapInstance.off('mouseleave', layerId, () => {});\n });\n\n // Remove all layers\n [\n clustersLayerId.value,\n clusterCountLayerId.value,\n unclusteredLayerId.value,\n ].forEach((layerId) => {\n if (mapInstance.getLayer(layerId)) {\n mapInstance.removeLayer(layerId);\n }\n });\n\n // Remove source\n if (mapInstance.getSource(props.sourceId)) {\n mapInstance.removeSource(props.sourceId);\n }\n } catch (error) {\n console.error('Error cleaning up cluster layers:', error);\n }\n });\n</script>\n\n<template>\n <slot></slot>\n</template>\n","<script setup lang=\"ts\">\n import type { Ref } from 'vue';\n import { onMounted, onBeforeUnmount, ref, watch, computed } from 'vue';\n import type {\n GeoJSONSource,\n Map,\n MapLayerMouseEvent,\n LineLayerSpecification,\n } from 'maplibre-gl';\n import { injectStrict, MapKey } from '../../../../utils';\n\n interface RouteClick {\n coordinates: {\n lng: number;\n lat: number;\n };\n }\n\n interface Props {\n /** Unique identifier for the route */\n id?: string;\n /** Array of [longitude, latitude] coordinate pairs defining the route */\n coordinates: [number, number][];\n /** Line color as CSS color value */\n color?: string;\n /** Line width in pixels */\n width?: number;\n /** Line opacity (0-1) */\n opacity?: number;\n /** Line cap style */\n lineCap?: 'butt' | 'round' | 'square';\n /** Line join style */\n lineJoin?: 'bevel' | 'round' | 'miter';\n /** Whether the route is visible */\n visible?: boolean;\n /** Whether the route is interactive (shows pointer cursor on hover) */\n interactive?: boolean;\n /** Render this layer before the specified layer */\n before?: string;\n /** Line dash array for dashed lines */\n dashArray?: number[];\n /** Line blur in pixels */\n blur?: number;\n }\n\n const props = withDefaults(defineProps<Props>(), {\n id: () => `route-${Math.random().toString(36).slice(2, 9)}`,\n color: '#4285F4',\n width: 4,\n opacity: 1,\n lineCap: 'round',\n lineJoin: 'round',\n visible: true,\n interactive: true,\n before: '',\n blur: 0,\n });\n\n const emit = defineEmits<{\n click: [event: RouteClick];\n mouseenter: [];\n mouseleave: [];\n }>();\n\n const map = injectStrict(MapKey);\n const loaded: Ref<boolean> = ref(false);\n\n const sourceId = computed(() => `${props.id}-source`);\n const layerId = computed(() => `${props.id}-layer`);\n\n // Create GeoJSON data from coordinates\n const geojsonData = computed(\n (): GeoJSON.FeatureCollection<GeoJSON.LineString> => ({\n type: 'FeatureCollection',\n features:\n props.coordinates.length >= 2\n ? [\n {\n type: 'Feature',\n properties: {},\n geometry: {\n type: 'LineString',\n coordinates: props.coordinates,\n },\n },\n ]\n : [],\n }),\n );\n\n // Helper function to safely get map instance\n const getMapInstance = (): Map | null => {\n return map.value || null;\n };\n\n // Setup map style load listener\n const setupMap = (mapInstance: Map) => {\n if (!mapInstance) return;\n\n mapInstance.on('style.load', () => {\n const styleTimeout = () => {\n if (!mapInstance.isStyleLoaded()) {\n loaded.value = false;\n setTimeout(styleTimeout, 200);\n } else {\n loaded.value = true;\n }\n };\n styleTimeout();\n });\n };\n\n const addLayer = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance || !mapInstance.isStyleLoaded()) return;\n\n // Don't add if no valid coordinates\n if (props.coordinates.length < 2) return;\n\n try {\n // Only add source if it doesn't exist\n if (!mapInstance.getSource(sourceId.value)) {\n mapInstance.addSource(sourceId.value, {\n type: 'geojson',\n data: geojsonData.value,\n });\n }\n\n // Only add layer if it doesn't exist\n if (!mapInstance.getLayer(layerId.value)) {\n const layerSpec: LineLayerSpecification = {\n id: layerId.value,\n type: 'line',\n source: sourceId.value,\n layout: {\n 'line-cap': props.lineCap,\n 'line-join': props.lineJoin,\n visibility: props.visible ? 'visible' : 'none',\n },\n paint: {\n 'line-color': props.color,\n 'line-width': props.width,\n 'line-opacity': props.opacity,\n ...(props.blur > 0 && { 'line-blur': props.blur }),\n ...(props.dashArray && { 'line-dasharray': props.dashArray }),\n },\n };\n\n mapInstance.addLayer(layerSpec, props.before || undefined);\n }\n } catch (error) {\n console.error('Error adding route layer:', error);\n }\n };\n\n const updateSource = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n const source = mapInstance.getSource(sourceId.value) as\n | GeoJSONSource\n | undefined;\n\n if (source && 'setData' in source) {\n source.setData(geojsonData.value);\n } else if (!source && props.coordinates.length >= 2) {\n addLayer();\n }\n } catch (error) {\n console.error('Error updating route source:', error);\n }\n };\n\n const updateLayerStyle = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance || !mapInstance.getLayer(layerId.value)) return;\n\n try {\n // Update paint properties\n mapInstance.setPaintProperty(layerId.value, 'line-color', props.color);\n mapInstance.setPaintProperty(layerId.value, 'line-width', props.width);\n mapInstance.setPaintProperty(\n layerId.value,\n 'line-opacity',\n props.opacity,\n );\n\n if (props.blur > 0) {\n mapInstance.setPaintProperty(layerId.value, 'line-blur', props.blur);\n }\n if (props.dashArray) {\n mapInstance.setPaintProperty(\n layerId.value,\n 'line-dasharray',\n props.dashArray,\n );\n }\n\n // Update layout properties\n mapInstance.setLayoutProperty(layerId.value, 'line-cap', props.lineCap);\n mapInstance.setLayoutProperty(layerId.value, 'line-join', props.lineJoin);\n mapInstance.setLayoutProperty(\n layerId.value,\n 'visibility',\n props.visible ? 'visible' : 'none',\n );\n } catch (error) {\n console.error('Error updating route layer style:', error);\n }\n };\n\n const setupLayerEvents = (mapInstance: Map) => {\n if (!mapInstance || !props.interactive) return;\n\n try {\n // Click handler\n mapInstance.on('click', layerId.value, (e: MapLayerMouseEvent) => {\n emit('click', {\n coordinates: e.lngLat,\n });\n });\n\n // Hover effects\n mapInstance.on('mouseenter', layerId.value, () => {\n mapInstance.getCanvas().style.cursor = 'pointer';\n emit('mouseenter');\n });\n\n mapInstance.on('mouseleave', layerId.value, () => {\n mapInstance.getCanvas().style.cursor = '';\n emit('mouseleave');\n });\n } catch (error) {\n console.error('Error setting up route layer events:', error);\n }\n };\n\n // Watch for coordinate changes\n watch(\n () => props.coordinates,\n () => {\n const mapInstance = getMapInstance();\n if (mapInstance?.isStyleLoaded()) {\n if (!mapInstance.getSource(sourceId.value)) {\n addLayer();\n } else {\n updateSource();\n }\n }\n },\n { deep: true },\n );\n\n // Watch for style changes\n watch(\n () => [\n props.color,\n props.width,\n props.opacity,\n props.lineCap,\n props.lineJoin,\n props.visible,\n props.blur,\n props.dashArray,\n ],\n () => updateLayerStyle(),\n { deep: true },\n );\n\n // Watch for map instance changes\n watch(\n map,\n (newMap) => {\n if (newMap) {\n setupMap(newMap);\n if (newMap.isStyleLoaded()) {\n loaded.value = true;\n }\n }\n },\n { immediate: true },\n );\n\n // Watch loaded state\n watch(loaded, (value) => {\n if (value && props.coordinates.length >= 2) {\n const mapInstance = getMapInstance();\n if (mapInstance) {\n addLayer();\n setupLayerEvents(mapInstance);\n }\n }\n });\n\n // Lifecycle hooks\n onMounted(() => {\n try {\n const mapInstance = getMapInstance();\n if (mapInstance?.isStyleLoaded() && props.coordinates.length >= 2) {\n addLayer();\n setupLayerEvents(mapInstance);\n }\n } catch (error) {\n console.error('Error mounting route layer:', error);\n }\n });\n\n onBeforeUnmount(() => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if (mapInstance.getLayer(layerId.value)) {\n mapInstance.removeLayer(layerId.value);\n }\n if (mapInstance.getSource(sourceId.value)) {\n mapInstance.removeSource(sourceId.value);\n }\n } catch (error) {\n console.error('Error cleaning up route layer:', error);\n }\n });\n</script>\n\n<template>\n <slot></slot>\n</template>\n","<script setup lang=\"ts\">\n import type { Ref } from 'vue';\n import {\n onMounted,\n onBeforeUnmount,\n ref,\n watch,\n computed,\n nextTick,\n } from 'vue';\n import type {\n GeoJSONSource,\n Map,\n MapLayerMouseEvent,\n FillLayerSpecification,\n LineLayerSpecification,\n } from 'maplibre-gl';\n import { injectStrict, MapKey } from '../../../../utils';\n\n interface IsochroneFeature {\n type: 'Feature';\n properties: {\n color: string;\n contour?: number;\n metric?: string;\n [key: string]: unknown;\n };\n geometry: GeoJSON.Polygon | GeoJSON.MultiPolygon;\n }\n\n interface IsochroneData {\n type: 'FeatureCollection';\n features: IsochroneFeature[];\n }\n\n interface IsochroneClick {\n feature: IsochroneFeature;\n coordinates: {\n lng: number;\n lat: number;\n };\n }\n\n interface Props {\n /** Unique identifier for the isochrone layer */\n id?: string;\n /** GeoJSON FeatureCollection with isochrone polygons (from Valhalla, OSRM, etc.) */\n data: IsochroneData | null;\n /** Fill opacity (0-1) */\n fillOpacity?: number;\n /** Line width in pixels for polygon outlines */\n lineWidth?: number;\n /** Line opacity (0-1) */\n lineOpacity?: number;\n /** Whether the layer is visible */\n visible?: boolean;\n /** Whether the layer is interactive (shows pointer cursor on hover) */\n interactive?: boolean;\n /** Render this layer before the specified layer */\n before?: string;\n /** Whether to reverse the feature order (for proper stacking of overlapping polygons) */\n reverseOrder?: boolean;\n }\n\n const props = withDefaults(defineProps<Props>(), {\n id: () => `isochrone-${Math.random().toString(36).slice(2, 9)}`,\n fillOpacity: 0.4,\n lineWidth: 2,\n lineOpacity: 0.8,\n visible: true,\n interactive: true,\n before: '',\n reverseOrder: true,\n });\n\n const emit = defineEmits<{\n click: [event: IsochroneClick];\n mouseenter: [feature: IsochroneFeature];\n mouseleave: [];\n }>();\n\n const map = injectStrict(MapKey);\n const loaded: Ref<boolean> = ref(false);\n const initialized = ref(false);\n\n const sourceId = computed(() => `${props.id}-source`);\n const fillLayerId = computed(() => `${props.id}-fill`);\n const lineLayerId = computed(() => `${props.id}-line`);\n\n /**\n * Process the GeoJSON data:\n * 1. Optionally reverse feature order for proper polygon stacking\n * 2. Add fillColor property with # prefix (Valhalla returns colors without #)\n */\n const processedData = computed((): IsochroneData | null => {\n if (!props.data || !props.data.features || props.data.features.length === 0)\n return null;\n\n const features = props.reverseOrder\n ? [...props.data.features].reverse()\n : props.data.features;\n\n return {\n type: 'FeatureCollection',\n features: features.map((f) => ({\n ...f,\n properties: {\n ...f.properties,\n // Add # prefix if color doesn't have it (Valhalla format)\n fillColor: f.properties.color.startsWith('#')\n ? f.properties.color\n : `#${f.properties.color}`,\n },\n })),\n };\n });\n\n // Helper function to safely get map instance\n const getMapInstance = (): Map | null => {\n return map.value || null;\n };\n\n // Setup map style load listener\n const setupMap = (mapInstance: Map) => {\n if (!mapInstance) return;\n\n mapInstance.on('style.load', () => {\n const styleTimeout = () => {\n if (!mapInstance.isStyleLoaded()) {\n loaded.value = false;\n setTimeout(styleTimeout, 200);\n } else {\n loaded.value = true;\n }\n };\n styleTimeout();\n });\n };\n\n const addLayers = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance || !mapInstance.isStyleLoaded()) return;\n\n const data = processedData.value;\n if (!data) return;\n\n try {\n // Add source if it doesn't exist\n if (!mapInstance.getSource(sourceId.value)) {\n mapInstance.addSource(sourceId.value, {\n type: 'geojson',\n data,\n });\n }\n\n // Add fill layer\n if (!mapInstance.getLayer(fillLayerId.value)) {\n const fillLayerSpec: FillLayerSpecification = {\n id: fillLayerId.value,\n type: 'fill',\n source: sourceId.value,\n layout: {\n visibility: props.visible ? 'visible' : 'none',\n },\n paint: {\n 'fill-color': ['get', 'fillColor'],\n 'fill-opacity': props.fillOpacity,\n },\n };\n\n mapInstance.addLayer(fillLayerSpec, props.before || undefined);\n }\n\n // Add line layer\n if (!mapInstance.getLayer(lineLayerId.value)) {\n const lineLayerSpec: LineLayerSpecification = {\n id: lineLayerId.value,\n type: 'line',\n source: sourceId.value,\n layout: {\n visibility: props.visible ? 'visible' : 'none',\n },\n paint: {\n 'line-color': ['get', 'fillColor'],\n 'line-width': props.lineWidth,\n 'line-opacity': props.lineOpacity,\n },\n };\n\n mapInstance.addLayer(lineLayerSpec, props.before || undefined);\n }\n } catch (error) {\n console.error('Error adding isochrone layers:', error);\n }\n };\n\n const updateSource = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n const source = mapInstance.getSource(sourceId.value) as\n | GeoJSONSource\n | undefined;\n\n const data = processedData.value;\n\n if (source && 'setData' in source) {\n if (data) {\n source.setData(data);\n }\n } else if (!source && data) {\n addLayers();\n }\n } catch (error) {\n console.error('Error updating isochrone source:', error);\n }\n };\n\n const updateLayerStyle = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n // Update fill layer\n if (mapInstance.getLayer(fillLayerId.value)) {\n mapInstance.setPaintProperty(\n fillLayerId.value,\n 'fill-opacity',\n props.fillOpacity,\n );\n mapInstance.setLayoutProperty(\n fillLayerId.value,\n 'visibility',\n props.visible ? 'visible' : 'none',\n );\n }\n\n // Update line layer\n if (mapInstance.getLayer(lineLayerId.value)) {\n mapInstance.setPaintProperty(\n lineLayerId.value,\n 'line-width',\n props.lineWidth,\n );\n mapInstance.setPaintProperty(\n lineLayerId.value,\n 'line-opacity',\n props.lineOpacity,\n );\n mapInstance.setLayoutProperty(\n lineLayerId.value,\n 'visibility',\n props.visible ? 'visible' : 'none',\n );\n }\n } catch (error) {\n console.error('Error updating isochrone layer style:', error);\n }\n };\n\n const setupLayerEvents = (mapInstance: Map) => {\n if (!mapInstance || !props.interactive) return;\n\n try {\n // Click handler on fill layer\n mapInstance.on('click', fillLayerId.value, (e: MapLayerMouseEvent) => {\n if (e.features && e.features.length > 0) {\n emit('click', {\n feature: e.features[0] as unknown as IsochroneFeature,\n coordinates: e.lngLat,\n });\n }\n });\n\n // Hover effects\n mapInstance.on(\n 'mouseenter',\n fillLayerId.value,\n (e: MapLayerMouseEvent) => {\n mapInstance.getCanvas().style.cursor = 'pointer';\n if (e.features && e.features.length > 0) {\n emit('mouseenter', e.features[0] as unknown as IsochroneFeature);\n }\n },\n );\n\n mapInstance.on('mouseleave', fillLayerId.value, () => {\n mapInstance.getCanvas().style.cursor = '';\n emit('mouseleave');\n });\n } catch (error) {\n console.error('Error setting up isochrone layer events:', error);\n }\n };\n\n // Single initialization function to prevent race conditions\n const initializeLayers = async () => {\n if (initialized.value) return;\n\n const mapInstance = getMapInstance();\n if (!mapInstance || !mapInstance.isStyleLoaded()) return;\n if (!processedData.value) return;\n\n // Wait for next tick to ensure all watchers are set up\n await nextTick();\n\n // Double-check we haven't been initialized during the tick\n if (initialized.value) return;\n\n addLayers();\n setupLayerEvents(mapInstance);\n initialized.value = true;\n };\n\n // Watch for data changes\n watch(\n () => props.data,\n () => {\n const mapInstance = getMapInstance();\n if (mapInstance?.isStyleLoaded()) {\n if (!mapInstance.getSource(sourceId.value)) {\n addLayers();\n } else {\n updateSource();\n }\n }\n },\n { deep: true },\n );\n\n // Watch for style changes\n watch(\n () => [\n props.fillOpacity,\n props.lineWidth,\n props.lineOpacity,\n props.visible,\n ],\n () => updateLayerStyle(),\n { deep: true },\n );\n\n // IMPORTANT: watch(loaded) must be defined BEFORE watch(map) with immediate: true\n // Otherwise, when map watcher sets loaded.value = true, this watcher won't catch it\n watch(loaded, (value) => {\n if (value) {\n initializeLayers();\n }\n });\n\n // Watch for map instance changes\n watch(\n map,\n (newMap) => {\n if (newMap) {\n setupMap(newMap);\n if (newMap.isStyleLoaded()) {\n loaded.value = true;\n // Also call initializeLayers directly in case loaded watcher already ran\n initializeLayers();\n }\n }\n },\n { immediate: true },\n );\n\n // Lifecycle hooks\n onMounted(() => {\n // Use nextTick to ensure all watchers are registered\n nextTick(() => {\n initializeLayers();\n });\n });\n\n onBeforeUnmount(() => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n // Remove layers\n if (mapInstance.getLayer(lineLayerId.value)) {\n mapInstance.removeLayer(lineLayerId.value);\n }\n if (mapInstance.getLayer(fillLayerId.value)) {\n mapInstance.removeLayer(fillLayerId.value);\n }\n // Remove source\n if (mapInstance.getSource(sourceId.value)) {\n mapInstance.removeSource(sourceId.value);\n }\n } catch (error) {\n console.error('Error cleaning up isochrone layer:', error);\n }\n });\n</script>\n\n<template>\n <slot></slot>\n</template>\n","import { defineAsyncComponent, type Component } from 'vue';\n\nexport const VLayerDeckgl: Component = defineAsyncComponent(() =>\n import('./generic').then((m) => m.VLayerDeckgl),\n);\n\nexport const VLayerDeckglScatterplot: Component = defineAsyncComponent(() =>\n import('./scatterplot').then((m) => m.VLayerDeckglScatterplot),\n);\nexport const VLayerDeckglArc: Component = defineAsyncComponent(() =>\n import('./arc').then((m) => m.VLayerDeckglArc),\n);\nexport const VLayerDeckglGeojson: Component = defineAsyncComponent(() =>\n import('./geojson').then((m) => m.VLayerDeckglGeojson),\n);\nexport const VLayerDeckglPath: Component = defineAsyncComponent(() =>\n import('./path').then((m) => m.VLayerDeckglPath),\n);\nexport const VLayerDeckglLine: Component = defineAsyncComponent(() =>\n import('./line').then((m) => m.VLayerDeckglLine),\n);\nexport const VLayerDeckglPolygon: Component = defineAsyncComponent(() =>\n import('./polygon').then((m) => m.VLayerDeckglPolygon),\n);\nexport const VLayerDeckglSolidPolygon: Component = defineAsyncComponent(() =>\n import('./solid-polygon').then((m) => m.VLayerDeckglSolidPolygon),\n);\nexport const VLayerDeckglIcon: Component = defineAsyncComponent(() =>\n import('./icon').then((m) => m.VLayerDeckglIcon),\n);\nexport const VLayerDeckglText: Component = defineAsyncComponent(() =>\n import('./text').then((m) => m.VLayerDeckglText),\n);\nexport const VLayerDeckglColumn: Component = defineAsyncComponent(() =>\n import('./column').then((m) => m.VLayerDeckglColumn),\n);\nexport const VLayerDeckglBitmap: Component = defineAsyncComponent(() =>\n import('./bitmap').then((m) => m.VLayerDeckglBitmap),\n);\nexport const VLayerDeckglGridCell: Component = defineAsyncComponent(() =>\n import('./grid-cell').then((m) => m.VLayerDeckglGridCell),\n);\nexport const VLayerDeckglPointCloud: Component = defineAsyncComponent(() =>\n import('./point-cloud').then((m) => m.VLayerDeckglPointCloud),\n);\n\nexport const VLayerDeckglHeatmap: Component = defineAsyncComponent(() =>\n import('./heatmap').then((m) => m.VLayerDeckglHeatmap),\n);\nexport const VLayerDeckglHexagon: Component = defineAsyncComponent(() =>\n import('./hexagon').then((m) => m.VLayerDeckglHexagon),\n);\nexport const VLayerDeckglGrid: Component = defineAsyncComponent(() =>\n import('./grid').then((m) => m.VLayerDeckglGrid),\n);\nexport const VLayerDeckglContour: Component = defineAsyncComponent(() =>\n import('./contour').then((m) => m.VLayerDeckglContour),\n);\nexport const VLayerDeckglScreenGrid: Component = defineAsyncComponent(() =>\n import('./screen-grid').then((m) => m.VLayerDeckglScreenGrid),\n);\n\nexport const VLayerDeckglTrips: Component = defineAsyncComponent(() =>\n import('./trips').then((m) => m.VLayerDeckglTrips),\n);\nexport const VLayerDeckglH3Hexagon: Component = defineAsyncComponent(() =>\n import('./h3-hexagon').then((m) => m.VLayerDeckglH3Hexagon),\n);\nexport const VLayerDeckglH3Cluster: Component = defineAsyncComponent(() =>\n import('./h3-cluster').then((m) => m.VLayerDeckglH3Cluster),\n);\nexport const VLayerDeckglMVT: Component = defineAsyncComponent(() =>\n import('./mvt').then((m) => m.VLayerDeckglMVT),\n);\nexport const VLayerDeckglTile: Component = defineAsyncComponent(() =>\n import('./tile').then((m) => m.VLayerDeckglTile),\n);\nexport const VLayerDeckglTile3D: Component = defineAsyncComponent(() =>\n import('./tile-3d').then((m) => m.VLayerDeckglTile3D),\n);\nexport const VLayerDeckglTerrain: Component = defineAsyncComponent(() =>\n import('./terrain').then((m) => m.VLayerDeckglTerrain),\n);\nexport const VLayerDeckglGreatCircle: Component = defineAsyncComponent(() =>\n import('./great-circle').then((m) => m.VLayerDeckglGreatCircle),\n);\nexport const VLayerDeckglS2: Component = defineAsyncComponent(() =>\n import('./s2').then((m) => m.VLayerDeckglS2),\n);\nexport const VLayerDeckglGeohash: Component = defineAsyncComponent(() =>\n import('./geohash').then((m) => m.VLayerDeckglGeohash),\n);\nexport const VLayerDeckglQuadkey: Component = defineAsyncComponent(() =>\n import('./quadkey').then((m) => m.VLayerDeckglQuadkey),\n);\nexport const VLayerDeckglWMS: Component = defineAsyncComponent(() =>\n import('./wms').then((m) => m.VLayerDeckglWMS),\n);\n\nexport const VLayerDeckglSimpleMesh: Component = defineAsyncComponent(() =>\n import('./simple-mesh').then((m) => m.VLayerDeckglSimpleMesh),\n);\nexport const VLayerDeckglScenegraph: Component = defineAsyncComponent(() =>\n import('./scenegraph').then((m) => m.VLayerDeckglScenegraph),\n);\n\nexport const VLayerDeckglCOG: Component = defineAsyncComponent(() =>\n import('./cog').then((m) => m.VLayerDeckglCOG),\n);\nexport const VLayerDeckglMosaic: Component = defineAsyncComponent(() =>\n import('./mosaic').then((m) => m.VLayerDeckglMosaic),\n);\nexport type { MosaicSource, MosaicRenderMode, RenderModule } from './mosaic';\nexport const VLayerDeckglMultiCOG: Component = defineAsyncComponent(() =>\n import('./multi-cog').then((m) => m.VLayerDeckglMultiCOG),\n);\nexport type { MultiCOGComposite } from './multi-cog';\nexport const VLayerDeckglZarr: Component = defineAsyncComponent(() =>\n import('./zarr').then((m) => m.VLayerDeckglZarr),\n);\n\nexport const VLayerDeckglGeoArrowScatterplot: Component = defineAsyncComponent(\n () =>\n import('./geoarrow-scatterplot').then(\n (m) => m.VLayerDeckglGeoArrowScatterplot,\n ),\n);\nexport const VLayerDeckglGeoArrowPath: Component = defineAsyncComponent(() =>\n import('./geoarrow-path').then((m) => m.VLayerDeckglGeoArrowPath),\n);\nexport const VLayerDeckglGeoArrowPolygon: Component = defineAsyncComponent(() =>\n import('./geoarrow-polygon').then((m) => m.VLayerDeckglGeoArrowPolygon),\n);\nexport const VLayerDeckglGeoArrowSolidPolygon: Component = defineAsyncComponent(\n () =>\n import('./geoarrow-solid-polygon').then(\n (m) => m.VLayerDeckglGeoArrowSolidPolygon,\n ),\n);\nexport const VLayerDeckglGeoArrowText: Component = defineAsyncComponent(() =>\n import('./geoarrow-text').then((m) => m.VLayerDeckglGeoArrowText),\n);\nexport const VLayerDeckglGeoArrowTrips: Component = defineAsyncComponent(() =>\n import('./geoarrow-trips').then((m) => m.VLayerDeckglGeoArrowTrips),\n);\n\nexport const VLayerDeckglWindParticle: Component = defineAsyncComponent(() =>\n import('./wind-particle').then((m) => m.VLayerDeckglWindParticle),\n);\nexport type {\n WindDataPoint,\n WindTextureResult,\n GenerateWindTextureOptions,\n ColorStop,\n} from './wind-particle';\n\nexport {\n useDeckOverlay,\n useDeckLayers,\n DeckOverlayKey,\n DeckLayersKey,\n} from './_shared';\nexport * from './_shared/types';\n","import { defineAsyncComponent, type Component } from 'vue';\n\nexport { CanvasLayer as VLayerMaplibreCanvas } from './maplibre/canvas';\nexport { GeojsonLayer as VLayerMaplibreGeojson } from './maplibre/geojson';\nexport { ImageLayer as VLayerMaplibreImage } from './maplibre/image';\nexport { RasterLayer as VLayerMaplibreRaster } from './maplibre/raster';\nexport { VectorLayer as VLayerMaplibreVector } from './maplibre/vector';\nexport { VideoLayer as VLayerMaplibreVideo } from './maplibre/video';\nexport { PmtileLayer as VLayerMaplibrePmtile } from './maplibre/pmtile';\nexport { ClusterLayer as VLayerMaplibreCluster } from './maplibre/custom/cluster';\nexport { RouteLayer as VLayerMaplibreRoute } from './maplibre/custom/route';\nexport { VLayerMaplibreIsochrone } from './maplibre/custom/isochrone';\n\nexport const VLayerMaplibreStarfield: Component = defineAsyncComponent(() =>\n import('./maplibre/custom/starfield').then((m) => m.StarfieldLayer),\n);\n\nexport * from './deckgl';\n","<script setup lang=\"ts\">\n import maplibregl, { Map } from 'maplibre-gl';\n import { Protocol } from 'pmtiles';\n import { onMounted, provide, ref, shallowRef } from 'vue';\n import type { MapOptions, MapEventType } from 'maplibre-gl';\n import type { Ref } from 'vue';\n import { mapEvents } from '../constants/events';\n import { MapKey, PMTileProtocolKey } from '../utils/symbols';\n import { useDeckOverlay } from '../layers/deckgl/_shared/useDeckOverlay';\n\n const props = withDefaults(\n defineProps<{\n options: MapOptions;\n supportPmtiles?: boolean;\n }>(),\n {\n options: () => ({ container: 'map' }) as MapOptions,\n supportPmtiles: false,\n },\n );\n const emit = defineEmits(['loaded', ...mapEvents]);\n\n if (props.supportPmtiles) {\n const protocol = new Protocol({ metadata: true });\n maplibregl.addProtocol('pmtiles', protocol.tile);\n provide(PMTileProtocolKey, protocol);\n }\n\n const map: Ref<Map | null> = shallowRef(null); // Initialize as null\n const loaded: Ref<boolean> = ref(false);\n const events: Ref<Array<keyof MapEventType>> = ref(mapEvents);\n\n // Provide the map reference immediately\n provide(MapKey, map);\n\n // Initialize deck.gl overlay at VMap level so all children can access it\n // This provides DeckOverlayKey and DeckLayersKey to all descendants\n useDeckOverlay(map);\n\n onMounted(() => {\n map.value = new Map(props.options);\n loaded.value = true;\n listenMapEvents();\n });\n\n const listenMapEvents = () => {\n if (!map.value) return;\n\n events.value.forEach((e) => {\n map.value?.on(e, (evt) => {\n switch (e) {\n case 'load':\n emit('loaded', map.value);\n break;\n default:\n emit(e, evt);\n break;\n }\n });\n });\n };\n</script>\n\n<template>\n <div :id=\"`${options?.container}`\" class=\"v-map-container\">\n <slot v-if=\"loaded\">\n <slot></slot>\n </slot>\n </div>\n</template>\n\n<style scoped>\n canvas {\n outline: none;\n }\n\n .v-map-container {\n width: 100%;\n height: 100%;\n }\n</style>\n","<script setup lang=\"ts\">\n import type { Ref } from 'vue';\n import { ref, onMounted, onBeforeUnmount, watch } from 'vue';\n import type { LngLatLike, Marker, PopupOptions, Map } from 'maplibre-gl';\n import { Popup } from 'maplibre-gl';\n import { popupEvents } from '../constants/events';\n import { injectStrict, MapKey } from '../utils';\n\n const props = withDefaults(\n defineProps<{\n options: PopupOptions;\n coordinates: LngLatLike;\n marker?: Marker;\n }>(),\n {\n options: () => ({}) as PopupOptions,\n coordinates: () => ({}) as LngLatLike,\n marker: () => ({}) as Marker,\n },\n );\n\n const emit = defineEmits<{\n (e: 'added', payload: { popup: Popup }): void;\n (e: 'removed' | 'open' | 'close'): void;\n }>();\n\n const map = injectStrict(MapKey);\n const popup = new Popup(props.options);\n const loaded: Ref<boolean> = ref(true);\n const content = ref<HTMLElement | null>(null);\n\n // Helper function to safely get map instance\n const getMapInstance = (): Map | null => {\n return map.value || null;\n };\n\n // Setup functions\n const setupMap = (mapInstance: Map) => {\n if (!mapInstance) return;\n\n mapInstance.on('style.load', () => {\n const styleTimeout = () => {\n if (!mapInstance.isStyleLoaded()) {\n loaded.value = false;\n setTimeout(styleTimeout, 200);\n } else {\n loaded.value = true;\n }\n };\n styleTimeout();\n });\n };\n\n const setPopupContent = (): void => {\n try {\n if (content.value) {\n popup.setDOMContent(content.value);\n }\n } catch (error) {\n console.error('Error setting popup content:', error);\n }\n };\n\n const setPopupCoordinates = (): void => {\n try {\n popup.setLngLat(props.coordinates);\n } catch (error) {\n console.error('Error setting popup coordinates:', error);\n }\n };\n\n const addToMarker = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if ('setPopup' in props.marker) {\n props.marker.setPopup(popup);\n } else {\n popup.addTo(mapInstance);\n }\n emit('added', { popup });\n } catch (error) {\n console.error('Error adding popup to marker:', error);\n }\n };\n\n const remove = (): void => {\n try {\n popup.remove();\n emit('removed');\n } catch (error) {\n console.error('Error removing popup:', error);\n }\n };\n\n const listenPopupEvents = (): void => {\n try {\n popupEvents.forEach((event) => {\n popup.on(event, () => {\n emit(event);\n });\n });\n } catch (error) {\n console.error('Error setting up popup events:', error);\n }\n };\n\n const removePopupEvents = (): void => {\n try {\n popupEvents.forEach((event) => {\n popup.off(event, () => {\n emit(event);\n });\n });\n } catch (error) {\n console.error('Error removing popup events:', error);\n }\n };\n\n // Watch for map instance changes\n watch(\n map,\n (newMap) => {\n if (newMap) {\n setupMap(newMap);\n }\n },\n { immediate: true },\n );\n\n // Watch for coordinates changes\n watch(\n () => props.coordinates,\n () => {\n setPopupCoordinates();\n },\n { deep: true },\n );\n\n // Lifecycle hooks\n onMounted(() => {\n if (loaded.value) {\n try {\n setPopupContent();\n setPopupCoordinates();\n addToMarker();\n listenPopupEvents();\n } catch (error) {\n console.error('Error initializing popup:', error);\n }\n } else {\n remove();\n removePopupEvents();\n }\n });\n\n onBeforeUnmount(() => {\n remove();\n removePopupEvents();\n });\n</script>\n\n<template>\n <section :id=\"`popup-${Date.now()}`\" ref=\"content\">\n <slot></slot>\n </section>\n</template>\n","<script setup lang=\"ts\">\n import type { Ref } from 'vue';\n import { ref, watch, onMounted, onBeforeUnmount, useSlots } from 'vue';\n import type {\n LngLatLike,\n MarkerOptions,\n PopupOptions,\n Map,\n } from 'maplibre-gl';\n import { Marker } from 'maplibre-gl';\n import VPopup from '../popups/VPopup.vue';\n import { markerDOMEvents, markerMapEvents } from '../constants/events';\n import { injectStrict, MapKey } from '../utils';\n\n const slots = useSlots();\n\n const props = withDefaults(\n defineProps<{\n coordinates: LngLatLike;\n options?: MarkerOptions;\n popupOptions?: PopupOptions;\n cursor?: string;\n }>(),\n {\n options: () => ({}),\n popupOptions: () => ({}),\n cursor: 'pointer',\n },\n );\n\n const emit = defineEmits([\n 'added',\n 'update:coordinates',\n 'removed',\n ...markerMapEvents,\n ...markerDOMEvents,\n ]);\n\n const map = injectStrict(MapKey);\n const marker: Ref<Marker | null> = ref(null);\n const loaded = ref(true);\n const isMarkerAvailable = ref(false);\n const slotRef = ref<HTMLElement | null>(null);\n\n // Helper function to safely get map instance\n const getMapInstance = (): Map | null => {\n return map.value || null;\n };\n\n // Setup functions\n const setupMap = (mapInstance: Map) => {\n if (!mapInstance) return;\n\n mapInstance.on('style.load', () => {\n const styleTimeout = () => {\n if (!mapInstance.isStyleLoaded()) {\n loaded.value = false;\n setTimeout(styleTimeout, 200);\n } else {\n loaded.value = true;\n }\n };\n styleTimeout();\n });\n };\n\n const setSlotRef = (el: HTMLElement | Element | null) => {\n if (el instanceof HTMLElement) {\n slotRef.value = el;\n }\n };\n\n const setMarkerCoordinates = (markerInstance: Marker): void => {\n try {\n markerInstance.setLngLat(props.coordinates);\n } catch (error) {\n console.error('Error setting marker coordinates:', error);\n }\n };\n\n const setCursorPointer = (markerInstance: Marker): void => {\n try {\n markerInstance.getElement().style.cursor = props.cursor || 'default';\n } catch (error) {\n console.error('Error setting cursor:', error);\n }\n };\n\n const addToMap = (markerInstance: Marker): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n markerInstance.addTo(mapInstance);\n emit('added', { marker: markerInstance });\n } catch (error) {\n console.error('Error adding marker to map:', error);\n }\n };\n\n const removeFromMap = (markerInstance: Marker): void => {\n try {\n markerInstance.remove();\n emit('removed');\n } catch (error) {\n console.error('Error removing marker from map:', error);\n }\n };\n\n const listenMarkerEvents = (markerInstance: Marker): void => {\n try {\n let coordinates: LngLatLike;\n markerMapEvents.forEach((event: string) => {\n markerInstance.on(event, (e: { target: Marker }) => {\n if (event === 'dragend') {\n if (Array.isArray(props.coordinates)) {\n coordinates = [\n e.target.getLngLat().lng,\n e.target.getLngLat().lat,\n ];\n } else {\n coordinates = e.target.getLngLat();\n }\n emit('update:coordinates', coordinates);\n }\n emit(event, e);\n });\n });\n\n markerDOMEvents.forEach((event: string) => {\n markerInstance.getElement().addEventListener(event, (e) => {\n emit(event, e);\n });\n });\n } catch (error) {\n console.error('Error setting up marker events:', error);\n }\n };\n\n // Watchers\n watch(marker, (markerValue) => {\n isMarkerAvailable.value = markerValue !== null && '_map' in markerValue;\n });\n\n // Watch for map instance changes\n watch(\n map,\n (newMap) => {\n if (newMap) {\n setupMap(newMap);\n }\n },\n { immediate: true },\n );\n\n const initMarker = (element?: HTMLElement) => {\n if (!loaded.value || marker.value) return;\n\n try {\n const markerOptions: MarkerOptions = {\n ...props.options,\n element: element || undefined,\n };\n marker.value = new Marker(markerOptions);\n setMarkerCoordinates(marker.value);\n addToMap(marker.value);\n setCursorPointer(marker.value);\n listenMarkerEvents(marker.value);\n } catch (error) {\n console.error('Error initializing marker:', error);\n }\n };\n\n watch(slotRef, (el) => {\n if (el && !marker.value) {\n initMarker(el);\n }\n });\n\n onMounted(() => {\n const hasCustomElement = !!slots.markers;\n if (!hasCustomElement) {\n initMarker();\n }\n });\n\n onBeforeUnmount(() => {\n if (marker.value) {\n removeFromMap(marker.value);\n }\n });\n</script>\n\n<template>\n <section :id=\"`marker-${Date.now()}`\" class=\"absolute\">\n <slot :set-ref=\"setSlotRef\" name=\"markers\"></slot>\n <template v-if=\"isMarkerAvailable && $slots.default\">\n <v-popup\n :marker=\"marker!\"\n :options=\"popupOptions\"\n :coordinates=\"coordinates\"\n >\n <slot></slot>\n </v-popup>\n </template>\n </section>\n</template>\n\n<style>\n .absolute {\n position: absolute !important;\n }\n</style>\n","import {\n VControlAttribution,\n VControlFullscreen,\n VControlGeolocate,\n VControlNavigation,\n VControlScale,\n VControlLidar,\n VControlLayer,\n VControlLayerGroup,\n VControlLegend,\n} from './controls';\n\nimport {\n VLayerMaplibreCanvas,\n VLayerMaplibreGeojson,\n VLayerMaplibreCluster,\n VLayerMaplibreImage,\n VLayerMaplibreRaster,\n VLayerMaplibreVector,\n VLayerMaplibreVideo,\n VLayerMaplibrePmtile,\n VLayerMaplibreRoute,\n VLayerMaplibreIsochrone,\n VLayerMaplibreStarfield,\n} from './layers';\n\nimport VMap from './map/VMap.vue';\nimport VMarker from './markers/VMarker.vue';\nimport VPopup from './popups/VPopup.vue';\n\nexport { requirePeer } from './utils';\n\nexport {\n VMap,\n VMarker,\n VPopup,\n VLayerMaplibreCanvas,\n VLayerMaplibreGeojson,\n VLayerMaplibreCluster,\n VLayerMaplibreImage,\n VLayerMaplibreRaster,\n VLayerMaplibreVector,\n VLayerMaplibreVideo,\n VLayerMaplibrePmtile,\n VLayerMaplibreRoute,\n VLayerMaplibreIsochrone,\n VLayerMaplibreStarfield,\n VControlAttribution,\n VControlFullscreen,\n VControlGeolocate,\n VControlNavigation,\n VControlScale,\n VControlLidar,\n VControlLayer,\n VControlLayerGroup,\n VControlLegend,\n};\n\nexport type {\n LidarControlOptions,\n ColorScheme,\n ColorSchemeType,\n ColorSchemeConfig,\n CopcLoadingMode,\n ColormapName,\n ColorRangeConfig,\n PointCloudInfo,\n PointCloudBounds,\n StreamingProgress,\n StreamingLoaderOptions,\n LayerControlOptions,\n LayerType,\n ControlPosition,\n LayerConfig,\n LegendType,\n CategoryLegendItem,\n GradientLegendItem,\n SizeLegendItem,\n TableLegendItem,\n LegendControlOptions,\n FilterState,\n} from './controls';\n\nexport * from './layers/deckgl';\n\nexport default VMap;\n"],"mappings":"q3BAME,IAAM,EAA4C,CAChD,QAAS,GACT,kBAAmB,IAAA,GACrB,CAEM,EAAQ,EAWR,EAAQ,GAAS,CAEjB,EAAM,EAAa,EAAM,CAE/B,MAAgB,CACd,GAAW,EACZ,CAED,IAAM,MAAyB,CAC7B,IAAI,EAAU,EACV,EAAM,UACR,EAAU,CACR,GAAG,EAAM,QACX,EAEE,GAAS,EAAM,WAAU,GAC3B,EAAQ,kBAAoB,EAAM,SAAQ,CAAE,GACzC,UAEL,IAAM,EAAU,IAAI,EAAmB,EAAO,CAC9C,EAAI,MAAO,WAAW,EAAS,EAAM,SAAQ,eAK/C,EAAa,EAAA,OAAA,UAAA,8GCzCb,IAAM,EAA2C,CAC/C,UAAW,IAAA,GACb,CAEM,EAAQ,EAWR,EAAM,EAAa,EAAM,CAE/B,MAAgB,CACd,GAAW,EACZ,CAED,IAAM,MAAyB,CAC7B,IAAM,EAAU,IAAI,GAAkB,EAAM,SAAW,EAAc,CACrE,EAAI,MAAO,WAAW,EAAS,EAAM,SAAQ,kBC7BpC,EAAmC,CAC9C,YACA,QACA,iBACA,yBACA,uBACD,2HCCC,IAAM,EAA0C,CAC9C,iBAAkB,CAChB,OAAQ,GACR,OAAQ,CAAC,EAAG,EAAC,CACb,QAAS,GACX,CACA,gBAAiB,CACf,mBAAoB,GACpB,WAAY,EACZ,QAAS,IACX,CACA,kBAAmB,GACnB,mBAAoB,GACpB,iBAAkB,GACpB,CAEM,EAAQ,EAWR,EAAO,EAEP,EAAM,EAAa,EAAM,CAE/B,MAAgB,CACd,GAAW,EACZ,CAED,IAAM,MAAyB,CAC7B,IAAM,EAAU,IAAI,EAAiB,EAAM,SAAW,EAAc,CACpE,EAAI,MAAO,WAAW,EAAS,EAAM,SAAQ,CAC7C,EAAO,QAAS,GAAkB,CAChC,EAAQ,GAAG,MAAa,CACtB,EAAK,EAAK,EACX,EACF,4HC3CH,IAAM,EAAoC,CACxC,YAAa,GACb,SAAU,GACV,eAAgB,GAClB,CAEM,EAAQ,EAWR,EAAM,EAAO,EAAM,CAEzB,MAAgB,CACd,GAAW,EACZ,CAED,IAAM,MAAyB,CAC7B,IAAM,EAAU,IAAI,EAAkB,EAAM,SAAW,EAAc,CACrE,EAAK,MAAO,WAAW,EAAS,EAAM,SAAQ,0HCzBhD,IAAM,EAAsC,CAC1C,SAAU,IACV,KAAM,SACR,CAEM,EAAQ,EAWR,EAAM,EAAO,EAAM,CAEzB,MAAgB,CACd,GAAW,EACZ,CAED,IAAM,MAAyB,CAC7B,IAAM,EAAU,IAAI,EAAa,EAAM,SAAW,EAAc,CAChE,GAAK,MAAO,WAAW,EAAS,EAAM,SAAQ,eAKhD,EAAa,EAAA,OAAA,UAAA,ICnCF,EAA+B,CAC1C,OACA,YACA,YACA,SACA,cACA,cACA,WACA,SACA,iBACA,gBACA,oBACA,gBACD,6JCUC,IAAM,EAAsC,CAC1C,UAAW,GACX,UAAW,EACX,YAAa,YACb,SAAU,GACV,SAAU,GACZ,CAEM,EAAQ,EAaR,EAAO,EAEP,EAAM,EAAa,EAAM,CAwDzB,EAAU,EAAiC,KAAI,CAErD,EAAU,SAAY,CACpB,MAAM,GAAW,EAClB,CAED,MAAkB,CACZ,EAAQ,OAAS,EAAI,QACvB,EAAI,MAAM,cAAc,EAAQ,MAAuC,CACvE,EAAQ,MAAQ,OAEnB,CAED,IAAM,EAAa,SAA2B,CAC5C,GAAM,CAAE,gBAAiB,MAAM,EAC7B,wBACM,OAAO,qBACf,CAEA,EAAQ,MAAQ,IAAI,EAClB,EAAM,SAAW,EACnB,CAEA,EAAI,MAAO,WACT,EAAQ,MACR,EAAM,SACR,CAEA,EAAO,QAAS,GAAkB,CAChC,EAAQ,MAAO,GAAG,EAAQ,GAAmB,CAC3C,EAAK,EAAO,EAAI,EACjB,EACF,CAEG,EAAM,YACR,EAAQ,MAAM,eAAe,EAAM,WAAU,SAIjD,EAAa,CACX,gBACE,EACA,IACG,EAAQ,OAAO,eAAe,EAAQ,EAAO,CAClD,yBACE,EACA,IACG,EAAQ,OAAO,wBAAwB,EAAQ,EAAO,CAC3D,4BACE,EACA,IACG,EAAQ,OAAO,2BAA2B,EAAQ,EAAO,CAC9D,iBAAmB,GAAgB,EAAQ,OAAO,iBAAiB,EAAE,CACrE,gBAAkB,GAAgB,EAAQ,OAAO,gBAAgB,EAAE,CACnE,aAAe,GAAiB,EAAQ,OAAO,aAAa,EAAI,CAChE,eAAiB,GACf,EAAQ,OAAO,eAAe,EAAM,CACtC,YAAc,GACZ,EAAQ,OAAO,YAAY,EAAQ,CACrC,gBAAmB,EAAQ,OAAO,aAAY,CAC9C,cAAgB,GACd,EAAQ,OAAO,cAAc,EAAM,CACrC,kBAAqB,EAAQ,OAAO,eAAc,CAClD,WAAa,GAAoB,EAAQ,OAAO,WAAW,EAAO,CAClE,YAAc,GAAsB,EAAQ,OAAO,YAAY,EAAQ,CACvE,iBAAmB,GAAiB,EAAQ,OAAO,iBAAiB,EAAG,CACvE,qBAAwB,EAAQ,OAAO,kBAAiB,CACxD,mBAAoB,EAAa,IAC/B,EAAQ,OAAO,kBAAkB,EAAK,EAAG,CAC3C,wBAA2B,EAAQ,OAAO,qBAAoB,CAC9D,eAAiB,GAAmB,EAAQ,OAAO,eAAe,EAAM,CACxE,WAAa,GAAmB,EAAQ,OAAO,WAAW,EAAM,CAChE,kBAAoB,GAClB,EAAQ,OAAO,kBAAkB,EAAO,CAC1C,eAAkB,EAAQ,OAAO,YAAW,CAC5C,WAAa,GAAqB,EAAQ,OAAO,WAAW,EAAO,CACnE,eAAkB,EAAQ,OAAO,YAAW,CAC5C,kBAAoB,GAClB,EAAQ,OAAO,kBAAkB,EAAM,CACzC,sBAAyB,EAAQ,OAAO,mBAAkB,CAC1D,6BAA8B,EAAc,IAC1C,EAAQ,OAAO,4BAA4B,EAAM,EAAO,CAC1D,2BAA8B,EAAQ,OAAO,wBAAuB,CACpE,2BAA8B,EAAQ,OAAO,wBAAuB,CACpE,6BAAgC,EAAQ,OAAO,0BAAyB,CACxE,gCACE,EAAQ,OAAO,6BAA4B,CAC7C,WAAc,EAAQ,OAAO,QAAO,CACpC,WAAc,EAAQ,OAAO,QAAO,CACpC,aAAgB,EAAQ,OAAO,UAAS,CACxC,aAAgB,EAAQ,OAAO,UAAS,CACxC,mBAAsB,EAAQ,OAAO,gBAAe,CACpD,cAAgB,GAAgB,EAAQ,OAAO,cAAc,EAAE,CAC/D,YAAc,GAAgB,EAAQ,OAAO,YAAY,EAAE,CAC3D,yBAA4B,EAAQ,OAAO,sBAAqB,CAChE,WAAc,EAAQ,OAAO,QAAO,CACpC,oBAAuB,EAAQ,OAAO,iBAAgB,CACtD,eAAkB,EAAQ,MAC3B,CAAA,WCxLH,SAAgB,EACd,EACA,EACA,EACM,CACN,IAAI,EAA2B,KAC3B,EAAU,GAOR,MAA2B,CAE7B,GACA,EAAa,OACb,CAAC,EAAa,MAAM,UAAU,SAAS,kBAAkB,EAEzD,EAAa,MAAM,UAAU,IAAI,kBAAkB,EAIvD,MAAgB,CACV,CAAC,EAAI,OAAS,CAAC,EAAa,QAEhC,EAAU,CACR,WACE,EAAa,OAAO,UAAU,IAAI,kBAAkB,CAC7C,EAAa,OAEtB,aAAsB,GACvB,CAED,EAAI,MAAM,WAAW,EAAS,EAAS,CACvC,EAAU,KACV,CAEF,MAAgB,CACd,GAAoB,EACpB,CAEF,MAAkB,CAChB,GAAI,EAAI,OAAS,EACf,GAAI,CACF,EAAI,MAAM,cAAc,EAAQ,MAC1B,IAIV,knBC3DF,IAAM,EAAQ,EAkBR,EAAO,EAOP,EAAM,EAAa,EAAM,CACzB,EAAa,EAAO,EAAe,KAAI,CACvC,EAAe,EAAwB,KAAI,CAC3C,EAAY,EAAI,EAAM,QAAO,CAC7B,EAAiB,EAAI,EAAM,QAAO,CAExC,EAAc,EAAK,EAAc,EAAM,SAAQ,CAG/C,IAAM,MACA,EAAM,UAAkB,EAAM,UAC7B,EAAI,MACa,EAAI,MAAM,SAAS,EAAM,QAC3C,CAAsB,WACtB,GACa,EAAW,WACP,CAAiC,KACjD,GAAM,EAAE,KAAO,EAAM,QAEpB,CAAkB,SAEjB,KAVgB,KAanB,MAA0C,CAC9C,GAAI,CAAC,EAAI,OAAS,GAAa,GAAM,WAAY,OAAO,KAExD,IAAM,EAAQ,EAAI,MAAM,SAAS,EAAM,QAAO,CAC9C,GAAI,CAAC,EAAO,OAAO,KAEnB,OAAQ,EAAM,KAAd,CACE,IAAK,OACH,MAAO,eACT,IAAK,OACH,MAAO,eACT,IAAK,SACH,MAAO,iBACT,IAAK,SACH,MAAO,eACT,QACE,OAAO,OAIP,EAAoB,GAAqB,CAC7C,IAAM,EAAY,GAAa,CAE/B,GAAI,IAAc,WAAY,CAC5B,GAAI,CAAC,EAAI,MAAO,OAEhB,GAAI,CADU,EAAI,MAAM,SAAS,EAAM,QAClC,CAAO,CACV,QAAQ,KAAK,6BAA6B,EAAM,UAAS,CACzD,OAEF,EAAI,MAAM,kBACR,EAAM,QACN,aACA,EAAU,UAAY,OACxB,MACK,GAAI,IAAc,SAAU,CACjC,GAAI,CAAC,EAAY,CACf,QAAQ,KACN,4CAA4C,EAAM,UACpD,CACA,OAGF,IAAM,EADS,EAAW,WAExB,CACA,KAAM,GAAM,EAAE,KAAO,EAAM,QAAO,CACpC,GAAI,CAAC,EAAe,CAClB,QAAQ,KAAK,4BAA4B,EAAM,UAAS,CACxD,OAEF,GAAI,OAAO,EAAc,OAAU,WAAY,CAC7C,IAAM,EAAe,EAAc,MAAM,CAAE,UAAS,CAAA,CACpD,EAAW,YAAY,EAAM,QAAS,EAAY,MAE/C,CACL,QAAQ,KAAK,2CAA2C,EAAM,UAAS,CACvE,OAGF,EAAK,oBAAqB,EAAO,CACjC,EAAK,iBAAkB,EAAO,EAG1B,EAAiB,GAAoB,CACzC,IAAM,EAAY,GAAa,CAE/B,GAAI,IAAc,WAAY,CAC5B,IAAM,EAAc,GAAmB,CACvC,GAAI,CAAC,EAAI,OAAS,CAAC,EAAa,OAEhC,GAAI,CADU,EAAI,MAAM,SAAS,EAAM,QAClC,CAAO,CACV,QAAQ,KAAK,6BAA6B,EAAM,UAAS,CACzD,OAEF,EAAI,MAAM,iBAAiB,EAAM,QAAS,EAAa,EAAO,MACzD,GAAI,IAAc,SAAU,CACjC,GAAI,CAAC,EAAY,CACf,QAAQ,KACN,4CAA4C,EAAM,UACpD,CACA,OAGF,IAAM,EADS,EAAW,WAExB,CACA,KAAM,GAAM,EAAE,KAAO,EAAM,QAAO,CACpC,GAAI,CAAC,EAAe,CAClB,QAAQ,KAAK,4BAA4B,EAAM,UAAS,CACxD,OAEF,GAAI,OAAO,EAAc,OAAU,WAAY,CAC7C,IAAM,EAAe,EAAc,MAAM,CAAE,UAAS,CAAA,CACpD,EAAW,YAAY,EAAM,QAAS,EAAY,MAE/C,CACL,QAAQ,KAAK,2CAA2C,EAAM,UAAS,CACvE,OAGF,EAAK,iBAAkB,EAAO,CAC9B,EAAK,iBAAkB,EAAO,EAG1B,MAAyB,CAC7B,EAAU,MAAQ,CAAC,EAAU,OAGzB,EAAsB,GAAiB,CAC3C,IAAM,EAAS,EAAM,OACrB,EAAe,MAAQ,OAAO,EAAO,MAAK,CAAI,YAGhD,EAAM,EAAY,GAAa,CAC7B,EAAiB,EAAQ,EAC1B,CAED,EAAM,EAAiB,GAAa,CAClC,EAAc,EAAQ,EACvB,CAED,MACQ,EAAM,QACX,GAAa,CACZ,EAAU,MAAQ,GAEtB,CAEA,MACQ,EAAM,QACX,GAAa,CACZ,EAAe,MAAQ,GAE3B,CAGA,MAAgB,CACd,IAAI,EAAU,GAER,MACA,EAAgB,GAEF,GACd,EACF,EAAU,GACV,EAAiB,EAAU,MAAK,CAChC,EAAc,EAAe,MAAK,CAC3B,IAEF,GAIT,GAAI,GAAc,CAAG,OAIrB,IAAM,EAAS,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAM,IAAM,IAAM,IAAM,IAAI,CACjE,EAAQ,EAEN,MAAc,CACd,GAAc,EAAK,GAAS,EAAO,QACvC,eAAiB,CACf,IACA,GAAM,EACL,EAAO,GAAM,EAGlB,GAAM,EACP,aAID,EA6DM,MAAA,SA7DG,eAAJ,IAAI,EAAe,MAAM,oBAC5B,EA0CM,MA1CN,GA0CM,CAzCJ,EAAsD,OAAtD,GAAsD,EAAf,EAAA,MAAK,CAAA,EAAA,CAC5C,EAuCS,SAAA,CAtCP,KAAK,SACL,MAAK,EAAA,CAAC,yBAAwB,CAAA,YAAA,CACN,EAAA,MAAS,CAAA,CAAA,CAChC,eAAc,EAAA,MACd,MAAO,EAAA,MAAS,aAAA,aAChB,QAAO,IAGA,EAAA,OAAA,GAAA,CADR,EAqBM,MArBN,GAqBM,CAAA,GAAA,EAAA,KAAA,EAAA,GAAA,CAdJ,EAME,OAAA,CALA,EAAE,8FACF,OAAO,eACP,eAAa,OACb,iBAAe,QACf,kBAAgB,kBAElB,EAME,SAAA,CALA,GAAG,IACH,GAAG,IACH,EAAE,MACF,OAAO,eACP,eAAa,2BAGjB,EAQM,MARN,GAQM,CAAA,GAAA,EAAA,KAAA,EAAA,GAAA,CAPJ,EAME,OAAA,CALA,EAAE,wMACF,OAAO,eACP,eAAa,OACb,iBAAe,QACf,kBAAgB,iCAMxB,EAaM,MAbN,GAaM,CAZJ,EAQE,QAAA,CAPA,KAAK,QACL,IAAI,IACJ,IAAI,MACH,MAAO,KAAK,MAAM,EAAA,MAAc,IAAA,CACjC,MAAM,yBACL,SAAQ,CAAG,EAAA,MACX,QAAO,eAEV,EAEC,OAFD,GAEC,EADK,KAAK,MAAM,EAAA,MAAc,IAAA,CAAA,CAAU,IAAC,EAAA,CAAA,CAAA,CAI5C,EAAa,EAAA,OAAA,UAAA,6wBCjRf,IAAM,EAAQ,EAgBR,EAAO,EAMP,EAAM,EAAa,EAAM,CACzB,EAAa,EAAO,EAAe,KAAI,CACvC,EAAe,EAAwB,KAAI,CAC3C,EAAc,EAAI,EAAM,UAAS,CAEjC,EAAc,EAClB,IAAI,IACN,CAEA,EAAc,EAAK,EAAc,EAAM,SAAQ,CAE/C,IAAM,MAAwB,CAC5B,IAAK,IAAM,KAAS,EAAM,OACxB,EAAY,MAAM,IAAI,EAAM,GAAI,CAC9B,QAAS,EAAM,SAAW,GAC1B,QAAS,EAAM,SAAW,EAC3B,CAAA,EAIC,GACJ,EACA,IAEI,IACC,EAAI,MAEa,EAAI,MAAM,SAAS,EACrC,CAAsB,WAEtB,GACa,EAAW,WACP,CAAiC,KACjD,GAAM,EAAE,KAAO,EAEd,CAAkB,SAEjB,KAZgB,MAenB,EAAsB,GAAmC,CAC7D,GAAI,CAAC,EAAI,MAAO,OAAO,KACvB,IAAM,EAAQ,EAAI,MAAM,SAAS,EAAO,CACxC,GAAI,CAAC,EAAO,OAAO,KAGnB,OADkB,EAAM,KACxB,CACE,IAAK,OACH,MAAO,eACT,IAAK,OACH,MAAO,eACT,IAAK,SACH,MAAO,iBACT,IAAK,SACH,MAAO,eACT,IAAK,SACH,MAAO,iBACT,QACE,OAAO,OAIP,GACJ,EACA,EACA,IACG,CACH,IAAM,EAAY,EAAa,EAAS,EAAU,CAElD,GAAI,IAAc,WAAY,CAC5B,GAAI,CAAC,EAAI,MAAO,OAEhB,GAAI,CADU,EAAI,MAAM,SAAS,EAC5B,CAAO,CACV,QAAQ,KACN,kDAAkD,IACpD,CACA,OAEF,EAAI,MAAM,kBACR,EACA,aACA,EAAU,UAAY,OACxB,MACK,GAAI,IAAc,SAAU,CACjC,GAAI,CAAC,EAAY,CACf,QAAQ,KACN,iEAAiE,IACnE,CACA,OAGF,IAAM,EADS,EAAW,WAExB,CACA,KAAM,GAAM,EAAE,KAAO,EAAO,CAC9B,GAAI,CAAC,EAAe,CAClB,QAAQ,KACN,iDAAiD,IACnD,CACA,OAEF,GAAI,OAAO,EAAc,OAAU,WAAY,CAC7C,IAAM,EAAe,EAAc,MAAM,CAAE,UAAS,CAAA,CACpD,EAAW,YAAY,EAAS,EAAY,MAEzC,CACL,QAAQ,KAAK,yCAAyC,IAAS,CAC/D,OAGF,EAAK,oBAAqB,CAAE,UAAS,UAAS,CAAA,EAG1C,GACJ,EACA,EACA,IACG,CACH,IAAM,EAAY,EAAa,EAAS,EAAU,CAElD,GAAI,IAAc,WAAY,CAC5B,IAAM,EAAc,EAAmB,EAAO,CAC9C,GAAI,CAAC,EAAI,OAAS,CAAC,EAAa,OAEhC,GAAI,CADU,EAAI,MAAM,SAAS,EAC5B,CAAO,CACV,QAAQ,KACN,kDAAkD,IACpD,CACA,OAEF,EAAI,MAAM,iBAAiB,EAAS,EAAa,EAAO,MACnD,GAAI,IAAc,SAAU,CACjC,GAAI,CAAC,EAAY,CACf,QAAQ,KACN,iEAAiE,IACnE,CACA,OAGF,IAAM,EADS,EAAW,WAExB,CACA,KAAM,GAAM,EAAE,KAAO,EAAO,CAC9B,GAAI,CAAC,EAAe,CAClB,QAAQ,KACN,iDAAiD,IACnD,CACA,OAEF,GAAI,OAAO,EAAc,OAAU,WAAY,CAC7C,IAAM,EAAe,EAAc,MAAM,CAAE,UAAS,CAAA,CACpD,EAAW,YAAY,EAAS,EAAY,MAEzC,CACL,QAAQ,KAAK,yCAAyC,IAAS,CAC/D,OAGF,EAAK,iBAAkB,CAAE,UAAS,UAAS,CAAA,EAGvC,EAAoB,GAAuB,CAC/C,IAAM,EAAQ,EAAY,MAAM,IAAI,EAAM,GAAE,CAC5C,GAAI,CAAC,EAAO,OAEZ,IAAM,EAAa,CAAC,EAAM,QAC1B,EAAM,QAAU,EAChB,EAAiB,EAAM,GAAI,EAAY,EAAM,KAAI,EAG7C,GAAsB,EAAoB,IAAiB,CAC/D,IAAM,EAAS,EAAM,OACf,EAAU,OAAO,EAAO,MAAK,CAAI,IAEjC,EAAQ,EAAY,MAAM,IAAI,EAAM,GAAE,CACvC,IAEL,EAAM,QAAU,EAChB,EAAc,EAAM,GAAI,EAAS,EAAM,KAAI,GAGvC,EAAY,GACT,EAAY,MAAM,IAAI,EAAO,EAAK,CAAE,QAAS,GAAM,QAAS,EAAE,CAGjE,MAAuB,CACvB,EAAM,cACR,EAAY,MAAQ,CAAC,EAAY,eAIrC,MACQ,EAAM,WACN,CACJ,GAAgB,EAElB,CAAE,KAAM,GACV,CAAA,CAEA,MACQ,EAAM,UACX,GAAa,CACZ,EAAY,MAAQ,GAExB,CAEA,MAAgB,CACd,GAAgB,CAEhB,IAAK,IAAM,KAAS,EAAM,OAAQ,CAChC,IAAM,EAAQ,EAAS,EAAM,GAAE,CAC/B,EAAiB,EAAM,GAAI,EAAM,QAAS,EAAM,KAAI,CACpD,EAAc,EAAM,GAAI,EAAM,QAAS,EAAM,KAAI,GAEpD,aAID,EAgGM,MAAA,SA/FA,eAAJ,IAAI,EACJ,MAAK,EAAA,CAAC,gCAA+B,CAAA,eACX,EAAA,MAAW,CAAA,CAAA,GAG7B,EAAA,aAAA,GAAA,CADR,EAuBS,SAAA,OArBP,KAAK,SACL,MAAM,uBACL,QAAO,IAER,EAAoD,OAApD,GAAoD,EAAf,EAAA,MAAK,CAAA,EAAA,EAAA,GAAA,CAC1C,EAeM,MAAA,CAdJ,MAAK,EAAA,CAAC,wBAAuB,CAAA,eACH,EAAA,MAAW,CAAA,CAAA,CACrC,MAAM,KACN,OAAO,KACP,QAAQ,YACR,KAAK,yBAEL,EAME,OAAA,CALA,EAAE,gBACF,OAAO,eACP,eAAa,MACb,iBAAe,QACf,kBAAgB,iCAItB,EAEM,MAFN,GAEM,CADJ,EAAoD,OAApD,GAAoD,EAAf,EAAA,MAAK,CAAA,EAAA,CAAA,CAAA,EAGhC,EAAA,oBAAA,GAAA,CAAZ,EA4DM,MA5DN,GA4DM,EAAA,EAAA,GAAA,CA3DJ,EA0DM,EAAA,KAAA,EA1De,EAAA,OAAT,QAAZ,EA0DM,MAAA,CA1DwB,IAAK,EAAM,GAAI,MAAM,uBACjD,EA0CM,MA1CN,GA0CM,CAzCJ,EAA+D,OAA/D,GAA+D,EAArB,EAAM,MAAK,CAAA,EAAA,CACrD,EAuCS,SAAA,CAtCP,KAAK,SACL,MAAK,EAAA,CAAC,uBAAsB,CAAA,YAAA,CACJ,EAAS,EAAM,GAAE,CAAE,QAAO,CAAA,CAAA,CACjD,eAAc,EAAS,EAAM,GAAE,CAAE,QACjC,MAAO,EAAS,EAAM,GAAE,CAAE,QAAO,aAAA,aACjC,QAAK,GAAE,EAAiB,EAAK,GAGtB,EAAS,EAAM,GAAE,CAAE,SAAA,GAAA,CAD3B,EAqBM,MArBN,GAqBM,CAAA,GAAA,EAAA,KAAA,EAAA,GAAA,CAdJ,EAME,OAAA,CALA,EAAE,8FACF,OAAO,eACP,eAAa,OACb,iBAAe,QACf,kBAAgB,kBAElB,EAME,SAAA,CALA,GAAG,IACH,GAAG,IACH,EAAE,MACF,OAAO,eACP,eAAa,2BAGjB,EAQM,MARN,GAQM,CAAA,GAAA,EAAA,KAAA,EAAA,GAAA,CAPJ,EAME,OAAA,CALA,EAAE,wMACF,OAAO,eACP,eAAa,OACb,iBAAe,QACf,kBAAgB,iCAKxB,EAaM,MAbN,GAaM,CAZJ,EAQE,QAAA,CAPA,KAAK,QACL,IAAI,IACJ,IAAI,MACH,MAAO,KAAK,MAAM,EAAS,EAAM,GAAE,CAAE,QAAO,IAAA,CAC7C,MAAM,uBACL,SAAQ,CAAG,EAAS,EAAM,GAAE,CAAE,QAC9B,QAAK,GAAE,EAAmB,EAAO,EAAM,cAE1C,EAEC,OAFD,GAEC,EADK,KAAK,MAAM,EAAS,EAAM,GAAE,CAAE,QAAO,IAAA,CAAA,CAAU,IAAC,EAAA,CAAA,CAAA,CAAA,CAAA,YAM5D,EAAa,EAAA,OAAA,UAAA,8xBC1Uf,IAAM,EAAQ,EAsBR,EAAO,EAMP,EAAM,EAAa,EAAM,CACzB,EAAa,EAAO,EAAe,KAAI,CACvC,EAAe,EAAwB,KAAI,CAC3C,EAAc,EAAI,EAAM,UAAS,CACjC,EAAyB,EAAmC,IAAI,IAAK,CACrE,EAAiB,EAAkB,EAAE,CAAA,CAE3C,EAAc,EAAK,EAAc,EAAM,SAAQ,CAE/C,IAAM,EACJ,GACyB,CACzB,IAAM,EAA8B,EAAC,CAC/B,EAAe,EAAW,EAAW,OAAS,GAEpD,IAAK,IAAI,EAAI,EAAG,EAAI,EAAW,OAAS,EAAG,GAAK,EAAG,CACjD,IAAM,EAAQ,EAAW,GACnB,EAAQ,EAAW,EAAI,GAE7B,GAAI,MAAM,QAAQ,EAAK,CACrB,IAAK,IAAM,KAAK,EACd,EAAM,KAAK,CACT,MAAO,EACP,MAAO,OAAO,EAAC,CACf,QACA,QAAS,GACV,CAAA,MAGH,EAAM,KAAK,CACF,QACP,MAAO,OAAO,EAAK,CACnB,QACA,QAAS,GACV,CAAA,CAaL,OATI,EAAM,OAAS,GAAK,GAAgB,OAAO,GAAiB,UAC9D,EAAM,KAAK,CACT,MAAO,cACP,MAAO,QACP,MAAO,EACP,QAAS,GACV,CAAA,CAGI,GAGH,EACJ,GAC8B,CAC9B,IAAM,EAAmB,EAAC,CACpB,EAAkB,EAAC,CAEnB,EAAe,EAAW,GAChC,EAAO,KAAK,EAAY,CAExB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAW,OAAQ,GAAK,EAAG,CAC7C,IAAM,EAAO,EAAW,GAClB,EAAQ,EAAW,EAAI,GAC7B,EAAM,KAAK,EAAI,CACf,EAAO,KAAK,EAAK,CAKnB,OAFI,EAAM,SAAW,EAAU,KAExB,CACL,IAAK,EAAM,GACX,IAAK,EAAM,EAAM,OAAS,GAC1B,SACA,QACF,EAGI,EACJ,GAC8B,CAC9B,IAAM,EAAmB,EAAC,CACpB,EAAkB,EAAC,CAEN,EAAW,IAAM,MAAM,QAAQ,EAAW,GAAE,CAE/D,IAAK,IAAI,EAAI,EAAY,EAAI,EAAW,OAAQ,GAAK,EAAG,CACtD,IAAM,EAAO,EAAW,GAClB,EAAQ,EAAW,EAAI,GAC7B,EAAM,KAAK,EAAI,CACf,EAAO,KAAK,EAAK,CAKnB,OAFI,EAAM,OAAS,EAAU,KAEtB,CACL,IAAK,EAAM,GACX,IAAK,EAAM,EAAM,OAAS,GAC1B,SACA,QACF,EAGI,MAA8C,CAClD,GAAI,CAAC,EAAM,cAAgB,CAAC,EAAM,UAAY,CAAC,EAAI,MAAO,MAAO,EAAC,CAElE,IAAM,EAAU,EAAM,SAAS,GAC/B,GAAI,CAAC,EAAS,MAAO,EAAC,CAGtB,GAAI,CADU,EAAI,MAAM,SAAS,EAC5B,CAEH,OADA,QAAQ,KAAK,qCAAqC,IAAS,CACpD,EAAC,CAGV,IAAM,EAAa,EAAI,MAAM,iBAAiB,EAAS,EAAM,SAAQ,CACrE,GAAI,CAAC,GAAc,CAAC,MAAM,QAAQ,EAAU,CAI1C,OAHA,QAAQ,KACN,oCAAoC,EAAM,SAAS,kCACrD,CACO,EAAC,CAGV,IAAM,EAAiB,EAAW,GAElC,GAAI,IAAmB,QACrB,OAAO,EAAqB,EAA+B,CAG7D,GAAI,IAAmB,OAAQ,CAC7B,IAAM,EAAW,EAAoB,EAA+B,CACpE,OAAO,EAAW,CAAC,EAAQ,CAAI,EAAC,CAGlC,GACE,IAAmB,eACnB,IAAmB,mBACnB,IAAmB,kBACnB,CACA,IAAM,EAAW,EACf,EACF,CACA,OAAO,EAAW,CAAC,EAAQ,CAAI,EAAC,CAMlC,OAHA,QAAQ,KACN,iDAAiD,IACnD,CACO,EAAC,EAGJ,EAAiB,MACjB,EAAM,OAAS,EAAM,MAAM,OAAS,EAC/B,EAAM,MAER,EAAe,MACvB,CAEK,EAAgB,MAChB,EAAM,OAAS,WACZ,EAAe,MAAM,OACzB,GACC,UAAW,GAAQ,UAAW,GAAQ,UAAW,EACrD,CAJsC,EAAC,CAKxC,CAEK,EAAe,MAAe,CAClC,GAAI,EAAM,OAAS,WAAY,OAAO,KACtC,IAAM,EAAQ,EAAe,MAC7B,GAAI,EAAM,SAAW,EAAG,OAAO,KAC/B,IAAM,EAAQ,EAAM,GAIpB,MAHI,QAAS,GAAS,QAAS,GAAS,WAAY,EAC3C,EAEF,MACR,CAEK,EAAY,MACZ,EAAM,OAAS,OACZ,EAAe,MAAM,OACzB,GAAiC,SAAU,GAAQ,UAAW,EACjE,CAHkC,EAAC,CAIpC,CAEK,GAAa,MACb,EAAM,OAAS,QACZ,EAAe,MACnB,OACE,GACC,UAAW,GACX,UAAW,GACX,UAAW,GACX,EAAE,SAAU,IACZ,EAAE,YAAa,GACnB,CACC,MAAM,EAAG,IAAM,EAAE,MAAQ,EAAE,MAAK,CAVA,EAAC,CAWrC,CAEK,EAAoB,GACpB,EAAK,eAAuB,EAAK,eAC9B,GAAG,EAAK,QAAQ,EAAK,MAAQ,KAGhC,EAAc,OAIX,CAAE,cAHa,MAAM,KAAK,EAAuB,MAAM,SAAS,CAAA,CACpE,QAAQ,EAAG,KAAa,EAAO,CAC/B,KAAK,CAAC,KAAW,EACX,CAAc,EACxB,CAEK,EAAgB,MACf,EAAa,MAEX,6BADY,EAAa,MAAM,OAAO,KAAK,KACd,CAAW,GAFf,GAGjC,CAEK,MAAuB,CAC3B,GAAI,EAAM,OAAS,WACjB,IAAK,IAAM,KAAQ,EAAc,MAC/B,EAAuB,MAAM,IAAI,EAAK,MAAO,EAAK,SAAW,GAAI,EAKjE,MAAoC,CACxC,GAAI,CAAC,EAAI,OAAS,CAAC,EAAM,UAAY,EAAM,OAAS,WAAY,OAEhE,IAAM,EAAgB,EAAY,MAAM,cAAc,OACnD,GAAM,IAAM,cACf,CACM,EAAY,EAAc,MAC7B,IAAK,GAAS,EAAK,MAAK,CACxB,OAAQ,GAAM,IAAM,cAAa,CAC9B,EAAa,EAAc,SAAW,EAAU,OAEtD,IAAK,IAAM,KAAW,EAAM,SACZ,KAAI,MAAM,SAAS,EAC5B,CAEL,GAAI,EACF,EAAI,MAAM,UAAU,EAAS,KAAI,MAC5B,GAAI,EAAc,SAAW,EAClC,EAAI,MAAM,UAAU,EAAS,CAAC,KAAM,CAAC,MAAO,gBAAe,CAAG,GAAK,CAAA,KAC9D,CACL,IAAM,EAAa,EAAI,MAAM,iBAAiB,EAAS,EAAM,SAAQ,CACrE,GAAI,CAAC,GAAc,CAAC,MAAM,QAAQ,EAAU,CAAG,SAE/C,IAAM,EAAY,EAAW,GACzB,EAA8B,KAE9B,MAAM,QAAQ,EAAS,EAAK,EAAU,KAAO,QAC/C,EAAe,EAAU,IAGvB,GACF,EAAI,MAAM,UAAU,EAAS,CAC3B,KACA,CAAC,MAAO,EAAY,CACpB,CAAC,UAAW,EAAa,CAC1B,CAAA,GAMH,MAAkC,CACtC,GAAI,CAAC,GAAc,EAAM,OAAS,WAAY,OAE9C,IAAM,EAAgB,EAAY,MAAM,cAAc,OACnD,GAAM,IAAM,cACf,CACM,EAAY,EAAc,MAC7B,IAAK,GAAS,EAAK,MAAK,CACxB,OAAQ,GAAM,IAAM,cAAa,CAC9B,EAAa,EAAc,SAAW,EAAU,OAEhD,EAAS,EAAW,WAAU,CAEpC,IAAK,IAAM,KAAW,EAAM,SAAU,CACpC,GAAI,EAAI,OAAO,SAAS,EAAO,CAAG,SAElC,IAAM,EAAY,EAAO,KAAM,GAAM,EAAE,KAAO,EAAO,CAChD,KAML,IAAI,CAJ2B,EAAU,OAAO,YAAY,KACzD,GAAQ,GAAK,aAAa,OAAS,sBACtC,CAE6B,CAC3B,QAAQ,KACN,mCAAmC,EAAQ,kIAE7C,CACA,SAGE,UAAO,EAAU,OAAU,WAE/B,GAAI,EAAY,CACd,IAAM,EAAe,EAAU,MAAM,CACnC,YAAa,CAAC,KAAW,IAAQ,CAClC,CAAA,CACD,EAAW,YAAY,EAAS,EAAY,MACvC,GAAI,EAAc,SAAW,EAAG,CACrC,IAAM,EAAe,EAAU,MAAM,CACnC,YAAa,CAAC,IAAU,IAAQ,CACjC,CAAA,CACD,EAAW,YAAY,EAAS,EAAY,KACvC,CACL,IAAM,EAAe,EAClB,IAAK,GAAM,EAAc,MAAM,UAAW,GAAS,EAAK,QAAU,EAAE,CAAA,CACpE,OAAQ,GAAM,GAAK,EAAC,CAEvB,GAAI,EAAa,OAAS,EAAG,CAC3B,IAAM,EAAW,KAAK,IAAI,GAAG,EAAY,CACnC,EAAW,KAAK,IAAI,GAAG,EAAY,CACnC,EAAe,EAAU,MAAM,CACnC,YAAa,CAAC,EAAW,GAAK,EAAW,GAAG,CAC7C,CAAA,CACD,EAAW,YAAY,EAAS,EAAY,MAM9C,GAAc,EAA0B,IAAkB,CAC9D,GAAI,CAAC,EAAM,YAAa,OAGxB,IAAM,EAAa,EADI,EAAuB,MAAM,IAAI,EAAK,MAAK,EAAK,IAEvE,EAAuB,MAAM,IAAI,EAAK,MAAO,EAAU,CAEvD,GAA4B,CAC5B,GAA0B,CAE1B,EAAK,aAAc,CAAE,OAAM,QAAO,QAAS,EAAY,CAAA,CACvD,EAAK,gBAAiB,CACpB,OAAQ,EAAY,MACpB,SAAU,EAAM,SACjB,CAAA,CACD,EAAK,gBAAiB,EAAY,MAAK,EAGnC,EAAiB,GACd,EAAuB,MAAM,IAAI,EAAK,MAAK,EAAK,GAGnD,MAAuB,CAC3B,EAAY,MAAQ,CAAC,EAAY,cAGnC,MACQ,EAAM,UACN,CACJ,GAAe,EAEjB,CAAE,KAAM,GACV,CAAA,CAEA,MACQ,EAAM,UACX,GAAa,CACZ,EAAY,MAAQ,GAExB,CAEA,MAAgB,CACV,EAAM,eACR,EAAe,MAAQ,GAAwB,EAEjD,GAAe,EAChB,aAID,EA0GM,MAAA,SAzGA,eAAJ,IAAI,EACJ,MAAK,EAAA,CAAC,mBAAkB,CAAA,eACE,EAAA,MAAW,CAAA,CAAA,GAErC,EAsBS,SAAA,CArBP,KAAK,SACL,MAAM,0BACL,QAAO,IAER,EAAuD,OAAvD,GAAuD,EAAf,EAAA,MAAK,CAAA,EAAA,EAAA,GAAA,CAC7C,EAeM,MAAA,CAdJ,MAAK,EAAA,CAAC,2BAA0B,CAAA,eACN,EAAA,MAAW,CAAA,CAAA,CACrC,MAAM,KACN,OAAO,KACP,QAAQ,YACR,KAAK,yBAEL,EAME,OAAA,CALA,EAAE,gBACF,OAAO,eACP,eAAa,MACb,iBAAe,QACf,kBAAgB,2BAKV,EAAA,oBAAA,GAAA,CAAZ,EA0EM,MA1EN,GA0EM,CAzEY,EAAA,OAAI,YAAA,EAAA,GAAA,CAClB,EAoBS,EAAA,CAAA,IAAA,EAAA,CAAA,EAnBiB,EAAA,OAAhB,EAAM,SADhB,EAoBS,SAAA,CAlBN,IAAK,EAAK,MACX,KAAK,SACL,MAAK,EAAA,CAAC,wBAAuB,kBACW,EAAA,yBAAuC,EAAc,EAAI,IAIhG,SAAQ,CAAG,EAAA,YACX,QAAK,GAAE,EAAW,EAAM,EAAK,GAE9B,EAGQ,OAAA,CAFN,MAAM,0BACL,MAAK,EAAA,CAAA,gBAAqB,EAAK,MAAK,CAAA,UAEvC,EAA4D,OAA5D,GAA4D,EAApB,EAAK,MAAK,CAAA,EAAA,CACtC,EAAK,QAAU,IAAA,GACZ,EAAA,OAAA,GAAA,EADY,GAAA,CAA3B,EAEO,OAFP,GAEO,EADF,EAAK,MAAK,CAAA,EAAA,kBAKE,EAAA,OAAI,YAAmB,EAAA,OAAA,GAAA,CAA5C,EASW,EAAA,CAAA,IAAA,EAAA,CAAA,CART,EAGO,MAAA,CAFL,MAAM,4BACL,MAAK,EAAA,CAAA,WAAgB,EAAA,MAAa,CAAA,UAErC,EAGM,MAHN,GAGM,CAFJ,EAA4D,OAAA,KAAA,EAAnD,EAAA,MAAa,UAAY,EAAA,MAAa,IAAG,CAAA,EAAA,CAClD,EAA4D,OAAA,KAAA,EAAnD,EAAA,MAAa,UAAY,EAAA,MAAa,IAAG,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,GAAA,EAIjC,EAAA,OAAI,QAAA,EAAA,GAAA,CACvB,EAeM,EAAA,CAAA,IAAA,EAAA,CAAA,EAdW,EAAA,MAAR,QADT,EAeM,MAAA,CAbH,IAAK,EAAK,MACX,MAAM,+BAEN,EAQM,MARN,GAQM,CAPJ,EAMO,MAAA,CALL,MAAM,+BACL,MAAK,EAAA,UAA8B,KAAK,IAAI,EAAK,KAAI,GAAA,CAAA,cAAsC,KAAK,IAAI,EAAK,KAAI,GAAA,CAAA,iBAMlH,EAA4D,OAA5D,GAA4D,EAApB,EAAK,MAAK,CAAA,EAAA,CAAA,CAAA,SAIjC,EAAA,OAAI,SAAA,GAAA,CACvB,EAgBM,MAhBN,GAgBM,EAAA,EAAA,GAAA,CAfJ,EAcM,EAAA,KAAA,EAbW,GAAA,MAAR,QADT,EAcM,MAAA,CAZH,IAAK,EAAK,MACX,MAAM,6BACL,MAAO,EAAK,cAEb,EAGQ,OAAA,CAFN,MAAM,0BACL,MAAK,EAAA,CAAA,gBAAqB,EAAK,MAAK,CAAA,UAEvC,EAAkE,OAAlE,GAAkE,EAApB,EAAK,MAAK,CAAA,EAAA,CACxD,EAEO,OAFP,GAEO,EADF,EAAiB,EAAI,CAAA,CAAA,EAAA,mCAOlC,EAAa,EAAA,OAAA,UAAA,iMClgBf,IAAM,EAAQ,EAeR,EAAM,EAAa,EAAM,CACzB,EAAuB,EAAI,GAAK,CAGhC,MACG,EAAI,OAAS,KAIhB,EAAY,GAAqB,CAChC,GAEL,EAAY,GAAG,iBAAoB,CACjC,IAAM,MAAqB,CACpB,EAAY,eAAc,CAI7B,EAAO,MAAQ,IAHf,EAAO,MAAQ,GACf,WAAW,EAAc,IAAG,GAKhC,GAAa,EACd,EAGG,MAAuB,CAC3B,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CAIF,GAHK,EAAY,UAAU,EAAM,SAAQ,EACvC,EAAY,UAAU,EAAM,SAAU,EAAM,OAAM,CAEhD,CAAC,EAAY,SAAS,EAAM,QAAO,CAAG,CACxC,IAAM,EAAY,CAChB,GAAG,EAAM,MACT,GAAI,EAAM,QACV,OAAQ,EAAM,SAChB,CACA,EAAY,SAAS,EAAW,EAAM,OAAM,QAEvC,EAAO,CACd,QAAQ,MAAM,6BAA8B,EAAK,UAgDrD,MAAY,EAAM,WA5Ce,CAC/B,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CAEE,EAAY,SAAS,EAAM,QAAO,EACpC,EAAY,YAAY,EAAM,QAAO,CAEnC,EAAY,UAAU,EAAM,SAAQ,EACtC,EAAY,aAAa,EAAM,SAAQ,CAGzC,EAAY,UAAU,EAAM,SAAU,EAAM,OAAM,CAClD,IAAM,EAAY,CAChB,GAAG,EAAM,MACT,GAAI,EAAM,QACV,OAAQ,EAAM,SAChB,CACA,EAAY,SAAS,EAAW,EAAM,OAAM,OACrC,EAAO,CACd,QAAQ,MAAM,gCAAiC,EAAK,GAuBhB,CAAE,KAAM,GAAM,CAAA,CACtD,MAAY,EAAM,UApBc,CAC9B,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CACE,EAAY,SAAS,EAAM,QAAO,GACpC,OAAO,QAAQ,EAAM,MAAM,OAAS,EAAE,CAAA,CAAE,SAAS,CAAC,EAAK,KAAW,CAChE,EAAY,iBAAiB,EAAM,QAAS,EAAK,EAAK,EACvD,CACD,OAAO,QAAQ,EAAM,MAAM,QAAU,EAAE,CAAA,CAAE,SAAS,CAAC,EAAK,KAAW,CACjE,EAAY,kBAAkB,EAAM,QAAS,EAAK,EAAK,EACxD,QAEI,EAAO,CACd,QAAQ,MAAM,+BAAgC,EAAK,GAMjB,CAAE,KAAM,GAAM,CAAA,CAGpD,EACE,EACC,GAAW,CACN,GACF,EAAS,EAAM,EAGnB,CAAE,UAAW,GACf,CAAA,CAGA,EAAM,EAAS,GAAU,CACnB,GACF,GAAS,EAEZ,CAGD,MAAgB,CACM,GAChB,EAAa,eAAc,EAC7B,GAAS,EAEZ,CAED,MAAsB,CACpB,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CACE,EAAY,SAAS,EAAM,QAAO,EACpC,EAAY,YAAY,EAAM,QAAO,CAEnC,EAAY,UAAU,EAAM,SAAQ,EACtC,EAAY,aAAa,EAAM,SAAQ,OAElC,EAAO,CACd,QAAQ,MAAM,kCAAmC,EAAK,GAEzD,QAID,EAAa,EAAA,OAAA,UAAA,2NCrIb,IAAM,EAAQ,EAMR,EAAO,EAIP,EAAM,EAAa,EAAM,CACzB,EAAuB,EAAI,GAAK,CAGhC,EACJ,GAEI,CAAC,GAAQ,OAAO,GAAS,SAAiB,GAC1C,GAAQ,OAAO,GAAS,UAAY,SAAU,EAC5C,EAAK,OAAS,qBAAuB,aAAc,EAC9C,EAAK,SAAS,OAAS,EAI9B,EAAK,OAAS,WACd,EAAK,OAAS,SACd,EAAK,OAAS,cACd,EAAK,OAAS,WACd,EAAK,OAAS,cACd,EAAK,OAAS,mBACd,EAAK,OAAS,eAGX,GAIH,MACa,EAAI,OAAS,KAK1B,EAAY,GAAqB,CAChC,GAIL,EAAY,GAAG,iBAAoB,CACjC,IAAM,MAAqB,CACpB,EAAY,eAAc,CAI7B,EAAO,MAAQ,IAHf,EAAO,MAAQ,GACf,WAAW,EAAc,IAAG,GAKhC,GAAa,EACd,EAGG,MAAuB,CAC3B,IAAM,EAAc,GAAe,CAC/B,MAAC,GAAe,CAAC,EAAY,eAAc,EAK/C,IAAI,CAAC,EAAa,EAAM,OAAO,KAAI,CAAG,CACpC,QAAQ,IACN,IAAI,EAAM,QAAQ,8CACpB,CACA,OAGF,GAAI,CAOF,GALK,EAAY,UAAU,EAAM,SAAQ,EACvC,EAAY,UAAU,EAAM,SAAU,EAAM,OAAM,CAIhD,CAAC,EAAY,SAAS,EAAM,QAAO,CAAG,CACxC,IAAM,EAAY,CAChB,GAAG,EAAM,MACT,GAAI,EAAM,QACV,OAAQ,EAAM,SAChB,CAEA,EAAY,SAAS,EAAW,EAAM,OAAM,QAEvC,EAAO,CACd,QAAQ,MAAM,8BAA+B,EAAK,IAIhD,MAA2B,CAC/B,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CACF,IAAM,EAAS,EAAY,UAAU,EAAM,SAAQ,CAInD,GAAI,GAAU,YAAa,EAAQ,CAGjC,IAAM,EAAiB,EACpB,UAAS,CACT,OAAO,OACL,GACC,EAAE,OAAS,cACX,WAAY,GACZ,EAAE,SAAW,EAAM,SACvB,EAKA,EAAe,SAAW,GAC1B,EAAe,IAAI,KAAO,EAAM,UAEhC,EAAO,QAAQ,EAAM,OAAO,KAAI,MAExB,GAEV,GAAS,OAEJ,EAAO,CACd,QAAQ,MAAM,iCAAkC,EAAK,GAInD,MAA0B,CAC9B,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CACE,EAAY,SAAS,EAAM,QAAO,EAEpC,OAAO,QAAQ,EAAM,MAAM,OAAS,EAAE,CAAA,CAAE,SAAS,CAAC,EAAK,KAAW,CAChE,EAAY,iBAAiB,EAAM,QAAS,EAAK,EAAK,EACvD,CAED,OAAO,QAAQ,EAAM,MAAM,QAAU,EAAE,CAAA,CAAE,SAAS,CAAC,EAAK,KAAW,CACjE,EAAY,kBAAkB,EAAM,QAAS,EAAK,EAAK,EACxD,EAGD,GAAS,OAEJ,EAAO,CACd,QAAQ,MAAM,gCAAiC,EAAK,GAIlD,EAAoB,GAAqB,CACxC,KAIL,GAAI,CAEF,EAAY,GAAG,QAAS,EAAM,QAAU,GAA0B,CAC5D,EAAE,UAAY,EAAE,SAAS,OAAS,GACpC,EAAK,WAAY,CACf,SAAU,EAAE,SACZ,YAAa,EAAE,OAChB,CAAA,EAEJ,CAGD,EAAY,GAAG,aAAc,EAAM,YAAe,CAChD,EAAY,WAAU,CAAE,MAAM,OAAS,WACxC,CAED,EAAY,GAAG,aAAc,EAAM,YAAe,CAChD,EAAY,WAAU,CAAE,MAAM,OAAS,IACxC,OACM,EAAO,CACd,QAAQ,MAAM,6BAA8B,EAAK,GAK/C,EAAc,EAAI,GAAK,CAGvB,EAAkB,SAAY,CAClC,GAAI,EAAY,MAAO,OAEvB,IAAM,EAAc,GAAe,CAC/B,CAAC,GAAe,CAAC,EAAY,eAAc,EAC1C,EAAa,EAAM,OAAO,KAAI,GAGnC,MAAM,GAAS,CAGX,GAAY,OACX,EAAY,eAAc,GAE/B,GAAS,CACT,EAAiB,EAAW,CAC5B,EAAY,MAAQ,aAItB,EAAM,EAAS,GAAU,CACnB,GACF,GAAgB,EAEnB,CAGD,EACE,EACC,GAAW,CACN,IACF,EAAS,EAAM,CAEX,EAAO,eAAc,GACvB,EAAO,MAAQ,GAEf,GAAgB,IAItB,CAAE,UAAW,GACf,CAAA,CAGA,MACQ,EAAM,QACX,EAAW,IAAc,CAEnB,KAAa,GAAW,KAAI,EAK7B,KAAK,UAAU,EAAU,KAAI,GAAM,KAAK,UAAU,GAAW,KAAI,CAAG,CACtE,IAAM,EAAc,GAAe,CAC/B,GAAa,eAAc,GAExB,EAAY,UAAU,EAAM,SAAQ,CAQvC,GAAa,EAPb,GAAS,CACJ,EAAY,QACf,EAAiB,EAAW,CAC5B,EAAY,MAAQ,QAS9B,CAAE,KAAM,GACV,CAAA,CAEA,MAAY,EAAM,MAAO,EAAa,CAAE,KAAM,GAAM,CAAA,CAGpD,MACQ,EAAM,MAAM,QAAQ,WACzB,GAAkB,CACjB,IAAM,EAAc,GAAe,CACnC,GAAI,CAAC,GAAe,CAAC,EAAY,eAAc,CAAG,OAElD,IAAM,EAAW,EAAY,SAAS,EAAM,QAAO,CAEnD,GAAI,CAAC,GAAY,IAAkB,UAE7B,EAAa,EAAM,OAAO,KAAI,EAChC,GAAS,MAEN,GAAI,EAET,GAAI,CACF,EAAY,kBACV,EAAM,QACN,aACA,EACF,OACO,EAAO,CACd,QAAQ,MACN,iCAAiC,EAAM,QAAQ,GAC/C,EACF,GAIN,CAAE,UAAW,GACf,CAAA,CAGA,MAAgB,CAEd,MAAe,CACb,GAAgB,EACjB,EACF,CAED,MAAsB,CACpB,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CAEE,EAAY,SAAS,EAAM,QAAO,EACpC,EAAY,YAAY,EAAM,QAAO,CAIb,EACvB,UAAS,CACT,OAAO,OACL,GACC,EAAE,OAAS,cACX,WAAY,GACZ,EAAE,SAAW,EAAM,SAIvB,CAAkB,SAAW,GAC7B,EAAY,UAAU,EAAM,SAAQ,EAEpC,EAAY,aAAa,EAAM,SAAQ,OAElC,EAAO,CACd,QAAQ,MAAM,mCAAoC,EAAK,GAE1D,QAID,EAAa,EAAA,OAAA,UAAA,gUCrWb,IAAM,EAAQ,EA2BR,EAAM,EAAa,EAAM,CACzB,EAAuB,EAAI,GAAK,CAGhC,MACG,EAAI,OAAS,KAIhB,EAAY,GAAqB,CAChC,GAEL,EAAY,GAAG,iBAAoB,CACjC,IAAM,MAAqB,CACpB,EAAY,eAAc,CAI7B,EAAO,MAAQ,IAHf,EAAO,MAAQ,GACf,WAAW,EAAc,IAAG,GAKhC,GAAa,EACd,EAGG,MAAuB,CAC3B,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CAIF,GAHK,EAAY,UAAU,EAAM,SAAQ,EACvC,EAAY,UAAU,EAAM,SAAU,EAAM,OAAM,CAEhD,CAAC,EAAY,SAAS,EAAM,QAAO,CAAG,CACxC,IAAM,EAAY,CAChB,GAAG,EAAM,MACT,GAAI,EAAM,QACV,OAAQ,EAAM,SAChB,CACA,EAAY,SAAS,EAAW,EAAM,OAAM,QAEvC,EAAO,CACd,QAAQ,MAAM,4BAA6B,EAAK,UA2DpD,MAAY,EAAM,WAvDe,CAC/B,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CACF,IAAM,EAAS,EAAY,UAAU,EAAM,SAAQ,CACnD,GAAI,EAEF,GAAI,EAAO,YACT,EAAO,YAAY,CACjB,IAAK,EAAM,OAAO,IAClB,YAAa,EAAM,OAAO,YAC3B,CAAA,KACI,CAED,EAAY,SAAS,EAAM,QAAO,EACpC,EAAY,YAAY,EAAM,QAAO,CAEnC,EAAY,UAAU,EAAM,SAAQ,EACtC,EAAY,aAAa,EAAM,SAAQ,CAGzC,EAAY,UAAU,EAAM,SAAU,EAAM,OAAM,CAClD,IAAM,EAAY,CAChB,GAAG,EAAM,MACT,GAAI,EAAM,QACV,OAAQ,EAAM,SAChB,CACA,EAAY,SAAS,EAAW,EAAM,OAAM,QAGzC,EAAO,CACd,QAAQ,MAAM,+BAAgC,EAAK,GAuBf,CAAE,KAAM,GAAM,CAAA,CACtD,MAAY,EAAM,UApBc,CAC9B,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CACE,EAAY,SAAS,EAAM,QAAO,GACpC,OAAO,QAAQ,EAAM,MAAM,OAAS,EAAE,CAAA,CAAE,SAAS,CAAC,EAAK,KAAW,CAChE,EAAY,iBAAiB,EAAM,QAAS,EAAK,EAAK,EACvD,CACD,OAAO,QAAQ,EAAM,MAAM,QAAU,EAAE,CAAA,CAAE,SAAS,CAAC,EAAK,KAAW,CACjE,EAAY,kBAAkB,EAAM,QAAS,EAAK,EAAK,EACxD,QAEI,EAAO,CACd,QAAQ,MAAM,8BAA+B,EAAK,GAMhB,CAAE,KAAM,GAAM,CAAA,CAGpD,EACE,EACC,GAAW,CACN,GACF,EAAS,EAAM,EAGnB,CAAE,UAAW,GACf,CAAA,CAGA,EAAM,EAAS,GAAU,CACnB,GACF,GAAS,EAEZ,CAGD,MAAgB,CACM,GAChB,EAAa,eAAc,EAC7B,GAAS,EAEZ,CAED,MAAsB,CACpB,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CACE,EAAY,SAAS,EAAM,QAAO,EACpC,EAAY,YAAY,EAAM,QAAO,CAEnC,EAAY,UAAU,EAAM,SAAQ,EACtC,EAAY,aAAa,EAAM,SAAQ,OAElC,EAAO,CACd,QAAQ,MAAM,iCAAkC,EAAK,GAExD,QAID,EAAa,EAAA,OAAA,UAAA,4GChLb,IAAM,EAAQ,EAQR,EAAM,EAAa,EAAM,CACzB,EAAuB,EAAI,GAAK,CAEhC,MACG,EAAI,OAAS,KAGhB,EAAY,GAAqB,CAChC,GAEL,EAAY,GAAG,iBAAoB,CACjC,IAAM,MAAqB,CACpB,EAAY,eAAc,CAI7B,EAAO,MAAQ,IAHf,EAAO,MAAQ,GACf,WAAW,EAAc,IAAG,GAKhC,GAAa,EACd,EAGG,MAAuB,CAC3B,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CACG,EAAY,UAAU,EAAM,SAAQ,EACvC,EAAY,UAAU,EAAM,SAAU,EAAM,OAAM,CAE/C,EAAY,SAAS,EAAM,QAAO,GAErC,EAAY,SAAS,EAAM,MAAO,EAAM,OAAM,CAG1C,EAAM,MAAM,QAAQ,YACtB,EAAY,kBACV,EAAM,QACN,aACA,EAAM,MAAM,OAAO,WACrB,QAGG,EAAO,CACd,QAAQ,MAAM,IAAI,EAAM,QAAQ,2BAA4B,EAAK,GAI/D,MAA2B,CAC/B,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CAEF,IAAM,EAAW,EAAM,OAEnB,EAAY,SAAS,EAAM,QAAO,EACpC,EAAY,YAAY,EAAM,QAAO,CAEvC,EAAY,aAAa,EAAM,SAAQ,CAEvC,EAAY,UAAU,EAAM,SAAU,EAAM,OAAM,CAClD,IAAM,EAAY,CAChB,GAAG,EAAM,MACT,GAAI,EAAM,QACV,KAAM,SACN,OAAQ,EAAM,SAChB,CAGI,GAAY,EAAY,SAAS,EAAQ,CAC3C,EAAY,SAAS,EAAW,EAAQ,CAExC,EAAY,SAAS,EAAS,OAEzB,EAAO,CACd,QAAQ,MAAM,gCAAiC,EAAK,UA4BxD,MACQ,EAAM,OAAO,QAAQ,IAC1B,EAAY,IAAe,CACtB,IAAe,GACjB,GAAa,EAGnB,CACA,MAAY,EAAM,UAhCc,CAC9B,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CACF,GAAI,EAAY,SAAS,EAAM,QAAO,CAAG,CAEvC,IAAM,EAAQ,EAAM,MAAM,OAAS,EAAC,CACpC,OAAO,QAAQ,EAAK,CAAE,SAAS,CAAC,EAAK,KAAW,CAC9C,EAAY,iBAAiB,EAAM,QAAS,EAAK,EAAK,EACvD,CAGD,IAAM,EAAS,EAAM,MAAM,QAAU,EAAC,CACtC,OAAO,QAAQ,EAAM,CAAE,SAAS,CAAC,EAAK,KAAW,CAC/C,EAAY,kBAAkB,EAAM,QAAS,EAAK,EAAK,EACxD,QAEI,EAAO,CACd,QAAQ,MAAM,+BAAgC,EAAK,GAajB,CAAE,KAAM,GAAM,CAAA,CACpD,EACE,EACC,GAAW,CACN,GACF,EAAS,EAAM,EAGnB,CAAE,UAAW,GACf,CAAA,CACA,EAAM,EAAS,GAAU,CACnB,GACF,GAAS,EAEZ,CACD,MACQ,EAAM,MAAM,QAAQ,WACzB,GAAkB,CACjB,IAAM,EAAc,GAAe,CAC9B,KAIL,GAFiB,EAAY,SAAS,EAAM,QAEvC,CAQH,GAAI,CAEF,EAAY,kBACV,EAAM,QACN,aACA,EACF,CAGI,IAAkB,WAAa,EAAM,QACvC,EAAY,UAAU,EAAM,QAAS,EAAM,OAAM,OAE5C,EAAO,CACd,QAAQ,MAAM,IAAI,EAAM,QAAQ,8BAA+B,EAAK,MAnBtE,GAAI,CACF,EAAY,SAAS,EAAM,MAAO,EAAM,OAAM,OACvC,EAAO,CACd,QAAQ,MAAM,IAAI,EAAM,QAAQ,uBAAwB,EAAK,GAoBnE,CAAE,UAAW,GACf,CAAA,CACA,MACQ,EAAM,OACX,GAAc,CACb,IAAM,EAAc,GAAe,CAC/B,MAAC,GAAe,CAAC,EAAY,SAAS,EAAM,QAAO,GAGnD,EAAM,MAAM,QAAQ,aAAe,UACrC,GAAI,CACF,QAAQ,IAAI,IAAI,EAAM,QAAQ,wBAAyB,EAAS,CAChE,EAAY,UAAU,EAAM,QAAS,EAAS,OACvC,EAAO,CACd,QAAQ,MAAM,IAAI,EAAM,QAAQ,uBAAwB,EAAK,GAIrE,CAGA,MAAgB,CACM,MACf,CAGL,GAAI,CACF,GAAS,OACF,EAAO,CACd,QAAQ,MAAM,IAAI,EAAM,QAAQ,2BAA4B,EAAK,GAEpE,QAID,EAAa,EAAA,OAAA,UAAA,ICpNF,EAAiD,CAC5D,QACA,WACA,YACA,UACA,YACA,aACA,aACA,YACA,WACA,cACA,aACA,WACA,cACD,CCdY,EAAuC,4cA+CnD,CCjDY,EAAkB,CAAC,YAAa,OAAQ,UAAU,CAClD,EAAkB,CAAC,QAAS,aAAc,aAAa,CCDvD,EAAc,CAAC,OAAQ,QAAQ,gICW1C,IAAM,EAAQ,EAOR,EAAO,EAEP,EAAM,EAAa,EAAM,CACzB,EAAuB,EAAI,GAAK,CAGhC,MACG,EAAI,OAAS,KAIhB,EAAY,GAAqB,CAChC,GAEL,EAAY,GAAG,iBAAoB,CACjC,IAAM,MAAqB,CACpB,EAAY,eAAc,CAI7B,EAAO,MAAQ,IAHf,EAAO,MAAQ,GACf,WAAW,EAAc,IAAG,GAKhC,GAAa,EACd,EAEG,MAAuB,CAC3B,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CACG,EAAY,UAAU,EAAM,SAAQ,EACvC,EAAY,UAAU,EAAM,SAAU,EAAM,OAAM,CAE/C,EAAY,SAAS,EAAM,QAAO,GAEjC,EAAM,MAAM,QAAQ,aAAe,UACrC,EAAY,SAAS,EAAM,MAAO,EAAM,OAAM,CAG9C,EAAY,SAAS,EAAM,MAAK,QAG7B,EAAO,CACd,QAAQ,MAAM,IAAI,EAAM,QAAQ,2BAA4B,EAAK,GAG/D,MAA2B,CAC/B,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CACF,IAAM,EAAiB,EAAY,UAAU,EAAM,SAAQ,CAE3D,GACE,GACA,KAAK,UAAU,EAAe,WAAW,CAAA,GACvC,KAAK,UAAU,EAAM,OAAM,CAC7B,CACI,EAAY,SAAS,EAAM,QAAO,EACpC,EAAY,YAAY,EAAM,QAAO,CAEvC,EAAY,aAAa,EAAM,SAAQ,CACvC,EAAY,UAAU,EAAM,SAAU,EAAM,OAAM,CAClD,IAAM,EAAY,CAChB,GAAG,EAAM,MACT,GAAI,EAAM,QACV,OAAQ,EAAM,SAChB,CACA,EAAY,SAAS,EAAW,EAAM,OAAM,QAEvC,EAAO,CACd,QAAQ,MAAM,gCAAiC,EAAK,GAGlD,MAA0B,CAC9B,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CACF,GAAI,EAAY,SAAS,EAAM,QAAO,CAAG,CAEvC,IAAM,EAAe,EAAY,SAAS,EAAM,QAAO,CACjD,EAAgB,GAAc,OAAS,EAAC,CAIxC,EAAiB,GAAc,QAAU,EAAC,CAMhD,OAAO,QAAQ,EAAM,MAAM,OAAS,EAAE,CAAA,CAAE,SAAS,CAAC,EAAK,KAAW,CAC5D,KAAK,UAAU,EAAa,GAAI,GAAM,KAAK,UAAU,EAAK,EAC5D,EAAY,iBAAiB,EAAM,QAAS,EAAK,EAAK,EAEzD,CAED,OAAO,QAAQ,EAAM,MAAM,QAAU,EAAE,CAAA,CAAE,SAAS,CAAC,EAAK,KAAW,CAC7D,KAAK,UAAU,EAAc,GAAI,GAAM,KAAK,UAAU,EAAK,EAC7D,EAAY,kBAAkB,EAAM,QAAS,EAAK,EAAK,EAE1D,QAEI,EAAO,CACd,QAAQ,MAAM,+BAAgC,EAAK,GAGjD,EAAoB,GAAqB,CACxC,KAEL,GAAI,CACF,EAAe,QAAS,GAAc,CACpC,EAAY,GAAG,EAAW,EAAM,QAAU,GAAM,CAC1C,IAAc,cAChB,EAAY,WAAU,CAAE,MAAM,OAAS,WAErC,IAAc,eAChB,EAAY,WAAU,CAAE,MAAM,OAAS,IAEzC,EAAK,EAAW,EAAC,EAClB,EACF,OACM,EAAO,CACd,QAAQ,MAAM,iCAAkC,EAAK,UAKzD,EACE,GACC,EAAQ,IAAW,CACd,GAAU,IAAW,GACvB,EAAS,EAAM,EAGnB,CAAE,UAAW,GACf,CAAA,CACA,EAAM,EAAS,GAAU,CACvB,GAAI,EAAO,CACT,IAAM,EAAc,GAAe,CACnC,GAAI,CAAC,EAAa,OAClB,GAAS,CACT,EAAiB,EAAW,GAE/B,CACD,MACQ,KAAK,UAAU,EAAM,OAAO,MAAK,EACtC,EAAU,IAAa,CAClB,IAAa,GACf,GAAa,EAGnB,CACA,OACS,CACL,MAAO,EAAM,MAAM,MAEnB,OAAQ,EAAM,MAAM,OAChB,CAAE,GAAG,EAAM,MAAM,OAAQ,WAAY,IAAA,GAAU,CAC/C,IAAA,GACN,GACC,EAAU,IAAa,CAClB,KAAK,UAAU,EAAQ,GAAM,KAAK,UAAU,EAAQ,EACtD,GAAY,EAGhB,CAAE,KAAM,GACV,CAAA,CACA,MACQ,EAAM,MAAM,QAAQ,WACzB,GAAkB,CACjB,IAAM,EAAc,GAAe,CAC9B,KAIL,GAFiB,EAAY,SAAS,EAAM,QAEvC,CAWH,GAAI,CAEF,EAAY,kBACV,EAAM,QACN,aACA,EACF,CAGI,IAAkB,WAAa,EAAM,QAEvC,eAAiB,CACf,EAAY,UAAU,EAAM,QAAS,EAAM,OAAM,EAChD,EAAC,OAEC,EAAO,CACd,QAAQ,MAAM,IAAI,EAAM,QAAQ,8BAA+B,EAAK,MAzBtE,GAAI,CACG,EAAY,UAAU,EAAM,SAAQ,EACvC,EAAY,UAAU,EAAM,SAAU,EAAM,OAAM,CAEpD,EAAY,SAAS,EAAM,MAAO,EAAM,OAAM,OACvC,EAAO,CACd,QAAQ,MAAM,IAAI,EAAM,QAAQ,uBAAwB,EAAK,GAuBnE,CAAE,UAAW,GACf,CAAA,CACA,MACQ,EAAM,OACX,GAAc,CACb,IAAM,EAAc,GAAe,CAC/B,MAAC,GAAe,CAAC,EAAY,SAAS,EAAM,QAAO,GAGnD,EAAM,MAAM,QAAQ,aAAe,UACrC,GAAI,CACF,EAAY,UAAU,EAAM,QAAS,EAAS,OACvC,EAAO,CACd,QAAQ,MACN,iCAAiC,EAAM,QAAQ,GAC/C,EACF,GAIR,CACA,MACQ,EAAM,MAAM,QAAQ,WACzB,GAAkB,CACjB,IAAM,EAAc,GAAe,CAC9B,KAIL,GAFiB,EAAY,SAAS,EAAM,QAEvC,CAYH,GAAI,CACF,EAAY,kBACV,EAAM,QACN,aACA,EACF,OACO,EAAO,CACd,QAAQ,MAAM,IAAI,EAAM,QAAQ,8BAA+B,EAAK,MAjBtE,GAAI,CACG,EAAY,UAAU,EAAM,SAAQ,EACvC,EAAY,UAAU,EAAM,SAAU,EAAM,OAAM,CAEpD,EAAY,SAAS,EAAM,MAAO,EAAM,OAAM,OACvC,EAAO,CACd,QAAQ,MAAM,IAAI,EAAM,QAAQ,uBAAwB,EAAK,GAenE,CAAE,UAAW,GACf,CAAA,CACA,MAAgB,CACM,MACf,CAGL,GAAI,CACF,GAAS,OACF,EAAO,CACd,QAAQ,MAAM,IAAI,EAAM,QAAQ,2BAA4B,EAAK,GAEpE,QAID,EAAa,EAAA,OAAA,UAAA,gUC5Rb,IAAM,EAAQ,EA2BR,EAAM,EAAa,EAAM,CACzB,EAAuB,EAAI,GAAK,CAGhC,MACG,EAAI,OAAS,KAIhB,EAAY,GAAqB,CAChC,GAEL,EAAY,GAAG,iBAAoB,CACjC,IAAM,MAAqB,CACpB,EAAY,eAAc,CAI7B,EAAO,MAAQ,IAHf,EAAO,MAAQ,GACf,WAAW,EAAc,IAAG,GAKhC,GAAa,EACd,EAGG,MAAuB,CAC3B,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CAIF,GAHK,EAAY,UAAU,EAAM,SAAQ,EACvC,EAAY,UAAU,EAAM,SAAU,EAAM,OAAM,CAEhD,CAAC,EAAY,SAAS,EAAM,QAAO,CAAG,CACxC,IAAM,EAAY,CAChB,GAAG,EAAM,MACT,GAAI,EAAM,QACV,OAAQ,EAAM,SAChB,CACA,EAAY,SAAS,EAAW,EAAM,OAAM,QAEvC,EAAO,CACd,QAAQ,MAAM,4BAA6B,EAAK,UA8DpD,MAAY,EAAM,WA1De,CAC/B,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CACF,IAAM,EAAS,EAAY,UAAU,EAAM,SAAQ,CACnD,GAAI,EAAQ,CAEN,EAAY,SAAS,EAAM,QAAO,EACpC,EAAY,YAAY,EAAM,QAAO,CAEnC,EAAY,UAAU,EAAM,SAAQ,EACtC,EAAY,aAAa,EAAM,SAAQ,CAGzC,EAAY,UAAU,EAAM,SAAU,EAAM,OAAM,CAClD,IAAM,EAAY,CAChB,GAAG,EAAM,MACT,GAAI,EAAM,QACV,OAAQ,EAAM,SAChB,CAIA,GAHA,EAAY,SAAS,EAAW,EAAM,OAAM,CAGxC,EAAO,SAAU,CACnB,IAAM,EAAe,EAAO,UAAS,CACjC,GAEF,EAAa,MAAK,CAAE,MAAO,GAAU,CACnC,QAAQ,MAAM,uBAAwB,EAAK,EAC5C,SAIA,EAAO,CACd,QAAQ,MAAM,+BAAgC,EAAK,GAuBf,CAAE,KAAM,GAAM,CAAA,CACtD,MAAY,EAAM,UApBc,CAC9B,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CACE,EAAY,SAAS,EAAM,QAAO,GACpC,OAAO,QAAQ,EAAM,MAAM,OAAS,EAAE,CAAA,CAAE,SAAS,CAAC,EAAK,KAAW,CAChE,EAAY,iBAAiB,EAAM,QAAS,EAAK,EAAK,EACvD,CACD,OAAO,QAAQ,EAAM,MAAM,QAAU,EAAE,CAAA,CAAE,SAAS,CAAC,EAAK,KAAW,CACjE,EAAY,kBAAkB,EAAM,QAAS,EAAK,EAAK,EACxD,QAEI,EAAO,CACd,QAAQ,MAAM,8BAA+B,EAAK,GAMhB,CAAE,KAAM,GAAM,CAAA,CAGpD,EACE,EACC,GAAW,CACN,GACF,EAAS,EAAM,EAGnB,CAAE,UAAW,GACf,CAAA,CAGA,EAAM,EAAS,GAAU,CACnB,GACF,GAAS,EAEZ,CAGD,MAAgB,CACM,GAChB,EAAa,eAAc,EAC7B,GAAS,EAEZ,CAED,MAAsB,CACpB,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CACF,IAAM,EAAS,EAAY,UAAU,EAAM,SAAQ,CACnD,GAAI,GAAQ,SAAU,CACpB,IAAM,EAAe,EAAO,UAAS,CACjC,IAEF,EAAa,OAAM,CACnB,EAAa,QAAO,EAIpB,EAAY,SAAS,EAAM,QAAO,EACpC,EAAY,YAAY,EAAM,QAAO,CAEnC,EAAY,UAAU,EAAM,SAAQ,EACtC,EAAY,aAAa,EAAM,SAAQ,OAElC,EAAO,CACd,QAAQ,MAAM,iCAAkC,EAAK,GAExD,QAID,EAAa,EAAA,OAAA,UAAA,gUC5Lb,IAAM,EAAQ,EA2BR,EAAW,EAAO,EAAiB,CACzC,GAAI,CAAC,EACH,MAAU,MAAM,wBAAuB,CAGzC,IAAM,EAAS,EAA+B,CAC5C,KAAM,SACN,IAAK,aAAa,EAAM,MACxB,SAAU,IACV,SAAU,GACX,CAAA,QACD,EAAU,SAAY,CACpB,IAAM,EAAI,IAAI,EAAQ,EAAM,IAAG,CAC/B,EAAS,IAAI,EAAC,EAGf,aAID,EASwB,EAAA,CARrB,YAAW,EAAA,SACX,WAAU,EAAA,QACV,OAAQ,EAAA,MACR,MAAK,IAAa,EAAA,qBAIlB,OAAQ,EAAA,ijBCtBX,IAAM,EAAQ,EAoBR,EAAO,EAKP,EAAM,EAAa,EAAM,CACzB,EAAuB,EAAI,GAAK,CAGhC,EAAkB,MAAe,GAAG,EAAM,YAAY,WAAU,CAChE,EAAsB,MACpB,GAAG,EAAM,YAAY,gBAC7B,CACM,EAAqB,MACnB,GAAG,EAAM,YAAY,oBAC7B,CAGM,MACG,EAAI,OAAS,KAIhB,EAAgB,GAChB,OAAO,GAAS,SAAiB,GACjC,GAAQ,OAAO,GAAS,UAAY,SAAU,GAC5C,EAAK,OAAS,qBAAuB,aAAc,EAC9C,EAAK,SAAS,OAAS,EAG3B,GAIH,MAA+B,CACnC,IAAM,EAAc,GAAe,CAC/B,MAAC,GAAe,CAAC,EAAY,eAAc,EAI/C,GAAI,CAEF,GAAI,CAAC,EAAY,UAAU,EAAM,SAAQ,CACvC,QAAQ,IAAI,4BAA4B,EAAM,WAAU,CACxD,EAAY,UAAU,EAAM,SAAU,CACpC,GAAG,EAAM,OACT,QAAS,GACT,eAAgB,GAChB,cAAe,GAChB,CAAA,KACI,CAEL,IAAM,EAAS,EAAY,UAAU,EAAM,SAAQ,CAC/C,GAAU,YAAa,GACzB,EAAO,QAAQ,EAAM,OAAO,KAAI,CAK/B,EAAY,SAAS,EAAgB,MAAK,GAC7C,QAAQ,IAAI,0BAA0B,EAAgB,QAAO,CAC7D,EAAY,SAAS,CACnB,GAAI,EAAgB,MACpB,KAAM,SACN,OAAQ,EAAM,SACd,OAAQ,CAAC,MAAO,cAAa,CAC7B,MAAO,CACL,eAAgB,CACd,OACA,CAAC,MAAO,cAAa,CACrB,EAAM,aAAa,OAAQ,GAC3B,EAAM,aAAa,YAAa,GAChC,EAAM,aAAa,OAAQ,GAC3B,EAAM,aAAa,YAAa,GAChC,EAAM,aAAa,OAAQ,GAC7B,CACA,gBAAiB,CACf,OACA,CAAC,MAAO,cAAa,CACrB,EAAM,aAAa,MAAO,GAC1B,EAAM,aAAa,YAAa,GAChC,EAAM,aAAa,MAAO,GAC1B,EAAM,aAAa,YAAa,GAChC,EAAM,aAAa,MAAO,GAC5B,CACA,sBAAuB,EACvB,sBAAuB,UACvB,iBAAkB,GACpB,CACA,OAAQ,CACN,WAAY,EAAM,WAAa,UAAY,OAC7C,CAC2B,CAAA,EAI1B,EAAY,SAAS,EAAoB,MAAK,GACjD,QAAQ,IAAI,+BAA+B,EAAoB,QAAO,CACtE,EAAY,SAAS,CACnB,GAAI,EAAoB,MACxB,KAAM,SACN,OAAQ,EAAM,SACd,OAAQ,CAAC,MAAO,cAAa,CAC7B,OAAQ,CACN,aAAc,4BACd,YAAa,EAAM,UAAU,KAC7B,YAAa,EAAM,UAAU,KAC7B,WAAY,EAAM,WAAa,UAAY,OAC7C,CACA,MAAO,CACL,aAAc,EAAM,UAAU,MAChC,CAC2B,CAAA,EAI1B,EAAY,SAAS,EAAmB,MAAK,GAChD,QAAQ,IACN,oCAAoC,EAAmB,QACzD,CACA,EAAY,SAAS,CACnB,GAAI,EAAmB,MACvB,KAAM,SACN,OAAQ,EAAM,SACd,OAAQ,CAAC,IAAK,CAAC,MAAO,cAAc,CAAA,CACpC,MAAO,CACL,eAAgB,EAAM,iBAAiB,MACvC,gBAAiB,EAAM,iBAAiB,OACxC,sBAAuB,EACvB,sBAAuB,UACvB,iBAAkB,IACpB,CACA,OAAQ,CACN,WAAY,EAAM,WAAa,UAAY,OAC7C,CAC2B,CAAA,EAG/B,QAAQ,IAAI,gCAAgC,EAAM,cAAa,CAG/D,EAAiB,EAAW,OACrB,EAAO,CACd,QAAQ,MAAM,+BAAgC,EAAK,GAKjD,MAA2B,CAC/B,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CACF,IAAM,EAAS,EAAY,UAAU,EAAM,SAAQ,CAG/C,GAAU,YAAa,GACzB,QAAQ,IAAI,mBAAmB,EAAM,SAAS,YAAW,CACzD,EAAO,QAAQ,EAAM,OAAO,KAAI,CAIhC,eAAiB,CAEf,GAAiB,EAChB,IAAG,EACI,GAEV,GAAiB,OAEZ,EAAO,CACd,QAAQ,MAAM,yBAA0B,EAAK,GAK3C,EAAoB,GAA2B,CACnD,IAAM,EAAc,GAAe,CACnC,GAAI,CAAC,EAAa,OAElB,IAAM,EAAa,EAAU,UAAY,OAEzC,CACE,EAAgB,MAChB,EAAoB,MACpB,EAAmB,MACrB,CAAE,QAAS,GAAY,CACjB,EAAY,SAAS,EAAO,EAC9B,EAAY,kBAAkB,EAAS,aAAc,EAAU,EAElE,EAIG,EAAoB,GAAqB,CACxC,KAEL,GAAI,CAEF,EAAY,GACV,QACA,EAAgB,MACf,GAA0B,CACrB,EAAE,UAAY,EAAE,SAAS,OAAS,GACpC,EAAK,gBAAiB,CACpB,SAAU,EAAE,SACZ,YAAa,EAAE,OAChB,CAAA,EAGP,CAGA,EAAY,GACV,QACA,EAAmB,MAClB,GAA0B,CACrB,EAAE,UAAY,EAAE,SAAS,OAAS,GACpC,EAAK,cAAe,CAClB,SAAU,EAAE,SACZ,YAAa,EAAE,OAChB,CAAA,EAGP,CAGA,CAAC,EAAgB,MAAO,EAAmB,MAAK,CAAE,QAAS,GAAY,CACrE,EAAY,GAAG,aAAc,MAAe,CAC1C,EAAY,WAAU,CAAE,MAAM,OAAS,WACxC,CAED,EAAY,GAAG,aAAc,MAAe,CAC1C,EAAY,WAAU,CAAE,MAAM,OAAS,IACxC,EACF,OACM,EAAO,CACd,QAAQ,MAAM,iCAAkC,EAAK,GAKnD,EAAY,GAAqB,CAChC,IAEL,EAAY,GAAG,iBAAoB,CACjC,IAAM,MAAyB,CACxB,EAAY,eAAc,EAI7B,EAAO,MAAQ,GAEX,EAAa,EAAM,OAAO,KAAI,EAChC,GAAiB,GANnB,EAAO,MAAQ,GACf,WAAW,EAAkB,IAAG,GASpC,GAAiB,EAClB,CAGG,EAAY,eAAc,GAC5B,EAAO,MAAQ,GAEX,EAAa,EAAM,OAAO,KAAI,EAChC,GAAiB,WAMvB,MACQ,EAAM,OAAO,KAClB,GAAY,CAEX,GAAI,EAAa,EAAO,CAAG,CACzB,IAAM,EAAc,GAAe,CAC/B,GAAa,eAAc,GAExB,EAAY,UAAU,EAAM,SAAQ,CAIvC,GAAa,CAHb,GAAiB,IAQzB,CAAE,KAAM,GAAM,UAAW,GAC3B,CAAA,CAEA,MAAY,EAAM,WAAY,EAAgB,CAE9C,EACE,EACC,GAAW,CACN,GACF,EAAS,EAAM,EAGnB,CAAE,UAAW,GACf,CAAA,CAGA,MAAgB,CACM,GAEhB,EAAa,eAAc,EAAK,EAAa,EAAM,OAAO,KAAI,EAChE,GAAiB,EAEpB,CAED,MAAsB,CACpB,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CAEF,CAAC,EAAgB,MAAO,EAAmB,MAAK,CAAE,QAAS,GAAY,CACrE,EAAY,IAAI,QAAS,MAAe,GAAE,CAC1C,EAAY,IAAI,aAAc,MAAe,GAAE,CAC/C,EAAY,IAAI,aAAc,MAAe,GAAE,EAChD,CAGD,CACE,EAAgB,MAChB,EAAoB,MACpB,EAAmB,MACrB,CAAE,QAAS,GAAY,CACjB,EAAY,SAAS,EAAO,EAC9B,EAAY,YAAY,EAAO,EAElC,CAGG,EAAY,UAAU,EAAM,SAAQ,EACtC,EAAY,aAAa,EAAM,SAAQ,OAElC,EAAO,CACd,QAAQ,MAAM,oCAAqC,EAAK,GAE3D,QAID,EAAa,EAAA,OAAA,UAAA,2aC9Wb,IAAM,EAAQ,EAaR,EAAO,EAMP,EAAM,EAAa,EAAM,CACzB,EAAuB,EAAI,GAAK,CAEhC,EAAW,MAAe,GAAG,EAAM,GAAG,SAAQ,CAC9C,EAAU,MAAe,GAAG,EAAM,GAAG,QAAO,CAG5C,EAAc,OACoC,CACpD,KAAM,oBACN,SACE,EAAM,YAAY,QAAU,EACxB,CACE,CACE,KAAM,UACN,WAAY,EAAC,CACb,SAAU,CACR,KAAM,aACN,YAAa,EAAM,YACrB,CAEJ,CAAA,CACA,EAAC,CACT,EACF,CAGM,MACG,EAAI,OAAS,KAIhB,EAAY,GAAqB,CAChC,GAEL,EAAY,GAAG,iBAAoB,CACjC,IAAM,MAAqB,CACpB,EAAY,eAAc,CAI7B,EAAO,MAAQ,IAHf,EAAO,MAAQ,GACf,WAAW,EAAc,IAAG,GAKhC,GAAa,EACd,EAGG,MAAuB,CAC3B,IAAM,EAAc,GAAe,CAC/B,MAAC,GAAe,CAAC,EAAY,eAAc,GAG3C,IAAM,YAAY,OAAS,GAE/B,GAAI,CAUF,GARK,EAAY,UAAU,EAAS,MAAK,EACvC,EAAY,UAAU,EAAS,MAAO,CACpC,KAAM,UACN,KAAM,EAAY,MACnB,CAAA,CAIC,CAAC,EAAY,SAAS,EAAQ,MAAK,CAAG,CACxC,IAAM,EAAoC,CACxC,GAAI,EAAQ,MACZ,KAAM,OACN,OAAQ,EAAS,MACjB,OAAQ,CACN,WAAY,EAAM,QAClB,YAAa,EAAM,SACnB,WAAY,EAAM,QAAU,UAAY,OAC1C,CACA,MAAO,CACL,aAAc,EAAM,MACpB,aAAc,EAAM,MACpB,eAAgB,EAAM,QACtB,GAAI,EAAM,KAAO,GAAK,CAAE,YAAa,EAAM,KAAK,CAChD,GAAI,EAAM,WAAa,CAAE,iBAAkB,EAAM,UAAU,CAC7D,CACF,CAEA,EAAY,SAAS,EAAW,EAAM,QAAU,IAAA,GAAS,QAEpD,EAAO,CACd,QAAQ,MAAM,4BAA6B,EAAK,GAI9C,MAA2B,CAC/B,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CACF,IAAM,EAAS,EAAY,UAAU,EAAS,MAAK,CAI/C,GAAU,YAAa,EACzB,EAAO,QAAQ,EAAY,MAAK,CACvB,CAAC,GAAU,EAAM,YAAY,QAAU,GAChD,GAAS,OAEJ,EAAO,CACd,QAAQ,MAAM,+BAAgC,EAAK,GAIjD,MAA+B,CACnC,IAAM,EAAc,GAAe,CAC/B,MAAC,GAAe,CAAC,EAAY,SAAS,EAAQ,MAAK,EAEvD,GAAI,CAEF,EAAY,iBAAiB,EAAQ,MAAO,aAAc,EAAM,MAAK,CACrE,EAAY,iBAAiB,EAAQ,MAAO,aAAc,EAAM,MAAK,CACrE,EAAY,iBACV,EAAQ,MACR,eACA,EAAM,QACR,CAEI,EAAM,KAAO,GACf,EAAY,iBAAiB,EAAQ,MAAO,YAAa,EAAM,KAAI,CAEjE,EAAM,WACR,EAAY,iBACV,EAAQ,MACR,iBACA,EAAM,UACR,CAIF,EAAY,kBAAkB,EAAQ,MAAO,WAAY,EAAM,QAAO,CACtE,EAAY,kBAAkB,EAAQ,MAAO,YAAa,EAAM,SAAQ,CACxE,EAAY,kBACV,EAAQ,MACR,aACA,EAAM,QAAU,UAAY,OAC9B,OACO,EAAO,CACd,QAAQ,MAAM,oCAAqC,EAAK,GAItD,EAAoB,GAAqB,CACzC,MAAC,GAAe,CAAC,EAAM,aAE3B,GAAI,CAEF,EAAY,GAAG,QAAS,EAAQ,MAAQ,GAA0B,CAChE,EAAK,QAAS,CACZ,YAAa,EAAE,OAChB,CAAA,EACF,CAGD,EAAY,GAAG,aAAc,EAAQ,UAAa,CAChD,EAAY,WAAU,CAAE,MAAM,OAAS,UACvC,EAAK,aAAY,EAClB,CAED,EAAY,GAAG,aAAc,EAAQ,UAAa,CAChD,EAAY,WAAU,CAAE,MAAM,OAAS,GACvC,EAAK,aAAY,EAClB,OACM,EAAO,CACd,QAAQ,MAAM,uCAAwC,EAAK,UAK/D,MACQ,EAAM,gBACN,CACJ,IAAM,EAAc,GAAe,CAC/B,GAAa,eAAc,GACxB,EAAY,UAAU,EAAS,MAAK,CAGvC,GAAa,CAFb,GAAS,GAMf,CAAE,KAAM,GACV,CAAA,CAGA,MACQ,CACJ,EAAM,MACN,EAAM,MACN,EAAM,QACN,EAAM,QACN,EAAM,SACN,EAAM,QACN,EAAM,KACN,EAAM,UACR,KACM,GAAiB,CACvB,CAAE,KAAM,GACV,CAAA,CAGA,EACE,EACC,GAAW,CACN,IACF,EAAS,EAAM,CACX,EAAO,eAAc,GACvB,EAAO,MAAQ,MAIrB,CAAE,UAAW,GACf,CAAA,CAGA,EAAM,EAAS,GAAU,CACvB,GAAI,GAAS,EAAM,YAAY,QAAU,EAAG,CAC1C,IAAM,EAAc,GAAe,CAC/B,IACF,GAAS,CACT,EAAiB,EAAW,IAGjC,CAGD,MAAgB,CACd,GAAI,CACF,IAAM,EAAc,GAAe,CAC/B,GAAa,eAAc,EAAK,EAAM,YAAY,QAAU,IAC9D,GAAS,CACT,EAAiB,EAAW,QAEvB,EAAO,CACd,QAAQ,MAAM,8BAA+B,EAAK,GAErD,CAED,MAAsB,CACpB,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CACE,EAAY,SAAS,EAAQ,MAAK,EACpC,EAAY,YAAY,EAAQ,MAAK,CAEnC,EAAY,UAAU,EAAS,MAAK,EACtC,EAAY,aAAa,EAAS,MAAK,OAElC,EAAO,CACd,QAAQ,MAAM,iCAAkC,EAAK,GAExD,QAID,EAAa,EAAA,OAAA,UAAA,wYCtQb,IAAM,EAAQ,EAWR,EAAO,EAMP,EAAM,EAAa,EAAM,CACzB,EAAuB,EAAI,GAAK,CAChC,EAAc,EAAI,GAAK,CAEvB,EAAW,MAAe,GAAG,EAAM,GAAG,SAAQ,CAC9C,EAAc,MAAe,GAAG,EAAM,GAAG,OAAM,CAC/C,EAAc,MAAe,GAAG,EAAM,GAAG,OAAM,CAO/C,EAAgB,MAChB,CAAC,EAAM,MAAQ,CAAC,EAAM,KAAK,UAAY,EAAM,KAAK,SAAS,SAAW,EACjE,KAMF,CACL,KAAM,oBACN,UANe,EAAM,aACnB,CAAC,GAAG,EAAM,KAAK,SAAQ,CAAE,SAAQ,CACjC,EAAM,KAAK,UAIM,IAAK,IAAO,CAC7B,GAAG,EACH,WAAY,CACV,GAAG,EAAE,WAEL,UAAW,EAAE,WAAW,MAAM,WAAW,IAAG,CACxC,EAAE,WAAW,MACb,IAAI,EAAE,WAAW,QACvB,CACF,EAAE,CACJ,CACD,CAGK,MACG,EAAI,OAAS,KAIhB,EAAY,GAAqB,CAChC,GAEL,EAAY,GAAG,iBAAoB,CACjC,IAAM,MAAqB,CACpB,EAAY,eAAc,CAI7B,EAAO,MAAQ,IAHf,EAAO,MAAQ,GACf,WAAW,EAAc,IAAG,GAKhC,GAAa,EACd,EAGG,MAAwB,CAC5B,IAAM,EAAc,GAAe,CACnC,GAAI,CAAC,GAAe,CAAC,EAAY,eAAc,CAAG,OAElD,IAAM,EAAO,EAAc,MACtB,KAEL,GAAI,CAUF,GARK,EAAY,UAAU,EAAS,MAAK,EACvC,EAAY,UAAU,EAAS,MAAO,CACpC,KAAM,UACN,OACD,CAAA,CAIC,CAAC,EAAY,SAAS,EAAY,MAAK,CAAG,CAC5C,IAAM,EAAwC,CAC5C,GAAI,EAAY,MAChB,KAAM,OACN,OAAQ,EAAS,MACjB,OAAQ,CACN,WAAY,EAAM,QAAU,UAAY,OAC1C,CACA,MAAO,CACL,aAAc,CAAC,MAAO,YAAW,CACjC,eAAgB,EAAM,YACxB,CACF,CAEA,EAAY,SAAS,EAAe,EAAM,QAAU,IAAA,GAAS,CAI/D,GAAI,CAAC,EAAY,SAAS,EAAY,MAAK,CAAG,CAC5C,IAAM,EAAwC,CAC5C,GAAI,EAAY,MAChB,KAAM,OACN,OAAQ,EAAS,MACjB,OAAQ,CACN,WAAY,EAAM,QAAU,UAAY,OAC1C,CACA,MAAO,CACL,aAAc,CAAC,MAAO,YAAW,CACjC,aAAc,EAAM,UACpB,eAAgB,EAAM,YACxB,CACF,CAEA,EAAY,SAAS,EAAe,EAAM,QAAU,IAAA,GAAS,QAExD,EAAO,CACd,QAAQ,MAAM,iCAAkC,EAAK,GAInD,MAA2B,CAC/B,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CACF,IAAM,EAAS,EAAY,UAAU,EAAS,MAAK,CAI7C,EAAO,EAAc,MAEvB,GAAU,YAAa,EACrB,GACF,EAAO,QAAQ,EAAI,CAEZ,CAAC,GAAU,GACpB,GAAU,OAEL,EAAO,CACd,QAAQ,MAAM,mCAAoC,EAAK,GAIrD,MAA+B,CACnC,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CAEE,EAAY,SAAS,EAAY,MAAK,GACxC,EAAY,iBACV,EAAY,MACZ,eACA,EAAM,YACR,CACA,EAAY,kBACV,EAAY,MACZ,aACA,EAAM,QAAU,UAAY,OAC9B,EAIE,EAAY,SAAS,EAAY,MAAK,GACxC,EAAY,iBACV,EAAY,MACZ,aACA,EAAM,UACR,CACA,EAAY,iBACV,EAAY,MACZ,eACA,EAAM,YACR,CACA,EAAY,kBACV,EAAY,MACZ,aACA,EAAM,QAAU,UAAY,OAC9B,QAEK,EAAO,CACd,QAAQ,MAAM,wCAAyC,EAAK,GAI1D,EAAoB,GAAqB,CACzC,MAAC,GAAe,CAAC,EAAM,aAE3B,GAAI,CAEF,EAAY,GAAG,QAAS,EAAY,MAAQ,GAA0B,CAChE,EAAE,UAAY,EAAE,SAAS,OAAS,GACpC,EAAK,QAAS,CACZ,QAAS,EAAE,SAAS,GACpB,YAAa,EAAE,OAChB,CAAA,EAEJ,CAGD,EAAY,GACV,aACA,EAAY,MACX,GAA0B,CACzB,EAAY,WAAU,CAAE,MAAM,OAAS,UACnC,EAAE,UAAY,EAAE,SAAS,OAAS,GACpC,EAAK,aAAc,EAAE,SAAS,GAAiC,EAGrE,CAEA,EAAY,GAAG,aAAc,EAAY,UAAa,CACpD,EAAY,WAAU,CAAE,MAAM,OAAS,GACvC,EAAK,aAAY,EAClB,OACM,EAAO,CACd,QAAQ,MAAM,2CAA4C,EAAK,GAK7D,EAAmB,SAAY,CACnC,GAAI,EAAY,MAAO,OAEvB,IAAM,EAAc,GAAe,CAC/B,CAAC,GAAe,CAAC,EAAY,eAAc,EAC1C,EAAc,QAGnB,MAAM,GAAS,CAGX,GAAY,QAEhB,GAAU,CACV,EAAiB,EAAW,CAC5B,EAAY,MAAQ,aAItB,MACQ,EAAM,SACN,CACJ,IAAM,EAAc,GAAe,CAC/B,GAAa,eAAc,GACxB,EAAY,UAAU,EAAS,MAAK,CAGvC,GAAa,CAFb,GAAU,GAMhB,CAAE,KAAM,GACV,CAAA,CAGA,MACQ,CACJ,EAAM,YACN,EAAM,UACN,EAAM,YACN,EAAM,QACR,KACM,GAAiB,CACvB,CAAE,KAAM,GACV,CAAA,CAIA,EAAM,EAAS,GAAU,CACnB,GACF,GAAiB,EAEpB,CAGD,EACE,EACC,GAAW,CACN,IACF,EAAS,EAAM,CACX,EAAO,eAAc,GACvB,EAAO,MAAQ,GAEf,GAAiB,IAIvB,CAAE,UAAW,GACf,CAAA,CAGA,MAAgB,CAEd,MAAe,CACb,GAAiB,EAClB,EACF,CAED,MAAsB,CACpB,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CAEE,EAAY,SAAS,EAAY,MAAK,EACxC,EAAY,YAAY,EAAY,MAAK,CAEvC,EAAY,SAAS,EAAY,MAAK,EACxC,EAAY,YAAY,EAAY,MAAK,CAGvC,EAAY,UAAU,EAAS,MAAK,EACtC,EAAY,aAAa,EAAS,MAAK,OAElC,EAAO,CACd,QAAQ,MAAM,qCAAsC,EAAK,GAE5D,QAID,EAAa,EAAA,OAAA,UAAA,IC5YF,GAA0B,MACrC,OAAO,yBAAa,KAAM,GAAM,EAAE,aAAa,CAChD,CAEY,GAAqC,MAChD,OAAO,6BAAiB,KAAM,GAAM,EAAE,wBAAwB,CAC/D,CACY,GAA6B,MACxC,OAAO,qBAAS,KAAM,GAAM,EAAE,gBAAgB,CAC/C,CACY,GAAiC,MAC5C,OAAO,yBAAa,KAAM,GAAM,EAAE,oBAAoB,CACvD,CACY,GAA8B,MACzC,OAAO,sBAAU,KAAM,GAAM,EAAE,iBAAiB,CACjD,CACY,GAA8B,MACzC,OAAO,sBAAU,KAAM,GAAM,EAAE,iBAAiB,CACjD,CACY,GAAiC,MAC5C,OAAO,yBAAa,KAAM,GAAM,EAAE,oBAAoB,CACvD,CACY,GAAsC,MACjD,OAAO,+BAAmB,KAAM,GAAM,EAAE,yBAAyB,CAClE,CACY,GAA8B,MACzC,OAAO,sBAAU,KAAM,GAAM,EAAE,iBAAiB,CACjD,CACY,GAA8B,MACzC,OAAO,sBAAU,KAAM,GAAM,EAAE,iBAAiB,CACjD,CACY,GAAgC,MAC3C,OAAO,wBAAY,KAAM,GAAM,EAAE,mBAAmB,CACrD,CACY,GAAgC,MAC3C,OAAO,wBAAY,KAAM,GAAM,EAAE,mBAAmB,CACrD,CACY,GAAkC,MAC7C,OAAO,2BAAe,KAAM,GAAM,EAAE,qBAAqB,CAC1D,CACY,GAAoC,MAC/C,OAAO,6BAAiB,KAAM,GAAM,EAAE,uBAAuB,CAC9D,CAEY,GAAiC,MAC5C,OAAO,yBAAa,KAAM,GAAM,EAAE,oBAAoB,CACvD,CACY,GAAiC,MAC5C,OAAO,yBAAa,KAAM,GAAM,EAAE,oBAAoB,CACvD,CACY,GAA8B,MACzC,OAAO,sBAAU,KAAM,GAAM,EAAE,iBAAiB,CACjD,CACY,GAAiC,MAC5C,OAAO,yBAAa,KAAM,GAAM,EAAE,oBAAoB,CACvD,CACY,GAAoC,MAC/C,OAAO,6BAAiB,KAAM,GAAM,EAAE,uBAAuB,CAC9D,CAEY,GAA+B,MAC1C,OAAO,uBAAW,KAAM,GAAM,EAAE,kBAAkB,CACnD,CACY,GAAmC,MAC9C,OAAO,4BAAgB,KAAM,GAAM,EAAE,sBAAsB,CAC5D,CACY,GAAmC,MAC9C,OAAO,4BAAgB,KAAM,GAAM,EAAE,sBAAsB,CAC5D,CACY,GAA6B,MACxC,OAAO,qBAAS,KAAM,GAAM,EAAE,gBAAgB,CAC/C,CACY,GAA8B,MACzC,OAAO,sBAAU,KAAM,GAAM,EAAE,iBAAiB,CACjD,CACY,GAAgC,MAC3C,OAAO,yBAAa,KAAM,GAAM,EAAE,mBAAmB,CACtD,CACY,GAAiC,MAC5C,OAAO,yBAAa,KAAM,GAAM,EAAE,oBAAoB,CACvD,CACY,GAAqC,MAChD,OAAO,8BAAkB,KAAM,GAAM,EAAE,wBAAwB,CAChE,CACY,GAA4B,MACvC,OAAO,oBAAQ,KAAM,GAAM,EAAE,eAAe,CAC7C,CACY,GAAiC,MAC5C,OAAO,yBAAa,KAAM,GAAM,EAAE,oBAAoB,CACvD,CACY,GAAiC,MAC5C,OAAO,yBAAa,KAAM,GAAM,EAAE,oBAAoB,CACvD,CACY,GAA6B,MACxC,OAAO,qBAAS,KAAM,GAAM,EAAE,gBAAgB,CAC/C,CAEY,GAAoC,MAC/C,OAAO,6BAAiB,KAAM,GAAM,EAAE,uBAAuB,CAC9D,CACY,GAAoC,MAC/C,OAAO,4BAAgB,KAAM,GAAM,EAAE,uBAAuB,CAC7D,CAEY,GAA6B,MACxC,OAAO,qBAAS,KAAM,GAAM,EAAE,gBAAgB,CAC/C,CACY,GAAgC,MAC3C,OAAO,wBAAY,KAAM,GAAM,EAAE,mBAAmB,CACrD,CAEY,GAAkC,MAC7C,OAAO,2BAAe,KAAM,GAAM,EAAE,qBAAqB,CAC1D,CAEY,GAA8B,MACzC,OAAO,sBAAU,KAAM,GAAM,EAAE,iBAAiB,CACjD,CAEY,GAA6C,MAEtD,OAAO,sCAA0B,KAC9B,GAAM,EAAE,gCACV,CACJ,CACY,GAAsC,MACjD,OAAO,+BAAmB,KAAM,GAAM,EAAE,yBAAyB,CAClE,CACY,GAAyC,MACpD,OAAO,kCAAsB,KAAM,GAAM,EAAE,4BAA4B,CACxE,CACY,GAA8C,MAEvD,OAAO,wCAA4B,KAChC,GAAM,EAAE,iCACV,CACJ,CACY,GAAsC,MACjD,OAAO,+BAAmB,KAAM,GAAM,EAAE,yBAAyB,CAClE,CACY,GAAuC,MAClD,OAAO,gCAAoB,KAAM,GAAM,EAAE,0BAA0B,CACpE,CAEY,GAAsC,MACjD,OAAO,+BAAmB,KAAM,GAAM,EAAE,yBAAyB,CAClE,CCvIY,GAAqC,MAChD,OAAO,2BAA+B,KAAM,GAAM,EAAE,eAAe,CACpE,qPCLC,IAAM,EAAQ,EAUR,EAAO,EAEb,GAAI,EAAM,eAAgB,CACxB,IAAM,EAAW,IAAI,EAAS,CAAE,SAAU,GAAM,CAAA,CAChD,EAAW,YAAY,UAAW,EAAS,KAAI,CAC/C,EAAQ,EAAmB,EAAQ,CAGrC,IAAM,EAAuB,EAAW,KAAI,CACtC,EAAuB,EAAI,GAAK,CAChC,EAAyC,EAAI,EAAS,CAG5D,EAAQ,EAAQ,EAAG,CAInB,EAAe,EAAG,CAElB,MAAgB,CACd,EAAI,MAAQ,IAAI,EAAI,EAAM,QAAO,CACjC,EAAO,MAAQ,GACf,GAAgB,EACjB,CAED,IAAM,MAAwB,CACvB,EAAI,OAET,EAAO,MAAM,QAAS,GAAM,CAC1B,EAAI,OAAO,GAAG,EAAI,GAAQ,CACxB,OAAQ,EAAR,CACE,IAAK,OACH,EAAK,SAAU,EAAI,MAAK,CACxB,MACF,QACE,EAAK,EAAG,EAAG,CACX,QAEL,EACF,oBAKH,EAIM,MAAA,CAJA,GAAE,GAAK,EAAA,SAAS,YAAa,MAAM,oBAC3B,EAAA,MAAZ,EAEO,EAAA,OAAA,UAAA,CAAA,IAAA,EAAA,KAAA,CADL,EAAa,EAAA,OAAA,UAAA,EAAA,CAAA,IAAA,GAAA,GAAA,CAAA,CAAA,GAAA,CAAA,EAAA,OAAA,GAAA,CAAA,CAAA,EAAA,GAAA,qOC1DjB,IAAM,EAAQ,EAaR,EAAO,EAKP,EAAM,EAAa,EAAM,CACzB,EAAQ,IAAI,EAAM,EAAM,QAAO,CAC/B,EAAuB,EAAI,GAAI,CAC/B,EAAU,EAAwB,KAAI,CAGtC,MACG,EAAI,OAAS,KAIhB,EAAY,GAAqB,CAChC,GAEL,EAAY,GAAG,iBAAoB,CACjC,IAAM,MAAqB,CACpB,EAAY,eAAc,CAI7B,EAAO,MAAQ,IAHf,EAAO,MAAQ,GACf,WAAW,EAAc,IAAG,GAKhC,GAAa,EACd,EAGG,MAA8B,CAClC,GAAI,CACE,EAAQ,OACV,EAAM,cAAc,EAAQ,MAAK,OAE5B,EAAO,CACd,QAAQ,MAAM,+BAAgC,EAAK,GAIjD,MAAkC,CACtC,GAAI,CACF,EAAM,UAAU,EAAM,YAAW,OAC1B,EAAO,CACd,QAAQ,MAAM,mCAAoC,EAAK,GAIrD,MAA0B,CAC9B,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CACE,aAAc,EAAM,OACtB,EAAM,OAAO,SAAS,EAAK,CAE3B,EAAM,MAAM,EAAW,CAEzB,EAAK,QAAS,CAAE,QAAO,CAAA,OAChB,EAAO,CACd,QAAQ,MAAM,gCAAiC,EAAK,GAIlD,MAAqB,CACzB,GAAI,CACF,EAAM,QAAO,CACb,EAAK,UAAS,OACP,EAAO,CACd,QAAQ,MAAM,wBAAyB,EAAK,GAI1C,MAAgC,CACpC,GAAI,CACF,EAAY,QAAS,GAAU,CAC7B,EAAM,GAAG,MAAa,CACpB,EAAK,EAAK,EACX,EACF,OACM,EAAO,CACd,QAAQ,MAAM,iCAAkC,EAAK,GAInD,MAAgC,CACpC,GAAI,CACF,EAAY,QAAS,GAAU,CAC7B,EAAM,IAAI,MAAa,CACrB,EAAK,EAAK,EACX,EACF,OACM,EAAO,CACd,QAAQ,MAAM,+BAAgC,EAAK,UAKvD,EACE,EACC,GAAW,CACN,GACF,EAAS,EAAM,EAGnB,CAAE,UAAW,GACf,CAAA,CAGA,MACQ,EAAM,gBACN,CACJ,GAAoB,EAEtB,CAAE,KAAM,GACV,CAAA,CAGA,MAAgB,CACd,GAAI,EAAO,MACT,GAAI,CACF,GAAgB,CAChB,GAAoB,CACpB,GAAY,CACZ,GAAkB,OACX,EAAO,CACd,QAAQ,MAAM,4BAA6B,EAAK,MAGlD,GAAO,CACP,GAAkB,EAErB,CAED,MAAsB,CACpB,GAAO,CACP,GAAkB,EACnB,aAID,EAEU,UAAA,CAFA,GAAE,SAAW,KAAK,KAAG,WAAU,UAAJ,IAAI,IACvC,EAAa,EAAA,OAAA,UAAA,CAAA,CAAA,EAAA,GAAA,8NCvJf,IAAM,EAAQ,GAAS,CAEjB,EAAQ,EAcR,EAAO,EAQP,EAAM,EAAa,EAAM,CACzB,EAA6B,EAAI,KAAI,CACrC,EAAS,EAAI,GAAI,CACjB,EAAoB,EAAI,GAAK,CAC7B,EAAU,EAAwB,KAAI,CAGtC,MACG,EAAI,OAAS,KAIhB,EAAY,GAAqB,CAChC,GAEL,EAAY,GAAG,iBAAoB,CACjC,IAAM,MAAqB,CACpB,EAAY,eAAc,CAI7B,EAAO,MAAQ,IAHf,EAAO,MAAQ,GACf,WAAW,EAAc,IAAG,GAKhC,GAAa,EACd,EAGG,EAAc,GAAqC,CACnD,aAAc,cAChB,EAAQ,MAAQ,IAId,EAAwB,GAAiC,CAC7D,GAAI,CACF,EAAe,UAAU,EAAM,YAAW,OACnC,EAAO,CACd,QAAQ,MAAM,oCAAqC,EAAK,GAItD,EAAoB,GAAiC,CACzD,GAAI,CACF,EAAe,YAAW,CAAE,MAAM,OAAS,EAAM,QAAU,gBACpD,EAAO,CACd,QAAQ,MAAM,wBAAyB,EAAK,GAI1C,EAAY,GAAiC,CACjD,IAAM,EAAc,GAAe,CAC9B,KAEL,GAAI,CACF,EAAe,MAAM,EAAW,CAChC,EAAK,QAAS,CAAE,OAAQ,EAAgB,CAAA,OACjC,EAAO,CACd,QAAQ,MAAM,8BAA+B,EAAK,GAIhD,EAAiB,GAAiC,CACtD,GAAI,CACF,EAAe,QAAO,CACtB,EAAK,UAAS,OACP,EAAO,CACd,QAAQ,MAAM,kCAAmC,EAAK,GAIpD,EAAsB,GAAiC,CAC3D,GAAI,CACF,IAAI,EACJ,EAAgB,QAAS,GAAkB,CACzC,EAAe,GAAG,EAAQ,GAA0B,CAC9C,IAAU,YACZ,AAME,EANE,MAAM,QAAQ,EAAM,YAAW,CACnB,CACZ,EAAE,OAAO,WAAU,CAAE,IACrB,EAAE,OAAO,WAAU,CAAE,IACvB,CAEc,EAAE,OAAO,WAAU,CAEnC,EAAK,qBAAsB,EAAW,EAExC,EAAK,EAAO,EAAC,EACd,EACF,CAED,EAAgB,QAAS,GAAkB,CACzC,EAAe,YAAW,CAAE,iBAAiB,EAAQ,GAAM,CACzD,EAAK,EAAO,EAAC,EACd,EACF,OACM,EAAO,CACd,QAAQ,MAAM,kCAAmC,EAAK,GAK1D,EAAM,EAAS,GAAgB,CAC7B,EAAkB,MAAQ,IAAgB,MAAQ,SAAU,GAC7D,CAGD,EACE,EACC,GAAW,CACN,GACF,EAAS,EAAM,EAGnB,CAAE,UAAW,GACf,CAAA,CAEA,IAAM,EAAc,GAA0B,CACxC,MAAC,EAAO,OAAS,EAAO,OAE5B,GAAI,CAKF,EAAO,MAAQ,IAAI,EAAO,CAHxB,GAAG,EAAM,QACT,QAAS,GAAW,IAAA,GAEiB,CAAA,CACvC,EAAqB,EAAO,MAAK,CACjC,EAAS,EAAO,MAAK,CACrB,EAAiB,EAAO,MAAK,CAC7B,EAAmB,EAAO,MAAK,OACxB,EAAO,CACd,QAAQ,MAAM,6BAA8B,EAAK,UAIrD,EAAM,EAAU,GAAO,CACjB,GAAM,CAAC,EAAO,OAChB,EAAW,EAAE,EAEhB,CAED,MAAgB,CACa,EAAM,SAE/B,GAAW,EAEd,CAED,MAAsB,CAChB,EAAO,OACT,EAAc,EAAO,MAAK,EAE7B,aAID,EAWU,UAAA,CAXA,GAAE,UAAY,KAAK,KAAG,GAAM,MAAM,aAC1C,EAAkD,EAAA,OAAA,UAAA,CAA3C,OAAS,EAAU,CAAA,CACV,EAAA,OAAqBA,EAAAA,OAAO,SAAA,GAAA,CAC1C,EAMU,GAAA,OALP,OAAQ,EAAA,MACR,QAAS,EAAA,aACT,YAAa,EAAA,4BAED,CAAb,EAAa,EAAA,OAAA,UAAA,CAAA,CAAA,qECrHrB,IAAA,GAAeC"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["$slots","VMap"],"sources":["../src/controls/attribution/VControlAttribution.vue","../src/controls/fullscreen/VControlFullscreen.vue","../src/controls/geolocate/events.ts","../src/controls/geolocate/VControlGeolocate.vue","../src/controls/navigation/VControlNavigation.vue","../src/controls/scale/VControlScale.vue","../src/controls/_shared/useMapControl.ts","../src/controls/layer/VControlLayer.vue","../src/controls/layer/VControlLayerGroup.vue","../src/controls/legend/VControlLegend.vue","../src/layers/maplibre/canvas/VLayerMaplibreCanvas.vue","../src/layers/maplibre/geojson/VLayerMaplibreGeojson.vue","../src/layers/maplibre/image/VLayerMaplibreImage.vue","../src/layers/maplibre/raster/VLayerMaplibreRaster.vue","../src/constants/events/layer.ts","../src/constants/events/map.ts","../src/constants/events/marker.ts","../src/constants/events/popup.ts","../src/layers/maplibre/vector/VLayerMaplibreVector.vue","../src/layers/maplibre/video/VLayerMaplibreVideo.vue","../src/layers/maplibre/pmtile/VLayerMaplibrePmtile.vue","../src/layers/maplibre/custom/cluster/VLayerMaplibreCluster.vue","../src/layers/maplibre/custom/route/VLayerMaplibreRoute.vue","../src/layers/maplibre/custom/isochrone/VLayerMaplibreIsochrone.vue","../src/map/VMap.vue","../src/popups/VPopup.vue","../src/markers/VMarker.vue","../src/index.ts"],"sourcesContent":["<script setup lang=\"ts\">\n import { AttributionControl } from 'maplibre-gl';\n import { onMounted, useSlots } from 'vue';\n import { MapKey, injectStrict } from '../../utils';\n import type { AttributionControlOptions, ControlPosition } from './types';\n\n const defaultOptions: AttributionControlOptions = {\n compact: false,\n customAttribution: undefined,\n };\n\n const props = withDefaults(\n defineProps<{\n options?: AttributionControlOptions;\n position?: ControlPosition;\n }>(),\n {\n options: undefined,\n position: 'bottom-right',\n },\n );\n\n const slots = useSlots();\n\n const map = injectStrict(MapKey);\n\n onMounted(() => {\n addControl();\n });\n\n const addControl = (): void => {\n let options = defaultOptions;\n if (props.options) {\n options = {\n ...props.options,\n };\n }\n if (slots && slots.default?.()) {\n options.customAttribution = slots.default()[0]!\n .children as unknown as string;\n }\n const control = new AttributionControl(options);\n map.value!.addControl(control, props.position);\n };\n</script>\n\n<template>\n <slot></slot>\n</template>\n","<script setup lang=\"ts\">\n import { FullscreenControl } from 'maplibre-gl';\n import { onMounted } from 'vue';\n import { MapKey, injectStrict } from '../../utils';\n import type { ControlPosition, FullscreenControlOptions } from './types';\n\n const defaultOptions: FullscreenControlOptions = {\n container: undefined,\n };\n\n const props = withDefaults(\n defineProps<{\n options?: FullscreenControlOptions;\n position?: ControlPosition;\n }>(),\n {\n options: undefined,\n position: 'top-left',\n },\n );\n\n const map = injectStrict(MapKey);\n\n onMounted(() => {\n addControl();\n });\n\n const addControl = (): void => {\n const control = new FullscreenControl(props.options || defaultOptions);\n map.value!.addControl(control, props.position);\n };\n</script>\n","export const geolocateControlEvents: string[] = [\n 'geolocate',\n 'error',\n 'outofmaxbounds',\n 'trackuserlocationstart',\n 'trackuserlocationend',\n];\n","<script setup lang=\"ts\">\n import { GeolocateControl } from 'maplibre-gl';\n import { onMounted } from 'vue';\n import { MapKey, injectStrict } from '../../utils';\n import { geolocateControlEvents as events } from './events';\n import type { ControlPosition, GeolocateControlOptions } from './types';\n\n const defaultOptions: GeolocateControlOptions = {\n fitBoundsOptions: {\n linear: false,\n offset: [0, 0],\n maxZoom: 22,\n },\n positionOptions: {\n enableHighAccuracy: true,\n maximumAge: 0,\n timeout: 6000,\n },\n trackUserLocation: true,\n showAccuracyCircle: true,\n showUserLocation: true,\n };\n\n const props = withDefaults(\n defineProps<{\n options?: GeolocateControlOptions;\n position?: ControlPosition;\n }>(),\n {\n options: undefined,\n position: 'top-left',\n },\n );\n\n const emit = defineEmits(events);\n\n const map = injectStrict(MapKey);\n\n onMounted(() => {\n addControl();\n });\n\n const addControl = (): void => {\n const control = new GeolocateControl(props.options || defaultOptions);\n map.value!.addControl(control, props.position);\n events.forEach((event: string) => {\n control.on(event, () => {\n emit(event);\n });\n });\n };\n</script>\n","<script setup lang=\"ts\">\n import { NavigationControl } from 'maplibre-gl';\n import { onMounted, inject } from 'vue';\n import { MapKey } from '../../utils';\n import type { ControlPosition, NavigationOptions } from './types';\n\n const defaultOptions: NavigationOptions = {\n showCompass: true,\n showZoom: true,\n visualizePitch: true,\n };\n\n const props = withDefaults(\n defineProps<{\n options?: NavigationOptions;\n position?: ControlPosition;\n }>(),\n {\n options: undefined,\n position: 'top-left',\n },\n );\n\n const map = inject(MapKey);\n\n onMounted(() => {\n addControl();\n });\n\n const addControl = (): void => {\n const control = new NavigationControl(props.options || defaultOptions);\n map!.value!.addControl(control, props.position);\n };\n</script>\n","<script setup lang=\"ts\">\n import { onMounted, inject } from 'vue';\n import { ScaleControl } from 'maplibre-gl';\n import { MapKey } from '../../utils';\n import type { ControlPosition, ScaleControlOptions } from './types';\n\n const defaultOptions: ScaleControlOptions = {\n maxWidth: 100,\n unit: 'metric',\n };\n\n const props = withDefaults(\n defineProps<{\n options?: ScaleControlOptions;\n position?: ControlPosition;\n }>(),\n {\n options: undefined,\n position: 'bottom-left',\n },\n );\n\n const map = inject(MapKey);\n\n onMounted(() => {\n addControl();\n });\n\n const addControl = (): void => {\n const control = new ScaleControl(props.options || defaultOptions);\n map?.value!.addControl(control, props.position);\n };\n</script>\n\n<template>\n <slot></slot>\n</template>\n","import {\n onMounted,\n onUnmounted,\n onUpdated,\n type Ref,\n type ShallowRef,\n} from 'vue';\nimport type { Map, IControl, ControlPosition } from 'maplibre-gl';\n\n/**\n * Register a Vue component as a MapLibre IControl for proper control stacking.\n *\n * @param map - Ref to the MapLibre map instance\n * @param containerRef - Ref to the component's root HTMLElement\n * @param position - Control position ('top-left' | 'top-right' | 'bottom-left' | 'bottom-right')\n */\nexport function useMapControl(\n map: ShallowRef<Map | null> | Ref<Map | null>,\n containerRef: Ref<HTMLElement | null>,\n position: ControlPosition,\n): void {\n let control: IControl | null = null;\n let isAdded = false;\n\n /**\n * Re-add the maplibregl-ctrl class if Vue's :class reconciliation removed it.\n * Vue overwrites the class attribute when dynamic :class bindings update,\n * which drops imperatively-added classes like maplibregl-ctrl.\n */\n const ensureControlClass = () => {\n if (\n isAdded &&\n containerRef.value &&\n !containerRef.value.classList.contains('maplibregl-ctrl')\n ) {\n containerRef.value.classList.add('maplibregl-ctrl');\n }\n };\n\n onMounted(() => {\n if (!map.value || !containerRef.value) return;\n\n control = {\n onAdd: (): HTMLElement => {\n containerRef.value?.classList.add('maplibregl-ctrl');\n return containerRef.value!;\n },\n onRemove: (): void => {},\n };\n\n map.value.addControl(control, position);\n isAdded = true;\n });\n\n onUpdated(() => {\n ensureControlClass();\n });\n\n onUnmounted(() => {\n if (map.value && control) {\n try {\n map.value.removeControl(control);\n } catch {\n // Control may already be removed if map was destroyed\n }\n }\n });\n}\n","<script setup lang=\"ts\">\n import { ref, watch, inject, onMounted } from 'vue';\n import { MapKey, injectStrict } from '../../utils';\n import { DeckLayersKey } from '../../layers/deckgl/_shared/useDeckOverlay';\n import { useMapControl } from '../_shared';\n import type { ControlPosition, LayerType } from './types';\n\n const props = withDefaults(\n defineProps<{\n layerId: string;\n position?: ControlPosition;\n visible?: boolean;\n opacity?: number;\n title?: string;\n layerType?: LayerType;\n }>(),\n {\n position: 'top-right',\n visible: true,\n opacity: 1,\n title: 'Layer Control',\n layerType: undefined,\n },\n );\n\n const emit = defineEmits<{\n 'visibility-change': [visible: boolean];\n 'opacity-change': [opacity: number];\n 'update:visible': [visible: boolean];\n 'update:opacity': [opacity: number];\n }>();\n\n const map = injectStrict(MapKey);\n const deckLayers = inject(DeckLayersKey, null);\n const containerRef = ref<HTMLElement | null>(null);\n const isVisible = ref(props.visible);\n const currentOpacity = ref(props.opacity);\n\n useMapControl(map, containerRef, props.position);\n\n // Function to detect layer type (called fresh each time, not cached)\n const getLayerType = (): LayerType | null => {\n if (props.layerType) return props.layerType;\n if (!map.value) return null;\n const maplibreLayer = map.value.getLayer(props.layerId);\n if (maplibreLayer) return 'maplibre';\n if (deckLayers) {\n const layers = deckLayers.getLayers();\n const deckLayer = (layers as Array<{ id: string }>).find(\n (l) => l.id === props.layerId,\n );\n if (deckLayer) return 'deckgl';\n }\n return null;\n };\n\n const getOpacityProperty = (): string | null => {\n if (!map.value || getLayerType() !== 'maplibre') return null;\n\n const layer = map.value.getLayer(props.layerId);\n if (!layer) return null;\n\n switch (layer.type) {\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 return 'icon-opacity';\n default:\n return null;\n }\n };\n\n const updateVisibility = (visible: boolean) => {\n const layerType = getLayerType();\n\n if (layerType === 'maplibre') {\n if (!map.value) return;\n const layer = map.value.getLayer(props.layerId);\n if (!layer) {\n console.warn(`MapLibre layer not found: ${props.layerId}`);\n return;\n }\n map.value.setLayoutProperty(\n props.layerId,\n 'visibility',\n visible ? 'visible' : 'none',\n );\n } else if (layerType === 'deckgl') {\n if (!deckLayers) {\n console.warn(\n `deck.gl overlay not available for layer: ${props.layerId}`,\n );\n return;\n }\n const layers = deckLayers.getLayers();\n const existingLayer = (\n layers as Array<{ id: string; clone?: (props: object) => unknown }>\n ).find((l) => l.id === props.layerId);\n if (!existingLayer) {\n console.warn(`deck.gl layer not found: ${props.layerId}`);\n return;\n }\n if (typeof existingLayer.clone === 'function') {\n const updatedLayer = existingLayer.clone({ visible });\n deckLayers.updateLayer(props.layerId, updatedLayer);\n }\n } else {\n console.warn(`Layer not found in MapLibre or deck.gl: ${props.layerId}`);\n return;\n }\n\n emit('visibility-change', visible);\n emit('update:visible', visible);\n };\n\n const updateOpacity = (opacity: number) => {\n const layerType = getLayerType();\n\n if (layerType === 'maplibre') {\n const opacityProp = getOpacityProperty();\n if (!map.value || !opacityProp) return;\n const layer = map.value.getLayer(props.layerId);\n if (!layer) {\n console.warn(`MapLibre layer not found: ${props.layerId}`);\n return;\n }\n map.value.setPaintProperty(props.layerId, opacityProp, opacity);\n } else if (layerType === 'deckgl') {\n if (!deckLayers) {\n console.warn(\n `deck.gl overlay not available for layer: ${props.layerId}`,\n );\n return;\n }\n const layers = deckLayers.getLayers();\n const existingLayer = (\n layers as Array<{ id: string; clone?: (props: object) => unknown }>\n ).find((l) => l.id === props.layerId);\n if (!existingLayer) {\n console.warn(`deck.gl layer not found: ${props.layerId}`);\n return;\n }\n if (typeof existingLayer.clone === 'function') {\n const updatedLayer = existingLayer.clone({ opacity });\n deckLayers.updateLayer(props.layerId, updatedLayer);\n }\n } else {\n console.warn(`Layer not found in MapLibre or deck.gl: ${props.layerId}`);\n return;\n }\n\n emit('opacity-change', opacity);\n emit('update:opacity', opacity);\n };\n\n const toggleVisibility = () => {\n isVisible.value = !isVisible.value;\n };\n\n const handleOpacityInput = (event: Event) => {\n const target = event.target as HTMLInputElement;\n currentOpacity.value = Number(target.value) / 100;\n };\n\n watch(isVisible, (newValue) => {\n updateVisibility(newValue);\n });\n\n watch(currentOpacity, (newValue) => {\n updateOpacity(newValue);\n });\n\n watch(\n () => props.visible,\n (newValue) => {\n isVisible.value = newValue;\n },\n );\n\n watch(\n () => props.opacity,\n (newValue) => {\n currentOpacity.value = newValue;\n },\n );\n\n // Wait for layer to be available, then apply initial settings\n onMounted(() => {\n let applied = false;\n\n const checkAndApply = () => {\n if (applied) return true;\n // Use function directly to get fresh result (not cached computed)\n const layerType = getLayerType();\n if (layerType) {\n applied = true;\n updateVisibility(isVisible.value);\n updateOpacity(currentOpacity.value);\n return true;\n }\n return false;\n };\n\n // Try immediately\n if (checkAndApply()) return;\n\n // If layer not found, retry with increasing intervals\n // Total wait: ~10 seconds (enough for data fetching)\n const delays = [100, 200, 300, 500, 500, 1000, 1000, 1000, 2000, 3000];\n let index = 0;\n\n const retry = () => {\n if (checkAndApply() || index >= delays.length) return;\n setTimeout(() => {\n index++;\n retry();\n }, delays[index]);\n };\n\n retry();\n });\n</script>\n\n<template>\n <div ref=\"containerRef\" class=\"v-layer-control\">\n <div class=\"v-layer-control-header\">\n <span class=\"v-layer-control-title\">{{ title }}</span>\n <button\n type=\"button\"\n class=\"v-layer-control-toggle\"\n :class=\"{ 'is-hidden': !isVisible }\"\n :aria-pressed=\"isVisible\"\n :title=\"isVisible ? 'Hide layer' : 'Show layer'\"\n @click=\"toggleVisibility\"\n >\n <svg\n v-if=\"isVisible\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n >\n <path\n d=\"M8 3C4.5 3 1.5 5.5 0.5 8C1.5 10.5 4.5 13 8 13C11.5 13 14.5 10.5 15.5 8C14.5 5.5 11.5 3 8 3Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <circle\n cx=\"8\"\n cy=\"8\"\n r=\"2.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n />\n </svg>\n <svg v-else width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path\n d=\"M2 2L14 14M6.5 6.5C5.9 7.1 5.5 7.9 5.5 8.8C5.5 10.4 6.9 11.5 8 11.5C8.9 11.5 9.7 11.1 10.3 10.5M8 3C4.5 3 1.5 5.5 0.5 8C1 9.2 1.8 10.3 2.8 11.2M13.2 11.2C14.2 10.3 15 9.2 15.5 8C14.5 5.5 11.5 3 8 3\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n\n <div class=\"v-layer-control-slider-row\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"100\"\n :value=\"Math.round(currentOpacity * 100)\"\n class=\"v-layer-control-slider\"\n :disabled=\"!isVisible\"\n @input=\"handleOpacityInput\"\n />\n <span class=\"v-layer-control-value\"\n >{{ Math.round(currentOpacity * 100) }}%</span\n >\n </div>\n\n <slot></slot>\n </div>\n</template>\n\n<style>\n .v-layer-control {\n min-width: 140px;\n max-width: 280px;\n margin: 10px;\n background: var(--color-card, #fff);\n border-radius: var(--radius, 0.5rem);\n border: 1px solid var(--color-border, #e5e7eb);\n box-shadow:\n 0 1px 3px 0 rgb(0 0 0 / 0.1),\n 0 1px 2px -1px rgb(0 0 0 / 0.1);\n font-family:\n ui-sans-serif,\n system-ui,\n -apple-system,\n sans-serif;\n font-size: 12px;\n overflow: hidden;\n padding: 8px 10px;\n /* Required: MapLibre control containers have pointer-events:none */\n pointer-events: auto;\n }\n\n .v-layer-control-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n margin-bottom: 8px;\n }\n\n .v-layer-control-title {\n font-weight: 500;\n font-size: 11px;\n color: var(--color-card-foreground, #111827);\n line-height: 1.2;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n min-width: 0;\n }\n\n .v-layer-control-toggle {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n padding: 0;\n border: none;\n border-radius: calc(var(--radius, 0.5rem) - 2px);\n background: transparent;\n color: var(--color-foreground, #374151);\n cursor: pointer;\n transition:\n background 0.15s ease,\n color 0.15s ease;\n flex-shrink: 0;\n }\n\n .v-layer-control-toggle svg {\n width: 14px;\n height: 14px;\n }\n\n .v-layer-control-toggle:hover {\n background: var(--color-accent, #f3f4f6);\n }\n\n .v-layer-control-toggle.is-hidden {\n color: var(--color-muted-foreground, #9ca3af);\n }\n\n .v-layer-control-toggle:focus {\n outline: none;\n }\n\n .v-layer-control-toggle:focus-visible {\n outline: 2px solid var(--color-primary, #3b82f6);\n outline-offset: -2px;\n }\n\n .v-layer-control-slider-row {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .v-layer-control-slider {\n flex: 1;\n height: 3px;\n border-radius: 2px;\n background: var(--color-secondary, #e5e7eb);\n cursor: pointer;\n -webkit-appearance: none;\n appearance: none;\n }\n\n .v-layer-control-slider:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n }\n\n .v-layer-control-value {\n font-size: 10px;\n font-weight: 500;\n color: var(--color-muted-foreground, #6b7280);\n font-variant-numeric: tabular-nums;\n min-width: 28px;\n text-align: right;\n }\n\n .v-layer-control-slider::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background: var(--color-primary, #3b82f6);\n cursor: pointer;\n border: 2px solid #fff;\n box-shadow: 0 1px 3px rgb(0 0 0 / 0.2);\n }\n\n .v-layer-control-slider::-moz-range-thumb {\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background: var(--color-primary, #3b82f6);\n cursor: pointer;\n border: 2px solid #fff;\n box-shadow: 0 1px 3px rgb(0 0 0 / 0.2);\n }\n\n .v-layer-control-slider:disabled::-webkit-slider-thumb {\n cursor: not-allowed;\n }\n\n .v-layer-control-slider:disabled::-moz-range-thumb {\n cursor: not-allowed;\n }\n\n .v-layer-control-slider:focus {\n outline: none;\n }\n\n .v-layer-control-slider:focus::-webkit-slider-thumb {\n box-shadow: 0 0 0 3px\n color-mix(in srgb, var(--color-primary, #3b82f6) 20%, transparent);\n }\n</style>\n","<script setup lang=\"ts\">\n import { ref, watch, inject, onMounted } from 'vue';\n import { MapKey, injectStrict } from '../../utils';\n import { DeckLayersKey } from '../../layers/deckgl/_shared/useDeckOverlay';\n import { useMapControl } from '../_shared';\n import type { ControlPosition, LayerType } from './types';\n\n export interface LayerConfig {\n id: string;\n title: string;\n visible?: boolean;\n opacity?: number;\n type?: LayerType;\n }\n\n const props = withDefaults(\n defineProps<{\n layers: LayerConfig[];\n position?: ControlPosition;\n title?: string;\n collapsible?: boolean;\n collapsed?: boolean;\n }>(),\n {\n position: 'top-right',\n title: 'Layers',\n collapsible: true,\n collapsed: false,\n },\n );\n\n const emit = defineEmits<{\n 'visibility-change': [data: { layerId: string; visible: boolean }];\n 'opacity-change': [data: { layerId: string; opacity: number }];\n 'update:layers': [layers: LayerConfig[]];\n }>();\n\n const map = injectStrict(MapKey);\n const deckLayers = inject(DeckLayersKey, null);\n const containerRef = ref<HTMLElement | null>(null);\n const isCollapsed = ref(props.collapsed);\n\n const layerStates = ref<Map<string, { visible: boolean; opacity: number }>>(\n new Map(),\n );\n\n useMapControl(map, containerRef, props.position);\n\n const initLayerStates = () => {\n for (const layer of props.layers) {\n layerStates.value.set(layer.id, {\n visible: layer.visible ?? true,\n opacity: layer.opacity ?? 1,\n });\n }\n };\n\n const getLayerType = (\n layerId: string,\n configType?: LayerType,\n ): LayerType | null => {\n if (configType) return configType;\n if (!map.value) return null;\n\n const maplibreLayer = map.value.getLayer(layerId);\n if (maplibreLayer) return 'maplibre';\n\n if (deckLayers) {\n const layers = deckLayers.getLayers();\n const deckLayer = (layers as Array<{ id: string }>).find(\n (l) => l.id === layerId,\n );\n if (deckLayer) return 'deckgl';\n }\n return null;\n };\n\n const getOpacityProperty = (layerId: string): string | null => {\n if (!map.value) return null;\n const layer = map.value.getLayer(layerId);\n if (!layer) return null;\n\n const layerType = layer.type;\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 return 'icon-opacity';\n case 'raster':\n return 'raster-opacity';\n default:\n return null;\n }\n };\n\n const updateVisibility = (\n layerId: string,\n visible: boolean,\n configType?: LayerType,\n ) => {\n const layerType = getLayerType(layerId, configType);\n\n if (layerType === 'maplibre') {\n if (!map.value) return;\n const layer = map.value.getLayer(layerId);\n if (!layer) {\n console.warn(\n `[VControlLayerGroup] MapLibre layer not found: ${layerId}`,\n );\n return;\n }\n map.value.setLayoutProperty(\n layerId,\n 'visibility',\n visible ? 'visible' : 'none',\n );\n } else if (layerType === 'deckgl') {\n if (!deckLayers) {\n console.warn(\n `[VControlLayerGroup] deck.gl overlay not available for layer: ${layerId}`,\n );\n return;\n }\n const layers = deckLayers.getLayers();\n const existingLayer = (\n layers as Array<{ id: string; clone?: (props: object) => unknown }>\n ).find((l) => l.id === layerId);\n if (!existingLayer) {\n console.warn(\n `[VControlLayerGroup] deck.gl layer not found: ${layerId}`,\n );\n return;\n }\n if (typeof existingLayer.clone === 'function') {\n const updatedLayer = existingLayer.clone({ visible });\n deckLayers.updateLayer(layerId, updatedLayer);\n }\n } else {\n console.warn(`[VControlLayerGroup] Layer not found: ${layerId}`);\n return;\n }\n\n emit('visibility-change', { layerId, visible });\n };\n\n const updateOpacity = (\n layerId: string,\n opacity: number,\n configType?: LayerType,\n ) => {\n const layerType = getLayerType(layerId, configType);\n\n if (layerType === 'maplibre') {\n const opacityProp = getOpacityProperty(layerId);\n if (!map.value || !opacityProp) return;\n const layer = map.value.getLayer(layerId);\n if (!layer) {\n console.warn(\n `[VControlLayerGroup] MapLibre layer not found: ${layerId}`,\n );\n return;\n }\n map.value.setPaintProperty(layerId, opacityProp, opacity);\n } else if (layerType === 'deckgl') {\n if (!deckLayers) {\n console.warn(\n `[VControlLayerGroup] deck.gl overlay not available for layer: ${layerId}`,\n );\n return;\n }\n const layers = deckLayers.getLayers();\n const existingLayer = (\n layers as Array<{ id: string; clone?: (props: object) => unknown }>\n ).find((l) => l.id === layerId);\n if (!existingLayer) {\n console.warn(\n `[VControlLayerGroup] deck.gl layer not found: ${layerId}`,\n );\n return;\n }\n if (typeof existingLayer.clone === 'function') {\n const updatedLayer = existingLayer.clone({ opacity });\n deckLayers.updateLayer(layerId, updatedLayer);\n }\n } else {\n console.warn(`[VControlLayerGroup] Layer not found: ${layerId}`);\n return;\n }\n\n emit('opacity-change', { layerId, opacity });\n };\n\n const toggleVisibility = (layer: LayerConfig) => {\n const state = layerStates.value.get(layer.id);\n if (!state) return;\n\n const newVisible = !state.visible;\n state.visible = newVisible;\n updateVisibility(layer.id, newVisible, layer.type);\n };\n\n const handleOpacityInput = (layer: LayerConfig, event: Event) => {\n const target = event.target as HTMLInputElement;\n const opacity = Number(target.value) / 100;\n\n const state = layerStates.value.get(layer.id);\n if (!state) return;\n\n state.opacity = opacity;\n updateOpacity(layer.id, opacity, layer.type);\n };\n\n const getState = (layerId: string) => {\n return layerStates.value.get(layerId) ?? { visible: true, opacity: 1 };\n };\n\n const toggleCollapse = () => {\n if (props.collapsible) {\n isCollapsed.value = !isCollapsed.value;\n }\n };\n\n watch(\n () => props.layers,\n () => {\n initLayerStates();\n },\n { deep: true },\n );\n\n watch(\n () => props.collapsed,\n (newValue) => {\n isCollapsed.value = newValue;\n },\n );\n\n onMounted(() => {\n initLayerStates();\n // Apply initial states\n for (const layer of props.layers) {\n const state = getState(layer.id);\n updateVisibility(layer.id, state.visible, layer.type);\n updateOpacity(layer.id, state.opacity, layer.type);\n }\n });\n</script>\n\n<template>\n <div\n ref=\"containerRef\"\n class=\"v-layer-group maplibregl-ctrl\"\n :class=\"{ 'is-collapsed': isCollapsed }\"\n >\n <button\n v-if=\"collapsible\"\n type=\"button\"\n class=\"v-layer-group-header\"\n @click=\"toggleCollapse\"\n >\n <span class=\"v-layer-group-title\">{{ title }}</span>\n <svg\n class=\"v-layer-group-chevron\"\n :class=\"{ 'is-collapsed': isCollapsed }\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n >\n <path\n d=\"M3 5L7 9L11 5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n <div v-else class=\"v-layer-group-header is-static\">\n <span class=\"v-layer-group-title\">{{ title }}</span>\n </div>\n\n <div v-if=\"!isCollapsed\" class=\"v-layer-group-content\">\n <div v-for=\"layer in layers\" :key=\"layer.id\" class=\"v-layer-group-item\">\n <div class=\"v-layer-group-item-header\">\n <span class=\"v-layer-group-item-title\">{{ layer.title }}</span>\n <button\n type=\"button\"\n class=\"v-layer-group-toggle\"\n :class=\"{ 'is-hidden': !getState(layer.id).visible }\"\n :aria-pressed=\"getState(layer.id).visible\"\n :title=\"getState(layer.id).visible ? 'Hide layer' : 'Show layer'\"\n @click=\"toggleVisibility(layer)\"\n >\n <svg\n v-if=\"getState(layer.id).visible\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n >\n <path\n d=\"M8 3C4.5 3 1.5 5.5 0.5 8C1.5 10.5 4.5 13 8 13C11.5 13 14.5 10.5 15.5 8C14.5 5.5 11.5 3 8 3Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <circle\n cx=\"8\"\n cy=\"8\"\n r=\"2.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n />\n </svg>\n <svg v-else width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path\n d=\"M2 2L14 14M6.5 6.5C5.9 7.1 5.5 7.9 5.5 8.8C5.5 10.4 6.9 11.5 8 11.5C8.9 11.5 9.7 11.1 10.3 10.5M8 3C4.5 3 1.5 5.5 0.5 8C1 9.2 1.8 10.3 2.8 11.2M13.2 11.2C14.2 10.3 15 9.2 15.5 8C14.5 5.5 11.5 3 8 3\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n <div class=\"v-layer-group-slider-row\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"100\"\n :value=\"Math.round(getState(layer.id).opacity * 100)\"\n class=\"v-layer-group-slider\"\n :disabled=\"!getState(layer.id).visible\"\n @input=\"handleOpacityInput(layer, $event)\"\n />\n <span class=\"v-layer-group-value\"\n >{{ Math.round(getState(layer.id).opacity * 100) }}%</span\n >\n </div>\n </div>\n </div>\n\n <slot></slot>\n </div>\n</template>\n\n<style>\n .v-layer-group {\n min-width: 140px;\n max-width: 280px;\n margin: 10px;\n background: var(--color-card, #fff);\n border-radius: var(--radius, 0.5rem);\n border: 1px solid var(--color-border, #e5e7eb);\n box-shadow:\n 0 1px 3px 0 rgb(0 0 0 / 0.1),\n 0 1px 2px -1px rgb(0 0 0 / 0.1);\n font-family:\n ui-sans-serif,\n system-ui,\n -apple-system,\n sans-serif;\n font-size: 12px;\n overflow: hidden;\n /* Required: MapLibre control containers have pointer-events:none */\n pointer-events: auto;\n }\n\n .v-layer-group-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n width: 100%;\n min-height: 36px;\n padding: 8px 10px;\n border: none;\n border-bottom: 1px solid var(--color-border, #e5e7eb);\n background: transparent;\n cursor: pointer;\n text-align: left;\n line-height: 1;\n touch-action: manipulation;\n -webkit-tap-highlight-color: transparent;\n }\n\n .v-layer-group-header.is-static {\n cursor: default;\n }\n\n .v-layer-group-header:not(.is-static):hover {\n background: var(--color-accent, #f3f4f6);\n }\n\n .v-layer-group-header:focus {\n outline: none;\n }\n\n .v-layer-group-header:focus-visible {\n outline: 2px solid var(--color-primary, #3b82f6);\n outline-offset: -2px;\n }\n\n .v-layer-group.is-collapsed .v-layer-group-header {\n border-bottom: none;\n }\n\n .v-layer-group-title {\n font-weight: 500;\n font-size: 11px;\n color: var(--color-card-foreground, #111827);\n line-height: 1.2;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n min-width: 0;\n }\n\n .v-layer-group-chevron {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n color: var(--color-muted-foreground, #6b7280);\n transition: transform 0.15s ease;\n flex-shrink: 0;\n }\n\n .v-layer-group-chevron.is-collapsed {\n transform: rotate(-90deg);\n }\n\n .v-layer-group-content {\n display: flex;\n flex-direction: column;\n }\n\n .v-layer-group-item {\n padding: 6px 10px 8px;\n border-bottom: 1px solid var(--color-border, #e5e7eb);\n }\n\n .v-layer-group-item:last-child {\n border-bottom: none;\n }\n\n .v-layer-group-item-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n margin-bottom: 6px;\n }\n\n .v-layer-group-item-title {\n font-weight: 500;\n font-size: 11px;\n color: var(--color-foreground, #374151);\n line-height: 1.2;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n min-width: 0;\n }\n\n .v-layer-group-toggle {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n padding: 0;\n border: none;\n border-radius: calc(var(--radius, 0.5rem) - 2px);\n background: transparent;\n color: var(--color-foreground, #374151);\n cursor: pointer;\n transition:\n background 0.15s ease,\n color 0.15s ease;\n flex-shrink: 0;\n }\n\n .v-layer-group-toggle svg {\n width: 14px;\n height: 14px;\n }\n\n .v-layer-group-toggle:hover {\n background: var(--color-accent, #f3f4f6);\n }\n\n .v-layer-group-toggle.is-hidden {\n color: var(--color-muted-foreground, #9ca3af);\n }\n\n .v-layer-group-slider-row {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .v-layer-group-slider {\n flex: 1;\n height: 3px;\n border-radius: 2px;\n background: var(--color-secondary, #e5e7eb);\n cursor: pointer;\n -webkit-appearance: none;\n appearance: none;\n }\n\n .v-layer-group-slider:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n }\n\n .v-layer-group-slider::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: var(--color-primary, #3b82f6);\n cursor: pointer;\n border: 2px solid #fff;\n box-shadow: 0 1px 3px rgb(0 0 0 / 0.2);\n }\n\n .v-layer-group-slider::-moz-range-thumb {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: var(--color-primary, #3b82f6);\n cursor: pointer;\n border: 2px solid #fff;\n box-shadow: 0 1px 3px rgb(0 0 0 / 0.2);\n }\n\n .v-layer-group-slider:disabled::-webkit-slider-thumb {\n cursor: not-allowed;\n }\n\n .v-layer-group-slider:disabled::-moz-range-thumb {\n cursor: not-allowed;\n }\n\n .v-layer-group-slider:focus {\n outline: none;\n }\n\n .v-layer-group-slider:focus::-webkit-slider-thumb {\n box-shadow: 0 0 0 3px\n color-mix(in srgb, var(--color-primary, #3b82f6) 20%, transparent);\n }\n\n .v-layer-group-value {\n font-size: 10px;\n font-weight: 500;\n color: var(--color-muted-foreground, #6b7280);\n font-variant-numeric: tabular-nums;\n min-width: 28px;\n text-align: right;\n }\n</style>\n","<script setup lang=\"ts\">\n import { ref, watch, computed, inject, onMounted } from 'vue';\n import { MapKey, injectStrict } from '../../utils';\n import { DeckLayersKey } from '../../layers/deckgl/_shared/useDeckOverlay';\n import { useMapControl } from '../_shared';\n import type {\n ControlPosition,\n LegendType,\n CategoryLegendItem,\n GradientLegendItem,\n SizeLegendItem,\n TableLegendItem,\n LegendItem,\n FilterState,\n ExpressionValue,\n DeckLayerWithExtensions,\n } from './types';\n\n const props = withDefaults(\n defineProps<{\n layerIds: string[];\n type?: LegendType;\n items?: LegendItem[];\n position?: ControlPosition;\n property?: string;\n autoGenerate?: boolean;\n title?: string;\n collapsed?: boolean;\n interactive?: boolean;\n }>(),\n {\n type: 'category',\n position: 'top-right',\n autoGenerate: false,\n title: 'Legend',\n collapsed: false,\n interactive: true,\n },\n );\n\n const emit = defineEmits<{\n 'item-click': [data: { item: LegendItem; index: number; visible: boolean }];\n 'filter-change': [data: { filter: FilterState; layerIds: string[] }];\n 'update:filter': [filter: FilterState];\n }>();\n\n const map = injectStrict(MapKey);\n const deckLayers = inject(DeckLayersKey, null);\n const containerRef = ref<HTMLElement | null>(null);\n const isCollapsed = ref(props.collapsed);\n const categoryItemVisibility = ref<Map<string | number, boolean>>(new Map());\n const generatedItems = ref<LegendItem[]>([]);\n\n useMapControl(map, containerRef, props.position);\n\n const parseMatchExpression = (\n expression: ExpressionValue[],\n ): CategoryLegendItem[] => {\n const items: CategoryLegendItem[] = [];\n const defaultColor = expression[expression.length - 1] as string;\n\n for (let i = 2; i < expression.length - 1; i += 2) {\n const value = expression[i];\n const color = expression[i + 1] as string;\n\n if (Array.isArray(value)) {\n for (const v of value) {\n items.push({\n value: v as string | number,\n label: String(v),\n color,\n visible: true,\n });\n }\n } else {\n items.push({\n value: value as string | number,\n label: String(value),\n color,\n visible: true,\n });\n }\n }\n\n if (items.length > 0 && defaultColor && typeof defaultColor === 'string') {\n items.push({\n value: '__default__',\n label: 'Other',\n color: defaultColor,\n visible: true,\n });\n }\n\n return items;\n };\n\n const parseStepExpression = (\n expression: ExpressionValue[],\n ): GradientLegendItem | null => {\n const colors: string[] = [];\n const stops: number[] = [];\n\n const defaultColor = expression[2] as string;\n colors.push(defaultColor);\n\n for (let i = 3; i < expression.length; i += 2) {\n const stop = expression[i] as number;\n const color = expression[i + 1] as string;\n stops.push(stop);\n colors.push(color);\n }\n\n if (stops.length === 0) return null;\n\n return {\n min: stops[0],\n max: stops[stops.length - 1],\n colors,\n stops,\n };\n };\n\n const parseInterpolateExpression = (\n expression: ExpressionValue[],\n ): GradientLegendItem | null => {\n const colors: string[] = [];\n const stops: number[] = [];\n\n const startIndex = expression[1] && Array.isArray(expression[1]) ? 3 : 3;\n\n for (let i = startIndex; i < expression.length; i += 2) {\n const stop = expression[i] as number;\n const color = expression[i + 1] as string;\n stops.push(stop);\n colors.push(color);\n }\n\n if (stops.length < 2) return null;\n\n return {\n min: stops[0],\n max: stops[stops.length - 1],\n colors,\n stops,\n };\n };\n\n const generateLegendFromPaint = (): LegendItem[] => {\n if (!props.autoGenerate || !props.property || !map.value) return [];\n\n const layerId = props.layerIds[0];\n if (!layerId) return [];\n\n const layer = map.value.getLayer(layerId);\n if (!layer) {\n console.warn(`[VControlLegend] Layer not found: ${layerId}`);\n return [];\n }\n\n const paintValue = map.value.getPaintProperty(layerId, props.property);\n if (!paintValue || !Array.isArray(paintValue)) {\n console.warn(\n `[VControlLegend] Paint property \"${props.property}\" not found or not an expression`,\n );\n return [];\n }\n\n const expressionType = paintValue[0];\n\n if (expressionType === 'match') {\n return parseMatchExpression(paintValue as ExpressionValue[]);\n }\n\n if (expressionType === 'step') {\n const gradient = parseStepExpression(paintValue as ExpressionValue[]);\n return gradient ? [gradient] : [];\n }\n\n if (\n expressionType === 'interpolate' ||\n expressionType === 'interpolate-hcl' ||\n expressionType === 'interpolate-lab'\n ) {\n const gradient = parseInterpolateExpression(\n paintValue as ExpressionValue[],\n );\n return gradient ? [gradient] : [];\n }\n\n console.warn(\n `[VControlLegend] Unsupported expression type: ${expressionType}`,\n );\n return [];\n };\n\n const effectiveItems = computed((): LegendItem[] => {\n if (props.items && props.items.length > 0) {\n return props.items;\n }\n return generatedItems.value;\n });\n\n const categoryItems = computed(() => {\n if (props.type !== 'category') return [];\n return effectiveItems.value.filter(\n (item): item is CategoryLegendItem =>\n 'value' in item && 'color' in item && 'label' in item,\n );\n });\n\n const gradientItem = computed(() => {\n if (props.type !== 'gradient') return null;\n const items = effectiveItems.value;\n if (items.length === 0) return null;\n const first = items[0];\n if ('min' in first && 'max' in first && 'colors' in first) {\n return first as GradientLegendItem;\n }\n return null;\n });\n\n const sizeItems = computed(() => {\n if (props.type !== 'size') return [];\n return effectiveItems.value.filter(\n (item): item is SizeLegendItem => 'size' in item && 'value' in item,\n );\n });\n\n const tableItems = computed((): TableLegendItem[] => {\n if (props.type !== 'table') return [];\n return effectiveItems.value\n .filter(\n (item): item is TableLegendItem =>\n 'label' in item &&\n 'color' in item &&\n 'value' in item &&\n !('size' in item) &&\n !('visible' in item),\n )\n .sort((a, b) => b.value - a.value);\n });\n\n const formatTableValue = (item: TableLegendItem): string => {\n if (item.formattedValue) return item.formattedValue;\n return `${item.value}${item.unit ?? ''}`;\n };\n\n const filterState = computed((): FilterState => {\n const visibleValues = Array.from(categoryItemVisibility.value.entries())\n .filter(([, visible]) => visible)\n .map(([value]) => value);\n return { visibleValues };\n });\n\n const gradientStyle = computed(() => {\n if (!gradientItem.value) return '';\n const colorStops = gradientItem.value.colors.join(', ');\n return `linear-gradient(to right, ${colorStops})`;\n });\n\n const initVisibility = () => {\n if (props.type === 'category') {\n for (const item of categoryItems.value) {\n categoryItemVisibility.value.set(item.value, item.visible ?? true);\n }\n }\n };\n\n const applyFilterToMapLibreLayers = () => {\n if (!map.value || !props.property || props.type !== 'category') return;\n\n const visibleValues = filterState.value.visibleValues.filter(\n (v) => v !== '__default__',\n );\n const allValues = categoryItems.value\n .map((item) => item.value)\n .filter((v) => v !== '__default__');\n const allVisible = visibleValues.length === allValues.length;\n\n for (const layerId of props.layerIds) {\n const layer = map.value.getLayer(layerId);\n if (!layer) continue;\n\n if (allVisible) {\n map.value.setFilter(layerId, null);\n } else if (visibleValues.length === 0) {\n map.value.setFilter(layerId, ['==', ['get', '_never_match_'], true]);\n } else {\n const paintValue = map.value.getPaintProperty(layerId, props.property);\n if (!paintValue || !Array.isArray(paintValue)) continue;\n\n const inputExpr = paintValue[1];\n let propertyName: string | null = null;\n\n if (Array.isArray(inputExpr) && inputExpr[0] === 'get') {\n propertyName = inputExpr[1] as string;\n }\n\n if (propertyName) {\n map.value.setFilter(layerId, [\n 'in',\n ['get', propertyName],\n ['literal', visibleValues],\n ]);\n }\n }\n }\n };\n\n const applyFilterToDeckglLayers = () => {\n if (!deckLayers || props.type !== 'category') return;\n\n const visibleValues = filterState.value.visibleValues.filter(\n (v) => v !== '__default__',\n );\n const allValues = categoryItems.value\n .map((item) => item.value)\n .filter((v) => v !== '__default__');\n const allVisible = visibleValues.length === allValues.length;\n\n const layers = deckLayers.getLayers() as DeckLayerWithExtensions[];\n\n for (const layerId of props.layerIds) {\n if (map.value?.getLayer(layerId)) continue;\n\n const deckLayer = layers.find((l) => l.id === layerId);\n if (!deckLayer) continue;\n\n const hasDataFilterExtension = deckLayer.props?.extensions?.some(\n (ext) => ext?.constructor?.name === 'DataFilterExtension',\n );\n\n if (!hasDataFilterExtension) {\n console.warn(\n `[VControlLegend] deck.gl layer \"${layerId}\" requires DataFilterExtension for filtering. ` +\n 'Add DataFilterExtension to layer extensions and configure getFilterValue accessor.',\n );\n continue;\n }\n\n if (typeof deckLayer.clone !== 'function') continue;\n\n if (allVisible) {\n const updatedLayer = deckLayer.clone({\n filterRange: [-Infinity, Infinity],\n });\n deckLayers.updateLayer(layerId, updatedLayer);\n } else if (visibleValues.length === 0) {\n const updatedLayer = deckLayer.clone({\n filterRange: [Infinity, Infinity],\n });\n deckLayers.updateLayer(layerId, updatedLayer);\n } else {\n const valueIndices = visibleValues\n .map((v) => categoryItems.value.findIndex((item) => item.value === v))\n .filter((i) => i >= 0);\n\n if (valueIndices.length > 0) {\n const minIndex = Math.min(...valueIndices);\n const maxIndex = Math.max(...valueIndices);\n const updatedLayer = deckLayer.clone({\n filterRange: [minIndex - 0.5, maxIndex + 0.5],\n });\n deckLayers.updateLayer(layerId, updatedLayer);\n }\n }\n }\n };\n\n const toggleItem = (item: CategoryLegendItem, index: number) => {\n if (!props.interactive) return;\n\n const currentVisible = categoryItemVisibility.value.get(item.value) ?? true;\n const newVisible = !currentVisible;\n categoryItemVisibility.value.set(item.value, newVisible);\n\n applyFilterToMapLibreLayers();\n applyFilterToDeckglLayers();\n\n emit('item-click', { item, index, visible: newVisible });\n emit('filter-change', {\n filter: filterState.value,\n layerIds: props.layerIds,\n });\n emit('update:filter', filterState.value);\n };\n\n const isItemVisible = (item: CategoryLegendItem) => {\n return categoryItemVisibility.value.get(item.value) ?? true;\n };\n\n const toggleCollapse = () => {\n isCollapsed.value = !isCollapsed.value;\n };\n\n watch(\n () => props.items,\n () => {\n initVisibility();\n },\n { deep: true },\n );\n\n watch(\n () => props.collapsed,\n (newValue) => {\n isCollapsed.value = newValue;\n },\n );\n\n onMounted(() => {\n if (props.autoGenerate) {\n generatedItems.value = generateLegendFromPaint();\n }\n initVisibility();\n });\n</script>\n\n<template>\n <div\n ref=\"containerRef\"\n class=\"v-legend-control\"\n :class=\"{ 'is-collapsed': isCollapsed }\"\n >\n <button\n type=\"button\"\n class=\"v-legend-control-header\"\n @click=\"toggleCollapse\"\n >\n <span class=\"v-legend-control-title\">{{ title }}</span>\n <svg\n class=\"v-legend-control-chevron\"\n :class=\"{ 'is-collapsed': isCollapsed }\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n >\n <path\n d=\"M3 5L7 9L11 5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n\n <div v-if=\"!isCollapsed\" class=\"v-legend-control-content\">\n <template v-if=\"type === 'category'\">\n <button\n v-for=\"(item, index) in categoryItems\"\n :key=\"item.value\"\n type=\"button\"\n class=\"v-legend-control-item\"\n :class=\"{\n 'is-interactive': interactive,\n 'is-hidden': !isItemVisible(item),\n }\"\n :disabled=\"!interactive\"\n @click=\"toggleItem(item, index)\"\n >\n <span\n class=\"v-legend-control-swatch\"\n :style=\"{ backgroundColor: item.color }\"\n ></span>\n <span class=\"v-legend-control-label\">{{ item.label }}</span>\n <span v-if=\"item.count !== undefined\" class=\"v-legend-control-count\">\n {{ item.count }}\n </span>\n </button>\n </template>\n\n <template v-else-if=\"type === 'gradient' && gradientItem\">\n <div\n class=\"v-legend-control-gradient\"\n :style=\"{ background: gradientStyle }\"\n ></div>\n <div class=\"v-legend-control-gradient-labels\">\n <span>{{ gradientItem.minLabel ?? gradientItem.min }}</span>\n <span>{{ gradientItem.maxLabel ?? gradientItem.max }}</span>\n </div>\n </template>\n\n <template v-else-if=\"type === 'size'\">\n <div\n v-for=\"item in sizeItems\"\n :key=\"item.value\"\n class=\"v-legend-control-size-item\"\n >\n <div class=\"v-legend-control-size-circle-wrap\">\n <div\n class=\"v-legend-control-size-circle\"\n :style=\"{\n width: `${Math.min(item.size, 20)}px`,\n height: `${Math.min(item.size, 20)}px`,\n }\"\n ></div>\n </div>\n <span class=\"v-legend-control-label\">{{ item.label }}</span>\n </div>\n </template>\n\n <template v-else-if=\"type === 'table'\">\n <div class=\"v-legend-control-table\">\n <div\n v-for=\"item in tableItems\"\n :key=\"item.label\"\n class=\"v-legend-control-table-row\"\n :title=\"item.description\"\n >\n <span\n class=\"v-legend-control-swatch\"\n :style=\"{ backgroundColor: item.color }\"\n ></span>\n <span class=\"v-legend-control-table-label\">{{ item.label }}</span>\n <span class=\"v-legend-control-table-value\">\n {{ formatTableValue(item) }}\n </span>\n </div>\n </div>\n </template>\n </div>\n\n <slot></slot>\n </div>\n</template>\n\n<style>\n .v-legend-control {\n min-width: 140px;\n max-width: 200px;\n margin: 10px;\n background: var(--color-card, #fff);\n border-radius: var(--radius, 0.5rem);\n border: 1px solid var(--color-border, #e5e7eb);\n box-shadow:\n 0 1px 3px 0 rgb(0 0 0 / 0.1),\n 0 1px 2px -1px rgb(0 0 0 / 0.1);\n font-family:\n ui-sans-serif,\n system-ui,\n -apple-system,\n sans-serif;\n font-size: 12px;\n overflow: hidden;\n /* Required: MapLibre control containers have pointer-events:none */\n pointer-events: auto;\n }\n\n .v-legend-control-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n width: 100%;\n min-height: 44px;\n padding: 8px 10px;\n border: none;\n border-bottom: 1px solid var(--color-border, #e5e7eb);\n background: transparent;\n cursor: pointer;\n text-align: left;\n line-height: 1;\n touch-action: manipulation;\n -webkit-tap-highlight-color: transparent;\n }\n\n .v-legend-control.is-collapsed .v-legend-control-header {\n border-bottom: none;\n }\n\n .v-legend-control-header:hover {\n background: var(--color-accent, #f3f4f6);\n }\n\n .v-legend-control-title {\n font-weight: 500;\n font-size: 13px;\n color: var(--color-card-foreground, #111827);\n line-height: 1;\n }\n\n .v-legend-control-chevron {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n color: var(--color-muted-foreground, #6b7280);\n transition: transform 0.15s ease;\n flex-shrink: 0;\n }\n\n .v-legend-control-chevron.is-collapsed {\n transform: rotate(-90deg);\n }\n\n .v-legend-control-content {\n padding: 6px;\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n\n .v-legend-control-item {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 6px 8px;\n border: none;\n border-radius: calc(var(--radius, 0.5rem) - 4px);\n background: transparent;\n text-align: left;\n transition:\n background 0.1s ease,\n opacity 0.1s ease;\n }\n\n .v-legend-control-item.is-interactive {\n cursor: pointer;\n }\n\n .v-legend-control-item.is-interactive:hover {\n background: var(--color-accent, #f3f4f6);\n }\n\n .v-legend-control-item.is-hidden {\n opacity: 0.4;\n }\n\n .v-legend-control-item.is-hidden .v-legend-control-label {\n text-decoration: line-through;\n }\n\n .v-legend-control-item:disabled {\n cursor: default;\n }\n\n .v-legend-control-swatch {\n width: 12px;\n height: 12px;\n border-radius: 3px;\n flex-shrink: 0;\n box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.1);\n }\n\n .v-legend-control-label {\n flex: 1;\n font-size: 11px;\n font-weight: 500;\n color: var(--color-foreground, #374151);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .v-legend-control-count {\n font-size: 10px;\n font-weight: 500;\n color: var(--color-muted-foreground, #6b7280);\n background: var(--color-secondary, #f3f4f6);\n padding: 1px 5px;\n border-radius: 8px;\n }\n\n .v-legend-control-gradient {\n height: 12px;\n border-radius: 3px;\n margin: 6px 8px 4px;\n }\n\n .v-legend-control-gradient-labels {\n display: flex;\n justify-content: space-between;\n padding: 0 8px 6px;\n font-size: 10px;\n font-weight: 500;\n color: var(--color-muted-foreground, #6b7280);\n }\n\n .v-legend-control-size-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 8px;\n }\n\n .v-legend-control-size-circle-wrap {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n }\n\n .v-legend-control-size-circle {\n border-radius: 50%;\n background: var(--color-primary, #3b82f6);\n box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.1);\n }\n\n .v-legend-control-table {\n max-height: 300px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 1px;\n }\n\n .v-legend-control-table-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 8px;\n border-radius: calc(var(--radius, 0.5rem) - 4px);\n }\n\n .v-legend-control-table-row:hover {\n background: var(--color-accent, #f3f4f6);\n }\n\n .v-legend-control-table-label {\n flex: 1;\n font-size: 11px;\n font-weight: 500;\n color: var(--color-foreground, #374151);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .v-legend-control-table-value {\n font-size: 10px;\n font-weight: 600;\n color: var(--color-muted-foreground, #6b7280);\n white-space: nowrap;\n font-variant-numeric: tabular-nums;\n }\n\n .v-legend-control:has(.v-legend-control-table) {\n max-width: 280px;\n }\n</style>\n","<script setup lang=\"ts\">\n import type {\n CanvasSourceSpecification,\n LayerSpecification,\n Map,\n } from 'maplibre-gl';\n import { onMounted, onBeforeUnmount, ref, watch } from 'vue';\n import { injectStrict, MapKey } from '../../../utils';\n\n const props = withDefaults(\n defineProps<{\n source: CanvasSourceSpecification;\n layer: LayerSpecification;\n sourceId?: string;\n layerId?: string;\n before?: string;\n }>(),\n {\n sourceId: 'maplibre.gl-canvas-source',\n layerId: 'maplibre.gl-canvas-layer',\n before: '',\n },\n );\n\n const map = injectStrict(MapKey);\n\n // Helper function to safely get map instance\n const getMapInstance = (): Map | null => {\n return map.value || null;\n };\n\n // Track if layer has been initialized to prevent duplicate setup\n const initialized = ref(false);\n\n // Bound readiness handlers so they can be removed on unmount / map rebind.\n let boundMap: Map | null = null;\n let styleLoadHandler: (() => void) | null = null;\n let idleHandler: (() => void) | null = null;\n\n // Single, idempotent entry point. Adds the source + layer exactly once, but\n // only when the style is loaded. Safe to call from any trigger.\n const tryAddLayer = (): boolean => {\n if (initialized.value) return true;\n\n const mapInstance = getMapInstance();\n if (!mapInstance) return false;\n\n // Style must be ready before sources/layers can be added.\n if (!mapInstance.isStyleLoaded()) return false;\n\n try {\n if (!mapInstance.getSource(props.sourceId)) {\n mapInstance.addSource(props.sourceId, props.source);\n }\n if (!mapInstance.getLayer(props.layerId)) {\n const layerSpec = {\n ...props.layer,\n id: props.layerId,\n source: props.sourceId,\n } as LayerSpecification;\n mapInstance.addLayer(layerSpec, props.before);\n }\n initialized.value = true;\n return true;\n } catch (error) {\n console.error('Error adding Canvas layer:', error);\n return false;\n }\n };\n\n // Bind readiness handlers exactly once, handling BOTH the \"style.load fires\n // after we bind\" case (style.load listener) AND the \"style.load already fired\n // before we bind\" case (synchronous attempt + idle fallback). This fixes the\n // production race where the basemap style loads before the layer mounts\n // (mapbox-gl-js#6707).\n const bindReadyHandlers = (mapInstance: Map): void => {\n if (boundMap === mapInstance) return;\n\n unbindReadyHandlers();\n boundMap = mapInstance;\n\n styleLoadHandler = () => {\n tryAddLayer();\n };\n mapInstance.on('style.load', styleLoadHandler);\n\n idleHandler = () => {\n if (initialized.value) {\n if (idleHandler && boundMap) boundMap.off('idle', idleHandler);\n idleHandler = null;\n return;\n }\n tryAddLayer();\n };\n mapInstance.on('idle', idleHandler);\n\n // Synchronous attempt for the already-fully-loaded case.\n tryAddLayer();\n };\n\n const unbindReadyHandlers = (): void => {\n if (boundMap) {\n if (styleLoadHandler) boundMap.off('style.load', styleLoadHandler);\n if (idleHandler) boundMap.off('idle', idleHandler);\n }\n boundMap = null;\n styleLoadHandler = null;\n idleHandler = null;\n };\n\n const updateSource = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n // For canvas sources, we need to remove and re-add both source and layer\n if (mapInstance.getLayer(props.layerId)) {\n mapInstance.removeLayer(props.layerId);\n }\n if (mapInstance.getSource(props.sourceId)) {\n mapInstance.removeSource(props.sourceId);\n }\n\n mapInstance.addSource(props.sourceId, props.source);\n const layerSpec = {\n ...props.layer,\n id: props.layerId,\n source: props.sourceId,\n } as LayerSpecification;\n mapInstance.addLayer(layerSpec, props.before);\n } catch (error) {\n console.error('Error updating Canvas source:', error);\n }\n };\n\n const updateLayer = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if (mapInstance.getLayer(props.layerId)) {\n Object.entries(props.layer.paint || {}).forEach(([key, value]) => {\n mapInstance.setPaintProperty(props.layerId, key, value);\n });\n Object.entries(props.layer.layout || {}).forEach(([key, value]) => {\n mapInstance.setLayoutProperty(props.layerId, key, value);\n });\n }\n } catch (error) {\n console.error('Error updating Canvas layer:', error);\n }\n };\n\n // Watchers\n watch(() => props.source, updateSource, { deep: true });\n watch(() => props.layer, updateLayer, { deep: true });\n\n // Watch for map instance changes. Immediate so an already-present map is\n // bound right away; bindReadyHandlers is idempotent and handles the\n // already-loaded style race internally.\n watch(\n map,\n (newMap) => {\n if (newMap) {\n bindReadyHandlers(newMap);\n } else {\n unbindReadyHandlers();\n initialized.value = false;\n }\n },\n { immediate: true },\n );\n\n // Lifecycle hooks\n onMounted(() => {\n // Final attempt after mount, in case map + style were ready synchronously.\n tryAddLayer();\n });\n\n onBeforeUnmount(() => {\n unbindReadyHandlers();\n\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if (mapInstance.getLayer(props.layerId)) {\n mapInstance.removeLayer(props.layerId);\n }\n if (mapInstance.getSource(props.sourceId)) {\n mapInstance.removeSource(props.sourceId);\n }\n } catch (error) {\n console.error('Error cleaning up Canvas layer:', error);\n }\n });\n</script>\n\n<template>\n <slot></slot>\n</template>\n","<!-- web/app/lib/v-mapbox/layers/maplibre/geojson/VLayerMaplibreGeojson.vue -->\n<script setup lang=\"ts\">\n import { onMounted, onBeforeUnmount, ref, watch, nextTick } from 'vue';\n import type {\n GeoJSONSource,\n GeoJSONSourceSpecification,\n LayerSpecification,\n Map,\n MapLayerMouseEvent,\n } from 'maplibre-gl';\n import { injectStrict, MapKey } from '../../../utils';\n\n interface LayerClick {\n features: GeoJSON.Feature[];\n coordinates: {\n lng: number;\n lat: number;\n };\n }\n\n interface Props {\n sourceId: string;\n layerId: string;\n source: GeoJSONSourceSpecification;\n layer: LayerSpecification;\n before?: string;\n }\n\n const props = withDefaults(defineProps<Props>(), {\n sourceId: 'maplibre-gl-geojson-source',\n layerId: 'maplibre-gl-geojson-layer',\n before: '',\n });\n\n const emit = defineEmits<{\n 'on-click': [event: LayerClick];\n }>();\n\n const map = injectStrict(MapKey);\n\n // Helper to check if data is valid GeoJSON with features\n const hasValidData = (\n data: string | GeoJSON.GeoJSON | undefined,\n ): boolean => {\n if (!data || typeof data === 'string') return false;\n if (data && typeof data === 'object' && 'type' in data) {\n if (data.type === 'FeatureCollection' && 'features' in data) {\n return data.features.length > 0;\n }\n // Also valid for single Feature or Geometry\n return (\n data.type === 'Feature' ||\n data.type === 'Point' ||\n data.type === 'LineString' ||\n data.type === 'Polygon' ||\n data.type === 'MultiPoint' ||\n data.type === 'MultiLineString' ||\n data.type === 'MultiPolygon'\n );\n }\n return false;\n };\n\n // Helper function to safely get map instance\n const getMapInstance = (): Map | null => {\n const instance = map.value || null;\n return instance;\n };\n\n // Track if layer has been initialized to prevent duplicate setup\n const initialized = ref(false);\n\n // The bound style.load handler (if any) so it can be removed on unmount /\n // when the map ref is reassigned.\n let boundMap: Map | null = null;\n let styleLoadHandler: (() => void) | null = null;\n let dataHandler: (() => void) | null = null;\n\n // Single, idempotent entry point. Adds the source + layer + events exactly\n // once, but only when the style is loaded AND the data is valid. Safe to\n // call from any number of triggers (style.load, data, prop changes, mount).\n const tryAddLayer = (): boolean => {\n if (initialized.value) return true;\n\n const mapInstance = getMapInstance();\n if (!mapInstance) return false;\n\n // Style must be ready before sources/layers can be added.\n if (!mapInstance.isStyleLoaded()) return false;\n\n // Data must be valid before adding the source (clustering / async loads).\n if (!hasValidData(props.source.data)) return false;\n\n try {\n if (!mapInstance.getSource(props.sourceId)) {\n mapInstance.addSource(props.sourceId, props.source);\n }\n\n if (!mapInstance.getLayer(props.layerId)) {\n const layerSpec = {\n ...props.layer,\n id: props.layerId,\n source: props.sourceId,\n } as LayerSpecification;\n\n mapInstance.addLayer(layerSpec, props.before);\n }\n\n setupLayerEvents(mapInstance);\n initialized.value = true;\n return true;\n } catch (error) {\n console.error('Error adding GeoJSON layer:', error);\n return false;\n }\n };\n\n // Bind the readiness handlers to a map instance exactly once. This must\n // handle BOTH cases robustly:\n // 1. style.load fires AFTER we bind -> the 'style.load' listener catches it\n // 2. style.load already fired BEFORE we bind (fast prod basemap) -> the\n // synchronous tryAddLayer() below catches the already-loaded style; if\n // the style reports not-yet-loaded only because sprite/glyph/source data\n // is still in flight, the 'idle' listener retries once everything settles.\n const bindReadyHandlers = (mapInstance: Map): void => {\n if (boundMap === mapInstance) return;\n\n // Clean up any handlers bound to a previous map instance.\n unbindReadyHandlers();\n boundMap = mapInstance;\n\n // (1) Catch style.load firing after we bind (e.g. theme switch, late style).\n styleLoadHandler = () => {\n tryAddLayer();\n };\n mapInstance.on('style.load', styleLoadHandler);\n\n // (2) Catch the window where style.load already fired but the style was not\n // fully ready at this exact tick (sprite/glyph/source still loading). The\n // 'idle' event fires once the map has finished loading and rendering.\n dataHandler = () => {\n if (initialized.value) {\n if (dataHandler && boundMap) boundMap.off('idle', dataHandler);\n dataHandler = null;\n return;\n }\n tryAddLayer();\n };\n mapInstance.on('idle', dataHandler);\n\n // (3) Synchronous attempt for the already-fully-loaded case.\n tryAddLayer();\n };\n\n const unbindReadyHandlers = (): void => {\n if (boundMap) {\n if (styleLoadHandler) boundMap.off('style.load', styleLoadHandler);\n if (dataHandler) boundMap.off('idle', dataHandler);\n }\n boundMap = null;\n styleLoadHandler = null;\n dataHandler = null;\n };\n\n const updateSource = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n const source = mapInstance.getSource(props.sourceId) as\n | GeoJSONSource\n | undefined;\n\n if (source && 'setData' in source) {\n // CRITICAL FIX: Only update data if source doesn't have clustering\n // or if this is the first/primary layer for this source\n const existingLayers = mapInstance\n .getStyle()\n .layers.filter(\n (l) =>\n l.type !== 'background' &&\n 'source' in l &&\n l.source === props.sourceId,\n );\n\n // Only update data if this is the first layer using this source\n // This prevents breaking clustering when multiple layers share a source\n if (\n existingLayers.length === 0 ||\n existingLayers[0]?.id === props.layerId\n ) {\n source.setData(props.source.data);\n }\n } else if (!source) {\n // If source doesn't exist, try to add the layer\n tryAddLayer();\n }\n } catch (error) {\n console.error('Error updating GeoJSON source:', error);\n }\n };\n\n const updateLayer = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if (mapInstance.getLayer(props.layerId)) {\n // Update paint properties\n Object.entries(props.layer.paint || {}).forEach(([key, value]) => {\n mapInstance.setPaintProperty(props.layerId, key, value);\n });\n // Update layout properties\n Object.entries(props.layer.layout || {}).forEach(([key, value]) => {\n mapInstance.setLayoutProperty(props.layerId, key, value);\n });\n } else {\n // If layer doesn't exist, try to add it\n tryAddLayer();\n }\n } catch (error) {\n console.error('Error updating GeoJSON layer:', error);\n }\n };\n\n const setupLayerEvents = (mapInstance: Map) => {\n if (!mapInstance) {\n return;\n }\n\n try {\n // Add click handler for the specific layer\n mapInstance.on('click', props.layerId, (e: MapLayerMouseEvent) => {\n if (e.features && e.features.length > 0) {\n emit('on-click', {\n features: e.features,\n coordinates: e.lngLat,\n });\n }\n });\n\n // Add hover effect to verify interactivity\n mapInstance.on('mouseenter', props.layerId, () => {\n mapInstance.getCanvas().style.cursor = 'pointer';\n });\n\n mapInstance.on('mouseleave', props.layerId, () => {\n mapInstance.getCanvas().style.cursor = '';\n });\n } catch (error) {\n console.error('Error in setupLayerEvents:', error);\n }\n };\n\n // Watch for map instance changes. Immediate so a map that already exists\n // when this component mounts is bound right away. bindReadyHandlers is\n // idempotent and handles the \"style already loaded\" race internally.\n watch(\n map,\n (newMap) => {\n if (newMap) {\n bindReadyHandlers(newMap);\n } else {\n // Map ref cleared (e.g. VMap unmounted / remounted on key change).\n unbindReadyHandlers();\n initialized.value = false;\n }\n },\n { immediate: true },\n );\n\n // Watchers for updates after initialization. Watching `props.source.data`\n // (not a deep watch on the whole object) catches the common case where the\n // page fetches GeoJSON asynchronously and assigns it AFTER the component has\n // mounted — at which point we either add the layer (if not yet added) or\n // update the existing source's data.\n watch(\n () => props.source.data,\n (newData, oldData) => {\n if (!hasValidData(newData)) {\n return;\n }\n\n // Layer not added yet: this data arrival may be the missing piece.\n if (!initialized.value) {\n const mapInstance = getMapInstance();\n if (mapInstance && !boundMap) {\n bindReadyHandlers(mapInstance);\n } else {\n tryAddLayer();\n }\n return;\n }\n\n // Layer already added: update the source data in place when it changed.\n if (JSON.stringify(newData) !== JSON.stringify(oldData)) {\n updateSource();\n }\n },\n );\n\n watch(() => props.layer, updateLayer, { deep: true });\n\n // Watch for visibility changes\n watch(\n () => props.layer.layout?.visibility,\n (newVisibility) => {\n const mapInstance = getMapInstance();\n if (!mapInstance || !mapInstance.isStyleLoaded()) return;\n\n const hasLayer = mapInstance.getLayer(props.layerId);\n\n if (!hasLayer && newVisibility === 'visible') {\n // Add layer if it doesn't exist and should be visible\n if (hasValidData(props.source.data)) {\n tryAddLayer();\n }\n } else if (hasLayer) {\n // Update visibility of existing layer\n try {\n mapInstance.setLayoutProperty(\n props.layerId,\n 'visibility',\n newVisibility,\n );\n } catch (error) {\n console.error(\n `Error updating visibility for ${props.layerId}:`,\n error,\n );\n }\n }\n },\n { immediate: true },\n );\n\n // Lifecycle hooks\n onMounted(() => {\n // Final attempt after Vue has finished mounting, in case the map + style +\n // data were all ready synchronously before the watchers settled.\n nextTick(() => {\n tryAddLayer();\n });\n });\n\n onBeforeUnmount(() => {\n unbindReadyHandlers();\n\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n // Remove layer\n if (mapInstance.getLayer(props.layerId)) {\n mapInstance.removeLayer(props.layerId);\n }\n\n // Only remove source if no other layers are using it\n const layersUsingSource = mapInstance\n .getStyle()\n .layers.filter(\n (l) =>\n l.type !== 'background' &&\n 'source' in l &&\n l.source === props.sourceId,\n );\n\n if (\n layersUsingSource.length === 0 &&\n mapInstance.getSource(props.sourceId)\n ) {\n mapInstance.removeSource(props.sourceId);\n }\n } catch (error) {\n console.error('Error cleaning up GeoJSON layer:', error);\n }\n });\n</script>\n\n<template>\n <slot></slot>\n</template>\n","<script setup lang=\"ts\">\n import type {\n LayerSpecification as AnyLayer,\n ImageSourceSpecification as ImageSourceRaw,\n ImageSource,\n Map,\n } from 'maplibre-gl';\n import type { PropType } from 'vue';\n import { onMounted, onBeforeUnmount, ref, watch } from 'vue';\n import { injectStrict, MapKey } from '../../../utils';\n\n const props = defineProps({\n sourceId: {\n type: String,\n default: 'maplibre.gl-image-source',\n required: true,\n },\n layerId: {\n type: String,\n default: 'maplibre.gl-image-layer',\n required: true,\n },\n source: {\n type: Object as PropType<ImageSourceRaw>,\n required: true,\n },\n layer: {\n type: Object as PropType<AnyLayer>,\n default: () => ({}),\n required: true,\n },\n before: {\n type: String,\n default: '',\n required: false,\n },\n });\n\n const map = injectStrict(MapKey);\n\n // Helper function to safely get map instance\n const getMapInstance = (): Map | null => {\n return map.value || null;\n };\n\n // Track if layer has been initialized to prevent duplicate setup\n const initialized = ref(false);\n\n // Bound readiness handlers so they can be removed on unmount / map rebind.\n let boundMap: Map | null = null;\n let styleLoadHandler: (() => void) | null = null;\n let idleHandler: (() => void) | null = null;\n\n // Single, idempotent entry point. Adds the source + layer exactly once, but\n // only when the style is loaded. Safe to call from any trigger.\n const tryAddLayer = (): boolean => {\n if (initialized.value) return true;\n\n const mapInstance = getMapInstance();\n if (!mapInstance) return false;\n\n // Style must be ready before sources/layers can be added.\n if (!mapInstance.isStyleLoaded()) return false;\n\n try {\n if (!mapInstance.getSource(props.sourceId)) {\n mapInstance.addSource(props.sourceId, props.source);\n }\n if (!mapInstance.getLayer(props.layerId)) {\n const layerSpec = {\n ...props.layer,\n id: props.layerId,\n source: props.sourceId,\n } as AnyLayer;\n mapInstance.addLayer(layerSpec, props.before);\n }\n initialized.value = true;\n return true;\n } catch (error) {\n console.error('Error adding Image layer:', error);\n return false;\n }\n };\n\n // Bind readiness handlers exactly once, handling BOTH the \"style.load fires\n // after we bind\" case (style.load listener) AND the \"style.load already fired\n // before we bind\" case (synchronous attempt + idle fallback). This fixes the\n // production race where the basemap style loads before the layer mounts\n // (mapbox-gl-js#6707).\n const bindReadyHandlers = (mapInstance: Map): void => {\n if (boundMap === mapInstance) return;\n\n unbindReadyHandlers();\n boundMap = mapInstance;\n\n styleLoadHandler = () => {\n tryAddLayer();\n };\n mapInstance.on('style.load', styleLoadHandler);\n\n idleHandler = () => {\n if (initialized.value) {\n if (idleHandler && boundMap) boundMap.off('idle', idleHandler);\n idleHandler = null;\n return;\n }\n tryAddLayer();\n };\n mapInstance.on('idle', idleHandler);\n\n // Synchronous attempt for the already-fully-loaded case.\n tryAddLayer();\n };\n\n const unbindReadyHandlers = (): void => {\n if (boundMap) {\n if (styleLoadHandler) boundMap.off('style.load', styleLoadHandler);\n if (idleHandler) boundMap.off('idle', idleHandler);\n }\n boundMap = null;\n styleLoadHandler = null;\n idleHandler = null;\n };\n\n const updateSource = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n const source = mapInstance.getSource(props.sourceId) as ImageSource;\n if (source) {\n // For image sources, we need to update coordinates and url\n if (source.updateImage) {\n source.updateImage({\n url: props.source.url,\n coordinates: props.source.coordinates,\n });\n } else {\n // If updateImage is not available, remove and re-add the source and layer\n if (mapInstance.getLayer(props.layerId)) {\n mapInstance.removeLayer(props.layerId);\n }\n if (mapInstance.getSource(props.sourceId)) {\n mapInstance.removeSource(props.sourceId);\n }\n\n mapInstance.addSource(props.sourceId, props.source);\n const layerSpec = {\n ...props.layer,\n id: props.layerId,\n source: props.sourceId,\n } as AnyLayer;\n mapInstance.addLayer(layerSpec, props.before);\n }\n }\n } catch (error) {\n console.error('Error updating Image source:', error);\n }\n };\n\n const updateLayer = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if (mapInstance.getLayer(props.layerId)) {\n Object.entries(props.layer.paint || {}).forEach(([key, value]) => {\n mapInstance.setPaintProperty(props.layerId, key, value);\n });\n Object.entries(props.layer.layout || {}).forEach(([key, value]) => {\n mapInstance.setLayoutProperty(props.layerId, key, value);\n });\n }\n } catch (error) {\n console.error('Error updating Image layer:', error);\n }\n };\n\n // Watchers\n watch(() => props.source, updateSource, { deep: true });\n watch(() => props.layer, updateLayer, { deep: true });\n\n // Watch for map instance changes. Immediate so an already-present map is\n // bound right away; bindReadyHandlers is idempotent and handles the\n // already-loaded style race internally.\n watch(\n map,\n (newMap) => {\n if (newMap) {\n bindReadyHandlers(newMap);\n } else {\n unbindReadyHandlers();\n initialized.value = false;\n }\n },\n { immediate: true },\n );\n\n // Lifecycle hooks\n onMounted(() => {\n // Final attempt after mount, in case map + style were ready synchronously.\n tryAddLayer();\n });\n\n onBeforeUnmount(() => {\n unbindReadyHandlers();\n\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if (mapInstance.getLayer(props.layerId)) {\n mapInstance.removeLayer(props.layerId);\n }\n if (mapInstance.getSource(props.sourceId)) {\n mapInstance.removeSource(props.sourceId);\n }\n } catch (error) {\n console.error('Error cleaning up Image layer:', error);\n }\n });\n</script>\n\n<template>\n <slot></slot>\n</template>\n","<script setup lang=\"ts\">\n import type {\n RasterSourceSpecification,\n RasterLayerSpecification,\n Map,\n } from 'maplibre-gl';\n import { onMounted, onBeforeUnmount, ref, watch } from 'vue';\n import { injectStrict, MapKey } from '../../../utils';\n\n const props = defineProps<{\n sourceId: string;\n source: RasterSourceSpecification;\n layerId: string;\n layer: RasterLayerSpecification;\n before?: string;\n }>();\n\n const map = injectStrict(MapKey);\n\n const getMapInstance = (): Map | null => {\n return map.value || null;\n };\n\n // Track if layer has been initialized to prevent duplicate setup\n const initialized = ref(false);\n\n // Bound readiness handlers so they can be removed on unmount / map rebind.\n let boundMap: Map | null = null;\n let styleLoadHandler: (() => void) | null = null;\n let idleHandler: (() => void) | null = null;\n\n // Single, idempotent entry point. Adds the source + layer exactly once, but\n // only when the style is loaded. Safe to call from any trigger.\n const tryAddLayer = (): boolean => {\n if (initialized.value) return true;\n\n const mapInstance = getMapInstance();\n if (!mapInstance) return false;\n\n // Style must be ready before sources/layers can be added.\n if (!mapInstance.isStyleLoaded()) return false;\n\n try {\n if (!mapInstance.getSource(props.sourceId)) {\n mapInstance.addSource(props.sourceId, props.source);\n }\n if (!mapInstance.getLayer(props.layerId)) {\n // Always add with proper ordering\n mapInstance.addLayer(props.layer, props.before);\n\n // Set initial visibility\n if (props.layer.layout?.visibility) {\n mapInstance.setLayoutProperty(\n props.layerId,\n 'visibility',\n props.layer.layout.visibility,\n );\n }\n }\n initialized.value = true;\n return true;\n } catch (error) {\n console.error(`[${props.layerId}] Error setting up layer:`, error);\n return false;\n }\n };\n\n // Bind readiness handlers exactly once, handling BOTH the \"style.load fires\n // after we bind\" case (style.load listener) AND the \"style.load already fired\n // before we bind\" case (synchronous attempt + idle fallback). This fixes the\n // production race where the basemap style loads before the layer mounts\n // (mapbox-gl-js#6707).\n const bindReadyHandlers = (mapInstance: Map): void => {\n if (boundMap === mapInstance) return;\n\n unbindReadyHandlers();\n boundMap = mapInstance;\n\n styleLoadHandler = () => {\n tryAddLayer();\n };\n mapInstance.on('style.load', styleLoadHandler);\n\n idleHandler = () => {\n if (initialized.value) {\n if (idleHandler && boundMap) boundMap.off('idle', idleHandler);\n idleHandler = null;\n return;\n }\n tryAddLayer();\n };\n mapInstance.on('idle', idleHandler);\n\n // Synchronous attempt for the already-fully-loaded case.\n tryAddLayer();\n };\n\n const unbindReadyHandlers = (): void => {\n if (boundMap) {\n if (styleLoadHandler) boundMap.off('style.load', styleLoadHandler);\n if (idleHandler) boundMap.off('idle', idleHandler);\n }\n boundMap = null;\n styleLoadHandler = null;\n idleHandler = null;\n };\n\n const updateSource = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n // Store the current beforeId since we'll need to reuse it\n const beforeId = props.before;\n\n if (mapInstance.getLayer(props.layerId)) {\n mapInstance.removeLayer(props.layerId);\n }\n mapInstance.removeSource(props.sourceId);\n\n mapInstance.addSource(props.sourceId, props.source);\n const layerSpec = {\n ...props.layer,\n id: props.layerId,\n type: 'raster',\n source: props.sourceId,\n } as RasterLayerSpecification;\n\n // Explicitly check if the beforeId layer exists before adding\n if (beforeId && mapInstance.getLayer(beforeId)) {\n mapInstance.addLayer(layerSpec, beforeId);\n } else {\n mapInstance.addLayer(layerSpec);\n }\n } catch (error) {\n console.error('Error updating Raster source:', error);\n }\n };\n\n const updateLayer = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if (mapInstance.getLayer(props.layerId)) {\n // Update paint properties\n const paint = props.layer.paint || {};\n Object.entries(paint).forEach(([key, value]) => {\n mapInstance.setPaintProperty(props.layerId, key, value);\n });\n\n // Update layout properties\n const layout = props.layer.layout || {};\n Object.entries(layout).forEach(([key, value]) => {\n mapInstance.setLayoutProperty(props.layerId, key, value);\n });\n }\n } catch (error) {\n console.error('Error updating Raster layer:', error);\n }\n };\n\n // Watchers\n watch(\n () => props.source.tiles?.[0], // Usually raster sources have a single tile URL\n (newTileUrl, oldTileUrl) => {\n if (newTileUrl !== oldTileUrl) {\n updateSource();\n }\n },\n );\n watch(() => props.layer, updateLayer, { deep: true });\n // Watch for map instance changes. Immediate so an already-present map is\n // bound right away; bindReadyHandlers is idempotent and handles the\n // already-loaded style race internally.\n watch(\n map,\n (newMap) => {\n if (newMap) {\n bindReadyHandlers(newMap);\n } else {\n unbindReadyHandlers();\n initialized.value = false;\n }\n },\n { immediate: true },\n );\n watch(\n () => props.layer.layout?.visibility,\n (newVisibility) => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n const hasLayer = mapInstance.getLayer(props.layerId);\n\n if (!hasLayer) {\n // Add layer with proper ordering\n try {\n mapInstance.addLayer(props.layer, props.before);\n } catch (error) {\n console.error(`[${props.layerId}] Error adding layer:`, error);\n }\n } else {\n try {\n // Update visibility\n mapInstance.setLayoutProperty(\n props.layerId,\n 'visibility',\n newVisibility,\n );\n\n // If becoming visible, ensure proper layer ordering\n if (newVisibility === 'visible' && props.before) {\n mapInstance.moveLayer(props.layerId, props.before);\n }\n } catch (error) {\n console.error(`[${props.layerId}] Error updating visibility:`, error);\n }\n }\n },\n { immediate: true },\n );\n watch(\n () => props.before,\n (newBefore) => {\n const mapInstance = getMapInstance();\n if (!mapInstance || !mapInstance.getLayer(props.layerId)) return;\n\n // Only move layer if it's visible\n if (props.layer.layout?.visibility === 'visible') {\n try {\n console.log(`[${props.layerId}] Moving layer before:`, newBefore);\n mapInstance.moveLayer(props.layerId, newBefore);\n } catch (error) {\n console.error(`[${props.layerId}] Error moving layer:`, error);\n }\n }\n },\n );\n\n onMounted(() => {\n // Final attempt after mount, in case map + style were ready synchronously.\n tryAddLayer();\n });\n\n onBeforeUnmount(() => {\n unbindReadyHandlers();\n });\n</script>\n\n<template>\n <slot></slot>\n</template>\n","import type { MapLayerEventType } from 'maplibre-gl';\n\nexport const mapLayerEvents: Array<keyof MapLayerEventType> = [\n 'click',\n 'dblclick',\n 'mousedown',\n 'mouseup',\n 'mousemove',\n 'mouseenter',\n 'mouseleave',\n 'mouseover',\n 'mouseout',\n 'contextmenu',\n 'touchstart',\n 'touchend',\n 'touchcancel',\n];\n","import type { MapEventType } from 'maplibre-gl';\n\nexport const mapEvents: Array<keyof MapEventType> = [\n 'error',\n 'load',\n 'idle',\n 'remove',\n 'render',\n 'resize',\n 'webglcontextlost',\n 'webglcontextrestored',\n 'dataloading',\n 'data',\n 'tiledataloading',\n 'sourcedataloading',\n 'styledataloading',\n 'sourcedata',\n 'styledata',\n 'boxzoomcancel',\n 'boxzoomstart',\n 'boxzoomend',\n 'touchcancel',\n 'touchmove',\n 'touchend',\n 'touchstart',\n 'click',\n 'contextmenu',\n 'dblclick',\n 'mousemove',\n 'mouseup',\n 'mousedown',\n 'mouseout',\n 'mouseover',\n 'movestart',\n 'move',\n 'moveend',\n 'zoomstart',\n 'zoom',\n 'zoomend',\n 'rotatestart',\n 'rotate',\n 'rotateend',\n 'dragstart',\n 'drag',\n 'dragend',\n 'pitchstart',\n 'pitch',\n 'pitchend',\n 'wheel',\n];\n","export const markerMapEvents = ['dragstart', 'drag', 'dragend'];\nexport const markerDOMEvents = ['click', 'mouseenter', 'mouseleave'];\n","export const popupEvents = ['open', 'close'] as Array<'open' | 'close'>;\n","<script setup lang=\"ts\">\n import { onMounted, onBeforeUnmount, ref, watch } from 'vue';\n import type {\n Map,\n VectorSourceSpecification,\n LayerSpecification,\n } from 'maplibre-gl';\n import { mapLayerEvents } from '../../../constants/events';\n import { injectStrict, MapKey } from '../../../utils';\n\n const props = defineProps<{\n sourceId: string;\n source: VectorSourceSpecification;\n layerId: string;\n layer: LayerSpecification;\n before?: string;\n }>();\n const emit = defineEmits([...mapLayerEvents]);\n\n const map = injectStrict(MapKey);\n\n // Helper function to safely get map instance\n const getMapInstance = (): Map | null => {\n return map.value || null;\n };\n\n // Track if layer has been initialized to prevent duplicate setup\n const initialized = ref(false);\n\n // Bound readiness handlers so they can be removed on unmount / map rebind.\n let boundMap: Map | null = null;\n let styleLoadHandler: (() => void) | null = null;\n let idleHandler: (() => void) | null = null;\n\n // Single, idempotent entry point. Adds the source + layer + events exactly\n // once, but only when the style is loaded. Safe to call from any trigger.\n const tryAddLayer = (): boolean => {\n if (initialized.value) return true;\n\n const mapInstance = getMapInstance();\n if (!mapInstance) return false;\n\n // Style must be ready before sources/layers can be added.\n if (!mapInstance.isStyleLoaded()) return false;\n\n try {\n if (!mapInstance.getSource(props.sourceId)) {\n mapInstance.addSource(props.sourceId, props.source);\n }\n if (!mapInstance.getLayer(props.layerId)) {\n // Always get a fresh beforeId when adding a layer\n if (props.layer.layout?.visibility === 'visible') {\n mapInstance.addLayer(props.layer, props.before);\n } else {\n // For hidden layers, just add them without worrying about order\n mapInstance.addLayer(props.layer);\n }\n }\n setupLayerEvents(mapInstance);\n initialized.value = true;\n return true;\n } catch (error) {\n console.error(`[${props.layerId}] Error setting up layer:`, error);\n return false;\n }\n };\n\n // Bind readiness handlers exactly once, handling BOTH the \"style.load fires\n // after we bind\" case (style.load listener) AND the \"style.load already fired\n // before we bind\" case (synchronous attempt + idle fallback). This fixes the\n // production race where the basemap style loads before the layer mounts\n // (mapbox-gl-js#6707).\n const bindReadyHandlers = (mapInstance: Map): void => {\n if (boundMap === mapInstance) return;\n\n unbindReadyHandlers();\n boundMap = mapInstance;\n\n styleLoadHandler = () => {\n tryAddLayer();\n };\n mapInstance.on('style.load', styleLoadHandler);\n\n idleHandler = () => {\n if (initialized.value) {\n if (idleHandler && boundMap) boundMap.off('idle', idleHandler);\n idleHandler = null;\n return;\n }\n tryAddLayer();\n };\n mapInstance.on('idle', idleHandler);\n\n // Synchronous attempt for the already-fully-loaded case.\n tryAddLayer();\n };\n\n const unbindReadyHandlers = (): void => {\n if (boundMap) {\n if (styleLoadHandler) boundMap.off('style.load', styleLoadHandler);\n if (idleHandler) boundMap.off('idle', idleHandler);\n }\n boundMap = null;\n styleLoadHandler = null;\n idleHandler = null;\n };\n const updateSource = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n const existingSource = mapInstance.getSource(props.sourceId);\n // Only update source if it has actually changed\n if (\n existingSource &&\n JSON.stringify(existingSource.serialize()) !==\n JSON.stringify(props.source)\n ) {\n if (mapInstance.getLayer(props.layerId)) {\n mapInstance.removeLayer(props.layerId);\n }\n mapInstance.removeSource(props.sourceId);\n mapInstance.addSource(props.sourceId, props.source);\n const layerSpec = {\n ...props.layer,\n id: props.layerId,\n source: props.sourceId,\n } as LayerSpecification;\n mapInstance.addLayer(layerSpec, props.before);\n }\n } catch (error) {\n console.error('Error updating vector source:', error);\n }\n };\n const updateLayer = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if (mapInstance.getLayer(props.layerId)) {\n // Get current paint and layout properties\n const currentLayer = mapInstance.getLayer(props.layerId);\n const currentPaint = (currentLayer?.paint || {}) as Record<\n string,\n unknown\n >;\n const currentLayout = (currentLayer?.layout || {}) as Record<\n string,\n unknown\n >;\n\n // Only update properties that have changed\n Object.entries(props.layer.paint || {}).forEach(([key, value]) => {\n if (JSON.stringify(currentPaint[key]) !== JSON.stringify(value)) {\n mapInstance.setPaintProperty(props.layerId, key, value);\n }\n });\n\n Object.entries(props.layer.layout || {}).forEach(([key, value]) => {\n if (JSON.stringify(currentLayout[key]) !== JSON.stringify(value)) {\n mapInstance.setLayoutProperty(props.layerId, key, value);\n }\n });\n }\n } catch (error) {\n console.error('Error updating vector layer:', error);\n }\n };\n const setupLayerEvents = (mapInstance: Map) => {\n if (!mapInstance) return;\n\n try {\n mapLayerEvents.forEach((eventName) => {\n mapInstance.on(eventName, props.layerId, (e) => {\n if (eventName === 'mousemove') {\n mapInstance.getCanvas().style.cursor = 'pointer';\n }\n if (eventName === 'mouseleave') {\n mapInstance.getCanvas().style.cursor = '';\n }\n emit(eventName, e);\n });\n });\n } catch (error) {\n console.error('Error setting up layer events:', error);\n }\n };\n\n // Watchers\n // Watch for map instance changes. Immediate so an already-present map is\n // bound right away; bindReadyHandlers is idempotent and handles the\n // already-loaded style race internally.\n watch(\n map,\n (newMap) => {\n if (newMap) {\n bindReadyHandlers(newMap);\n } else {\n unbindReadyHandlers();\n initialized.value = false;\n }\n },\n { immediate: true },\n );\n watch(\n () => JSON.stringify(props.source.tiles),\n (newTiles, oldTiles) => {\n if (newTiles !== oldTiles) {\n updateSource();\n }\n },\n );\n watch(\n () => ({\n paint: props.layer.paint,\n // Watch layout changes but exclude visibility since it's handled separately\n layout: props.layer.layout\n ? { ...props.layer.layout, visibility: undefined }\n : undefined,\n }),\n (newValue, oldValue) => {\n if (JSON.stringify(newValue) !== JSON.stringify(oldValue)) {\n updateLayer();\n }\n },\n { deep: true },\n );\n watch(\n () => props.layer.layout?.visibility,\n (newVisibility) => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n const hasLayer = mapInstance.getLayer(props.layerId);\n\n if (!hasLayer) {\n // Add layer if it doesn't exist\n try {\n if (!mapInstance.getSource(props.sourceId)) {\n mapInstance.addSource(props.sourceId, props.source);\n }\n mapInstance.addLayer(props.layer, props.before);\n } catch (error) {\n console.error(`[${props.layerId}] Error adding layer:`, error);\n }\n } else {\n try {\n // Update visibility\n mapInstance.setLayoutProperty(\n props.layerId,\n 'visibility',\n newVisibility,\n );\n\n // If becoming visible, ensure proper layer order\n if (newVisibility === 'visible' && props.before) {\n // Small timeout to ensure target layer is ready\n setTimeout(() => {\n mapInstance.moveLayer(props.layerId, props.before);\n }, 0);\n }\n } catch (error) {\n console.error(`[${props.layerId}] Error updating visibility:`, error);\n }\n }\n },\n { immediate: true },\n );\n watch(\n () => props.before,\n (newBefore) => {\n const mapInstance = getMapInstance();\n if (!mapInstance || !mapInstance.getLayer(props.layerId)) return;\n\n // Only move visible layers\n if (props.layer.layout?.visibility === 'visible') {\n try {\n mapInstance.moveLayer(props.layerId, newBefore);\n } catch (error) {\n console.error(\n `Error reordering vector layer ${props.layerId}:`,\n error,\n );\n }\n }\n },\n );\n watch(\n () => props.layer.layout?.visibility,\n (newVisibility) => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n const hasLayer = mapInstance.getLayer(props.layerId);\n\n if (!hasLayer) {\n // Only add layer if it doesn't exist\n try {\n if (!mapInstance.getSource(props.sourceId)) {\n mapInstance.addSource(props.sourceId, props.source);\n }\n mapInstance.addLayer(props.layer, props.before);\n } catch (error) {\n console.error(`[${props.layerId}] Error adding layer:`, error);\n }\n } else {\n // Just update visibility if layer exists\n try {\n mapInstance.setLayoutProperty(\n props.layerId,\n 'visibility',\n newVisibility,\n );\n } catch (error) {\n console.error(`[${props.layerId}] Error updating visibility:`, error);\n }\n }\n },\n { immediate: true },\n );\n onMounted(() => {\n // Final attempt after mount, in case map + style were ready synchronously.\n tryAddLayer();\n });\n\n onBeforeUnmount(() => {\n unbindReadyHandlers();\n });\n</script>\n\n<template>\n <slot></slot>\n</template>\n","<script setup lang=\"ts\">\n import type {\n LayerSpecification as AnyLayer,\n VideoSourceSpecification,\n VideoSource,\n Map,\n } from 'maplibre-gl';\n import type { PropType } from 'vue';\n import { onMounted, onBeforeUnmount, ref, watch } from 'vue';\n import { injectStrict, MapKey } from '../../../utils';\n\n const props = defineProps({\n sourceId: {\n type: String,\n default: 'maplibre.gl-video-source',\n required: true,\n },\n layerId: {\n type: String,\n default: 'maplibre.gl-video-layer',\n required: true,\n },\n source: {\n type: Object as PropType<VideoSourceSpecification>,\n required: true,\n },\n layer: {\n type: Object as PropType<AnyLayer>,\n default: () => ({}),\n required: true,\n },\n before: {\n type: String,\n default: '',\n required: false,\n },\n });\n\n const map = injectStrict(MapKey);\n\n // Helper function to safely get map instance\n const getMapInstance = (): Map | null => {\n return map.value || null;\n };\n\n // Track if layer has been initialized to prevent duplicate setup\n const initialized = ref(false);\n\n // Bound readiness handlers so they can be removed on unmount / map rebind.\n let boundMap: Map | null = null;\n let styleLoadHandler: (() => void) | null = null;\n let idleHandler: (() => void) | null = null;\n\n // Single, idempotent entry point. Adds the source + layer exactly once, but\n // only when the style is loaded. Safe to call from any trigger.\n const tryAddLayer = (): boolean => {\n if (initialized.value) return true;\n\n const mapInstance = getMapInstance();\n if (!mapInstance) return false;\n\n // Style must be ready before sources/layers can be added.\n if (!mapInstance.isStyleLoaded()) return false;\n\n try {\n if (!mapInstance.getSource(props.sourceId)) {\n mapInstance.addSource(props.sourceId, props.source);\n }\n if (!mapInstance.getLayer(props.layerId)) {\n const layerSpec = {\n ...props.layer,\n id: props.layerId,\n source: props.sourceId,\n } as AnyLayer;\n mapInstance.addLayer(layerSpec, props.before);\n }\n initialized.value = true;\n return true;\n } catch (error) {\n console.error('Error adding Video layer:', error);\n return false;\n }\n };\n\n // Bind readiness handlers exactly once, handling BOTH the \"style.load fires\n // after we bind\" case (style.load listener) AND the \"style.load already fired\n // before we bind\" case (synchronous attempt + idle fallback). This fixes the\n // production race where the basemap style loads before the layer mounts\n // (mapbox-gl-js#6707).\n const bindReadyHandlers = (mapInstance: Map): void => {\n if (boundMap === mapInstance) return;\n\n unbindReadyHandlers();\n boundMap = mapInstance;\n\n styleLoadHandler = () => {\n tryAddLayer();\n };\n mapInstance.on('style.load', styleLoadHandler);\n\n idleHandler = () => {\n if (initialized.value) {\n if (idleHandler && boundMap) boundMap.off('idle', idleHandler);\n idleHandler = null;\n return;\n }\n tryAddLayer();\n };\n mapInstance.on('idle', idleHandler);\n\n // Synchronous attempt for the already-fully-loaded case.\n tryAddLayer();\n };\n\n const unbindReadyHandlers = (): void => {\n if (boundMap) {\n if (styleLoadHandler) boundMap.off('style.load', styleLoadHandler);\n if (idleHandler) boundMap.off('idle', idleHandler);\n }\n boundMap = null;\n styleLoadHandler = null;\n idleHandler = null;\n };\n\n const updateSource = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n const source = mapInstance.getSource(props.sourceId) as VideoSource;\n if (source) {\n // For video sources, we need to remove and re-add since there's no direct update method\n if (mapInstance.getLayer(props.layerId)) {\n mapInstance.removeLayer(props.layerId);\n }\n if (mapInstance.getSource(props.sourceId)) {\n mapInstance.removeSource(props.sourceId);\n }\n\n mapInstance.addSource(props.sourceId, props.source);\n const layerSpec = {\n ...props.layer,\n id: props.layerId,\n source: props.sourceId,\n } as AnyLayer;\n mapInstance.addLayer(layerSpec, props.before);\n\n // Additional video-specific operations if needed\n if (source.getVideo) {\n const videoElement = source.getVideo();\n if (videoElement) {\n // Handle video element updates if needed\n videoElement.play().catch((error) => {\n console.error('Error playing video:', error);\n });\n }\n }\n }\n } catch (error) {\n console.error('Error updating Video source:', error);\n }\n };\n\n const updateLayer = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if (mapInstance.getLayer(props.layerId)) {\n Object.entries(props.layer.paint || {}).forEach(([key, value]) => {\n mapInstance.setPaintProperty(props.layerId, key, value);\n });\n Object.entries(props.layer.layout || {}).forEach(([key, value]) => {\n mapInstance.setLayoutProperty(props.layerId, key, value);\n });\n }\n } catch (error) {\n console.error('Error updating Video layer:', error);\n }\n };\n\n // Watchers\n watch(() => props.source, updateSource, { deep: true });\n watch(() => props.layer, updateLayer, { deep: true });\n\n // Watch for map instance changes. Immediate so an already-present map is\n // bound right away; bindReadyHandlers is idempotent and handles the\n // already-loaded style race internally.\n watch(\n map,\n (newMap) => {\n if (newMap) {\n bindReadyHandlers(newMap);\n } else {\n unbindReadyHandlers();\n initialized.value = false;\n }\n },\n { immediate: true },\n );\n\n // Lifecycle hooks\n onMounted(() => {\n // Final attempt after mount, in case map + style were ready synchronously.\n tryAddLayer();\n });\n\n onBeforeUnmount(() => {\n unbindReadyHandlers();\n\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n const source = mapInstance.getSource(props.sourceId) as VideoSource;\n if (source?.getVideo) {\n const videoElement = source.getVideo();\n if (videoElement) {\n // Stop and cleanup video if needed\n videoElement.pause();\n videoElement.remove();\n }\n }\n\n if (mapInstance.getLayer(props.layerId)) {\n mapInstance.removeLayer(props.layerId);\n }\n if (mapInstance.getSource(props.sourceId)) {\n mapInstance.removeSource(props.sourceId);\n }\n } catch (error) {\n console.error('Error cleaning up Video layer:', error);\n }\n });\n</script>\n\n<template>\n <slot></slot>\n</template>\n","<script setup lang=\"ts\">\n import { PMTiles } from 'pmtiles';\n import { inject, onMounted, ref } from 'vue';\n import type { PropType } from 'vue';\n import type {\n RasterLayerSpecification,\n RasterSourceSpecification,\n } from 'maplibre-gl';\n import VLayerMaplibreRaster from '../raster/VLayerMaplibreRaster.vue';\n import { PMTileProtocolKey } from '../../../utils/symbols';\n\n const props = defineProps({\n sourceId: {\n type: String,\n default: 'maplibre.gl-pmtile-source',\n required: true,\n },\n layerId: {\n type: String,\n default: 'maplibre.gl-pmtile-layer',\n required: true,\n },\n url: {\n type: String,\n required: true,\n },\n layer: {\n type: Object as PropType<RasterLayerSpecification>,\n default: () => ({}),\n required: true,\n },\n before: {\n type: String,\n default: '',\n required: false,\n },\n });\n\n const protocol = inject(PMTileProtocolKey);\n if (!protocol) {\n throw new Error('Protocol not provided');\n }\n\n const source = ref<RasterSourceSpecification>({\n type: 'raster',\n url: `pmtiles://${props.url}`,\n tileSize: 512,\n volatile: true,\n });\n onMounted(async () => {\n const p = new PMTiles(props.url);\n protocol.add(p);\n // Optional: You could fetch the header here if you need metadata\n // const header = await p.getHeader();\n });\n</script>\n\n<template>\n <VLayerMaplibreRaster\n :source-id=\"sourceId\"\n :layer-id=\"layerId\"\n :source=\"source\"\n :layer=\"{\n ...layer,\n type: 'raster',\n }\"\n :before=\"before\"\n ></VLayerMaplibreRaster>\n</template>\n","<!-- web/app/lib/v-mapbox/layers/maplibre/cluster/VLayerMaplibreCluster.vue -->\n<script setup lang=\"ts\">\n import type { Ref } from 'vue';\n import { onMounted, onBeforeUnmount, ref, watch, computed } from 'vue';\n import type {\n GeoJSONSource,\n GeoJSONSourceSpecification,\n CircleLayerSpecification,\n SymbolLayerSpecification,\n Map,\n MapLayerMouseEvent,\n DataDrivenPropertyValueSpecification,\n } from 'maplibre-gl';\n import { injectStrict, MapKey } from '../../../../utils';\n\n interface LayerClick {\n features: GeoJSON.Feature[];\n coordinates: {\n lng: number;\n lat: number;\n };\n }\n\n interface Props {\n sourceId: string;\n baseLayerId: string;\n source: GeoJSONSourceSpecification;\n visibility?: boolean;\n clusterPaint?: {\n colors?: string[];\n radii?: number[];\n breakpoints?: number[];\n };\n unclusteredPaint?: {\n color?: DataDrivenPropertyValueSpecification<string>;\n radius?: number;\n };\n textPaint?: {\n color?: string;\n font?: string[];\n size?: number;\n };\n }\n\n const props = withDefaults(defineProps<Props>(), {\n sourceId: 'cluster-source',\n baseLayerId: 'cluster',\n visibility: true,\n clusterPaint: () => ({\n colors: ['#51bbd6', '#f1f075', '#f28cb1'],\n radii: [20, 30, 40],\n breakpoints: [100, 750],\n }),\n unclusteredPaint: () => ({\n color: '#51bbd6',\n radius: 6,\n }),\n textPaint: () => ({\n color: '#ffffff',\n font: ['DIN Offc Pro Medium', 'Arial Unicode MS Bold'],\n size: 12,\n }),\n });\n\n const emit = defineEmits<{\n 'cluster-click': [event: LayerClick];\n 'point-click': [event: LayerClick];\n }>();\n\n const map = injectStrict(MapKey);\n const loaded: Ref<boolean> = ref(false);\n\n // Layer IDs\n const clustersLayerId = computed(() => `${props.baseLayerId}-clusters`);\n const clusterCountLayerId = computed(\n () => `${props.baseLayerId}-cluster-count`,\n );\n const unclusteredLayerId = computed(\n () => `${props.baseLayerId}-unclustered-point`,\n );\n\n // Helper function to safely get map instance\n const getMapInstance = (): Map | null => {\n return map.value || null;\n };\n\n // Helper to check if data is valid GeoJSON with features\n const hasValidData = (data: string | GeoJSON.GeoJSON): boolean => {\n if (typeof data === 'string') return false;\n if (data && typeof data === 'object' && 'type' in data) {\n if (data.type === 'FeatureCollection' && 'features' in data) {\n return data.features.length > 0;\n }\n }\n return false;\n };\n\n // Add all cluster-related layers at once\n const addClusterLayers = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance || !mapInstance.isStyleLoaded()) {\n return;\n }\n\n try {\n // 1. Add source if it doesn't exist\n if (!mapInstance.getSource(props.sourceId)) {\n console.log(`Adding clustered source: ${props.sourceId}`);\n mapInstance.addSource(props.sourceId, {\n ...props.source,\n cluster: true,\n clusterMaxZoom: 14,\n clusterRadius: 50,\n });\n } else {\n // If source exists, update its data\n const source = mapInstance.getSource(props.sourceId) as GeoJSONSource;\n if (source && 'setData' in source) {\n source.setData(props.source.data);\n }\n }\n\n // 2. Add clusters layer\n if (!mapInstance.getLayer(clustersLayerId.value)) {\n console.log(`Adding clusters layer: ${clustersLayerId.value}`);\n mapInstance.addLayer({\n id: clustersLayerId.value,\n type: 'circle',\n source: props.sourceId,\n filter: ['has', 'point_count'],\n paint: {\n 'circle-color': [\n 'step',\n ['get', 'point_count'],\n props.clusterPaint.colors![0]!,\n props.clusterPaint.breakpoints![0]!,\n props.clusterPaint.colors![1]!,\n props.clusterPaint.breakpoints![1]!,\n props.clusterPaint.colors![2]!,\n ],\n 'circle-radius': [\n 'step',\n ['get', 'point_count'],\n props.clusterPaint.radii![0]!,\n props.clusterPaint.breakpoints![0]!,\n props.clusterPaint.radii![1]!,\n props.clusterPaint.breakpoints![1]!,\n props.clusterPaint.radii![2]!,\n ],\n 'circle-stroke-width': 2,\n 'circle-stroke-color': '#ffffff',\n 'circle-opacity': 0.9,\n },\n layout: {\n visibility: props.visibility ? 'visible' : 'none',\n },\n } as CircleLayerSpecification);\n }\n\n // 3. Add cluster count text layer\n if (!mapInstance.getLayer(clusterCountLayerId.value)) {\n console.log(`Adding cluster count layer: ${clusterCountLayerId.value}`);\n mapInstance.addLayer({\n id: clusterCountLayerId.value,\n type: 'symbol',\n source: props.sourceId,\n filter: ['has', 'point_count'],\n layout: {\n 'text-field': '{point_count_abbreviated}',\n 'text-font': props.textPaint.font!,\n 'text-size': props.textPaint.size!,\n visibility: props.visibility ? 'visible' : 'none',\n },\n paint: {\n 'text-color': props.textPaint.color!,\n },\n } as SymbolLayerSpecification);\n }\n\n // 4. Add unclustered points layer\n if (!mapInstance.getLayer(unclusteredLayerId.value)) {\n console.log(\n `Adding unclustered points layer: ${unclusteredLayerId.value}`,\n );\n mapInstance.addLayer({\n id: unclusteredLayerId.value,\n type: 'circle',\n source: props.sourceId,\n filter: ['!', ['has', 'point_count']],\n paint: {\n 'circle-color': props.unclusteredPaint.color!,\n 'circle-radius': props.unclusteredPaint.radius!,\n 'circle-stroke-width': 2,\n 'circle-stroke-color': '#ffffff',\n 'circle-opacity': 0.95,\n },\n layout: {\n visibility: props.visibility ? 'visible' : 'none',\n },\n } as CircleLayerSpecification);\n }\n\n console.log(`All cluster layers added for ${props.baseLayerId}`);\n\n // Setup click handlers after layers are added\n setupLayerEvents(mapInstance);\n } catch (error) {\n console.error('Error adding cluster layers:', error);\n }\n };\n\n // Update source data\n const updateSource = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n const source = mapInstance.getSource(props.sourceId) as\n | GeoJSONSource\n | undefined;\n if (source && 'setData' in source) {\n console.log(`Updating source ${props.sourceId} with data`);\n source.setData(props.source.data);\n\n // After updating data, ensure all layers are properly added\n // This fixes the issue where layers might not render correctly with initial empty data\n setTimeout(() => {\n // Re-add layers if they're missing (this won't duplicate them)\n addClusterLayers();\n }, 100);\n } else if (!source) {\n // Source doesn't exist, add all layers\n addClusterLayers();\n }\n } catch (error) {\n console.error('Error updating source:', error);\n }\n };\n\n // Update visibility for all layers\n const updateVisibility = (visible: boolean): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n const visibility = visible ? 'visible' : 'none';\n\n [\n clustersLayerId.value,\n clusterCountLayerId.value,\n unclusteredLayerId.value,\n ].forEach((layerId) => {\n if (mapInstance.getLayer(layerId)) {\n mapInstance.setLayoutProperty(layerId, 'visibility', visibility);\n }\n });\n };\n\n // Setup click handlers for layers\n const setupLayerEvents = (mapInstance: Map) => {\n if (!mapInstance) return;\n\n try {\n // Click handler for clusters\n mapInstance.on(\n 'click',\n clustersLayerId.value,\n (e: MapLayerMouseEvent) => {\n if (e.features && e.features.length > 0) {\n emit('cluster-click', {\n features: e.features,\n coordinates: e.lngLat,\n });\n }\n },\n );\n\n // Click handler for individual points\n mapInstance.on(\n 'click',\n unclusteredLayerId.value,\n (e: MapLayerMouseEvent) => {\n if (e.features && e.features.length > 0) {\n emit('point-click', {\n features: e.features,\n coordinates: e.lngLat,\n });\n }\n },\n );\n\n // Add hover effects\n [clustersLayerId.value, unclusteredLayerId.value].forEach((layerId) => {\n mapInstance.on('mouseenter', layerId, () => {\n mapInstance.getCanvas().style.cursor = 'pointer';\n });\n\n mapInstance.on('mouseleave', layerId, () => {\n mapInstance.getCanvas().style.cursor = '';\n });\n });\n } catch (error) {\n console.error('Error setting up layer events:', error);\n }\n };\n\n // Setup map\n const setupMap = (mapInstance: Map) => {\n if (!mapInstance) return;\n\n mapInstance.on('style.load', () => {\n const checkStyleLoaded = () => {\n if (!mapInstance.isStyleLoaded()) {\n loaded.value = false;\n setTimeout(checkStyleLoaded, 200);\n } else {\n loaded.value = true;\n // Only add layers if we have data\n if (hasValidData(props.source.data)) {\n addClusterLayers();\n }\n }\n };\n checkStyleLoaded();\n });\n\n // If style is already loaded\n if (mapInstance.isStyleLoaded()) {\n loaded.value = true;\n // Only add layers if we have data\n if (hasValidData(props.source.data)) {\n addClusterLayers();\n }\n }\n };\n\n // Watchers\n watch(\n () => props.source.data,\n (newData) => {\n // Only proceed if we have actual data\n if (hasValidData(newData)) {\n const mapInstance = getMapInstance();\n if (mapInstance?.isStyleLoaded()) {\n // First time with data - add all layers\n if (!mapInstance.getSource(props.sourceId)) {\n addClusterLayers();\n } else {\n // Source exists, just update data\n updateSource();\n }\n }\n }\n },\n { deep: true, immediate: true },\n );\n\n watch(() => props.visibility, updateVisibility);\n\n watch(\n map,\n (newMap) => {\n if (newMap) {\n setupMap(newMap);\n }\n },\n { immediate: true },\n );\n\n // Lifecycle\n onMounted(() => {\n const mapInstance = getMapInstance();\n // Only add layers if map is ready AND we have data\n if (mapInstance?.isStyleLoaded() && hasValidData(props.source.data)) {\n addClusterLayers();\n }\n });\n\n onBeforeUnmount(() => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n // Remove click handlers\n [clustersLayerId.value, unclusteredLayerId.value].forEach((layerId) => {\n mapInstance.off('click', layerId, () => {});\n mapInstance.off('mouseenter', layerId, () => {});\n mapInstance.off('mouseleave', layerId, () => {});\n });\n\n // Remove all layers\n [\n clustersLayerId.value,\n clusterCountLayerId.value,\n unclusteredLayerId.value,\n ].forEach((layerId) => {\n if (mapInstance.getLayer(layerId)) {\n mapInstance.removeLayer(layerId);\n }\n });\n\n // Remove source\n if (mapInstance.getSource(props.sourceId)) {\n mapInstance.removeSource(props.sourceId);\n }\n } catch (error) {\n console.error('Error cleaning up cluster layers:', error);\n }\n });\n</script>\n\n<template>\n <slot></slot>\n</template>\n","<script setup lang=\"ts\">\n import type { Ref } from 'vue';\n import { onMounted, onBeforeUnmount, ref, watch, computed } from 'vue';\n import type {\n GeoJSONSource,\n Map,\n MapLayerMouseEvent,\n LineLayerSpecification,\n } from 'maplibre-gl';\n import { injectStrict, MapKey } from '../../../../utils';\n\n interface RouteClick {\n coordinates: {\n lng: number;\n lat: number;\n };\n }\n\n interface Props {\n /** Unique identifier for the route */\n id?: string;\n /** Array of [longitude, latitude] coordinate pairs defining the route */\n coordinates: [number, number][];\n /** Line color as CSS color value */\n color?: string;\n /** Line width in pixels */\n width?: number;\n /** Line opacity (0-1) */\n opacity?: number;\n /** Line cap style */\n lineCap?: 'butt' | 'round' | 'square';\n /** Line join style */\n lineJoin?: 'bevel' | 'round' | 'miter';\n /** Whether the route is visible */\n visible?: boolean;\n /** Whether the route is interactive (shows pointer cursor on hover) */\n interactive?: boolean;\n /** Render this layer before the specified layer */\n before?: string;\n /** Line dash array for dashed lines */\n dashArray?: number[];\n /** Line blur in pixels */\n blur?: number;\n }\n\n const props = withDefaults(defineProps<Props>(), {\n id: () => `route-${Math.random().toString(36).slice(2, 9)}`,\n color: '#4285F4',\n width: 4,\n opacity: 1,\n lineCap: 'round',\n lineJoin: 'round',\n visible: true,\n interactive: true,\n before: '',\n blur: 0,\n });\n\n const emit = defineEmits<{\n click: [event: RouteClick];\n mouseenter: [];\n mouseleave: [];\n }>();\n\n const map = injectStrict(MapKey);\n const loaded: Ref<boolean> = ref(false);\n\n const sourceId = computed(() => `${props.id}-source`);\n const layerId = computed(() => `${props.id}-layer`);\n\n // Create GeoJSON data from coordinates\n const geojsonData = computed(\n (): GeoJSON.FeatureCollection<GeoJSON.LineString> => ({\n type: 'FeatureCollection',\n features:\n props.coordinates.length >= 2\n ? [\n {\n type: 'Feature',\n properties: {},\n geometry: {\n type: 'LineString',\n coordinates: props.coordinates,\n },\n },\n ]\n : [],\n }),\n );\n\n // Helper function to safely get map instance\n const getMapInstance = (): Map | null => {\n return map.value || null;\n };\n\n // Setup map style load listener\n const setupMap = (mapInstance: Map) => {\n if (!mapInstance) return;\n\n mapInstance.on('style.load', () => {\n const styleTimeout = () => {\n if (!mapInstance.isStyleLoaded()) {\n loaded.value = false;\n setTimeout(styleTimeout, 200);\n } else {\n loaded.value = true;\n }\n };\n styleTimeout();\n });\n };\n\n const addLayer = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance || !mapInstance.isStyleLoaded()) return;\n\n // Don't add if no valid coordinates\n if (props.coordinates.length < 2) return;\n\n try {\n // Only add source if it doesn't exist\n if (!mapInstance.getSource(sourceId.value)) {\n mapInstance.addSource(sourceId.value, {\n type: 'geojson',\n data: geojsonData.value,\n });\n }\n\n // Only add layer if it doesn't exist\n if (!mapInstance.getLayer(layerId.value)) {\n const layerSpec: LineLayerSpecification = {\n id: layerId.value,\n type: 'line',\n source: sourceId.value,\n layout: {\n 'line-cap': props.lineCap,\n 'line-join': props.lineJoin,\n visibility: props.visible ? 'visible' : 'none',\n },\n paint: {\n 'line-color': props.color,\n 'line-width': props.width,\n 'line-opacity': props.opacity,\n ...(props.blur > 0 && { 'line-blur': props.blur }),\n ...(props.dashArray && { 'line-dasharray': props.dashArray }),\n },\n };\n\n mapInstance.addLayer(layerSpec, props.before || undefined);\n }\n } catch (error) {\n console.error('Error adding route layer:', error);\n }\n };\n\n const updateSource = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n const source = mapInstance.getSource(sourceId.value) as\n | GeoJSONSource\n | undefined;\n\n if (source && 'setData' in source) {\n source.setData(geojsonData.value);\n } else if (!source && props.coordinates.length >= 2) {\n addLayer();\n }\n } catch (error) {\n console.error('Error updating route source:', error);\n }\n };\n\n const updateLayerStyle = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance || !mapInstance.getLayer(layerId.value)) return;\n\n try {\n // Update paint properties\n mapInstance.setPaintProperty(layerId.value, 'line-color', props.color);\n mapInstance.setPaintProperty(layerId.value, 'line-width', props.width);\n mapInstance.setPaintProperty(\n layerId.value,\n 'line-opacity',\n props.opacity,\n );\n\n if (props.blur > 0) {\n mapInstance.setPaintProperty(layerId.value, 'line-blur', props.blur);\n }\n if (props.dashArray) {\n mapInstance.setPaintProperty(\n layerId.value,\n 'line-dasharray',\n props.dashArray,\n );\n }\n\n // Update layout properties\n mapInstance.setLayoutProperty(layerId.value, 'line-cap', props.lineCap);\n mapInstance.setLayoutProperty(layerId.value, 'line-join', props.lineJoin);\n mapInstance.setLayoutProperty(\n layerId.value,\n 'visibility',\n props.visible ? 'visible' : 'none',\n );\n } catch (error) {\n console.error('Error updating route layer style:', error);\n }\n };\n\n const setupLayerEvents = (mapInstance: Map) => {\n if (!mapInstance || !props.interactive) return;\n\n try {\n // Click handler\n mapInstance.on('click', layerId.value, (e: MapLayerMouseEvent) => {\n emit('click', {\n coordinates: e.lngLat,\n });\n });\n\n // Hover effects\n mapInstance.on('mouseenter', layerId.value, () => {\n mapInstance.getCanvas().style.cursor = 'pointer';\n emit('mouseenter');\n });\n\n mapInstance.on('mouseleave', layerId.value, () => {\n mapInstance.getCanvas().style.cursor = '';\n emit('mouseleave');\n });\n } catch (error) {\n console.error('Error setting up route layer events:', error);\n }\n };\n\n // Watch for coordinate changes\n watch(\n () => props.coordinates,\n () => {\n const mapInstance = getMapInstance();\n if (mapInstance?.isStyleLoaded()) {\n if (!mapInstance.getSource(sourceId.value)) {\n addLayer();\n } else {\n updateSource();\n }\n }\n },\n { deep: true },\n );\n\n // Watch for style changes\n watch(\n () => [\n props.color,\n props.width,\n props.opacity,\n props.lineCap,\n props.lineJoin,\n props.visible,\n props.blur,\n props.dashArray,\n ],\n () => updateLayerStyle(),\n { deep: true },\n );\n\n // Watch for map instance changes\n watch(\n map,\n (newMap) => {\n if (newMap) {\n setupMap(newMap);\n if (newMap.isStyleLoaded()) {\n loaded.value = true;\n }\n }\n },\n { immediate: true },\n );\n\n // Watch loaded state\n watch(loaded, (value) => {\n if (value && props.coordinates.length >= 2) {\n const mapInstance = getMapInstance();\n if (mapInstance) {\n addLayer();\n setupLayerEvents(mapInstance);\n }\n }\n });\n\n // Lifecycle hooks\n onMounted(() => {\n try {\n const mapInstance = getMapInstance();\n if (mapInstance?.isStyleLoaded() && props.coordinates.length >= 2) {\n addLayer();\n setupLayerEvents(mapInstance);\n }\n } catch (error) {\n console.error('Error mounting route layer:', error);\n }\n });\n\n onBeforeUnmount(() => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if (mapInstance.getLayer(layerId.value)) {\n mapInstance.removeLayer(layerId.value);\n }\n if (mapInstance.getSource(sourceId.value)) {\n mapInstance.removeSource(sourceId.value);\n }\n } catch (error) {\n console.error('Error cleaning up route layer:', error);\n }\n });\n</script>\n\n<template>\n <slot></slot>\n</template>\n","<script setup lang=\"ts\">\n import type { Ref } from 'vue';\n import {\n onMounted,\n onBeforeUnmount,\n ref,\n watch,\n computed,\n nextTick,\n } from 'vue';\n import type {\n GeoJSONSource,\n Map,\n MapLayerMouseEvent,\n FillLayerSpecification,\n LineLayerSpecification,\n } from 'maplibre-gl';\n import { injectStrict, MapKey } from '../../../../utils';\n\n interface IsochroneFeature {\n type: 'Feature';\n properties: {\n color: string;\n contour?: number;\n metric?: string;\n [key: string]: unknown;\n };\n geometry: GeoJSON.Polygon | GeoJSON.MultiPolygon;\n }\n\n interface IsochroneData {\n type: 'FeatureCollection';\n features: IsochroneFeature[];\n }\n\n interface IsochroneClick {\n feature: IsochroneFeature;\n coordinates: {\n lng: number;\n lat: number;\n };\n }\n\n interface Props {\n /** Unique identifier for the isochrone layer */\n id?: string;\n /** GeoJSON FeatureCollection with isochrone polygons (from Valhalla, OSRM, etc.) */\n data: IsochroneData | null;\n /** Fill opacity (0-1) */\n fillOpacity?: number;\n /** Line width in pixels for polygon outlines */\n lineWidth?: number;\n /** Line opacity (0-1) */\n lineOpacity?: number;\n /** Whether the layer is visible */\n visible?: boolean;\n /** Whether the layer is interactive (shows pointer cursor on hover) */\n interactive?: boolean;\n /** Render this layer before the specified layer */\n before?: string;\n /** Whether to reverse the feature order (for proper stacking of overlapping polygons) */\n reverseOrder?: boolean;\n }\n\n const props = withDefaults(defineProps<Props>(), {\n id: () => `isochrone-${Math.random().toString(36).slice(2, 9)}`,\n fillOpacity: 0.4,\n lineWidth: 2,\n lineOpacity: 0.8,\n visible: true,\n interactive: true,\n before: '',\n reverseOrder: true,\n });\n\n const emit = defineEmits<{\n click: [event: IsochroneClick];\n mouseenter: [feature: IsochroneFeature];\n mouseleave: [];\n }>();\n\n const map = injectStrict(MapKey);\n const loaded: Ref<boolean> = ref(false);\n const initialized = ref(false);\n\n const sourceId = computed(() => `${props.id}-source`);\n const fillLayerId = computed(() => `${props.id}-fill`);\n const lineLayerId = computed(() => `${props.id}-line`);\n\n /**\n * Process the GeoJSON data:\n * 1. Optionally reverse feature order for proper polygon stacking\n * 2. Add fillColor property with # prefix (Valhalla returns colors without #)\n */\n const processedData = computed((): IsochroneData | null => {\n if (!props.data || !props.data.features || props.data.features.length === 0)\n return null;\n\n const features = props.reverseOrder\n ? [...props.data.features].reverse()\n : props.data.features;\n\n return {\n type: 'FeatureCollection',\n features: features.map((f) => ({\n ...f,\n properties: {\n ...f.properties,\n // Add # prefix if color doesn't have it (Valhalla format)\n fillColor: f.properties.color.startsWith('#')\n ? f.properties.color\n : `#${f.properties.color}`,\n },\n })),\n };\n });\n\n // Helper function to safely get map instance\n const getMapInstance = (): Map | null => {\n return map.value || null;\n };\n\n // Setup map style load listener\n const setupMap = (mapInstance: Map) => {\n if (!mapInstance) return;\n\n mapInstance.on('style.load', () => {\n const styleTimeout = () => {\n if (!mapInstance.isStyleLoaded()) {\n loaded.value = false;\n setTimeout(styleTimeout, 200);\n } else {\n loaded.value = true;\n }\n };\n styleTimeout();\n });\n };\n\n const addLayers = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance || !mapInstance.isStyleLoaded()) return;\n\n const data = processedData.value;\n if (!data) return;\n\n try {\n // Add source if it doesn't exist\n if (!mapInstance.getSource(sourceId.value)) {\n mapInstance.addSource(sourceId.value, {\n type: 'geojson',\n data,\n });\n }\n\n // Add fill layer\n if (!mapInstance.getLayer(fillLayerId.value)) {\n const fillLayerSpec: FillLayerSpecification = {\n id: fillLayerId.value,\n type: 'fill',\n source: sourceId.value,\n layout: {\n visibility: props.visible ? 'visible' : 'none',\n },\n paint: {\n 'fill-color': ['get', 'fillColor'],\n 'fill-opacity': props.fillOpacity,\n },\n };\n\n mapInstance.addLayer(fillLayerSpec, props.before || undefined);\n }\n\n // Add line layer\n if (!mapInstance.getLayer(lineLayerId.value)) {\n const lineLayerSpec: LineLayerSpecification = {\n id: lineLayerId.value,\n type: 'line',\n source: sourceId.value,\n layout: {\n visibility: props.visible ? 'visible' : 'none',\n },\n paint: {\n 'line-color': ['get', 'fillColor'],\n 'line-width': props.lineWidth,\n 'line-opacity': props.lineOpacity,\n },\n };\n\n mapInstance.addLayer(lineLayerSpec, props.before || undefined);\n }\n } catch (error) {\n console.error('Error adding isochrone layers:', error);\n }\n };\n\n const updateSource = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n const source = mapInstance.getSource(sourceId.value) as\n | GeoJSONSource\n | undefined;\n\n const data = processedData.value;\n\n if (source && 'setData' in source) {\n if (data) {\n source.setData(data);\n }\n } else if (!source && data) {\n addLayers();\n }\n } catch (error) {\n console.error('Error updating isochrone source:', error);\n }\n };\n\n const updateLayerStyle = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n // Update fill layer\n if (mapInstance.getLayer(fillLayerId.value)) {\n mapInstance.setPaintProperty(\n fillLayerId.value,\n 'fill-opacity',\n props.fillOpacity,\n );\n mapInstance.setLayoutProperty(\n fillLayerId.value,\n 'visibility',\n props.visible ? 'visible' : 'none',\n );\n }\n\n // Update line layer\n if (mapInstance.getLayer(lineLayerId.value)) {\n mapInstance.setPaintProperty(\n lineLayerId.value,\n 'line-width',\n props.lineWidth,\n );\n mapInstance.setPaintProperty(\n lineLayerId.value,\n 'line-opacity',\n props.lineOpacity,\n );\n mapInstance.setLayoutProperty(\n lineLayerId.value,\n 'visibility',\n props.visible ? 'visible' : 'none',\n );\n }\n } catch (error) {\n console.error('Error updating isochrone layer style:', error);\n }\n };\n\n const setupLayerEvents = (mapInstance: Map) => {\n if (!mapInstance || !props.interactive) return;\n\n try {\n // Click handler on fill layer\n mapInstance.on('click', fillLayerId.value, (e: MapLayerMouseEvent) => {\n if (e.features && e.features.length > 0) {\n emit('click', {\n feature: e.features[0] as unknown as IsochroneFeature,\n coordinates: e.lngLat,\n });\n }\n });\n\n // Hover effects\n mapInstance.on(\n 'mouseenter',\n fillLayerId.value,\n (e: MapLayerMouseEvent) => {\n mapInstance.getCanvas().style.cursor = 'pointer';\n if (e.features && e.features.length > 0) {\n emit('mouseenter', e.features[0] as unknown as IsochroneFeature);\n }\n },\n );\n\n mapInstance.on('mouseleave', fillLayerId.value, () => {\n mapInstance.getCanvas().style.cursor = '';\n emit('mouseleave');\n });\n } catch (error) {\n console.error('Error setting up isochrone layer events:', error);\n }\n };\n\n // Single initialization function to prevent race conditions\n const initializeLayers = async () => {\n if (initialized.value) return;\n\n const mapInstance = getMapInstance();\n if (!mapInstance || !mapInstance.isStyleLoaded()) return;\n if (!processedData.value) return;\n\n // Wait for next tick to ensure all watchers are set up\n await nextTick();\n\n // Double-check we haven't been initialized during the tick\n if (initialized.value) return;\n\n addLayers();\n setupLayerEvents(mapInstance);\n initialized.value = true;\n };\n\n // Watch for data changes\n watch(\n () => props.data,\n () => {\n const mapInstance = getMapInstance();\n if (mapInstance?.isStyleLoaded()) {\n if (!mapInstance.getSource(sourceId.value)) {\n addLayers();\n } else {\n updateSource();\n }\n }\n },\n { deep: true },\n );\n\n // Watch for style changes\n watch(\n () => [\n props.fillOpacity,\n props.lineWidth,\n props.lineOpacity,\n props.visible,\n ],\n () => updateLayerStyle(),\n { deep: true },\n );\n\n // IMPORTANT: watch(loaded) must be defined BEFORE watch(map) with immediate: true\n // Otherwise, when map watcher sets loaded.value = true, this watcher won't catch it\n watch(loaded, (value) => {\n if (value) {\n initializeLayers();\n }\n });\n\n // Watch for map instance changes\n watch(\n map,\n (newMap) => {\n if (newMap) {\n setupMap(newMap);\n if (newMap.isStyleLoaded()) {\n loaded.value = true;\n // Also call initializeLayers directly in case loaded watcher already ran\n initializeLayers();\n }\n }\n },\n { immediate: true },\n );\n\n // Lifecycle hooks\n onMounted(() => {\n // Use nextTick to ensure all watchers are registered\n nextTick(() => {\n initializeLayers();\n });\n });\n\n onBeforeUnmount(() => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n // Remove layers\n if (mapInstance.getLayer(lineLayerId.value)) {\n mapInstance.removeLayer(lineLayerId.value);\n }\n if (mapInstance.getLayer(fillLayerId.value)) {\n mapInstance.removeLayer(fillLayerId.value);\n }\n // Remove source\n if (mapInstance.getSource(sourceId.value)) {\n mapInstance.removeSource(sourceId.value);\n }\n } catch (error) {\n console.error('Error cleaning up isochrone layer:', error);\n }\n });\n</script>\n\n<template>\n <slot></slot>\n</template>\n","<script setup lang=\"ts\">\n import maplibregl, { Map } from 'maplibre-gl';\n import { Protocol } from 'pmtiles';\n import { onMounted, provide, ref, shallowRef } from 'vue';\n import type { MapOptions, MapEventType } from 'maplibre-gl';\n import type { Ref } from 'vue';\n import { mapEvents } from '../constants/events';\n import { MapKey, PMTileProtocolKey } from '../utils/symbols';\n import { useDeckOverlay } from '../layers/deckgl/_shared/useDeckOverlay';\n\n const props = withDefaults(\n defineProps<{\n options: MapOptions;\n supportPmtiles?: boolean;\n projection?: 'globe' | 'mercator';\n }>(),\n {\n options: () => ({ container: 'map' }) as MapOptions,\n supportPmtiles: false,\n projection: 'mercator',\n },\n );\n const emit = defineEmits(['loaded', ...mapEvents]);\n\n if (props.supportPmtiles) {\n const protocol = new Protocol({ metadata: true });\n maplibregl.addProtocol('pmtiles', protocol.tile);\n provide(PMTileProtocolKey, protocol);\n }\n\n const map: Ref<Map | null> = shallowRef(null); // Initialize as null\n const loaded: Ref<boolean> = ref(false);\n const events: Ref<Array<keyof MapEventType>> = ref(mapEvents);\n\n // Provide the map reference immediately\n provide(MapKey, map);\n\n // Initialize deck.gl overlay at VMap level so all children can access it\n // This provides DeckOverlayKey and DeckLayersKey to all descendants\n useDeckOverlay(map, { globe: props.projection === 'globe' });\n\n onMounted(() => {\n map.value = new Map(props.options);\n loaded.value = true;\n listenMapEvents();\n });\n\n const listenMapEvents = () => {\n if (!map.value) return;\n\n events.value.forEach((e) => {\n map.value?.on(e, (evt) => {\n switch (e) {\n case 'load':\n emit('loaded', map.value);\n break;\n default:\n emit(e, evt);\n break;\n }\n });\n });\n };\n</script>\n\n<template>\n <div :id=\"`${options?.container}`\" class=\"v-map-container\">\n <slot v-if=\"loaded\">\n <slot></slot>\n </slot>\n </div>\n</template>\n\n<style scoped>\n canvas {\n outline: none;\n }\n\n .v-map-container {\n width: 100%;\n height: 100%;\n }\n</style>\n","<script setup lang=\"ts\">\n import type { Ref } from 'vue';\n import { ref, onMounted, onBeforeUnmount, watch } from 'vue';\n import type { LngLatLike, Marker, PopupOptions, Map } from 'maplibre-gl';\n import { Popup } from 'maplibre-gl';\n import { popupEvents } from '../constants/events';\n import { injectStrict, MapKey } from '../utils';\n\n const props = withDefaults(\n defineProps<{\n options: PopupOptions;\n coordinates: LngLatLike;\n marker?: Marker;\n }>(),\n {\n options: () => ({}) as PopupOptions,\n coordinates: () => ({}) as LngLatLike,\n marker: () => ({}) as Marker,\n },\n );\n\n const emit = defineEmits<{\n (e: 'added', payload: { popup: Popup }): void;\n (e: 'removed' | 'open' | 'close'): void;\n }>();\n\n const map = injectStrict(MapKey);\n const popup = new Popup(props.options);\n const loaded: Ref<boolean> = ref(true);\n const content = ref<HTMLElement | null>(null);\n\n // Helper function to safely get map instance\n const getMapInstance = (): Map | null => {\n return map.value || null;\n };\n\n // Setup functions\n const setupMap = (mapInstance: Map) => {\n if (!mapInstance) return;\n\n mapInstance.on('style.load', () => {\n const styleTimeout = () => {\n if (!mapInstance.isStyleLoaded()) {\n loaded.value = false;\n setTimeout(styleTimeout, 200);\n } else {\n loaded.value = true;\n }\n };\n styleTimeout();\n });\n };\n\n const setPopupContent = (): void => {\n try {\n if (content.value) {\n popup.setDOMContent(content.value);\n }\n } catch (error) {\n console.error('Error setting popup content:', error);\n }\n };\n\n const setPopupCoordinates = (): void => {\n try {\n popup.setLngLat(props.coordinates);\n } catch (error) {\n console.error('Error setting popup coordinates:', error);\n }\n };\n\n const addToMarker = (): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n if ('setPopup' in props.marker) {\n props.marker.setPopup(popup);\n } else {\n popup.addTo(mapInstance);\n }\n emit('added', { popup });\n } catch (error) {\n console.error('Error adding popup to marker:', error);\n }\n };\n\n const remove = (): void => {\n try {\n popup.remove();\n emit('removed');\n } catch (error) {\n console.error('Error removing popup:', error);\n }\n };\n\n const listenPopupEvents = (): void => {\n try {\n popupEvents.forEach((event) => {\n popup.on(event, () => {\n emit(event);\n });\n });\n } catch (error) {\n console.error('Error setting up popup events:', error);\n }\n };\n\n const removePopupEvents = (): void => {\n try {\n popupEvents.forEach((event) => {\n popup.off(event, () => {\n emit(event);\n });\n });\n } catch (error) {\n console.error('Error removing popup events:', error);\n }\n };\n\n // Watch for map instance changes\n watch(\n map,\n (newMap) => {\n if (newMap) {\n setupMap(newMap);\n }\n },\n { immediate: true },\n );\n\n // Watch for coordinates changes\n watch(\n () => props.coordinates,\n () => {\n setPopupCoordinates();\n },\n { deep: true },\n );\n\n // Lifecycle hooks\n onMounted(() => {\n if (loaded.value) {\n try {\n setPopupContent();\n setPopupCoordinates();\n addToMarker();\n listenPopupEvents();\n } catch (error) {\n console.error('Error initializing popup:', error);\n }\n } else {\n remove();\n removePopupEvents();\n }\n });\n\n onBeforeUnmount(() => {\n remove();\n removePopupEvents();\n });\n</script>\n\n<template>\n <section :id=\"`popup-${Date.now()}`\" ref=\"content\">\n <slot></slot>\n </section>\n</template>\n","<script setup lang=\"ts\">\n import type { Ref } from 'vue';\n import { ref, watch, onMounted, onBeforeUnmount, useSlots } from 'vue';\n import type {\n LngLatLike,\n MarkerOptions,\n PopupOptions,\n Map,\n } from 'maplibre-gl';\n import { Marker } from 'maplibre-gl';\n import VPopup from '../popups/VPopup.vue';\n import { markerDOMEvents, markerMapEvents } from '../constants/events';\n import { injectStrict, MapKey } from '../utils';\n\n const slots = useSlots();\n\n const props = withDefaults(\n defineProps<{\n coordinates: LngLatLike;\n options?: MarkerOptions;\n popupOptions?: PopupOptions;\n cursor?: string;\n }>(),\n {\n options: () => ({}),\n popupOptions: () => ({}),\n cursor: 'pointer',\n },\n );\n\n const emit = defineEmits([\n 'added',\n 'update:coordinates',\n 'removed',\n ...markerMapEvents,\n ...markerDOMEvents,\n ]);\n\n const map = injectStrict(MapKey);\n const marker: Ref<Marker | null> = ref(null);\n const loaded = ref(true);\n const isMarkerAvailable = ref(false);\n const slotRef = ref<HTMLElement | null>(null);\n\n // Helper function to safely get map instance\n const getMapInstance = (): Map | null => {\n return map.value || null;\n };\n\n // Setup functions\n const setupMap = (mapInstance: Map) => {\n if (!mapInstance) return;\n\n mapInstance.on('style.load', () => {\n const styleTimeout = () => {\n if (!mapInstance.isStyleLoaded()) {\n loaded.value = false;\n setTimeout(styleTimeout, 200);\n } else {\n loaded.value = true;\n }\n };\n styleTimeout();\n });\n };\n\n const setSlotRef = (el: HTMLElement | Element | null) => {\n if (el instanceof HTMLElement) {\n slotRef.value = el;\n }\n };\n\n const setMarkerCoordinates = (markerInstance: Marker): void => {\n try {\n markerInstance.setLngLat(props.coordinates);\n } catch (error) {\n console.error('Error setting marker coordinates:', error);\n }\n };\n\n const setCursorPointer = (markerInstance: Marker): void => {\n try {\n markerInstance.getElement().style.cursor = props.cursor || 'default';\n } catch (error) {\n console.error('Error setting cursor:', error);\n }\n };\n\n const addToMap = (markerInstance: Marker): void => {\n const mapInstance = getMapInstance();\n if (!mapInstance) return;\n\n try {\n markerInstance.addTo(mapInstance);\n emit('added', { marker: markerInstance });\n } catch (error) {\n console.error('Error adding marker to map:', error);\n }\n };\n\n const removeFromMap = (markerInstance: Marker): void => {\n try {\n markerInstance.remove();\n emit('removed');\n } catch (error) {\n console.error('Error removing marker from map:', error);\n }\n };\n\n const listenMarkerEvents = (markerInstance: Marker): void => {\n try {\n let coordinates: LngLatLike;\n markerMapEvents.forEach((event: string) => {\n markerInstance.on(event, (e: { target: Marker }) => {\n if (event === 'dragend') {\n if (Array.isArray(props.coordinates)) {\n coordinates = [\n e.target.getLngLat().lng,\n e.target.getLngLat().lat,\n ];\n } else {\n coordinates = e.target.getLngLat();\n }\n emit('update:coordinates', coordinates);\n }\n emit(event, e);\n });\n });\n\n markerDOMEvents.forEach((event: string) => {\n markerInstance.getElement().addEventListener(event, (e) => {\n emit(event, e);\n });\n });\n } catch (error) {\n console.error('Error setting up marker events:', error);\n }\n };\n\n // Watchers\n watch(marker, (markerValue) => {\n isMarkerAvailable.value = markerValue !== null && '_map' in markerValue;\n });\n\n // Watch for map instance changes\n watch(\n map,\n (newMap) => {\n if (newMap) {\n setupMap(newMap);\n }\n },\n { immediate: true },\n );\n\n const initMarker = (element?: HTMLElement) => {\n if (!loaded.value || marker.value) return;\n\n try {\n const markerOptions: MarkerOptions = {\n ...props.options,\n element: element || undefined,\n };\n marker.value = new Marker(markerOptions);\n setMarkerCoordinates(marker.value);\n addToMap(marker.value);\n setCursorPointer(marker.value);\n listenMarkerEvents(marker.value);\n } catch (error) {\n console.error('Error initializing marker:', error);\n }\n };\n\n watch(slotRef, (el) => {\n if (el && !marker.value) {\n initMarker(el);\n }\n });\n\n onMounted(() => {\n const hasCustomElement = !!slots.markers;\n if (!hasCustomElement) {\n initMarker();\n }\n });\n\n onBeforeUnmount(() => {\n if (marker.value) {\n removeFromMap(marker.value);\n }\n });\n</script>\n\n<template>\n <section :id=\"`marker-${Date.now()}`\" class=\"absolute\">\n <slot :set-ref=\"setSlotRef\" name=\"markers\"></slot>\n <template v-if=\"isMarkerAvailable && $slots.default\">\n <v-popup\n :marker=\"marker!\"\n :options=\"popupOptions\"\n :coordinates=\"coordinates\"\n >\n <slot></slot>\n </v-popup>\n </template>\n </section>\n</template>\n\n<style>\n .absolute {\n position: absolute !important;\n }\n</style>\n","import {\n VControlAttribution,\n VControlFullscreen,\n VControlGeolocate,\n VControlNavigation,\n VControlScale,\n VControlLayer,\n VControlLayerGroup,\n VControlLegend,\n} from './controls';\n\nimport {\n VLayerMaplibreCanvas,\n VLayerMaplibreGeojson,\n VLayerMaplibreCluster,\n VLayerMaplibreImage,\n VLayerMaplibreRaster,\n VLayerMaplibreVector,\n VLayerMaplibreVideo,\n VLayerMaplibrePmtile,\n VLayerMaplibreRoute,\n VLayerMaplibreIsochrone,\n} from './layers';\n\nimport VMap from './map/VMap.vue';\nimport VMarker from './markers/VMarker.vue';\nimport VPopup from './popups/VPopup.vue';\n\nexport { requirePeer } from './utils';\n\nexport {\n VMap,\n VMarker,\n VPopup,\n VLayerMaplibreCanvas,\n VLayerMaplibreGeojson,\n VLayerMaplibreCluster,\n VLayerMaplibreImage,\n VLayerMaplibreRaster,\n VLayerMaplibreVector,\n VLayerMaplibreVideo,\n VLayerMaplibrePmtile,\n VLayerMaplibreRoute,\n VLayerMaplibreIsochrone,\n VControlAttribution,\n VControlFullscreen,\n VControlGeolocate,\n VControlNavigation,\n VControlScale,\n VControlLayer,\n VControlLayerGroup,\n VControlLegend,\n};\n\nexport type {\n LayerControlOptions,\n LayerType,\n ControlPosition,\n LayerConfig,\n LegendType,\n CategoryLegendItem,\n GradientLegendItem,\n SizeLegendItem,\n TableLegendItem,\n LegendControlOptions,\n FilterState,\n} from './controls';\n\nexport default VMap;\n"],"mappings":"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"}
|