zenit-sdk 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-URDEEWUZ.mjs → chunk-R5WJ7K2D.mjs} +550 -177
- package/dist/chunk-R5WJ7K2D.mjs.map +1 -0
- package/dist/{index-BSljZaYk.d.mts → index-uCIChcHJ.d.mts} +21 -1
- package/dist/{index-BSljZaYk.d.ts → index-uCIChcHJ.d.ts} +21 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +618 -243
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5 -1
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +2 -2
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +618 -243
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +5 -1
- package/package.json +1 -1
- package/dist/chunk-URDEEWUZ.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/ZenitMap.tsx","../src/maps/helpers.ts","../src/engine/LayerStateEngine.ts","../src/react/layerStyleHelpers.ts","../src/react/zoomOpacity.ts","../src/react/map/layer-geojson.tsx","../src/react/map/location-control.tsx","../src/react/hooks/use-geolocation.ts","../src/react/map/map-utils.ts","../src/react/map/map-handlers.tsx","../src/react/ZenitLayerManager.tsx","../src/react/icons.tsx","../src/react/ui/ZenitSelect.tsx","../src/react/ZenitFeatureFilterPanel.tsx","../src/react/ai/FloatingChatBox.tsx","../src/react/hooks/use-chat.ts","../src/ai/chat.service.ts","../src/react/components/MarkdownRenderer.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState, forwardRef } from 'react';\r\nimport { MapContainer, Marker, TileLayer, ZoomControl } from 'react-leaflet';\r\nimport L, { LatLngBoundsExpression, PathOptions } from 'leaflet';\r\nimport type { ZenitClient } from '../config/ZenitSdkConfig';\r\nimport type { Bbox, GeoJsonFeatureCollection, LayerDto } from '../layers/types';\r\nimport type { MapDto, MapLayerConfig } from '../maps/types';\r\nimport {\r\n centroidFromBBox,\r\n computeBBoxFromFeature,\r\n extractMapDto,\r\n normalizeMapCenter,\r\n normalizeMapLayers,\r\n} from '../maps/helpers';\r\nimport type { EffectiveLayerState, LayerOverrideState } from '../engine/LayerStateEngine';\r\nimport { applyLayerOverrides, initLayerStates, resetOverrides } from '../engine/LayerStateEngine';\r\nimport { getStyleByLayerId, type LayerStyle } from './layerStyleHelpers';\r\nimport { clampOpacity } from './zoomOpacity';\r\nimport { LayerGeoJson } from './map/layer-geojson';\r\nimport { LocationControl } from './map/location-control';\r\nimport { BBoxZoomHandler, MapInstanceBridge, MapInvalidator, ZoomBasedOpacityHandler } from './map/map-handlers';\r\nimport {\r\n calculateZoomBasedOpacity,\r\n createCustomIcon,\r\n createPopupContent,\r\n ensurePopupStyles,\r\n getPopupDimensions,\r\n layerStyleToLeaflet,\r\n} from './map/map-utils';\r\n\r\nexport interface LayerSnapshot {\r\n layerId: number | string;\r\n visible: boolean;\r\n opacity: number;\r\n}\r\n\r\nexport interface ZenitMapRef {\r\n setLayerOpacity: (layerId: number | string, opacity: number) => void;\r\n setLayerVisibility: (layerId: number | string, visible: boolean) => void;\r\n fitBounds: (bbox: Bbox, options?: { padding?: [number, number]; animate?: boolean }) => void;\r\n fitToBbox: (bbox: Bbox, padding?: number) => void;\r\n fitToGeoJson: (fc: GeoJsonFeatureCollection, padding?: number) => void;\r\n setView: (coordinates: { lat: number; lon: number }, zoom?: number) => void;\r\n getLayerSnapshot: () => LayerSnapshot[];\r\n restoreLayerSnapshot: (snapshot: LayerSnapshot[]) => void;\r\n highlightFeature: (layerId: number | string, featureId?: number | string) => void;\r\n updateLayerGeoJson: (layerId: number | string, featureCollection: GeoJsonFeatureCollection) => void;\r\n restoreLayerGeoJson: (layerId: number | string) => void;\r\n getMapInstance: () => L.Map | null;\r\n}\r\n\r\nexport interface ZenitMapProps {\r\n client: ZenitClient;\r\n mapId: number;\r\n height?: string;\r\n width?: string;\r\n initialZoom?: number;\r\n initialCenter?: [number, number];\r\n showLayerPanel?: boolean;\r\n overlayGeojson?: GeoJsonFeatureCollection | null;\r\n overlayStyle?: PathOptions;\r\n layerControls?: Array<{ layerId: number | string; visible?: boolean; opacity?: number }>;\r\n layerStates?: EffectiveLayerState[];\r\n layerGeojson?: Record<string | number, GeoJsonFeatureCollection | null | undefined>;\r\n onLayerStateChange?: (states: EffectiveLayerState[]) => void;\r\n onError?: (error: unknown, ctx: 'map') => void;\r\n onLoadingChange?: (ctx: 'map', loading: boolean) => void;\r\n onFeatureClick?: (feature: any, layerId?: number | string) => void;\r\n onFeatureHover?: (feature: any, layerId?: number | string) => void;\r\n featureInfoMode?: 'popup' | 'none';\r\n mapLayers?: Array<{\r\n layerId: number | string;\r\n style?: LayerStyle | null;\r\n }>;\r\n zoomToBbox?: Bbox | null;\r\n zoomToGeojson?: GeoJsonFeatureCollection | null;\r\n onZoomChange?: (zoom: number) => void;\r\n onMapReady?: (map: L.Map) => void;\r\n}\r\n\r\ntype MapLayerWithId = MapLayerConfig & { layerId: number | string };\r\n\r\ninterface LayerState {\r\n mapLayer: MapLayerWithId;\r\n layer?: LayerDto;\r\n displayOrder: number;\r\n effective?: EffectiveLayerState;\r\n}\r\n\r\nconst DEFAULT_CENTER: [number, number] = [0, 0];\r\nconst DEFAULT_ZOOM = 3;\r\nconst LABELS_PANE_NAME = 'zenit-labels-pane';\r\n\r\nfunction isRecord(value: unknown): value is Record<string, unknown> {\r\n return typeof value === 'object' && value !== null;\r\n}\r\n\r\nfunction isGeoJsonFeatureCollection(value: unknown): value is GeoJsonFeatureCollection {\r\n if (!isRecord(value)) return false;\r\n const features = value.features;\r\n if (!Array.isArray(features)) return false;\r\n const type = value.type;\r\n return type === undefined || type === 'FeatureCollection';\r\n}\r\n\r\nfunction extractGeoJsonFeatureCollection(value: unknown): GeoJsonFeatureCollection | null {\r\n if (isRecord(value) && 'data' in value) {\r\n const data = value.data;\r\n return isGeoJsonFeatureCollection(data) ? data : null;\r\n }\r\n return isGeoJsonFeatureCollection(value) ? value : null;\r\n}\r\n\r\nfunction getFeatureLayerId(feature?: { properties?: Record<string, unknown> }): number | string | null {\r\n const layerId =\r\n (feature?.properties as { __zenit_layerId?: number | string })?.__zenit_layerId ??\r\n (feature?.properties as { layerId?: number | string })?.layerId ??\r\n (feature?.properties as { layer_id?: number | string })?.layer_id;\r\n\r\n if (layerId === undefined || layerId === null) return null;\r\n return layerId;\r\n}\r\n\r\nconst DESCRIPTION_KEYS = new Set(['descripcion', 'description']);\r\n\r\nfunction normalizeDescriptionValue(value: unknown): string | null {\r\n if (value === undefined || value === null) return null;\r\n if (typeof value === 'string') {\r\n const trimmed = value.trim();\r\n return trimmed ? trimmed : null;\r\n }\r\n if (typeof value === 'number' || typeof value === 'boolean') {\r\n return String(value);\r\n }\r\n return null;\r\n}\r\n\r\nfunction extractDescriptionValue(properties?: Record<string, unknown>): string | null {\r\n if (!properties) return null;\r\n const matches = Object.entries(properties).find(([key]) =>\r\n DESCRIPTION_KEYS.has(key.toLowerCase())\r\n );\r\n if (!matches) return null;\r\n return normalizeDescriptionValue(matches[1]);\r\n}\r\n\r\n\r\nfunction getFeatureStyleOverrides(feature?: any): LayerStyle | null {\r\n const candidate = feature?.properties?._style;\r\n if (!candidate || typeof candidate !== 'object' || Array.isArray(candidate)) return null;\r\n\r\n const styleCandidate = candidate as Partial<LayerStyle>;\r\n return {\r\n color: styleCandidate.color,\r\n weight: styleCandidate.weight,\r\n fillColor: styleCandidate.fillColor,\r\n fillOpacity: styleCandidate.fillOpacity,\r\n };\r\n}\r\n\r\nfunction buildFeaturePopupHtml(feature?: any): string | null {\r\n const properties = feature?.properties as Record<string, unknown> | undefined;\r\n if (!properties) return null;\r\n\r\n const rendered = createPopupContent(properties);\r\n return rendered ? rendered : null;\r\n}\r\n\r\nfunction pickIntersectFeature(\r\n baseFeature: any,\r\n candidates: any[]\r\n): any | null {\r\n if (!Array.isArray(candidates) || candidates.length === 0) return null;\r\n const baseId = baseFeature?.id;\r\n if (baseId !== undefined && baseId !== null) {\r\n const matchById = candidates.find((candidate) => candidate?.id === baseId);\r\n if (matchById) return matchById;\r\n }\r\n const matchWithDescription = candidates.find((candidate) =>\r\n extractDescriptionValue(candidate?.properties)\r\n );\r\n return matchWithDescription ?? candidates[0];\r\n}\r\n\r\n// ✅ center puede ser tuple o objeto, normalizamos a tuple siempre\r\ntype CenterInput = [number, number] | { lat: number; lon: number };\r\n\r\nfunction normalizeCenterTuple(center: unknown): [number, number] | null {\r\n if (!center) return null;\r\n\r\n if (Array.isArray(center) && center.length >= 2) {\r\n const lat = center[0];\r\n const lon = center[1];\r\n if (typeof lat === 'number' && typeof lon === 'number') return [lat, lon];\r\n return null;\r\n }\r\n\r\n const maybeObj = center as Partial<{ lat: unknown; lon: unknown }>;\r\n if (typeof maybeObj.lat === 'number' && typeof maybeObj.lon === 'number') {\r\n return [maybeObj.lat, maybeObj.lon];\r\n }\r\n\r\n return null;\r\n}\r\n\r\nexport const ZenitMap = forwardRef<ZenitMapRef, ZenitMapProps>(({\r\n client,\r\n mapId,\r\n height = '500px',\r\n width = '100%',\r\n initialZoom,\r\n initialCenter,\r\n showLayerPanel = true,\r\n overlayGeojson,\r\n overlayStyle,\r\n layerControls,\r\n layerStates,\r\n layerGeojson,\r\n onLayerStateChange,\r\n onError,\r\n onLoadingChange,\r\n onFeatureClick,\r\n onFeatureHover,\r\n featureInfoMode = 'popup',\r\n mapLayers,\r\n zoomToBbox,\r\n zoomToGeojson,\r\n onZoomChange,\r\n onMapReady,\r\n}, ref) => {\r\n const [map, setMap] = useState<MapDto | null>(null);\r\n const [layers, setLayers] = useState<LayerState[]>([]);\r\n const [effectiveStates, setEffectiveStates] = useState<EffectiveLayerState[]>([]);\r\n const [loadingMap, setLoadingMap] = useState(false);\r\n const [mapError, setMapError] = useState<string | null>(null);\r\n const [mapInstance, setMapInstance] = useState<L.Map | null>(null);\r\n const [layerGeojsonOverrides, setLayerGeojsonOverrides] = useState<Record<string, GeoJsonFeatureCollection | null>>({});\r\n const originalGeojsonByLayerIdRef = useRef<Record<string, GeoJsonFeatureCollection>>({});\r\n const [panesReady, setPanesReady] = useState(false);\r\n const [currentZoom, setCurrentZoom] = useState<number>(initialZoom ?? DEFAULT_ZOOM);\r\n const [isPopupOpen, setIsPopupOpen] = useState(false);\r\n const [isMobile, setIsMobile] = useState<boolean>(() => {\r\n if (typeof window === 'undefined') return false;\r\n return window.matchMedia('(max-width: 768px)').matches;\r\n });\r\n const normalizedLayers = useMemo(() => normalizeMapLayers(map), [map]);\r\n\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n\r\n const mql = window.matchMedia('(max-width: 768px)');\r\n\r\n const onChange = (e: MediaQueryListEvent) => {\r\n setIsMobile(e.matches);\r\n };\r\n\r\n setIsMobile(mql.matches);\r\n\r\n if (typeof mql.addEventListener === 'function') {\r\n mql.addEventListener('change', onChange);\r\n return () => mql.removeEventListener('change', onChange);\r\n }\r\n\r\n const legacy = mql as any;\r\n if (typeof legacy.addListener === 'function') {\r\n legacy.addListener(onChange);\r\n return () => legacy.removeListener(onChange);\r\n }\r\n\r\n return;\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (featureInfoMode === 'popup') {\r\n ensurePopupStyles();\r\n }\r\n }, [featureInfoMode]);\r\n\r\n useEffect(() => {\r\n if (featureInfoMode !== 'popup') {\r\n setIsPopupOpen(false);\r\n }\r\n }, [featureInfoMode]);\r\n\r\n useEffect(() => {\r\n if (!mapInstance) return;\r\n\r\n const popupPane = mapInstance.getPane('popupPane');\r\n if (popupPane) {\r\n popupPane.style.zIndex = '800';\r\n }\r\n\r\n const labelsPane = mapInstance.getPane(LABELS_PANE_NAME) ?? mapInstance.createPane(LABELS_PANE_NAME);\r\n labelsPane.style.zIndex = '600';\r\n }, [mapInstance]);\r\n\r\n useEffect(() => {\r\n if (!mapInstance) return;\r\n\r\n const handlePopupOpen = () => setIsPopupOpen(true);\r\n const handlePopupClose = () => setIsPopupOpen(false);\r\n\r\n mapInstance.on('popupopen', handlePopupOpen);\r\n mapInstance.on('popupclose', handlePopupClose);\r\n\r\n return () => {\r\n mapInstance.off('popupopen', handlePopupOpen);\r\n mapInstance.off('popupclose', handlePopupClose);\r\n };\r\n }, [mapInstance]);\r\n\r\n const layerStyleIndex = useMemo(() => {\r\n const index = new Map<string, LayerStyle>();\r\n\r\n (map?.mapLayers ?? []).forEach((entry) => {\r\n const layerStyle =\r\n (entry as { layer?: { style?: LayerStyle | null } }).layer?.style ??\r\n (entry as { mapLayer?: { layer?: { style?: LayerStyle | null } } }).mapLayer?.layer?.style ??\r\n (entry as { style?: LayerStyle | null }).style ??\r\n null;\r\n\r\n const layerId =\r\n (entry as { layerId?: number | string }).layerId ??\r\n (entry as { mapLayer?: { layerId?: number | string; layer?: { id?: number | string } } }).mapLayer\r\n ?.layerId ??\r\n (entry as { mapLayer?: { layer?: { id?: number | string } } }).mapLayer?.layer?.id ??\r\n (entry as { layer?: { id?: number | string } }).layer?.id;\r\n\r\n if (layerId !== undefined && layerId !== null && layerStyle) {\r\n index.set(String(layerId), layerStyle);\r\n }\r\n });\r\n\r\n return index;\r\n }, [map]);\r\n\r\n const labelKeyIndex = useMemo(() => {\r\n const index = new Map<string, string>();\r\n\r\n normalizedLayers.forEach((entry) => {\r\n const label =\r\n (entry.layer as { label?: string } | undefined)?.label ??\r\n (entry.mapLayer as { label?: string } | undefined)?.label ??\r\n (entry.mapLayer.layerConfig as { label?: string } | undefined)?.label;\r\n\r\n if (typeof label === 'string' && label.trim().length > 0) {\r\n index.set(String(entry.layerId), label);\r\n }\r\n });\r\n\r\n return index;\r\n }, [normalizedLayers]);\r\n\r\n const layerMetaIndex = useMemo(() => {\r\n const index = new Map<string, { layerType?: string; geometryType?: string }>();\r\n\r\n normalizedLayers.forEach((entry) => {\r\n index.set(String(entry.layerId), {\r\n layerType:\r\n typeof entry.layer?.layerType === 'string'\r\n ? entry.layer.layerType\r\n : typeof (entry.mapLayer as { layerType?: string }).layerType === 'string'\r\n ? (entry.mapLayer as { layerType?: string }).layerType\r\n : undefined,\r\n geometryType:\r\n typeof entry.layer?.geometryType === 'string'\r\n ? entry.layer.geometryType\r\n : typeof (entry.mapLayer.layerConfig as { geometryType?: string } | undefined)?.geometryType === 'string'\r\n ? (entry.mapLayer.layerConfig as { geometryType?: string }).geometryType\r\n : undefined,\r\n });\r\n });\r\n\r\n return index;\r\n }, [normalizedLayers]);\r\n\r\n const overlayStyleFunction = useMemo(() => {\r\n return (feature?: any): PathOptions => {\r\n const featureLayerId = getFeatureLayerId(feature);\r\n const featureStyleOverrides = getFeatureStyleOverrides(feature);\r\n\r\n let style: LayerStyle | null = null;\r\n\r\n if (featureLayerId !== null) {\r\n style =\r\n getStyleByLayerId(featureLayerId, mapLayers) ??\r\n layerStyleIndex.get(String(featureLayerId)) ??\r\n null;\r\n }\r\n\r\n const resolvedStyle: LayerStyle | null = featureStyleOverrides\r\n ? { ...(style ?? {}), ...featureStyleOverrides }\r\n : style;\r\n\r\n const defaultOptions: PathOptions = {\r\n color: resolvedStyle?.color ?? resolvedStyle?.fillColor ?? '#2563eb',\r\n weight: resolvedStyle?.weight ?? 2,\r\n fillColor: resolvedStyle?.fillColor ?? resolvedStyle?.color ?? '#2563eb',\r\n fillOpacity: resolvedStyle?.fillOpacity ?? 0.15,\r\n ...(overlayStyle ?? {}),\r\n };\r\n\r\n return defaultOptions;\r\n };\r\n }, [layerStyleIndex, mapLayers, overlayStyle]);\r\n\r\n const overlayStyleFn = useCallback(\r\n (feature: any, _layerType?: string, _baseOpacity?: number) => overlayStyleFunction(feature),\r\n [overlayStyleFunction]\r\n );\r\n\r\n const [baseStates, setBaseStates] = useState<EffectiveLayerState[]>([]);\r\n const [mapOverrides, setMapOverrides] = useState<LayerOverrideState[]>([]);\r\n const [controlOverrides, setControlOverrides] = useState<LayerOverrideState[]>([]);\r\n const [uiOverrides, setUiOverrides] = useState<LayerOverrideState[]>([]);\r\n\r\n useEffect(() => {\r\n let isMounted = true;\r\n setLoadingMap(true);\r\n setMapError(null);\r\n onLoadingChange?.('map', true);\r\n\r\n client.maps\r\n .getMap(mapId, true)\r\n .then((mapResponse) => {\r\n if (!isMounted) return;\r\n const extracted = extractMapDto(mapResponse);\r\n const resolved = extracted ? normalizeMapCenter(extracted) : null;\r\n setMap(resolved);\r\n })\r\n .catch((err: unknown) => {\r\n if (!isMounted) return;\r\n setMapError(err instanceof Error ? err.message : 'No se pudo obtener el mapa');\r\n onError?.(err, 'map');\r\n })\r\n .finally(() => {\r\n if (!isMounted) return;\r\n setLoadingMap(false);\r\n onLoadingChange?.('map', false);\r\n });\r\n\r\n return () => {\r\n isMounted = false;\r\n };\r\n }, [client.maps, mapId, onError, onLoadingChange]);\r\n\r\n useEffect(() => {\r\n if (normalizedLayers.length === 0) {\r\n setLayers([]);\r\n setBaseStates([]);\r\n setMapOverrides([]);\r\n setUiOverrides([]);\r\n return;\r\n }\r\n\r\n const nextLayers: LayerState[] = normalizedLayers.map((entry) => ({\r\n mapLayer: { ...entry.mapLayer, layerId: entry.layerId } as MapLayerWithId,\r\n layer: entry.layer,\r\n displayOrder: entry.displayOrder,\r\n }));\r\n\r\n const base = initLayerStates(\r\n normalizedLayers.map((entry) => ({\r\n ...entry.mapLayer,\r\n layerId: entry.layerId,\r\n opacity: entry.opacity,\r\n isVisible: entry.isVisible,\r\n })) as MapLayerWithId[]\r\n );\r\n\r\n const initialOverrides: LayerOverrideState[] = normalizedLayers.map((entry) => ({\r\n layerId: entry.layerId,\r\n overrideVisible: entry.isVisible,\r\n overrideOpacity: entry.opacity,\r\n }));\r\n\r\n setLayers(nextLayers);\r\n setBaseStates(base);\r\n setMapOverrides(initialOverrides);\r\n setUiOverrides([]);\r\n }, [normalizedLayers]);\r\n\r\n useEffect(() => {\r\n if (!layerControls) {\r\n setControlOverrides([]);\r\n return;\r\n }\r\n const overrides = layerControls.map((entry) => ({\r\n layerId: entry.layerId,\r\n overrideVisible: entry.visible,\r\n overrideOpacity: entry.opacity,\r\n }));\r\n setControlOverrides(overrides);\r\n }, [layerControls]);\r\n\r\n useEffect(() => {\r\n // Si layerStates se proporciona como prop, no sobrescribir\r\n if (layerStates) {\r\n return;\r\n }\r\n\r\n if (Array.isArray(layerControls) && layerControls.length === 0 && effectiveStates.length > 0) {\r\n const reset = resetOverrides(baseStates);\r\n setEffectiveStates(reset);\r\n onLayerStateChange?.(reset);\r\n }\r\n }, [baseStates, effectiveStates.length, layerControls, layerStates, onLayerStateChange]);\r\n\r\n useEffect(() => {\r\n if (layerStates) {\r\n setEffectiveStates(layerStates);\r\n }\r\n }, [layerStates]);\r\n\r\n useEffect(() => {\r\n // Si layerStates se proporciona como prop, no sobrescribir con baseStates\r\n // Esto permite que el componente padre controle completamente los estados\r\n if (layerStates) {\r\n return;\r\n }\r\n\r\n if (mapOverrides.length === 0 && controlOverrides.length === 0 && uiOverrides.length === 0) {\r\n setEffectiveStates(baseStates);\r\n return;\r\n }\r\n const combined = [...mapOverrides, ...controlOverrides, ...uiOverrides];\r\n const next = applyLayerOverrides(baseStates, combined);\r\n setEffectiveStates(next);\r\n onLayerStateChange?.(next);\r\n }, [baseStates, controlOverrides, layerStates, mapOverrides, onLayerStateChange, uiOverrides]);\r\n\r\n useEffect(() => {\r\n if (!Array.isArray(layerControls) || layerControls.length > 0) return;\r\n setUiOverrides([]);\r\n }, [layerControls]);\r\n\r\n useEffect(() => {\r\n // Si layerStates se proporciona como prop, no sobrescribir\r\n if (layerStates) {\r\n return;\r\n }\r\n\r\n if (!Array.isArray(layerControls) && effectiveStates.length > 0 && baseStates.length > 0) {\r\n const next = resetOverrides(baseStates);\r\n setEffectiveStates(next);\r\n onLayerStateChange?.(next);\r\n }\r\n }, [baseStates, effectiveStates.length, layerControls, layerStates, onLayerStateChange]);\r\n\r\n const upsertUiOverride = (layerId: number | string, patch: Partial<LayerOverrideState>) => {\r\n setUiOverrides((prev) => {\r\n const filtered = prev.filter((entry) => entry.layerId !== layerId);\r\n const nextEntry: LayerOverrideState = {\r\n layerId,\r\n ...patch,\r\n };\r\n return [...filtered, nextEntry];\r\n });\r\n };\r\n\r\n const updateOpacityFromUi = useCallback(\r\n (layerId: number | string, uiOpacity: number) => {\r\n const meta = layerMetaIndex.get(String(layerId));\r\n const baseOpacity = clampOpacity(uiOpacity);\r\n const effectiveOpacity = calculateZoomBasedOpacity(\r\n currentZoom,\r\n baseOpacity,\r\n meta?.layerType,\r\n meta?.geometryType\r\n );\r\n\r\n if (layerStates && onLayerStateChange) {\r\n const next = effectiveStates.map((state) =>\r\n state.layerId === layerId\r\n ? {\r\n ...state,\r\n baseOpacity,\r\n opacity: effectiveOpacity,\r\n overrideOpacity: uiOpacity,\r\n }\r\n : state\r\n );\r\n onLayerStateChange(next);\r\n return;\r\n }\r\n\r\n setBaseStates((prev) =>\r\n prev.map((state) => (state.layerId === layerId ? { ...state, baseOpacity } : state))\r\n );\r\n setUiOverrides((prev) => {\r\n const existing = prev.find((entry) => entry.layerId === layerId);\r\n const filtered = prev.filter((entry) => entry.layerId !== layerId);\r\n if (existing && existing.overrideVisible !== undefined) {\r\n return [\r\n ...filtered,\r\n { layerId, overrideVisible: existing.overrideVisible },\r\n ];\r\n }\r\n return filtered;\r\n });\r\n },\r\n [currentZoom, effectiveStates, layerMetaIndex, layerStates, onLayerStateChange]\r\n );\r\n\r\n const center = useMemo<[number, number]>(() => {\r\n if (initialCenter) {\r\n return initialCenter;\r\n }\r\n\r\n const normalized = normalizeCenterTuple(map?.settings?.center as unknown);\r\n if (normalized) {\r\n return normalized;\r\n }\r\n\r\n return DEFAULT_CENTER;\r\n }, [initialCenter, map?.settings?.center]);\r\n\r\n const zoom = initialZoom ?? map?.settings?.zoom ?? DEFAULT_ZOOM;\r\n\r\n useEffect(() => {\r\n setCurrentZoom(zoom);\r\n }, [zoom]);\r\n\r\n useEffect(() => {\r\n if (!layerGeojson) return;\r\n\r\n layers.forEach((layer) => {\r\n const layerKey = String(layer.mapLayer.layerId);\r\n const incoming =\r\n layerGeojson[layer.mapLayer.layerId] ??\r\n layerGeojson[layerKey] ??\r\n null;\r\n if (incoming && !originalGeojsonByLayerIdRef.current[layerKey]) {\r\n originalGeojsonByLayerIdRef.current[layerKey] = incoming;\r\n }\r\n });\r\n }, [layerGeojson, layers]);\r\n\r\n const decoratedLayers = useMemo(() => {\r\n return layers.map((layer) => {\r\n const layerKey = String(layer.mapLayer.layerId);\r\n const override = layerGeojsonOverrides[layerKey];\r\n return {\r\n ...layer,\r\n effective: effectiveStates.find((state) => state.layerId === layer.mapLayer.layerId),\r\n data:\r\n override ??\r\n layerGeojson?.[layer.mapLayer.layerId] ??\r\n layerGeojson?.[layerKey] ??\r\n null,\r\n };\r\n });\r\n }, [effectiveStates, layerGeojson, layerGeojsonOverrides, layers]);\r\n\r\n const orderedLayers = useMemo(() => {\r\n return [...decoratedLayers]\r\n .filter((layer) => layer.effective?.visible && layer.data)\r\n .sort((a, b) => a.displayOrder - b.displayOrder);\r\n }, [decoratedLayers]);\r\n\r\n const autoZoomGeojson = useMemo(\r\n () =>\r\n orderedLayers\r\n .map((layer) => layer.data)\r\n .filter((collection): collection is GeoJsonFeatureCollection => !!collection),\r\n [orderedLayers]\r\n );\r\n\r\n const resolveLayerStyle = useCallback(\r\n (layerId: number | string): LayerStyle | null => {\r\n return (\r\n getStyleByLayerId(layerId, mapLayers) ?? layerStyleIndex.get(String(layerId)) ?? null\r\n );\r\n },\r\n [layerStyleIndex, mapLayers]\r\n );\r\n\r\n const labelMarkers = useMemo(() => {\r\n const markers: Array<{\r\n key: string;\r\n position: [number, number];\r\n label: string;\r\n opacity: number;\r\n layerId: number | string;\r\n color: string;\r\n }> = [];\r\n\r\n decoratedLayers.forEach((layerState) => {\r\n if (!layerState.effective?.visible) return;\r\n\r\n const labelKey = labelKeyIndex.get(String(layerState.mapLayer.layerId));\r\n if (!labelKey) return;\r\n\r\n const data = layerState.data;\r\n if (!data) return;\r\n\r\n const resolvedStyle = resolveLayerStyle(layerState.mapLayer.layerId);\r\n const layerColor =\r\n resolvedStyle?.fillColor ?? resolvedStyle?.color ?? 'rgba(37, 99, 235, 1)';\r\n const meta = layerMetaIndex.get(String(layerState.mapLayer.layerId));\r\n const baseOpacity = layerState.effective?.baseOpacity ?? layerState.effective?.opacity ?? 1;\r\n const opacity = calculateZoomBasedOpacity(\r\n currentZoom,\r\n baseOpacity,\r\n meta?.layerType,\r\n meta?.geometryType\r\n );\r\n\r\n data.features.forEach((feature, index) => {\r\n const properties = feature.properties as Record<string, unknown> | undefined;\r\n const value = properties?.[labelKey];\r\n if (value === undefined || value === null || value === '') return;\r\n\r\n const bbox = computeBBoxFromFeature(feature);\r\n if (!bbox) return;\r\n\r\n const [lat, lng] = centroidFromBBox(bbox);\r\n markers.push({\r\n key: `${layerState.mapLayer.layerId}-label-${index}`,\r\n position: [lat, lng],\r\n label: String(value),\r\n opacity,\r\n layerId: layerState.mapLayer.layerId,\r\n color: layerColor,\r\n });\r\n });\r\n });\r\n\r\n return markers;\r\n }, [currentZoom, decoratedLayers, labelKeyIndex, layerMetaIndex, resolveLayerStyle]);\r\n\r\n const ensureLayerPanes = useCallback(\r\n (targetMap: L.Map, targetLayers: Array<{ layerId: number | string; displayOrder: number }>) => {\r\n const baseZIndex = 400;\r\n\r\n targetLayers.forEach((layer) => {\r\n const order = Number.isFinite(layer.displayOrder) ? layer.displayOrder : 0;\r\n const orderOffset = Math.max(0, Math.min(order, 150));\r\n const fillPaneName = `zenit-layer-${layer.layerId}-fill`;\r\n const pointPaneName = `zenit-layer-${layer.layerId}-points`;\r\n const fillPane = targetMap.getPane(fillPaneName) ?? targetMap.createPane(fillPaneName);\r\n const pointPane = targetMap.getPane(pointPaneName) ?? targetMap.createPane(pointPaneName);\r\n\r\n fillPane.style.zIndex = String(baseZIndex + orderOffset);\r\n pointPane.style.zIndex = String(baseZIndex + orderOffset + 100);\r\n });\r\n },\r\n []\r\n );\r\n\r\n const handleMapReady = useCallback(\r\n (instance: L.Map) => {\r\n setPanesReady(false);\r\n setMapInstance(instance);\r\n onMapReady?.(instance);\r\n // NO crear panes aquí, se hará en el useEffect\r\n },\r\n [onMapReady]\r\n );\r\n\r\n // Crear/actualizar panes cuando cambien orderedLayers\r\n useEffect(() => {\r\n // Si no hay instancia del mapa, resetear panesReady\r\n if (!mapInstance) {\r\n setPanesReady(false);\r\n return;\r\n }\r\n\r\n // Si no hay capas ordenadas, solo salir sin resetear panesReady\r\n if (orderedLayers.length === 0) {\r\n return; // ← CAMBIO CRÍTICO: NO hacer setPanesReady(false) aquí\r\n }\r\n\r\n const layerTargets = orderedLayers.map((layer) => ({\r\n layerId: layer.mapLayer.layerId,\r\n displayOrder: layer.displayOrder,\r\n }));\r\n\r\n ensureLayerPanes(mapInstance, layerTargets);\r\n const first = layerTargets[0];\r\n const testPane = mapInstance.getPane(`zenit-layer-${first.layerId}-fill`);\r\n const labelsPane = mapInstance.getPane(LABELS_PANE_NAME);\r\n if (testPane && labelsPane) {\r\n setPanesReady(true);\r\n }\r\n }, [mapInstance, orderedLayers, ensureLayerPanes]);\r\n\r\n const overlayOnEachFeature = useMemo(() => {\r\n return (feature: any, layer: any) => {\r\n const layerId = getFeatureLayerId(feature) ?? undefined;\r\n const geometryType = (feature as { geometry?: { type?: string } })?.geometry?.type;\r\n const isPointFeature =\r\n geometryType === 'Point' ||\r\n geometryType === 'MultiPoint' ||\r\n layer instanceof L.CircleMarker;\r\n const originalStyle =\r\n layer instanceof L.Path\r\n ? {\r\n color: layer.options.color,\r\n weight: layer.options.weight,\r\n fillColor: layer.options.fillColor,\r\n opacity: layer.options.opacity,\r\n fillOpacity: layer.options.fillOpacity,\r\n }\r\n : null;\r\n const originalRadius =\r\n layer instanceof L.CircleMarker ? layer.getRadius() : null;\r\n\r\n if (featureInfoMode === 'popup') {\r\n const content = buildFeaturePopupHtml(feature);\r\n if (content) {\r\n const { maxWidth, minWidth, maxHeight } = getPopupDimensions();\r\n layer.bindPopup(content, {\r\n maxWidth,\r\n minWidth,\r\n maxHeight,\r\n className: 'custom-leaflet-popup',\r\n autoPan: true,\r\n closeButton: true,\r\n keepInView: true,\r\n });\r\n }\r\n }\r\n\r\n if (isPointFeature && layer.bindTooltip) {\r\n layer.bindTooltip('Click para ver detalle', {\r\n sticky: true,\r\n direction: 'top',\r\n opacity: 0.9,\r\n className: 'zenit-map-tooltip',\r\n });\r\n }\r\n\r\n layer.on('click', () => {\r\n if (\r\n featureInfoMode === 'popup' &&\r\n client &&\r\n layerId !== undefined &&\r\n !extractDescriptionValue(feature?.properties) &&\r\n feature?.geometry\r\n ) {\r\n const trackedFeature = feature as {\r\n __zenit_popup_loaded?: boolean;\r\n properties?: Record<string, unknown>;\r\n };\r\n if (!trackedFeature.__zenit_popup_loaded) {\r\n trackedFeature.__zenit_popup_loaded = true;\r\n client.layers\r\n .getLayerGeoJsonIntersect({\r\n id: layerId,\r\n geometry: feature.geometry,\r\n })\r\n .then((response) => {\r\n const geo = extractGeoJsonFeatureCollection(response);\r\n const candidates = geo?.features ?? [];\r\n const resolved = pickIntersectFeature(feature, candidates);\r\n if (!resolved?.properties) return;\r\n const mergedProperties = {\r\n ...(trackedFeature.properties ?? {}),\r\n ...(resolved.properties as Record<string, unknown>),\r\n };\r\n trackedFeature.properties = mergedProperties;\r\n const updatedHtml = buildFeaturePopupHtml({\r\n ...feature,\r\n properties: mergedProperties,\r\n });\r\n if (updatedHtml && layer.setPopupContent) {\r\n layer.setPopupContent(updatedHtml);\r\n }\r\n })\r\n .catch(() => {\r\n trackedFeature.__zenit_popup_loaded = false;\r\n });\r\n }\r\n }\r\n\r\n onFeatureClick?.(feature, layerId);\r\n });\r\n layer.on('mouseover', () => {\r\n if (layer instanceof L.Path && originalStyle) {\r\n layer.setStyle({\r\n ...originalStyle,\r\n weight: (originalStyle.weight ?? 2) + 1,\r\n opacity: Math.min(1, (originalStyle.opacity ?? 1) + 0.2),\r\n fillOpacity: Math.min(1, (originalStyle.fillOpacity ?? 0.8) + 0.1),\r\n });\r\n }\r\n if (layer instanceof L.CircleMarker && typeof originalRadius === 'number') {\r\n layer.setRadius(originalRadius + 1);\r\n }\r\n onFeatureHover?.(feature, layerId);\r\n });\r\n layer.on('mouseout', () => {\r\n if (layer instanceof L.Path && originalStyle) {\r\n layer.setStyle(originalStyle);\r\n }\r\n if (layer instanceof L.CircleMarker && typeof originalRadius === 'number') {\r\n layer.setRadius(originalRadius);\r\n }\r\n });\r\n };\r\n }, [client, featureInfoMode, onFeatureClick, onFeatureHover]);\r\n\r\n const buildLayerStyle = (\r\n layerId: number | string,\r\n baseOpacity: number,\r\n feature?: any,\r\n layerType?: string\r\n ): PathOptions => {\r\n const style = resolveLayerStyle(layerId);\r\n const featureStyleOverrides = getFeatureStyleOverrides(feature);\r\n const resolvedStyle: LayerStyle | null = featureStyleOverrides\r\n ? { ...(style ?? {}), ...featureStyleOverrides }\r\n : style;\r\n const geometryType = (feature as { geometry?: { type?: string } } | undefined)?.geometry?.type;\r\n const resolvedLayerType = layerType ?? geometryType;\r\n\r\n return layerStyleToLeaflet({\r\n baseOpacity,\r\n zoom: currentZoom,\r\n layerStyle: resolvedStyle,\r\n geometryType,\r\n layerType: resolvedLayerType,\r\n });\r\n };\r\n\r\n const makeStyleFnForLayer = (layerId: number | string) => {\r\n return (feature: any, layerType?: string, baseOpacity?: number) => {\r\n return buildLayerStyle(layerId, baseOpacity ?? 1, feature, layerType);\r\n };\r\n };\r\n\r\n // Expose imperative API via ref\r\n useImperativeHandle(ref, () => ({\r\n setLayerOpacity: (layerId: number | string, opacity: number) => {\r\n upsertUiOverride(layerId, { overrideOpacity: opacity });\r\n },\r\n setLayerVisibility: (layerId: number | string, visible: boolean) => {\r\n upsertUiOverride(layerId, { overrideVisible: visible });\r\n },\r\n fitBounds: (bbox: Bbox, options?: { padding?: [number, number]; animate?: boolean }) => {\r\n if (!mapInstance) return;\r\n\r\n // Validate bbox before using it\r\n if (\r\n typeof bbox.minLat !== 'number' ||\r\n typeof bbox.minLon !== 'number' ||\r\n typeof bbox.maxLat !== 'number' ||\r\n typeof bbox.maxLon !== 'number' ||\r\n !Number.isFinite(bbox.minLat) ||\r\n !Number.isFinite(bbox.minLon) ||\r\n !Number.isFinite(bbox.maxLat) ||\r\n !Number.isFinite(bbox.maxLon)\r\n ) {\r\n console.warn('[ZenitMap.fitBounds] Invalid bbox: missing or non-finite coordinates', bbox);\r\n return;\r\n }\r\n\r\n const bounds: LatLngBoundsExpression = [\r\n [bbox.minLat, bbox.minLon],\r\n [bbox.maxLat, bbox.maxLon],\r\n ];\r\n const fitOptions = {\r\n padding: options?.padding ?? [12, 12],\r\n animate: options?.animate ?? true,\r\n };\r\n mapInstance.fitBounds(bounds, fitOptions);\r\n },\r\n fitToBbox: (bbox: Bbox, padding?: number) => {\r\n if (!mapInstance) return;\r\n\r\n if (\r\n typeof bbox.minLat !== 'number' ||\r\n typeof bbox.minLon !== 'number' ||\r\n typeof bbox.maxLat !== 'number' ||\r\n typeof bbox.maxLon !== 'number' ||\r\n !Number.isFinite(bbox.minLat) ||\r\n !Number.isFinite(bbox.minLon) ||\r\n !Number.isFinite(bbox.maxLat) ||\r\n !Number.isFinite(bbox.maxLon)\r\n ) {\r\n console.warn('[ZenitMap.fitToBbox] Invalid bbox', bbox);\r\n return;\r\n }\r\n\r\n const resolvedPadding = padding ?? (isMobile ? 40 : 24);\r\n const bounds = L.latLngBounds([bbox.minLat, bbox.minLon], [bbox.maxLat, bbox.maxLon]);\r\n mapInstance.fitBounds(bounds, { padding: [resolvedPadding, resolvedPadding], animate: true });\r\n },\r\n fitToGeoJson: (fc: GeoJsonFeatureCollection, padding?: number) => {\r\n if (!mapInstance) return;\r\n if (!fc?.features?.length) return;\r\n\r\n const bounds = L.geoJSON(fc as any).getBounds();\r\n if (!bounds.isValid()) return;\r\n\r\n const resolvedPadding = padding ?? (isMobile ? 40 : 24);\r\n mapInstance.fitBounds(bounds, { padding: [resolvedPadding, resolvedPadding], animate: true });\r\n },\r\n setView: (coordinates: { lat: number; lon: number }, zoom?: number) => {\r\n if (!mapInstance) return;\r\n mapInstance.setView([coordinates.lat, coordinates.lon], zoom ?? mapInstance.getZoom(), {\r\n animate: true,\r\n });\r\n },\r\n getLayerSnapshot: (): LayerSnapshot[] => {\r\n return effectiveStates.map((state) => ({\r\n layerId: state.layerId,\r\n visible: state.visible,\r\n opacity: state.opacity,\r\n }));\r\n },\r\n restoreLayerSnapshot: (snapshot: LayerSnapshot[]) => {\r\n const overrides = snapshot.map((s) => ({\r\n layerId: s.layerId,\r\n overrideVisible: s.visible,\r\n overrideOpacity: s.opacity,\r\n }));\r\n setUiOverrides(overrides);\r\n },\r\n highlightFeature: (layerId: number | string, featureId?: number | string) => {\r\n // For now, just ensure the layer is visible with high opacity\r\n // In a future enhancement, this could style specific features\r\n upsertUiOverride(layerId, { overrideVisible: true, overrideOpacity: 1.0 });\r\n },\r\n updateLayerGeoJson: (layerId: number | string, featureCollection: GeoJsonFeatureCollection) => {\r\n const layerKey = String(layerId);\r\n setLayerGeojsonOverrides((prev) => ({ ...prev, [layerKey]: featureCollection }));\r\n },\r\n restoreLayerGeoJson: (layerId: number | string) => {\r\n const layerKey = String(layerId);\r\n const original = originalGeojsonByLayerIdRef.current[layerKey];\r\n setLayerGeojsonOverrides((prev) => {\r\n const next = { ...prev };\r\n if (original) {\r\n next[layerKey] = original;\r\n } else {\r\n delete next[layerKey];\r\n }\r\n return next;\r\n });\r\n },\r\n getMapInstance: () => mapInstance,\r\n }), [effectiveStates, isMobile, mapInstance]);\r\n\r\n if (loadingMap) {\r\n return <div style={{ padding: 16, height, width }}>Cargando mapa...</div>;\r\n }\r\n\r\n if (mapError) {\r\n return (\r\n <div style={{ padding: 16, height, width, color: 'red' }}>\r\n Error al cargar mapa: {mapError}\r\n </div>\r\n );\r\n }\r\n\r\n if (!map) {\r\n return null;\r\n }\r\n\r\n const handleZoomChange = (zoomValue: number) => {\r\n setCurrentZoom(zoomValue);\r\n onZoomChange?.(zoomValue);\r\n };\r\n\r\n return (\r\n <div\r\n style={{\r\n display: 'flex',\r\n height,\r\n width,\r\n border: '1px solid #e2e8f0',\r\n borderRadius: 4,\r\n overflow: 'hidden',\r\n boxSizing: 'border-box',\r\n }}\r\n >\r\n <div\r\n className={`zenit-map-shell${isPopupOpen ? ' popup-open' : ''}`}\r\n style={{ flex: 1, position: 'relative' }}\r\n >\r\n <MapContainer\r\n center={center}\r\n zoom={zoom}\r\n style={{ height: '100%', width: '100%' }}\r\n scrollWheelZoom\r\n zoomControl={false}\r\n key={String(mapId)}\r\n >\r\n <TileLayer\r\n url=\"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png\"\r\n attribution=\"© OpenStreetMap contributors\"\r\n />\r\n <ZoomControl position=\"topright\" />\r\n <MapInstanceBridge onReady={handleMapReady} />\r\n <MapInvalidator trigger={mapId} />\r\n <BBoxZoomHandler\r\n bbox={zoomToBbox ?? undefined}\r\n geojson={zoomToGeojson ?? undefined}\r\n autoGeojson={autoZoomGeojson}\r\n />\r\n <ZoomBasedOpacityHandler onZoomChange={handleZoomChange} />\r\n <LocationControl />\r\n {orderedLayers.map((layerState) => {\r\n const baseOpacity =\r\n layerState.effective?.baseOpacity ?? layerState.effective?.opacity ?? 1;\r\n const fillPaneName = `zenit-layer-${layerState.mapLayer.layerId}-fill`;\r\n const pointsPaneName = `zenit-layer-${layerState.mapLayer.layerId}-points`;\r\n const layerType =\r\n layerState.layer?.layerType ??\r\n (layerState.mapLayer as { layerType?: string }).layerType ??\r\n undefined;\r\n const labelKey = labelKeyIndex.get(String(layerState.mapLayer.layerId));\r\n\r\n return (\r\n <React.Fragment key={layerState.mapLayer.layerId.toString()}>\r\n {layerState.data && (\r\n <LayerGeoJson\r\n layerId={layerState.mapLayer.layerId}\r\n data={layerState.data}\r\n baseOpacity={baseOpacity}\r\n isMobile={isMobile}\r\n panesReady={panesReady}\r\n mapInstance={mapInstance}\r\n fillPaneName={fillPaneName}\r\n pointsPaneName={pointsPaneName}\r\n layerType={layerType}\r\n styleFn={makeStyleFnForLayer(layerState.mapLayer.layerId)}\r\n onEachFeature={overlayOnEachFeature}\r\n onPolygonLabel={\r\n labelKey\r\n ? (feature, layer) => {\r\n const geometryType = (feature as { geometry?: { type?: string } })\r\n ?.geometry?.type;\r\n if (geometryType !== 'Polygon' && geometryType !== 'MultiPolygon') return;\r\n const properties = feature?.properties as Record<string, unknown> | undefined;\r\n const value = properties?.[labelKey];\r\n if (!value || !layer.bindTooltip) return;\r\n layer.bindTooltip(String(value), {\r\n sticky: true,\r\n direction: 'center',\r\n opacity: 0.9,\r\n className: 'polygon-label-tooltip',\r\n });\r\n }\r\n : undefined\r\n }\r\n />\r\n )}\r\n {panesReady && mapInstance?.getPane(LABELS_PANE_NAME)\r\n ? labelMarkers\r\n .filter(\r\n (marker) => String(marker.layerId) === String(layerState.mapLayer.layerId)\r\n )\r\n .map((marker) => (\r\n <Marker\r\n key={marker.key}\r\n position={marker.position}\r\n icon={createCustomIcon(marker.label, marker.opacity, marker.color)}\r\n interactive={false}\r\n pane={LABELS_PANE_NAME}\r\n />\r\n ))\r\n : null}\r\n </React.Fragment>\r\n );\r\n })}\r\n {overlayGeojson && (\r\n <LayerGeoJson\r\n layerId=\"overlay-geojson\"\r\n data={overlayGeojson as GeoJsonFeatureCollection}\r\n baseOpacity={1}\r\n isMobile={isMobile}\r\n panesReady={panesReady}\r\n mapInstance={mapInstance}\r\n fillPaneName=\"zenit-overlay-fill\"\r\n pointsPaneName=\"zenit-overlay-points\"\r\n styleFn={overlayStyleFn}\r\n onEachFeature={overlayOnEachFeature}\r\n />\r\n )}\r\n </MapContainer>\r\n </div>\r\n\r\n {showLayerPanel && decoratedLayers.length > 0 && (\r\n <div\r\n style={{\r\n width: 260,\r\n borderLeft: '1px solid #e2e8f0',\r\n padding: '12px 16px',\r\n background: '#fafafa',\r\n fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif',\r\n fontSize: 14,\r\n overflowY: 'auto',\r\n }}\r\n >\r\n {overlayGeojson && (\r\n <div\r\n style={{\r\n border: '1px solid #bfdbfe',\r\n background: '#eff6ff',\r\n color: '#1e40af',\r\n padding: '8px 10px',\r\n borderRadius: 8,\r\n marginBottom: 12,\r\n }}\r\n >\r\n <div style={{ fontWeight: 600, marginBottom: 4 }}>Overlay activo</div>\r\n <div style={{ fontSize: 13 }}>\r\n GeoJSON externo con {(overlayGeojson.features?.length ?? 0).toLocaleString()} elementos.\r\n </div>\r\n </div>\r\n )}\r\n <div style={{ fontWeight: 600, marginBottom: 12 }}>Capas</div>\r\n {decoratedLayers.map((layerState) => (\r\n <div\r\n key={layerState.mapLayer.layerId.toString()}\r\n style={{ borderBottom: '1px solid #e5e7eb', paddingBottom: 10, marginBottom: 10 }}\r\n >\r\n <label style={{ display: 'flex', gap: 8, alignItems: 'center' }}>\r\n <input\r\n type=\"checkbox\"\r\n checked={layerState.effective?.visible ?? false}\r\n onChange={(e) => {\r\n const visible = e.target.checked;\r\n upsertUiOverride(layerState.mapLayer.layerId, { overrideVisible: visible });\r\n }}\r\n />\r\n <span>{layerState.layer?.name ?? `Capa ${layerState.mapLayer.layerId}`}</span>\r\n </label>\r\n\r\n <div style={{ marginTop: 8 }}>\r\n <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 4 }}>\r\n <span style={{ color: '#4a5568' }}>Opacidad</span>\r\n <span>{Math.round((layerState.effective?.opacity ?? 1) * 100)}%</span>\r\n </div>\r\n <input\r\n type=\"range\"\r\n min={0}\r\n max={1}\r\n step={0.05}\r\n value={layerState.effective?.opacity ?? 1}\r\n onChange={(e) => {\r\n const value = Number(e.target.value);\r\n updateOpacityFromUi(layerState.mapLayer.layerId, value);\r\n }}\r\n style={{ width: '100%' }}\r\n />\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n});\r\n\r\nZenitMap.displayName = 'ZenitMap';\r\n\r\nexport const GenericMap = ZenitMap;\r\n","import type {\r\n Bbox,\r\n FilterMultipleMetadata,\r\n GeoJsonFeature,\r\n GeoJsonFeatureCollection,\r\n LayerDto,\r\n} from '../layers/types';\r\nimport type { MapDto, MapLayerConfig, NormalizedMapLayer } from './types';\r\n\r\nfunction toNumber(value: unknown): number | undefined {\r\n if (typeof value === 'number' && Number.isFinite(value)) {\r\n return value;\r\n }\r\n if (typeof value === 'string') {\r\n const parsed = parseFloat(value);\r\n if (Number.isFinite(parsed)) {\r\n return parsed;\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction clampOpacity(value: number | undefined): number {\r\n if (!Number.isFinite(value ?? NaN)) {\r\n return 1;\r\n }\r\n return Math.min(1, Math.max(0, value ?? 1));\r\n}\r\n\r\nfunction resolveLayerId(mapLayer: MapLayerConfig): number | string | undefined {\r\n if (mapLayer.layerId !== undefined && mapLayer.layerId !== null) {\r\n return mapLayer.layerId;\r\n }\r\n const embedded = (mapLayer as MapLayerConfig & { layer?: LayerDto }).layer;\r\n return embedded?.id;\r\n}\r\n\r\nexport function extractMapDto(map: unknown): MapDto | null {\r\n if (map && typeof map === 'object' && 'data' in map) {\r\n const data = (map as { data?: MapDto | null }).data;\r\n return data ?? null;\r\n }\r\n if (map && typeof map === 'object') {\r\n return map as MapDto;\r\n }\r\n return null;\r\n}\r\n\r\nexport function normalizeMapCenter(map: MapDto): MapDto {\r\n const center = map.settings?.center as unknown;\r\n\r\n if (Array.isArray(center) && center.length >= 2) {\r\n const [lon, lat] = center;\r\n return {\r\n ...map,\r\n settings: {\r\n ...map.settings,\r\n center: { lon, lat },\r\n },\r\n };\r\n }\r\n\r\n return map;\r\n}\r\n\r\nexport function normalizeMapLayers(mapOrResponse: unknown): NormalizedMapLayer[] {\r\n const map = extractMapDto(mapOrResponse);\r\n if (!map?.mapLayers) {\r\n return [];\r\n }\r\n\r\n const normalized: NormalizedMapLayer[] = [];\r\n\r\n map.mapLayers.forEach((mapLayer, index) => {\r\n const layerId = resolveLayerId(mapLayer);\r\n if (layerId === undefined) {\r\n return;\r\n }\r\n\r\n const embeddedLayer = (mapLayer as MapLayerConfig & { layer?: LayerDto }).layer;\r\n const visible = mapLayer.isVisible !== false;\r\n const opacity = clampOpacity(toNumber(mapLayer.opacity) ?? 1);\r\n const layerType = embeddedLayer?.layerType ?? (mapLayer as { layerType?: string }).layerType;\r\n const geometryType =\r\n (embeddedLayer as { geometryType?: string } | undefined)?.geometryType ??\r\n (mapLayer as { geometryType?: string }).geometryType;\r\n const layerName = embeddedLayer?.name ?? (mapLayer as { name?: string }).name;\r\n const orderCandidate =\r\n toNumber((mapLayer as { displayOrder?: number | string }).displayOrder) ??\r\n toNumber(mapLayer.order) ??\r\n toNumber((embeddedLayer as { displayOrder?: number | string } | undefined)?.displayOrder) ??\r\n index;\r\n\r\n normalized.push({\r\n layerId,\r\n displayOrder: orderCandidate ?? index,\r\n isVisible: visible,\r\n opacity,\r\n layer: embeddedLayer,\r\n layerType,\r\n geometryType,\r\n layerName,\r\n mapLayer,\r\n });\r\n });\r\n\r\n return normalized.sort((a, b) => a.displayOrder - b.displayOrder);\r\n}\r\n\r\nexport function computeBBoxFromFeature(feature?: GeoJsonFeature | null): Bbox | null {\r\n if (!feature || typeof feature !== 'object') return null;\r\n\r\n const geometry = (feature as { geometry?: { coordinates?: unknown } }).geometry;\r\n if (!geometry || !('coordinates' in geometry)) return null;\r\n\r\n const coords: Array<[number, number]> = [];\r\n\r\n const collect = (candidate: unknown) => {\r\n if (!Array.isArray(candidate)) return;\r\n if (\r\n candidate.length === 2 &&\r\n typeof candidate[0] === 'number' &&\r\n typeof candidate[1] === 'number'\r\n ) {\r\n coords.push([candidate[0], candidate[1]]);\r\n return;\r\n }\r\n\r\n candidate.forEach((entry) => collect(entry));\r\n };\r\n\r\n collect(geometry.coordinates);\r\n\r\n if (coords.length === 0) return null;\r\n\r\n const [firstLon, firstLat] = coords[0];\r\n const bbox: Bbox = { minLon: firstLon, minLat: firstLat, maxLon: firstLon, maxLat: firstLat };\r\n\r\n coords.forEach(([lon, lat]) => {\r\n bbox.minLon = Math.min(bbox.minLon, lon);\r\n bbox.minLat = Math.min(bbox.minLat, lat);\r\n bbox.maxLon = Math.max(bbox.maxLon, lon);\r\n bbox.maxLat = Math.max(bbox.maxLat, lat);\r\n });\r\n\r\n return bbox;\r\n}\r\n\r\nexport function centroidFromBBox(bbox: Bbox): [number, number] {\r\n return [(bbox.minLat + bbox.maxLat) / 2, (bbox.minLon + bbox.maxLon) / 2];\r\n}\r\n\r\nexport interface FilteredGeoJSONApplication {\r\n overlay: GeoJsonFeatureCollection | null;\r\n metadata?: FilterMultipleMetadata;\r\n layerControls: Array<{\r\n layerId: number | string;\r\n visible: boolean;\r\n opacity: number;\r\n }>;\r\n}\r\n\r\nexport function applyFilteredGeoJSONStrategy(options: {\r\n normalizedLayers: NormalizedMapLayer[];\r\n filteredGeojson: GeoJsonFeatureCollection | null;\r\n metadata?: FilterMultipleMetadata;\r\n}): FilteredGeoJSONApplication {\r\n const layerControls = options.normalizedLayers.map((entry) => ({\r\n layerId: entry.layerId,\r\n visible: entry.isVisible,\r\n opacity: entry.opacity,\r\n }));\r\n\r\n return {\r\n overlay: options.filteredGeojson,\r\n metadata: options.metadata,\r\n layerControls,\r\n };\r\n}\r\n","import type { MapLayerConfig, NormalizedMapLayer } from '../maps/types';\r\n\r\ntype LayerLike = Pick<MapLayerConfig | NormalizedMapLayer, 'layerId' | 'isVisible' | 'opacity'>;\r\n\r\nexport interface LayerBaseState {\r\n layerId: number | string;\r\n baseVisible: boolean;\r\n baseOpacity: number;\r\n}\r\n\r\nexport interface LayerOverrideState {\r\n layerId: number | string;\r\n overrideVisible?: boolean | null;\r\n overrideOpacity?: number | string | null;\r\n}\r\n\r\nexport interface EffectiveLayerState extends LayerBaseState, LayerOverrideState {\r\n visible: boolean;\r\n opacity: number;\r\n}\r\n\r\nfunction clampOpacity(value: number | string | null | undefined): number {\r\n if (typeof value === 'number' && Number.isFinite(value)) {\r\n return Math.min(1, Math.max(0, value));\r\n }\r\n\r\n if (typeof value === 'string') {\r\n const parsed = parseFloat(value);\r\n if (Number.isFinite(parsed)) {\r\n return Math.min(1, Math.max(0, parsed));\r\n }\r\n }\r\n\r\n return 1;\r\n}\r\n\r\n// The SDK mirrors the frontend default: layers start hidden until toggled externally.\r\nconst resolveBaseVisibility = (_layer?: LayerLike): boolean => false;\r\n\r\nfunction resolveBaseOpacity(layer: LayerLike): number {\r\n if ('opacity' in layer) {\r\n return clampOpacity(layer.opacity as number | string | null | undefined);\r\n }\r\n\r\n return 1;\r\n}\r\n\r\nfunction toEffectiveState(base: LayerBaseState, override?: LayerOverrideState | null): EffectiveLayerState {\r\n const overrideVisible = override?.overrideVisible ?? undefined;\r\n const overrideOpacity = override?.overrideOpacity ?? undefined;\r\n\r\n const opacitySource =\r\n overrideOpacity !== undefined && overrideOpacity !== null ? overrideOpacity : base.baseOpacity;\r\n\r\n return {\r\n layerId: base.layerId,\r\n baseVisible: base.baseVisible,\r\n baseOpacity: base.baseOpacity,\r\n overrideVisible,\r\n overrideOpacity,\r\n visible: overrideVisible ?? base.baseVisible,\r\n opacity: clampOpacity(opacitySource),\r\n };\r\n}\r\n\r\nexport function initLayerStates(mapLayers: LayerLike[]): EffectiveLayerState[] {\r\n const bases: LayerBaseState[] = mapLayers\r\n .filter((layer): layer is LayerLike & { layerId: number | string } => layer.layerId !== undefined)\r\n .map((layer) => ({\r\n layerId: layer.layerId as number | string,\r\n baseVisible: resolveBaseVisibility(layer),\r\n baseOpacity: resolveBaseOpacity(layer),\r\n }));\r\n\r\n return bases.map((base) => toEffectiveState(base));\r\n}\r\n\r\nexport function applyLayerOverrides(\r\n states: EffectiveLayerState[],\r\n overrides: LayerOverrideState[],\r\n): EffectiveLayerState[] {\r\n const overrideMap = new Map<number | string, LayerOverrideState>();\r\n overrides.forEach((entry) => overrideMap.set(entry.layerId, entry));\r\n\r\n return states.map((state) => {\r\n const nextOverride = overrideMap.get(state.layerId);\r\n const mergedOverrideVisible =\r\n nextOverride && 'overrideVisible' in nextOverride && nextOverride.overrideVisible !== undefined\r\n ? nextOverride.overrideVisible\r\n : state.overrideVisible;\r\n\r\n const mergedOverrideOpacity =\r\n nextOverride && 'overrideOpacity' in nextOverride && nextOverride.overrideOpacity !== undefined\r\n ? nextOverride.overrideOpacity\r\n : state.overrideOpacity;\r\n\r\n return toEffectiveState(state, {\r\n layerId: state.layerId,\r\n overrideVisible: mergedOverrideVisible ?? undefined,\r\n overrideOpacity: mergedOverrideOpacity ?? undefined,\r\n });\r\n });\r\n}\r\n\r\nexport function resetOverrides(states: EffectiveLayerState[]): EffectiveLayerState[] {\r\n return states.map((state) => toEffectiveState(state));\r\n}\r\n","export interface LayerStyle {\r\n color?: string;\r\n weight?: number;\r\n fillColor?: string;\r\n fillOpacity?: number;\r\n}\r\n\r\n/**\r\n * Resuelve el color de acento para una capa basado en su estilo.\r\n * Prioridad: fillColor → color → null\r\n */\r\nexport function resolveLayerAccent(style?: LayerStyle | null): string | null {\r\n if (!style) return null;\r\n return style.fillColor ?? style.color ?? null;\r\n}\r\n\r\n/**\r\n * Obtiene el color de acento para una capa, con fallback a un color neutral.\r\n * @param style - El estilo de la capa\r\n * @param fallback - Color de fallback (por defecto gris neutral)\r\n */\r\nexport function getLayerColor(style?: LayerStyle | null, fallback = '#94a3b8'): string {\r\n return resolveLayerAccent(style) ?? fallback;\r\n}\r\n\r\n/**\r\n * Busca el estilo de una capa en un arreglo de mapLayers por su layerId.\r\n */\r\nexport function getStyleByLayerId(\r\n layerId: string | number,\r\n mapLayers?: Array<{\r\n layerId: number | string;\r\n style?: LayerStyle | null;\r\n }>,\r\n): LayerStyle | null {\r\n if (!mapLayers) return null;\r\n const match = mapLayers.find((ml) => String(ml.layerId) === String(layerId));\r\n return match?.style ?? null;\r\n}\r\n\r\n/**\r\n * Obtiene el color de acento de una capa por su layerId.\r\n */\r\nexport function getAccentByLayerId(\r\n layerId: string | number,\r\n mapLayers?: Array<{\r\n layerId: number | string;\r\n style?: LayerStyle | null;\r\n }>,\r\n): string | null {\r\n const style = getStyleByLayerId(layerId, mapLayers);\r\n return resolveLayerAccent(style);\r\n}\r\n","export interface ZoomOpacityOptions {\r\n minZoom?: number;\r\n maxZoom?: number;\r\n minFactor?: number;\r\n maxFactor?: number;\r\n minOpacity?: number;\r\n maxOpacity?: number;\r\n}\r\n\r\nconst DEFAULT_OPTIONS: Required<ZoomOpacityOptions> = {\r\n minZoom: 11,\r\n maxZoom: 15,\r\n minFactor: 0.3,\r\n maxFactor: 1,\r\n minOpacity: 0.1,\r\n maxOpacity: 0.92,\r\n};\r\n\r\nexport function clampNumber(value: number, min: number, max: number): number {\r\n return Math.min(max, Math.max(min, value));\r\n}\r\n\r\nexport function clampOpacity(value: number): number {\r\n return clampNumber(value, 0, 1);\r\n}\r\n\r\nexport function isPolygonLayer(layerType?: string, geometryType?: string): boolean {\r\n const candidate = (layerType ?? geometryType ?? '').toLowerCase();\r\n return candidate === 'polygon' || candidate === 'multipolygon';\r\n}\r\n\r\nexport function getZoomOpacityFactor(zoom: number, options?: ZoomOpacityOptions): number {\r\n const settings = { ...DEFAULT_OPTIONS, ...options };\r\n const { minZoom, maxZoom, minFactor, maxFactor } = settings;\r\n\r\n if (maxZoom <= minZoom) return clampNumber(maxFactor, minFactor, maxFactor);\r\n\r\n const t = clampNumber((zoom - minZoom) / (maxZoom - minZoom), 0, 1);\r\n const factor = maxFactor + (minFactor - maxFactor) * t;\r\n return clampNumber(factor, minFactor, maxFactor);\r\n}\r\n\r\nexport function getLayerZoomOpacityFactor(\r\n zoom: number,\r\n layerType?: string,\r\n geometryType?: string,\r\n options?: ZoomOpacityOptions,\r\n): number {\r\n if (!isPolygonLayer(layerType, geometryType)) return 1;\r\n return getZoomOpacityFactor(zoom, options);\r\n}\r\n\r\nexport function getEffectiveLayerOpacity(\r\n baseOpacity: number,\r\n zoom: number,\r\n layerType?: string,\r\n geometryType?: string,\r\n options?: ZoomOpacityOptions,\r\n): number {\r\n if (!isPolygonLayer(layerType, geometryType)) {\r\n return clampOpacity(baseOpacity);\r\n }\r\n\r\n const settings = { ...DEFAULT_OPTIONS, ...options };\r\n const factor = getZoomOpacityFactor(zoom, options);\r\n const effective = clampOpacity(baseOpacity) * factor;\r\n return clampNumber(effective, settings.minOpacity, settings.maxOpacity);\r\n}\r\n","import React, { useEffect, useRef } from 'react';\r\nimport { GeoJSON } from 'react-leaflet';\r\nimport L, { PathOptions } from 'leaflet';\r\nimport type { GeoJsonFeatureCollection } from '../../layers/types';\r\n\r\nconst POINT_GEOMETRY_TYPES = new Set(['Point', 'MultiPoint']);\r\n\r\ntype AnyGeoJsonFeature = {\r\n geometry?: { type?: unknown } | null;\r\n};\r\n\r\n\r\ntype BboxTuple = [number, number, number, number];\r\n\r\ntype FeatureWithProperties = {\r\n id?: unknown;\r\n properties?: {\r\n featureId?: unknown;\r\n } | null;\r\n};\r\n\r\nfunction normalizeBboxFromData(data: GeoJsonFeatureCollection): BboxTuple | null {\r\n const bboxCandidate = (data as { bbox?: unknown }).bbox;\r\n if (!Array.isArray(bboxCandidate) || bboxCandidate.length < 4) return null;\r\n\r\n const [minLon, minLat, maxLon, maxLat] = bboxCandidate;\r\n const values = [minLon, minLat, maxLon, maxLat].map((value) => Number(value));\r\n if (values.every((value) => Number.isFinite(value))) {\r\n return values as BboxTuple;\r\n }\r\n return null;\r\n}\r\n\r\nfunction buildIdsSample(features: unknown[]): string {\r\n return features\r\n .slice(0, 10)\r\n .map((feature) => {\r\n const typedFeature = feature as FeatureWithProperties;\r\n if (typedFeature.id !== undefined && typedFeature.id !== null) {\r\n return String(typedFeature.id);\r\n }\r\n const featureId = typedFeature.properties?.featureId;\r\n return featureId !== undefined && featureId !== null ? String(featureId) : '';\r\n })\r\n .join(',');\r\n}\r\n\r\nfunction getGeometryType(feature: unknown): string | null {\r\n const t = (feature as AnyGeoJsonFeature | null | undefined)?.geometry?.type;\r\n return typeof t === 'string' ? t : null;\r\n}\r\n\r\nfunction isPointGeometry(feature: unknown): boolean {\r\n const geometryType = getGeometryType(feature);\r\n return geometryType !== null && POINT_GEOMETRY_TYPES.has(geometryType);\r\n}\r\n\r\nfunction isNonPointGeometry(feature: unknown): boolean {\r\n const geometryType = getGeometryType(feature);\r\n return geometryType !== null && !POINT_GEOMETRY_TYPES.has(geometryType);\r\n}\r\n\r\nfunction buildFeatureCollection(features: any[]): GeoJsonFeatureCollection {\r\n return {\r\n type: 'FeatureCollection',\r\n features,\r\n } as GeoJsonFeatureCollection;\r\n}\r\n\r\nexport type LayerGeoJsonProps = {\r\n layerId: number | string;\r\n data: GeoJsonFeatureCollection;\r\n baseOpacity: number;\r\n isMobile: boolean;\r\n panesReady: boolean;\r\n mapInstance: L.Map | null;\r\n fillPaneName: string;\r\n pointsPaneName: string;\r\n layerType?: string;\r\n styleFn: (feature: any, layerType?: string, baseOpacity?: number) => PathOptions;\r\n onEachFeature: (feature: any, layer: any) => void;\r\n onPolygonLabel?: (feature: any, layer: any) => void;\r\n};\r\n\r\nexport const LayerGeoJson: React.FC<LayerGeoJsonProps> = ({\r\n layerId,\r\n data,\r\n baseOpacity,\r\n isMobile,\r\n panesReady,\r\n mapInstance,\r\n fillPaneName,\r\n pointsPaneName,\r\n layerType,\r\n styleFn,\r\n onEachFeature,\r\n onPolygonLabel,\r\n}) => {\r\n const features = data.features ?? [];\r\n const fillFeatures = features.filter(isNonPointGeometry);\r\n const pointFeatures = features.filter(isPointGeometry);\r\n\r\n // Track data version to force GeoJSON component remount when data changes.\r\n // react-leaflet's GeoJSON updateGeoJSON only handles style changes,\r\n // so changing the key is the only way to get new data rendered.\r\n // Use a content signature instead of reference equality so that in-place\r\n // mutations (same object, different contents) also trigger a remount.\r\n const dataVersionRef = useRef(0);\r\n const prevSignatureRef = useRef('');\r\n const firstId = features.length > 0 ? String((features[0] as FeatureWithProperties | undefined)?.id ?? '') : '';\r\n const lastId =\r\n features.length > 0\r\n ? String((features[features.length - 1] as FeatureWithProperties | undefined)?.id ?? '')\r\n : '';\r\n const bbox = normalizeBboxFromData(data);\r\n const idsSample = buildIdsSample(features);\r\n const signature = bbox\r\n ? `${layerId}|${features.length}|${firstId}|${lastId}|${idsSample}|${bbox[0]}|${bbox[1]}|${bbox[2]}|${bbox[3]}`\r\n : `${layerId}|${features.length}|${firstId}|${lastId}|${idsSample}`;\r\n const signatureToken = signature.replace(/[^a-zA-Z0-9_-]/g, '_');\r\n if (prevSignatureRef.current !== signature) {\r\n dataVersionRef.current += 1;\r\n prevSignatureRef.current = signature;\r\n }\r\n\r\n const fillData = fillFeatures.length > 0 ? buildFeatureCollection(fillFeatures) : null;\r\n const pointsData = pointFeatures.length > 0 ? buildFeatureCollection(pointFeatures) : null;\r\n const clusterLayerRef = useRef<L.LayerGroup | null>(null);\r\n\r\n const canCluster =\r\n typeof (L as { markerClusterGroup?: () => L.LayerGroup }).markerClusterGroup === 'function';\r\n\r\n useEffect(() => {\r\n if (!mapInstance || !panesReady || !pointsData || !canCluster) return;\r\n\r\n const markerClusterGroup = (L as { markerClusterGroup: () => L.LayerGroup }).markerClusterGroup;\r\n const clusterLayer = clusterLayerRef.current ?? markerClusterGroup();\r\n clusterLayerRef.current = clusterLayer;\r\n\r\n if (!mapInstance.hasLayer(clusterLayer)) {\r\n mapInstance.addLayer(clusterLayer);\r\n }\r\n\r\n clusterLayer.clearLayers();\r\n\r\n const geoJsonLayer = L.geoJSON(pointsData, {\r\n pointToLayer: (feature, latlng) =>\r\n L.circleMarker(latlng, {\r\n radius: isMobile ? 8 : 6,\r\n pane: mapInstance.getPane(pointsPaneName) ? pointsPaneName : undefined,\r\n ...styleFn(feature, layerType, baseOpacity),\r\n }),\r\n onEachFeature,\r\n });\r\n\r\n clusterLayer.addLayer(geoJsonLayer);\r\n\r\n return () => {\r\n clusterLayer.clearLayers();\r\n if (mapInstance.hasLayer(clusterLayer)) {\r\n mapInstance.removeLayer(clusterLayer);\r\n }\r\n };\r\n }, [\r\n baseOpacity,\r\n canCluster,\r\n isMobile,\r\n layerType,\r\n mapInstance,\r\n onEachFeature,\r\n panesReady,\r\n pointsData,\r\n pointsPaneName,\r\n styleFn,\r\n ]);\r\n\r\n return (\r\n <>\r\n {fillData && (\r\n <GeoJSON\r\n key={`fill-${layerId}-${signatureToken}-v${dataVersionRef.current}`}\r\n data={fillData}\r\n pane={panesReady && mapInstance?.getPane(fillPaneName) ? fillPaneName : undefined}\r\n style={(feature) => styleFn(feature, layerType, baseOpacity)}\r\n onEachFeature={(feature, layer) => {\r\n onEachFeature(feature, layer);\r\n onPolygonLabel?.(feature, layer);\r\n }}\r\n />\r\n )}\r\n {pointsData && !canCluster && (\r\n <GeoJSON\r\n key={`points-${layerId}-${signatureToken}-v${dataVersionRef.current}`}\r\n data={pointsData}\r\n pane={panesReady && mapInstance?.getPane(pointsPaneName) ? pointsPaneName : undefined}\r\n pointToLayer={(feature, latlng) =>\r\n L.circleMarker(latlng, {\r\n radius: isMobile ? 8 : 6,\r\n ...styleFn(feature, layerType, baseOpacity),\r\n })\r\n }\r\n onEachFeature={onEachFeature}\r\n />\r\n )}\r\n </>\r\n );\r\n};\r\n","import React, { useEffect, useMemo, useRef } from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport { Circle, Marker, useMap } from 'react-leaflet';\r\nimport L from 'leaflet';\r\nimport { useGeolocation } from '../hooks/use-geolocation';\r\nimport { createLocationIcon } from './map-utils';\r\n\r\nconst LOCATION_STYLE_ID = 'zenit-location-control-styles';\r\n\r\nconst LOCATION_STYLES = `\r\n.zenit-location-control {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n}\r\n\r\n.zenit-location-button {\r\n width: 42px;\r\n height: 42px;\r\n border-radius: 12px;\r\n border: none;\r\n background: #ffffff;\r\n color: #0f172a;\r\n box-shadow: 0 8px 18px rgba(15, 23, 42, 0.2);\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n position: relative;\r\n}\r\n\r\n.zenit-location-button.zenit-location-button--tracking {\r\n animation: zenitLocationPulse 1.8s infinite;\r\n}\r\n\r\n.zenit-location-button:hover {\r\n background: #f8fafc;\r\n}\r\n\r\n.zenit-location-badge {\r\n position: absolute;\r\n top: -6px;\r\n right: -6px;\r\n width: 18px;\r\n height: 18px;\r\n border-radius: 999px;\r\n background: #ef4444;\r\n color: #fff;\r\n font-size: 11px;\r\n font-weight: 700;\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n box-shadow: 0 4px 10px rgba(239, 68, 68, 0.35);\r\n}\r\n\r\n.zenit-location-error {\r\n background: rgba(15, 23, 42, 0.92);\r\n color: #f8fafc;\r\n border-radius: 10px;\r\n padding: 8px 10px;\r\n font-size: 12px;\r\n max-width: 200px;\r\n box-shadow: 0 10px 24px rgba(15, 23, 42, 0.3);\r\n}\r\n\r\n@keyframes zenitLocationPulse {\r\n 0% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.35); }\r\n 70% { box-shadow: 0 0 0 12px rgba(16, 185, 129, 0); }\r\n 100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0); }\r\n}\r\n`;\r\n\r\nconst LocateIcon = () => (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\r\n <line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"5\" />\r\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"22\" />\r\n <line x1=\"2\" y1=\"12\" x2=\"5\" y2=\"12\" />\r\n <line x1=\"19\" y1=\"12\" x2=\"22\" y2=\"12\" />\r\n </svg>\r\n);\r\n\r\nexport type LocationControlProps = {\r\n position?: L.ControlPosition;\r\n zoom?: number;\r\n};\r\n\r\nexport const LocationControl: React.FC<LocationControlProps> = ({ position = 'bottomleft', zoom = 16 }) => {\r\n const map = useMap();\r\n const controlRef = useRef<HTMLDivElement | null>(null);\r\n const hasCenteredRef = useRef(false);\r\n const { isTracking, location, error, toggleTracking, clearError } = useGeolocation();\r\n\r\n useEffect(() => {\r\n if (typeof document === 'undefined') return;\r\n if (document.getElementById(LOCATION_STYLE_ID)) return;\r\n const styleTag = document.createElement('style');\r\n styleTag.id = LOCATION_STYLE_ID;\r\n styleTag.textContent = LOCATION_STYLES;\r\n document.head.appendChild(styleTag);\r\n }, []);\r\n\r\n useEffect(() => {\r\n const control = L.control({ position });\r\n control.onAdd = () => {\r\n const container = L.DomUtil.create('div', 'zenit-location-control');\r\n L.DomEvent.disableClickPropagation(container);\r\n controlRef.current = container;\r\n return container;\r\n };\r\n control.addTo(map);\r\n\r\n return () => {\r\n control.remove();\r\n controlRef.current = null;\r\n };\r\n }, [map, position]);\r\n\r\n useEffect(() => {\r\n if (!location || !isTracking) return;\r\n if (hasCenteredRef.current) return;\r\n hasCenteredRef.current = true;\r\n map.flyTo([location.lat, location.lon], zoom, { animate: true });\r\n }, [isTracking, location, map, zoom]);\r\n\r\n const markerIcon = useMemo(() => createLocationIcon(), []);\r\n\r\n return (\r\n <>\r\n {controlRef.current &&\r\n createPortal(\r\n <div>\r\n <button\r\n type=\"button\"\r\n className={`zenit-location-button${isTracking ? ' zenit-location-button--tracking' : ''}`}\r\n onClick={() => {\r\n if (error) {\r\n clearError();\r\n }\r\n toggleTracking();\r\n }}\r\n aria-label={isTracking ? 'Detener ubicación' : 'Mostrar mi ubicación'}\r\n >\r\n <LocateIcon />\r\n {error && <span className=\"zenit-location-badge\">!</span>}\r\n </button>\r\n {error && (\r\n <div className=\"zenit-location-error\">\r\n {error.message || 'No se pudo acceder a tu ubicación.'}\r\n </div>\r\n )}\r\n </div>,\r\n controlRef.current\r\n )}\r\n\r\n {location && (\r\n <>\r\n <Marker position={[location.lat, location.lon]} icon={markerIcon} />\r\n <Circle\r\n center={[location.lat, location.lon]}\r\n radius={location.accuracy}\r\n pathOptions={{ color: '#2563eb', fillColor: '#2563eb', fillOpacity: 0.15 }}\r\n />\r\n </>\r\n )}\r\n </>\r\n );\r\n};\r\n","import { useCallback, useEffect, useRef, useState } from 'react';\r\n\r\ntype GeoLocationState = {\r\n lat: number;\r\n lon: number;\r\n accuracy: number;\r\n};\r\n\r\ntype GeoLocationOptions = {\r\n enableHighAccuracy?: boolean;\r\n timeout?: number;\r\n maximumAge?: number;\r\n};\r\n\r\nexport type GeolocationError = {\r\n code: number;\r\n message: string;\r\n};\r\n\r\nexport function useGeolocation(options?: GeoLocationOptions) {\r\n const [isTracking, setIsTracking] = useState(false);\r\n const [location, setLocation] = useState<GeoLocationState | null>(null);\r\n const [error, setError] = useState<GeolocationError | null>(null);\r\n const watchIdRef = useRef<number | null>(null);\r\n\r\n const stopTracking = useCallback(() => {\r\n if (watchIdRef.current !== null && typeof navigator !== 'undefined' && navigator.geolocation) {\r\n navigator.geolocation.clearWatch(watchIdRef.current);\r\n }\r\n watchIdRef.current = null;\r\n setIsTracking(false);\r\n }, []);\r\n\r\n const startTracking = useCallback(() => {\r\n if (typeof navigator === 'undefined' || !navigator.geolocation) {\r\n setError({ code: 0, message: 'La geolocalización no está disponible en este navegador.' });\r\n return;\r\n }\r\n\r\n setError(null);\r\n\r\n watchIdRef.current = navigator.geolocation.watchPosition(\r\n (position) => {\r\n setLocation({\r\n lat: position.coords.latitude,\r\n lon: position.coords.longitude,\r\n accuracy: position.coords.accuracy,\r\n });\r\n setIsTracking(true);\r\n },\r\n (err) => {\r\n setError({ code: err.code, message: err.message });\r\n stopTracking();\r\n },\r\n {\r\n enableHighAccuracy: options?.enableHighAccuracy ?? true,\r\n timeout: options?.timeout ?? 12000,\r\n maximumAge: options?.maximumAge ?? 0,\r\n }\r\n );\r\n }, [options?.enableHighAccuracy, options?.maximumAge, options?.timeout, stopTracking]);\r\n\r\n const toggleTracking = useCallback(() => {\r\n if (isTracking) {\r\n stopTracking();\r\n } else {\r\n startTracking();\r\n }\r\n }, [isTracking, startTracking, stopTracking]);\r\n\r\n const clearError = useCallback(() => setError(null), []);\r\n\r\n useEffect(() => {\r\n return () => {\r\n stopTracking();\r\n };\r\n }, [stopTracking]);\r\n\r\n return {\r\n isTracking,\r\n location,\r\n error,\r\n startTracking,\r\n stopTracking,\r\n toggleTracking,\r\n clearError,\r\n };\r\n}\r\n","import L, { PathOptions } from 'leaflet';\r\nimport type { LayerStyle } from '../layerStyleHelpers';\r\n\r\nconst POPUP_STYLE_ID = 'zenit-leaflet-popup-styles';\r\n\r\nconst POPUP_EXCLUDED_KEYS = new Set(['geom', 'geometry', '_private']);\r\nconst POPUP_HEADER_KEYS = ['nombre', 'name', 'title', 'titulo'];\r\n\r\nconst DESKTOP_POPUP_DIMENSIONS = { maxWidth: 360, minWidth: 280, maxHeight: 520 };\r\nconst MOBILE_POPUP_DIMENSIONS = { maxWidth: 300, minWidth: 240, maxHeight: 420 };\r\n\r\nconst ZENIT_LEAFLET_POPUP_STYLES = `\r\n.custom-leaflet-popup .leaflet-popup-content-wrapper {\r\n border-radius: 12px;\r\n padding: 0;\r\n background: #ffffff;\r\n box-shadow: 0 12px 24px rgba(15, 23, 42, 0.18);\r\n border: 1px solid rgba(15, 23, 42, 0.08);\r\n}\r\n\r\n.custom-leaflet-popup .leaflet-popup-content {\r\n margin: 0;\r\n padding: 12px 14px;\r\n font-size: 13px;\r\n line-height: 1.4;\r\n color: #0f172a;\r\n max-height: min(70vh, 520px);\r\n overflow: auto;\r\n scrollbar-width: thin;\r\n scrollbar-color: rgba(148, 163, 184, 0.6) transparent;\r\n}\r\n\r\n.custom-leaflet-popup .leaflet-popup-close-button {\r\n color: #64748b;\r\n font-size: 16px;\r\n padding: 6px 8px;\r\n border-radius: 8px;\r\n transition: background-color 0.15s ease, color 0.15s ease;\r\n}\r\n\r\n.custom-leaflet-popup .leaflet-popup-close-button:hover {\r\n color: #0f172a;\r\n background: rgba(148, 163, 184, 0.2);\r\n}\r\n\r\n.custom-leaflet-popup .leaflet-popup-content::-webkit-scrollbar {\r\n width: 6px;\r\n}\r\n\r\n.custom-leaflet-popup .leaflet-popup-content::-webkit-scrollbar-thumb {\r\n background: rgba(148, 163, 184, 0.5);\r\n border-radius: 999px;\r\n}\r\n\r\n.custom-leaflet-popup .leaflet-popup-content::-webkit-scrollbar-track {\r\n background: transparent;\r\n}\r\n\r\n@media (max-width: 640px) {\r\n .custom-leaflet-popup .leaflet-popup-content {\r\n font-size: 12px;\r\n padding: 10px 12px;\r\n max-height: min(65vh, 420px);\r\n }\r\n\r\n .custom-leaflet-popup .leaflet-popup-close-button {\r\n font-size: 14px;\r\n padding: 4px 6px;\r\n }\r\n}\r\n\r\n.zenit-map-tooltip {\r\n background-color: rgba(31, 41, 55, 0.95);\r\n border: none;\r\n border-radius: 6px;\r\n color: #ffffff;\r\n font-size: 12px;\r\n font-weight: 500;\r\n padding: 6px 10px;\r\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\r\n}\r\n\r\n.zenit-map-tooltip::before {\r\n border-top-color: rgba(31, 41, 55, 0.95);\r\n}\r\n\r\n.polygon-label-tooltip {\r\n background: rgba(15, 23, 42, 0.92);\r\n border: none;\r\n border-radius: 6px;\r\n color: #f8fafc;\r\n font-weight: 600;\r\n font-size: 12px;\r\n padding: 4px 8px;\r\n}\r\n`;\r\n\r\nfunction clampNumber(value: number, min: number, max: number): number {\r\n return Math.min(max, Math.max(min, value));\r\n}\r\n\r\nexport function clampOpacity(value: number): number {\r\n return clampNumber(value, 0, 1);\r\n}\r\n\r\nexport function ensurePopupStyles(): void {\r\n if (typeof document === 'undefined') return;\r\n if (document.getElementById(POPUP_STYLE_ID)) return;\r\n const styleTag = document.createElement('style');\r\n styleTag.id = POPUP_STYLE_ID;\r\n styleTag.textContent = ZENIT_LEAFLET_POPUP_STYLES;\r\n document.head.appendChild(styleTag);\r\n}\r\n\r\nexport function getPopupDimensions(): { maxWidth: number; minWidth: number; maxHeight: number } {\r\n if (typeof window === 'undefined') {\r\n return DESKTOP_POPUP_DIMENSIONS;\r\n }\r\n\r\n const isSmallWidth = window.innerWidth < 640;\r\n const isShortHeight = window.innerHeight < 768;\r\n const base = isSmallWidth ? MOBILE_POPUP_DIMENSIONS : DESKTOP_POPUP_DIMENSIONS;\r\n const maxHeight = isShortHeight ? Math.min(base.maxHeight, 360) : base.maxHeight;\r\n return { ...base, maxHeight };\r\n}\r\n\r\nfunction escapeHtml(value: string): string {\r\n return value\r\n .replace(/&/g, '&')\r\n .replace(/</g, '<')\r\n .replace(/>/g, '>')\r\n .replace(/\"/g, '"')\r\n .replace(/'/g, ''');\r\n}\r\n\r\nfunction formatLabel(key: string): string {\r\n return key\r\n .replace(/_/g, ' ')\r\n .replace(/([a-z])([A-Z])/g, '$1 $2')\r\n .trim();\r\n}\r\n\r\nfunction renderPopupValue(value: unknown): string {\r\n if (value === null || value === undefined) return '<span style=\"color:#94a3b8;\">Sin datos</span>';\r\n if (value instanceof Date) {\r\n return escapeHtml(value.toLocaleDateString('es-GT'));\r\n }\r\n if (typeof value === 'number') {\r\n return escapeHtml(value.toLocaleString('es-GT'));\r\n }\r\n if (typeof value === 'string') {\r\n const trimmed = value.trim();\r\n if (!trimmed) return '<span style=\"color:#94a3b8;\">Sin datos</span>';\r\n return escapeHtml(trimmed);\r\n }\r\n if (typeof value === 'object') {\r\n try {\r\n return `<pre style=\"margin:0; white-space:pre-wrap; font-size:11px; background:#f8fafc; border:1px solid #e2e8f0; padding:6px 8px; border-radius:6px;\">${escapeHtml(\r\n JSON.stringify(value, null, 2)\r\n )}</pre>`;\r\n } catch {\r\n return escapeHtml(String(value));\r\n }\r\n }\r\n return escapeHtml(String(value));\r\n}\r\n\r\nfunction extractPopupHeader(properties: Record<string, unknown>): string | null {\r\n const entry = Object.entries(properties).find(([key, value]) => {\r\n if (typeof value !== 'string') return false;\r\n const normalized = key.trim().toLowerCase();\r\n return POPUP_HEADER_KEYS.includes(normalized) && value.trim().length > 0;\r\n });\r\n\r\n return entry ? entry[1].trim() : null;\r\n}\r\n\r\nfunction shouldIncludePopupEntry(key: string, value: unknown): boolean {\r\n if (!key) return false;\r\n const normalized = key.trim().toLowerCase();\r\n if (!normalized) return false;\r\n if (normalized.startsWith('_')) return false;\r\n if (POPUP_EXCLUDED_KEYS.has(normalized)) return false;\r\n if (value === null || value === undefined) return false;\r\n if (typeof value === 'string' && !value.trim()) return false;\r\n return true;\r\n}\r\n\r\nexport function createPopupContent(properties: Record<string, unknown>): string {\r\n const headerText = extractPopupHeader(properties);\r\n const entries = Object.entries(properties).filter(([key, value]) => {\r\n if (!shouldIncludePopupEntry(key, value)) return false;\r\n if (headerText && POPUP_HEADER_KEYS.includes(key.trim().toLowerCase())) return false;\r\n return true;\r\n });\r\n\r\n if (entries.length === 0) {\r\n return '<div style=\"padding:8px 0; color:#64748b; text-align:center;\">Sin datos disponibles</div>';\r\n }\r\n\r\n const headerHtml = headerText\r\n ? `<div style=\"font-weight:700; font-size:14px; margin-bottom:8px; color:#0f172a;\">${escapeHtml(\r\n headerText\r\n )}</div>`\r\n : '';\r\n\r\n const rowsHtml = entries\r\n .map(([key, value]) => {\r\n const label = escapeHtml(formatLabel(key));\r\n const valueHtml = renderPopupValue(value);\r\n return `\r\n <div style=\"display:grid; grid-template-columns:minmax(90px, 35%) 1fr; gap:8px; padding:6px 0; border-bottom:1px solid #e2e8f0;\">\r\n <div style=\"font-size:11px; font-weight:600; text-transform:uppercase; letter-spacing:0.04em; color:#64748b;\">${label}</div>\r\n <div style=\"font-size:13px; color:#0f172a; word-break:break-word;\">${valueHtml}</div>\r\n </div>\r\n `;\r\n })\r\n .join('');\r\n\r\n return `<div>${headerHtml}${rowsHtml}</div>`;\r\n}\r\n\r\nfunction isPolygonType(layerType?: string, geometryType?: string): boolean {\r\n const candidate = (layerType ?? geometryType ?? '').toLowerCase();\r\n return candidate === 'polygon' || candidate === 'multipolygon';\r\n}\r\n\r\nexport function calculateZoomBasedOpacity(\r\n zoom: number,\r\n baseOpacity: number,\r\n layerType?: string,\r\n geometryType?: string\r\n): number {\r\n if (!isPolygonType(layerType, geometryType)) return clampOpacity(baseOpacity);\r\n\r\n const minZoom = 11;\r\n const maxZoom = 15;\r\n const minFactor = 0.3;\r\n\r\n if (maxZoom <= minZoom) return clampOpacity(baseOpacity * minFactor);\r\n\r\n const t = clampNumber((zoom - minZoom) / (maxZoom - minZoom), 0, 1);\r\n const factor = 1 - (1 - minFactor) * t;\r\n return clampOpacity(baseOpacity * factor);\r\n}\r\n\r\nexport function layerStyleToLeaflet(options: {\r\n baseOpacity: number;\r\n zoom: number;\r\n layerStyle?: LayerStyle | null;\r\n geometryType?: string;\r\n layerType?: string;\r\n}): PathOptions {\r\n const { baseOpacity, zoom, layerStyle, geometryType, layerType } = options;\r\n const sanitizedOpacity = clampOpacity(baseOpacity);\r\n const zoomOpacity = calculateZoomBasedOpacity(zoom, sanitizedOpacity, layerType, geometryType);\r\n const styleFillOpacity =\r\n typeof layerStyle?.fillOpacity === 'number'\r\n ? clampOpacity(layerStyle.fillOpacity)\r\n : 0.8;\r\n\r\n return {\r\n color: layerStyle?.color ?? layerStyle?.fillColor ?? '#2563eb',\r\n weight: layerStyle?.weight ?? 2,\r\n fillColor: layerStyle?.fillColor ?? layerStyle?.color ?? '#2563eb',\r\n opacity: clampOpacity(Math.max(0.35, zoomOpacity * 0.9)),\r\n fillOpacity: clampOpacity(zoomOpacity * styleFillOpacity),\r\n };\r\n}\r\n\r\nfunction getRgbFromColor(color: string): { r: number; g: number; b: number } | null {\r\n const trimmed = color.trim();\r\n if (trimmed.startsWith('#')) {\r\n const hex = trimmed.replace('#', '');\r\n const expanded =\r\n hex.length === 3\r\n ? hex\r\n .split('')\r\n .map((char) => `${char}${char}`)\r\n .join('')\r\n : hex;\r\n if (expanded.length === 6) {\r\n const r = parseInt(expanded.slice(0, 2), 16);\r\n const g = parseInt(expanded.slice(2, 4), 16);\r\n const b = parseInt(expanded.slice(4, 6), 16);\r\n return { r, g, b };\r\n }\r\n }\r\n\r\n const rgbMatch = trimmed.match(/rgba?\\(([^)]+)\\)/i);\r\n if (rgbMatch) {\r\n const [r, g, b] = rgbMatch[1]\r\n .split(',')\r\n .map((value) => parseFloat(value.trim()))\r\n .slice(0, 3);\r\n if ([r, g, b].every((value) => Number.isFinite(value))) {\r\n return { r, g, b };\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction getLabelTextStyles(color: string): { color: string; shadow: string } {\r\n const rgb = getRgbFromColor(color);\r\n if (!rgb) {\r\n return { color: '#0f172a', shadow: '0 1px 2px rgba(255, 255, 255, 0.6)' };\r\n }\r\n\r\n const luminance = (0.2126 * rgb.r + 0.7152 * rgb.g + 0.0722 * rgb.b) / 255;\r\n if (luminance > 0.6) {\r\n return { color: '#0f172a', shadow: '0 1px 2px rgba(255, 255, 255, 0.7)' };\r\n }\r\n\r\n return { color: '#ffffff', shadow: '0 1px 2px rgba(0, 0, 0, 0.4)' };\r\n}\r\n\r\nfunction withAlpha(color: string, alpha: number): string {\r\n const trimmed = color.trim();\r\n if (trimmed.startsWith('#')) {\r\n const hex = trimmed.replace('#', '');\r\n const expanded =\r\n hex.length === 3\r\n ? hex\r\n .split('')\r\n .map((char) => `${char}${char}`)\r\n .join('')\r\n : hex;\r\n if (expanded.length === 6) {\r\n const r = parseInt(expanded.slice(0, 2), 16);\r\n const g = parseInt(expanded.slice(2, 4), 16);\r\n const b = parseInt(expanded.slice(4, 6), 16);\r\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\r\n }\r\n }\r\n\r\n if (trimmed.startsWith('rgb(')) {\r\n const inner = trimmed.slice(4, -1);\r\n return `rgba(${inner}, ${alpha})`;\r\n }\r\n\r\n if (trimmed.startsWith('rgba(')) {\r\n const inner = trimmed.slice(5, -1).split(',').slice(0, 3).map((value) => value.trim());\r\n return `rgba(${inner.join(', ')}, ${alpha})`;\r\n }\r\n\r\n return color;\r\n}\r\n\r\nexport function createCustomIcon(label: string, opacity: number, color: string): L.DivIcon {\r\n const size = 60;\r\n const innerSize = 44;\r\n const textStyles = getLabelTextStyles(color);\r\n const safeLabel = escapeHtml(label);\r\n const clampedOpacity = Math.min(1, Math.max(0.92, opacity));\r\n const innerBackground = withAlpha(color, 0.9);\r\n\r\n return L.divIcon({\r\n className: 'zenit-label-marker',\r\n iconSize: [size, size],\r\n iconAnchor: [size / 2, size / 2],\r\n html: `\r\n <div\r\n title=\"${safeLabel}\"\r\n style=\"\r\n width:${size}px;\r\n height:${size}px;\r\n border-radius:9999px;\r\n background:rgba(255, 255, 255, 0.95);\r\n border:3px solid rgba(255, 255, 255, 1);\r\n display:flex;\r\n align-items:center;\r\n justify-content:center;\r\n opacity:${clampedOpacity};\r\n box-shadow:0 2px 6px rgba(0, 0, 0, 0.25);\r\n pointer-events:none;\r\n \"\r\n >\r\n <div\r\n style=\"\r\n width:${innerSize}px;\r\n height:${innerSize}px;\r\n border-radius:9999px;\r\n background:${innerBackground};\r\n display:flex;\r\n align-items:center;\r\n justify-content:center;\r\n box-shadow:inset 0 0 0 1px rgba(15, 23, 42, 0.12);\r\n \"\r\n >\r\n <span\r\n style=\"\r\n color:${textStyles.color};\r\n font-size:20px;\r\n font-weight:800;\r\n text-shadow:${textStyles.shadow};\r\n \"\r\n >\r\n ${safeLabel}\r\n </span>\r\n </div>\r\n </div>\r\n `,\r\n });\r\n}\r\n\r\nexport function createLocationIcon(): L.DivIcon {\r\n return L.divIcon({\r\n className: 'zenit-location-marker',\r\n iconSize: [18, 18],\r\n iconAnchor: [9, 9],\r\n html: `\r\n <div style=\"width:18px;height:18px;border-radius:9999px;background:#2563eb;border:2px solid #fff;box-shadow:0 0 0 4px rgba(37, 99, 235, 0.25);\"></div>\r\n `,\r\n });\r\n}\r\n","import React, { useEffect, useRef } from 'react';\r\nimport { useMap } from 'react-leaflet';\r\nimport type { LatLngBoundsExpression, Map as LeafletMap } from 'leaflet';\r\nimport type { Bbox, GeoJsonFeatureCollection } from '../../layers/types';\r\n\r\ntype MapInvalidatorProps = {\r\n trigger?: unknown;\r\n};\r\n\r\nexport const MapInvalidator: React.FC<MapInvalidatorProps> = ({ trigger }) => {\r\n const map = useMap();\r\n const lastTrigger = useRef<unknown>(undefined);\r\n\r\n useEffect(() => {\r\n if (lastTrigger.current === trigger) return;\r\n lastTrigger.current = trigger;\r\n requestAnimationFrame(() => {\r\n map.invalidateSize();\r\n });\r\n }, [map, trigger]);\r\n\r\n return null;\r\n};\r\n\r\nfunction computeBBoxFromGeojson(geojson?: GeoJsonFeatureCollection | null): Bbox | null {\r\n if (!geojson || !Array.isArray(geojson.features)) return null;\r\n const coords: Array<[number, number]> = [];\r\n\r\n const collect = (candidate: unknown) => {\r\n if (!Array.isArray(candidate)) return;\r\n if (\r\n candidate.length === 2 &&\r\n typeof candidate[0] === 'number' &&\r\n typeof candidate[1] === 'number' &&\r\n Number.isFinite(candidate[0]) &&\r\n Number.isFinite(candidate[1])\r\n ) {\r\n coords.push([candidate[0], candidate[1]]);\r\n return;\r\n }\r\n\r\n candidate.forEach((item) => collect(item));\r\n };\r\n\r\n geojson.features.forEach((feature) => {\r\n collect((feature as { geometry?: { coordinates?: unknown } }).geometry?.coordinates);\r\n });\r\n\r\n if (coords.length === 0) return null;\r\n\r\n const [firstLon, firstLat] = coords[0];\r\n const bbox: Bbox = { minLon: firstLon, minLat: firstLat, maxLon: firstLon, maxLat: firstLat };\r\n\r\n coords.forEach(([lon, lat]) => {\r\n bbox.minLon = Math.min(bbox.minLon, lon);\r\n bbox.minLat = Math.min(bbox.minLat, lat);\r\n bbox.maxLon = Math.max(bbox.maxLon, lon);\r\n bbox.maxLat = Math.max(bbox.maxLat, lat);\r\n });\r\n\r\n return bbox;\r\n}\r\n\r\nfunction mergeBBoxes(bboxes: Array<Bbox | null>): Bbox | null {\r\n const valid = bboxes.filter((bbox): bbox is Bbox => !!bbox);\r\n if (valid.length === 0) return null;\r\n\r\n const first = valid[0];\r\n return valid.slice(1).reduce(\r\n (acc, bbox) => ({\r\n minLon: Math.min(acc.minLon, bbox.minLon),\r\n minLat: Math.min(acc.minLat, bbox.minLat),\r\n maxLon: Math.max(acc.maxLon, bbox.maxLon),\r\n maxLat: Math.max(acc.maxLat, bbox.maxLat),\r\n }),\r\n { ...first }\r\n );\r\n}\r\n\r\ntype BBoxZoomHandlerProps = {\r\n bbox?: Bbox | null;\r\n geojson?: GeoJsonFeatureCollection | null;\r\n autoGeojson?: GeoJsonFeatureCollection[];\r\n enabled?: boolean;\r\n};\r\n\r\nexport const BBoxZoomHandler: React.FC<BBoxZoomHandlerProps> = ({\r\n bbox,\r\n geojson,\r\n autoGeojson = [],\r\n enabled = true,\r\n}) => {\r\n const map = useMap();\r\n const lastAppliedBBox = useRef<string | null>(null);\r\n const lastUserInteracted = useRef(false);\r\n\r\n useEffect(() => {\r\n const handleInteraction = () => {\r\n lastUserInteracted.current = true;\r\n };\r\n\r\n map.on('dragstart', handleInteraction);\r\n map.on('zoomstart', handleInteraction);\r\n\r\n return () => {\r\n map.off('dragstart', handleInteraction);\r\n map.off('zoomstart', handleInteraction);\r\n };\r\n }, [map]);\r\n\r\n useEffect(() => {\r\n if (!enabled) return;\r\n\r\n let resolvedBBox = bbox ?? null;\r\n\r\n if (!resolvedBBox && geojson) {\r\n resolvedBBox = computeBBoxFromGeojson(geojson);\r\n }\r\n\r\n if (!resolvedBBox && autoGeojson.length > 0) {\r\n const bboxes = autoGeojson.map((collection) => computeBBoxFromGeojson(collection));\r\n resolvedBBox = mergeBBoxes(bboxes);\r\n }\r\n\r\n if (!resolvedBBox) return;\r\n\r\n const serialized = JSON.stringify(resolvedBBox);\r\n if (lastAppliedBBox.current === serialized) return;\r\n\r\n if (lastUserInteracted.current && !bbox && !geojson) {\r\n lastUserInteracted.current = false;\r\n return;\r\n }\r\n\r\n const bounds: LatLngBoundsExpression = [\r\n [resolvedBBox.minLat, resolvedBBox.minLon],\r\n [resolvedBBox.maxLat, resolvedBBox.maxLon],\r\n ];\r\n map.fitBounds(bounds, { padding: [12, 12] });\r\n lastAppliedBBox.current = serialized;\r\n }, [autoGeojson, bbox, enabled, geojson, map]);\r\n\r\n return null;\r\n};\r\n\r\ntype ZoomBasedOpacityHandlerProps = {\r\n onZoomChange: (zoom: number) => void;\r\n};\r\n\r\nexport const ZoomBasedOpacityHandler: React.FC<ZoomBasedOpacityHandlerProps> = ({ onZoomChange }) => {\r\n const map = useMap();\r\n\r\n useEffect(() => {\r\n const handleZoom = () => {\r\n onZoomChange(map.getZoom());\r\n };\r\n\r\n map.on('zoomend', handleZoom);\r\n handleZoom();\r\n\r\n return () => {\r\n map.off('zoomend', handleZoom);\r\n };\r\n }, [map, onZoomChange]);\r\n\r\n return null;\r\n};\r\n\r\ntype MapInstanceBridgeProps = {\r\n onReady: (mapInstance: LeafletMap) => void;\r\n};\r\n\r\nexport const MapInstanceBridge: React.FC<MapInstanceBridgeProps> = ({ onReady }) => {\r\n const map = useMap();\r\n\r\n useEffect(() => {\r\n onReady(map);\r\n }, [map, onReady]);\r\n\r\n return null;\r\n};\r\n","import React, { useEffect, useMemo, useRef, useState } from 'react';\r\nimport type { ZenitClient } from '../config/ZenitSdkConfig';\r\nimport type { GeoJsonPolygon, LayerDto } from '../layers/types';\r\nimport type { MapDto, MapLayerConfig } from '../maps/types';\r\nimport { extractMapDto, normalizeMapCenter, normalizeMapLayers } from '../maps/helpers';\r\nimport type { EffectiveLayerState, LayerOverrideState } from '../engine/LayerStateEngine';\r\nimport { applyLayerOverrides, initLayerStates } from '../engine/LayerStateEngine';\r\nimport { Eye, EyeOff, Layers, Upload } from './icons';\r\nimport { ZenitSelect } from './ui/ZenitSelect';\r\nimport { getEffectiveLayerOpacity } from './zoomOpacity';\r\n\r\nexport interface LayerStyle {\r\n color?: string;\r\n weight?: number;\r\n fillColor?: string;\r\n fillOpacity?: number;\r\n}\r\n\r\nexport interface ZenitLayerManagerProps {\r\n client: ZenitClient;\r\n mapId: number | string;\r\n side?: 'left' | 'right';\r\n className?: string;\r\n style?: React.CSSProperties;\r\n height?: string;\r\n layerStates?: EffectiveLayerState[];\r\n onLayerStatesChange?: (states: EffectiveLayerState[]) => void;\r\n mapZoom?: number;\r\n autoOpacityOnZoom?: boolean;\r\n autoOpacityConfig?: {\r\n minZoom?: number;\r\n maxZoom?: number;\r\n minOpacity?: number;\r\n maxOpacity?: number;\r\n };\r\n showUploadTab?: boolean;\r\n showLayerVisibilityIcon?: boolean;\r\n layerFeatureCounts?: Record<string | number, number | null | undefined>;\r\n mapLayers?: Array<{\r\n layerId: number | string;\r\n geometryType?: string | null;\r\n layerType?: string | null;\r\n name?: string | null;\r\n style?: LayerStyle | null;\r\n bboxGeometry?: GeoJsonPolygon | null;\r\n displayOrder?: number | null;\r\n }>;\r\n onZoomToLayer?: (layerId: number | string, bboxGeometry?: GeoJsonPolygon | null) => void;\r\n onApplyLayerFilter?: (params: {\r\n layerId: number | string;\r\n field: string;\r\n value: string;\r\n }) => Promise<void> | void;\r\n onClearLayerFilter?: (params: { layerId: number | string; field?: string }) => Promise<void> | void;\r\n}\r\n\r\ntype MapLayerWithId = MapLayerConfig & { layerId: number | string; layer?: LayerDto };\r\n\r\ninterface ManagedLayerState {\r\n mapLayer: MapLayerWithId;\r\n layer?: LayerDto;\r\n effective?: EffectiveLayerState;\r\n visible?: boolean;\r\n opacity?: number;\r\n displayOrder?: number;\r\n initialIndex?: number;\r\n featureCount?: number | null;\r\n layerName?: string;\r\n}\r\n\r\nconst FLOAT_TOLERANCE = 0.001;\r\n\r\nfunction areEffectiveStatesEqual(a: EffectiveLayerState[], b: EffectiveLayerState[]): boolean {\r\n if (a.length !== b.length) return false;\r\n return a.every((state, index) => {\r\n const other = b[index];\r\n if (!other) return false;\r\n const opacityDiff = Math.abs((state.opacity ?? 1) - (other.opacity ?? 1));\r\n return (\r\n String(state.layerId) === String(other.layerId) &&\r\n (state.visible ?? false) === (other.visible ?? false) &&\r\n opacityDiff <= FLOAT_TOLERANCE\r\n );\r\n });\r\n}\r\n\r\nfunction getLayerColor(style?: LayerStyle | null): string {\r\n if (!style) return '#94a3b8';\r\n\r\n return style.fillColor ?? style.color ?? '#94a3b8';\r\n}\r\n\r\nfunction resolveDisplayOrder(value?: number | string | null): number {\r\n if (typeof value === 'number' && Number.isFinite(value)) return value;\r\n if (typeof value === 'string') {\r\n const parsed = Number.parseFloat(value);\r\n if (Number.isFinite(parsed)) return parsed;\r\n }\r\n return 0;\r\n}\r\n\r\nexport const ZenitLayerManager: React.FC<ZenitLayerManagerProps> = ({\r\n client,\r\n mapId,\r\n side = 'right',\r\n className,\r\n style,\r\n height,\r\n layerStates,\r\n onLayerStatesChange,\r\n mapZoom,\r\n autoOpacityOnZoom = false,\r\n autoOpacityConfig,\r\n showUploadTab = true,\r\n showLayerVisibilityIcon = true,\r\n layerFeatureCounts,\r\n mapLayers,\r\n onApplyLayerFilter,\r\n onClearLayerFilter,\r\n}) => {\r\n const [map, setMap] = useState<MapDto | null>(null);\r\n const [loadingMap, setLoadingMap] = useState(false);\r\n const [mapError, setMapError] = useState<string | null>(null);\r\n const [layers, setLayers] = useState<ManagedLayerState[]>([]);\r\n const [activeTab, setActiveTab] = useState<'layers' | 'filters' | 'upload'>('layers');\r\n const [panelVisible, setPanelVisible] = useState(true);\r\n const [selectedFilterLayerId, setSelectedFilterLayerId] = useState<string>('');\r\n const [selectedFilterField, setSelectedFilterField] = useState<string>('');\r\n const [selectedFilterValue, setSelectedFilterValue] = useState<string>('');\r\n const [catalogByLayerField, setCatalogByLayerField] = useState<Record<string, string[]>>({});\r\n const [loadingCatalog, setLoadingCatalog] = useState(false);\r\n const [applyingFilter, setApplyingFilter] = useState(false);\r\n const [filterError, setFilterError] = useState<string | null>(null);\r\n const [appliedFilter, setAppliedFilter] = useState<{\r\n layerId: number | string;\r\n field: string;\r\n value: string;\r\n } | null>(null);\r\n const catalogAbortRef = useRef<AbortController | null>(null);\r\n const lastEmittedStatesRef = useRef<EffectiveLayerState[] | null>(null);\r\n // Controlled mode: emit changes to parent instead of mutating local layer state.\r\n const isControlled = Array.isArray(layerStates) && typeof onLayerStatesChange === 'function';\r\n\r\n const baseStates = useMemo(\r\n () =>\r\n initLayerStates(\r\n layers.map((entry) => ({\r\n ...entry.mapLayer,\r\n layerId: entry.mapLayer.layerId,\r\n isVisible: entry.visible,\r\n opacity: entry.opacity,\r\n })) as MapLayerWithId[]\r\n ),\r\n [layers]\r\n );\r\n\r\n const overrideStates = useMemo(\r\n () =>\r\n layers.map(\r\n (entry): LayerOverrideState => ({\r\n layerId: entry.mapLayer.layerId,\r\n overrideVisible: entry.visible,\r\n overrideOpacity: entry.opacity,\r\n })\r\n ),\r\n [layers]\r\n );\r\n\r\n const effectiveStates = useMemo(\r\n () => layerStates ?? applyLayerOverrides(baseStates, overrideStates),\r\n [baseStates, layerStates, overrideStates]\r\n );\r\n\r\n const layerMetaIndex = useMemo(() => {\r\n const index = new Map<string, { layerType?: string; geometryType?: string }>();\r\n mapLayers?.forEach((entry) => {\r\n const key = String(entry.layerId);\r\n index.set(key, { layerType: entry.layerType ?? undefined, geometryType: entry.geometryType ?? undefined });\r\n });\r\n map?.mapLayers?.forEach((entry) => {\r\n const key = String(entry.layerId);\r\n if (!index.has(key)) {\r\n index.set(key, { layerType: entry.layerType ?? undefined, geometryType: entry.geometryType ?? undefined });\r\n }\r\n });\r\n return index;\r\n }, [map, mapLayers]);\r\n\r\n const resolveUserOpacity = React.useCallback((state: EffectiveLayerState): number => {\r\n if (typeof state.overrideOpacity === 'number') return state.overrideOpacity;\r\n if (typeof state.overrideOpacity === 'string') {\r\n const parsed = Number.parseFloat(state.overrideOpacity);\r\n if (Number.isFinite(parsed)) return parsed;\r\n }\r\n return state.opacity ?? 1;\r\n }, []);\r\n\r\n const resolveEffectiveOpacity = React.useCallback(\r\n (layerId: number | string, userOpacity: number): number => {\r\n if (!autoOpacityOnZoom || typeof mapZoom !== 'number') {\r\n return userOpacity;\r\n }\r\n const meta = layerMetaIndex.get(String(layerId));\r\n return getEffectiveLayerOpacity(\r\n userOpacity,\r\n mapZoom,\r\n meta?.layerType,\r\n meta?.geometryType,\r\n autoOpacityConfig\r\n );\r\n },\r\n [autoOpacityConfig, autoOpacityOnZoom, layerMetaIndex, mapZoom]\r\n );\r\n\r\n const effectiveStatesWithZoom = useMemo(() => {\r\n if (!autoOpacityOnZoom || typeof mapZoom !== 'number') {\r\n return effectiveStates;\r\n }\r\n\r\n return effectiveStates.map((state) => {\r\n const userOpacity = resolveUserOpacity(state);\r\n const adjustedOpacity = resolveEffectiveOpacity(state.layerId, userOpacity);\r\n return {\r\n ...state,\r\n opacity: adjustedOpacity,\r\n overrideOpacity: userOpacity,\r\n };\r\n });\r\n }, [autoOpacityOnZoom, effectiveStates, mapZoom, resolveEffectiveOpacity, resolveUserOpacity]);\r\n\r\n useEffect(() => {\r\n let cancelled = false;\r\n setLoadingMap(true);\r\n setMapError(null);\r\n setLayers([]);\r\n client.maps\r\n .getMap(mapId, true)\r\n .then((mapResponse) => {\r\n if (cancelled) return;\r\n const extractedMap = extractMapDto(mapResponse);\r\n const resolvedMap = extractedMap ? normalizeMapCenter(extractedMap) : null;\r\n setMap(resolvedMap);\r\n const normalizedLayers = normalizeMapLayers(resolvedMap);\r\n setLayers(\r\n normalizedLayers.map((entry, index) => ({\r\n mapLayer: { ...(entry.mapLayer as MapLayerConfig & { layer?: LayerDto }), layerId: entry.layerId } as MapLayerWithId,\r\n layer: entry.layer,\r\n visible: entry.isVisible,\r\n opacity: entry.opacity,\r\n displayOrder: entry.displayOrder,\r\n initialIndex: index,\r\n }))\r\n );\r\n })\r\n .catch((err: unknown) => {\r\n if (cancelled) return;\r\n const message = err instanceof Error ? err.message : 'No se pudo cargar el mapa';\r\n setMapError(message);\r\n })\r\n .finally(() => {\r\n if (!cancelled) setLoadingMap(false);\r\n });\r\n\r\n return () => {\r\n cancelled = true;\r\n };\r\n }, [client.maps, mapId]);\r\n\r\n useEffect(() => {\r\n if (!showUploadTab && activeTab === 'upload') {\r\n setActiveTab('layers');\r\n }\r\n }, [activeTab, showUploadTab]);\r\n\r\n useEffect(() => {\r\n if (isControlled) return;\r\n if (!onLayerStatesChange) return;\r\n const emitStates =\r\n autoOpacityOnZoom && typeof mapZoom === 'number' ? effectiveStatesWithZoom : effectiveStates;\r\n const previous = lastEmittedStatesRef.current;\r\n if (previous && areEffectiveStatesEqual(previous, emitStates)) {\r\n return;\r\n }\r\n lastEmittedStatesRef.current = emitStates;\r\n onLayerStatesChange(emitStates);\r\n }, [\r\n autoOpacityOnZoom,\r\n effectiveStates,\r\n effectiveStatesWithZoom,\r\n isControlled,\r\n mapZoom,\r\n onLayerStatesChange,\r\n ]);\r\n\r\n const updateLayerVisible = React.useCallback(\r\n (layerId: number | string, visible: boolean) => {\r\n if (!onLayerStatesChange) return;\r\n const next = effectiveStates.map((state) =>\r\n state.layerId === layerId\r\n ? { ...state, visible, overrideVisible: visible }\r\n : state\r\n );\r\n onLayerStatesChange(next);\r\n },\r\n [effectiveStates, onLayerStatesChange]\r\n );\r\n\r\n const updateLayerOpacity = React.useCallback(\r\n (layerId: number | string, opacity: number) => {\r\n if (!onLayerStatesChange) return;\r\n const adjustedOpacity = resolveEffectiveOpacity(layerId, opacity);\r\n const next = effectiveStates.map((state) =>\r\n state.layerId === layerId\r\n ? { ...state, opacity: adjustedOpacity, overrideOpacity: opacity }\r\n : state\r\n );\r\n onLayerStatesChange(next);\r\n },\r\n [effectiveStates, onLayerStatesChange, resolveEffectiveOpacity]\r\n );\r\n\r\n const resolveFeatureCount = React.useCallback(\r\n (layerId: number | string, layer?: LayerDto) => {\r\n const resolvedFeatureCount =\r\n layerFeatureCounts?.[layerId] ?? layerFeatureCounts?.[String(layerId)];\r\n if (typeof resolvedFeatureCount === 'number') return resolvedFeatureCount;\r\n\r\n const featureCount =\r\n (layer as { featuresCount?: number } | undefined)?.featuresCount ??\r\n (layer as { featureCount?: number } | undefined)?.featureCount ??\r\n (layer as { totalFeatures?: number } | undefined)?.totalFeatures;\r\n\r\n return typeof featureCount === 'number' ? featureCount : null;\r\n },\r\n [layerFeatureCounts]\r\n );\r\n\r\n const decoratedLayers = useMemo(() => {\r\n return layers\r\n .map((entry) => ({\r\n ...entry,\r\n effective: effectiveStates.find((state) => state.layerId === entry.mapLayer.layerId),\r\n featureCount: resolveFeatureCount(entry.mapLayer.layerId, entry.layer),\r\n layerName: entry.layer?.name ?? entry.mapLayer.name ?? `Capa ${entry.mapLayer.layerId}`,\r\n }))\r\n .sort((a, b) => {\r\n const aOrder = resolveDisplayOrder(\r\n a.displayOrder ?? a.mapLayer.displayOrder ?? a.mapLayer.order\r\n );\r\n const bOrder = resolveDisplayOrder(\r\n b.displayOrder ?? b.mapLayer.displayOrder ?? b.mapLayer.order\r\n );\r\n const aHasOrder =\r\n a.displayOrder ?? a.mapLayer.displayOrder ?? a.mapLayer.order ?? null;\r\n const bHasOrder =\r\n b.displayOrder ?? b.mapLayer.displayOrder ?? b.mapLayer.order ?? null;\r\n if (aHasOrder !== null && bHasOrder !== null) {\r\n const orderCompare = aOrder - bOrder;\r\n if (orderCompare !== 0) return orderCompare;\r\n }\r\n\r\n const aInitial = a.initialIndex ?? 0;\r\n const bInitial = b.initialIndex ?? 0;\r\n if (aInitial !== bInitial) return aInitial - bInitial;\r\n\r\n const aName = a.layerName ?? String(a.mapLayer.layerId);\r\n const bName = b.layerName ?? String(b.mapLayer.layerId);\r\n const nameCompare = aName.localeCompare(bName, undefined, { sensitivity: 'base' });\r\n if (nameCompare !== 0) return nameCompare;\r\n\r\n return String(a.mapLayer.layerId).localeCompare(String(b.mapLayer.layerId));\r\n });\r\n }, [effectiveStates, layers, resolveFeatureCount]);\r\n\r\n const filterableLayers = useMemo(() => {\r\n return decoratedLayers.filter((entry) => {\r\n const prefilters = (entry.mapLayer.layerConfig as { prefilters?: Record<string, unknown> } | undefined)?.prefilters;\r\n return !!prefilters && Object.keys(prefilters).length > 0;\r\n });\r\n }, [decoratedLayers]);\r\n\r\n const selectedFilterLayer = useMemo(\r\n () => filterableLayers.find((layer) => String(layer.mapLayer.layerId) === selectedFilterLayerId) ?? null,\r\n [filterableLayers, selectedFilterLayerId]\r\n );\r\n\r\n const filterFields = useMemo(() => {\r\n const prefilters = (selectedFilterLayer?.mapLayer.layerConfig as { prefilters?: Record<string, unknown> } | undefined)?.prefilters;\r\n return prefilters ? Object.keys(prefilters) : [];\r\n }, [selectedFilterLayer]);\r\n\r\n const activeCatalogKey = selectedFilterLayer ? `${selectedFilterLayer.mapLayer.layerId}:${selectedFilterField}` : null;\r\n const activeCatalogValues = activeCatalogKey ? catalogByLayerField[activeCatalogKey] ?? [] : [];\r\n\r\n const extractCatalogValues = React.useCallback((catalogData: unknown, field: string): string[] => {\r\n const values = new Set<string>();\r\n\r\n const pushValue = (value: unknown) => {\r\n if (value === null || value === undefined) return;\r\n const normalized = String(value).trim();\r\n if (normalized) values.add(normalized);\r\n };\r\n\r\n if (catalogData && typeof catalogData === 'object') {\r\n const maybeRecord = catalogData as Record<string, unknown>;\r\n const directField = maybeRecord[field];\r\n if (Array.isArray(directField)) {\r\n directField.forEach(pushValue);\r\n }\r\n\r\n const items = maybeRecord.items;\r\n if (Array.isArray(items)) {\r\n items.forEach((item) => {\r\n if (!item || typeof item !== 'object') return;\r\n const row = item as Record<string, unknown>;\r\n const rowField = row.field;\r\n if (String(rowField ?? '').toUpperCase() === field.toUpperCase() && Array.isArray(row.values)) {\r\n row.values.forEach(pushValue);\r\n }\r\n });\r\n }\r\n\r\n const features = maybeRecord.features;\r\n if (Array.isArray(features)) {\r\n features.forEach((feature) => {\r\n if (!feature || typeof feature !== 'object') return;\r\n const properties = (feature as { properties?: Record<string, unknown> }).properties;\r\n if (properties && field in properties) {\r\n pushValue(properties[field]);\r\n }\r\n });\r\n }\r\n }\r\n\r\n return [...values].sort((a, b) => a.localeCompare(b, undefined, { sensitivity: 'base' }));\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (!filterableLayers.length) {\r\n setSelectedFilterLayerId('');\r\n return;\r\n }\r\n\r\n if (!selectedFilterLayerId || !filterableLayers.some((layer) => String(layer.mapLayer.layerId) === selectedFilterLayerId)) {\r\n setSelectedFilterLayerId(String(filterableLayers[0].mapLayer.layerId));\r\n }\r\n }, [filterableLayers, selectedFilterLayerId]);\r\n\r\n useEffect(() => {\r\n if (!filterFields.length) {\r\n setSelectedFilterField('');\r\n return;\r\n }\r\n if (!selectedFilterField || !filterFields.includes(selectedFilterField)) {\r\n setSelectedFilterField(filterFields[0]);\r\n setSelectedFilterValue('');\r\n }\r\n }, [filterFields, selectedFilterField]);\r\n\r\n useEffect(() => {\r\n if (activeTab !== 'filters') return;\r\n if (!selectedFilterLayer || !selectedFilterField || !activeCatalogKey) return;\r\n if (catalogByLayerField[activeCatalogKey]) return;\r\n\r\n catalogAbortRef.current?.abort();\r\n const controller = new AbortController();\r\n catalogAbortRef.current = controller;\r\n setLoadingCatalog(true);\r\n setFilterError(null);\r\n\r\n client.layers\r\n .getLayerFeaturesCatalog(selectedFilterLayer.mapLayer.layerId)\r\n .then((response) => {\r\n if (controller.signal.aborted) return;\r\n const values = extractCatalogValues(response.data, selectedFilterField);\r\n setCatalogByLayerField((prev) => ({ ...prev, [activeCatalogKey]: values }));\r\n })\r\n .catch((error: unknown) => {\r\n if (controller.signal.aborted) return;\r\n const message = error instanceof Error ? error.message : 'No se pudo cargar el catálogo';\r\n setFilterError(message);\r\n })\r\n .finally(() => {\r\n if (!controller.signal.aborted) setLoadingCatalog(false);\r\n });\r\n\r\n return () => {\r\n controller.abort();\r\n };\r\n }, [activeCatalogKey, activeTab, catalogByLayerField, client.layers, extractCatalogValues, selectedFilterField, selectedFilterLayer]);\r\n\r\n const handleApplyFilter = React.useCallback(async () => {\r\n if (!selectedFilterLayer || !selectedFilterField || !selectedFilterValue || !onApplyLayerFilter) return;\r\n setApplyingFilter(true);\r\n setFilterError(null);\r\n try {\r\n await onApplyLayerFilter({\r\n layerId: selectedFilterLayer.mapLayer.layerId,\r\n field: selectedFilterField,\r\n value: selectedFilterValue,\r\n });\r\n setAppliedFilter({\r\n layerId: selectedFilterLayer.mapLayer.layerId,\r\n field: selectedFilterField,\r\n value: selectedFilterValue,\r\n });\r\n } catch (error: unknown) {\r\n const message = error instanceof Error ? error.message : 'No se pudo aplicar el filtro';\r\n setFilterError(message);\r\n } finally {\r\n setApplyingFilter(false);\r\n }\r\n }, [onApplyLayerFilter, selectedFilterField, selectedFilterLayer, selectedFilterValue]);\r\n\r\n const handleClearFilter = React.useCallback(async () => {\r\n if (!selectedFilterLayer) return;\r\n setApplyingFilter(true);\r\n setFilterError(null);\r\n try {\r\n await onClearLayerFilter?.({ layerId: selectedFilterLayer.mapLayer.layerId, field: selectedFilterField || undefined });\r\n setSelectedFilterValue('');\r\n setAppliedFilter(null);\r\n } catch (error: unknown) {\r\n const message = error instanceof Error ? error.message : 'No se pudo limpiar el filtro';\r\n setFilterError(message);\r\n } finally {\r\n setApplyingFilter(false);\r\n }\r\n }, [onClearLayerFilter, selectedFilterField, selectedFilterLayer]);\r\n\r\n const resolveLayerStyle = React.useCallback(\r\n (layerId: number | string): LayerStyle | undefined => {\r\n const layerKey = String(layerId);\r\n\r\n const fromProp = mapLayers?.find((entry) => String(entry.layerId) === layerKey)?.style;\r\n if (fromProp) return fromProp;\r\n\r\n const fromMapDto = map?.mapLayers?.find((entry) => String(entry.layerId) === layerKey);\r\n if (fromMapDto?.layer) {\r\n const layer = fromMapDto.layer as LayerDto & { style?: LayerStyle };\r\n if (layer.style) return layer.style;\r\n }\r\n\r\n return undefined;\r\n },\r\n [map, mapLayers]\r\n );\r\n\r\n const panelStyle: React.CSSProperties = {\r\n width: 360,\r\n borderLeft: side === 'right' ? '1px solid #e2e8f0' : undefined,\r\n borderRight: side === 'left' ? '1px solid #e2e8f0' : undefined,\r\n background: '#f1f5f9',\r\n fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif',\r\n fontSize: 14,\r\n boxSizing: 'border-box',\r\n height: height ?? '100%',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n boxShadow: '0 12px 28px rgba(15, 23, 42, 0.08)',\r\n ...style,\r\n ...(height ? { height } : {}),\r\n };\r\n\r\n if (loadingMap) {\r\n return <div className={className} style={panelStyle}>Cargando capas…</div>;\r\n }\r\n\r\n if (mapError) {\r\n return (\r\n <div className={className} style={{ ...panelStyle, color: '#c53030' }}>\r\n Error al cargar mapa: {mapError}\r\n </div>\r\n );\r\n }\r\n\r\n if (!map) {\r\n return null;\r\n }\r\n\r\n const headerStyle: React.CSSProperties = {\r\n padding: '14px 16px',\r\n borderBottom: '1px solid #e2e8f0',\r\n background: '#fff',\r\n position: 'sticky',\r\n top: 0,\r\n zIndex: 2,\r\n boxShadow: '0 1px 0 rgba(148, 163, 184, 0.25)',\r\n };\r\n\r\n const renderLayerCards = () => {\r\n return (\r\n <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>\r\n {decoratedLayers.map((layerState) => {\r\n const layerId = layerState.mapLayer.layerId;\r\n const layerName = layerState.layerName ?? `Capa ${layerId}`;\r\n const visible = layerState.effective?.visible ?? false;\r\n const userOpacity = layerState.effective ? resolveUserOpacity(layerState.effective) : 1;\r\n const featureCount = layerState.featureCount;\r\n const layerColor = getLayerColor(resolveLayerStyle(layerId));\r\n const muted = !visible;\r\n const opacityPercent = Math.round(userOpacity * 100);\r\n const sliderBackground = `linear-gradient(to right, ${layerColor} 0%, ${layerColor} ${opacityPercent}%, #e5e7eb ${opacityPercent}%, #e5e7eb 100%)`;\r\n\r\n return (\r\n <div\r\n key={layerId.toString()}\r\n className={`zlm-card${muted ? ' is-muted' : ''}`}\r\n style={{\r\n border: '1px solid #e2e8f0',\r\n borderRadius: 12,\r\n padding: 12,\r\n background: '#fff',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: 10,\r\n width: '100%',\r\n }}\r\n >\r\n <div style={{ display: 'flex', justifyContent: 'space-between', gap: 12 }}>\r\n <div style={{ display: 'flex', gap: 10, alignItems: 'flex-start', minWidth: 0, flex: 1 }}>\r\n <div\r\n style={{\r\n width: 14,\r\n height: 14,\r\n borderRadius: '50%',\r\n backgroundColor: layerColor,\r\n border: '2px solid #e2e8f0',\r\n flexShrink: 0,\r\n marginTop: 4,\r\n }}\r\n title=\"Color de la capa\"\r\n />\r\n {showLayerVisibilityIcon && (\r\n <button\r\n type=\"button\"\r\n className={`zlm-icon-button${visible ? ' is-active' : ''}`}\r\n onClick={() =>\r\n isControlled\r\n ? updateLayerVisible(layerId, !visible)\r\n : setLayers((prev) =>\r\n prev.map((entry) =>\r\n entry.mapLayer.layerId === layerId ? { ...entry, visible: !visible } : entry\r\n )\r\n )\r\n }\r\n aria-label={visible ? 'Ocultar capa' : 'Mostrar capa'}\r\n >\r\n {visible ? <Eye size={16} /> : <EyeOff size={16} />}\r\n </button>\r\n )}\r\n <div style={{ minWidth: 0, flex: 1 }}>\r\n <div\r\n className=\"zlm-layer-name\"\r\n style={{\r\n fontWeight: 700,\r\n display: '-webkit-box',\r\n WebkitLineClamp: 2,\r\n WebkitBoxOrient: 'vertical',\r\n overflow: 'hidden',\r\n overflowWrap: 'anywhere',\r\n lineHeight: 1.2,\r\n color: muted ? '#64748b' : '#0f172a',\r\n }}\r\n title={layerName}\r\n >\r\n {layerName}\r\n </div>\r\n <div style={{ color: muted ? '#94a3b8' : '#64748b', fontSize: 12 }}>ID {layerId}</div>\r\n </div>\r\n </div>\r\n <div style={{ display: 'flex', alignItems: 'flex-start', gap: 6, flexShrink: 0 }}>\r\n {typeof featureCount === 'number' && (\r\n <span className=\"zlm-badge\">\r\n {featureCount.toLocaleString()} features\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n\r\n <div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>\r\n <div style={{ flex: 1 }}>\r\n <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 6, color: '#64748b', fontSize: 12 }}>\r\n <span>Opacidad</span>\r\n <span>{opacityPercent}%</span>\r\n </div>\r\n <input\r\n className=\"zlm-range\"\r\n type=\"range\"\r\n min={0}\r\n max={1}\r\n step={0.05}\r\n value={userOpacity}\r\n style={{\r\n width: '100%',\r\n accentColor: layerColor,\r\n background: sliderBackground,\r\n height: 6,\r\n borderRadius: 999,\r\n }}\r\n onChange={(e) => {\r\n const value = Number(e.target.value);\r\n if (isControlled) {\r\n updateLayerOpacity(layerId, value);\r\n return;\r\n }\r\n setLayers((prev) =>\r\n prev.map((entry) =>\r\n entry.mapLayer.layerId === layerId ? { ...entry, opacity: value } : entry\r\n )\r\n );\r\n }}\r\n aria-label={`Opacidad de la capa ${layerName}`}\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <div className={['zenit-layer-manager', className].filter(Boolean).join(' ')} style={panelStyle}>\r\n <style>\r\n {`\r\n .zenit-layer-manager .zlm-card {\r\n transition: box-shadow 0.2s ease, transform 0.2s ease, opacity 0.2s ease;\r\n box-shadow: 0 6px 16px rgba(15, 23, 42, 0.08);\r\n }\r\n .zenit-layer-manager .zlm-card.is-muted {\r\n opacity: 0.7;\r\n }\r\n .zenit-layer-manager .zlm-badge {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 4px;\r\n margin-top: 6px;\r\n padding: 2px 8px;\r\n border-radius: 999px;\r\n background: #f1f5f9;\r\n color: #475569;\r\n font-size: 11px;\r\n font-weight: 600;\r\n }\r\n .zenit-layer-manager .zlm-icon-button {\r\n border: 1px solid #e2e8f0;\r\n background: #f8fafc;\r\n color: #475569;\r\n border-radius: 8px;\r\n width: 34px;\r\n height: 34px;\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n transition: all 0.15s ease;\r\n }\r\n .zenit-layer-manager .zlm-icon-button.is-active {\r\n background: #0f172a;\r\n color: #fff;\r\n border-color: #0f172a;\r\n }\r\n .zenit-layer-manager .zlm-icon-button:hover {\r\n box-shadow: 0 4px 10px rgba(15, 23, 42, 0.12);\r\n }\r\n .zenit-layer-manager .zlm-icon-button:focus-visible {\r\n outline: 2px solid #60a5fa;\r\n outline-offset: 2px;\r\n }\r\n .zenit-layer-manager .zlm-range {\r\n width: 100%;\r\n accent-color: #0f172a;\r\n }\r\n .zenit-layer-manager .zlm-tab {\r\n flex: 1;\r\n padding: 8px 12px;\r\n border: none;\r\n background: transparent;\r\n color: #475569;\r\n font-weight: 600;\r\n cursor: pointer;\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 6px;\r\n font-size: 13px;\r\n }\r\n .zenit-layer-manager .zlm-tab.is-active {\r\n background: #fff;\r\n color: #0f172a;\r\n box-shadow: 0 4px 10px rgba(15, 23, 42, 0.08);\r\n border-radius: 10px;\r\n }\r\n .zenit-layer-manager .zlm-tab:focus-visible {\r\n outline: 2px solid #60a5fa;\r\n outline-offset: 2px;\r\n }\r\n .zenit-layer-manager .zlm-panel-toggle {\r\n border: 1px solid #e2e8f0;\r\n background: #fff;\r\n color: #0f172a;\r\n border-radius: 10px;\r\n padding: 6px 10px;\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 6px;\r\n font-size: 12px;\r\n font-weight: 600;\r\n cursor: pointer;\r\n transition: all 0.15s ease;\r\n }\r\n .zenit-layer-manager .zlm-panel-toggle:hover {\r\n box-shadow: 0 4px 10px rgba(15, 23, 42, 0.12);\r\n }\r\n .zenit-layer-manager .zlm-panel-toggle:focus-visible {\r\n outline: 2px solid #60a5fa;\r\n outline-offset: 2px;\r\n }\r\n `}\r\n </style>\r\n <div style={headerStyle}>\r\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>\r\n <div>\r\n <div style={{ fontWeight: 800, fontSize: 16, color: '#0f172a' }}>Gestión de Capas</div>\r\n <div style={{ color: '#64748b', fontSize: 12 }}>Mapa #{map.id}</div>\r\n </div>\r\n <button\r\n type=\"button\"\r\n onClick={() => setPanelVisible((prev) => !prev)}\r\n className=\"zlm-panel-toggle\"\r\n aria-label={panelVisible ? 'Ocultar panel de capas' : 'Mostrar panel de capas'}\r\n >\r\n {panelVisible ? <Eye size={16} /> : <EyeOff size={16} />}\r\n {panelVisible ? 'Ocultar' : 'Mostrar'}\r\n </button>\r\n </div>\r\n <div\r\n style={{\r\n display: 'flex',\r\n gap: 6,\r\n marginTop: 12,\r\n padding: 4,\r\n border: '1px solid #e2e8f0',\r\n borderRadius: 12,\r\n background: '#f1f5f9',\r\n }}\r\n >\r\n <button\r\n type=\"button\"\r\n className={`zlm-tab${activeTab === 'layers' ? ' is-active' : ''}`}\r\n onClick={() => setActiveTab('layers')}\r\n >\r\n <Layers size={16} />\r\n Capas\r\n </button>\r\n {showUploadTab && (\r\n <button\r\n type=\"button\"\r\n className={`zlm-tab${activeTab === 'upload' ? ' is-active' : ''}`}\r\n onClick={() => setActiveTab('upload')}\r\n >\r\n <Upload size={16} />\r\n Subir\r\n </button>\r\n )}\r\n <button\r\n type=\"button\"\r\n className={`zlm-tab${activeTab === 'filters' ? ' is-active' : ''}`}\r\n onClick={() => setActiveTab('filters')}\r\n >\r\n <Layers size={16} />\r\n Filtros\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {panelVisible && (\r\n <div style={{ padding: '12px 10px 18px', overflowY: 'auto', flex: 1, minHeight: 0 }}>\r\n {activeTab === 'layers' && renderLayerCards()}\r\n {activeTab === 'filters' && (\r\n <div className=\"zlm-filter-panel\" style={{ display: 'flex', flexDirection: 'column', gap: 12, background: '#fff', border: '1px solid #e2e8f0', borderRadius: 12, padding: 12 }}>\r\n {!filterableLayers.length ? (\r\n <div style={{ color: '#64748b', fontSize: 13 }}>No hay filtros disponibles para las capas de este mapa.</div>\r\n ) : (\r\n <>\r\n {filterableLayers.length > 1 && (\r\n <label style={{ display: 'flex', flexDirection: 'column', gap: 6, fontSize: 12, color: '#475569' }}>\r\n Capa\r\n <ZenitSelect\r\n ariaLabel=\"Seleccionar capa para filtrar\"\r\n value={selectedFilterLayerId}\r\n onValueChange={setSelectedFilterLayerId}\r\n options={filterableLayers.map((layer) => ({\r\n value: String(layer.mapLayer.layerId),\r\n label: layer.layerName ?? `Capa ${layer.mapLayer.layerId}`,\r\n }))}\r\n />\r\n </label>\r\n )}\r\n <label style={{ display: 'flex', flexDirection: 'column', gap: 6, fontSize: 12, color: '#475569' }}>\r\n Campo\r\n <ZenitSelect\r\n ariaLabel=\"Seleccionar campo de filtrado\"\r\n value={selectedFilterField}\r\n onValueChange={(nextField) => {\r\n setSelectedFilterField(nextField);\r\n setSelectedFilterValue('');\r\n }}\r\n options={filterFields.map((field) => ({ value: field, label: field }))}\r\n />\r\n </label>\r\n <label style={{ display: 'flex', flexDirection: 'column', gap: 6, fontSize: 12, color: '#475569' }}>\r\n Valor\r\n <ZenitSelect\r\n ariaLabel=\"Seleccionar valor de filtrado\"\r\n value={selectedFilterValue}\r\n placeholder=\"Seleccionar…\"\r\n onValueChange={(nextValue) => setSelectedFilterValue(nextValue)}\r\n disabled={loadingCatalog || activeCatalogValues.length === 0}\r\n options={activeCatalogValues.map((catalogValue) => ({\r\n value: catalogValue,\r\n label: catalogValue,\r\n }))}\r\n />\r\n </label>\r\n {loadingCatalog && <div style={{ color: '#64748b', fontSize: 12 }}>Cargando catálogo…</div>}\r\n {!loadingCatalog && selectedFilterField && activeCatalogValues.length === 0 && (\r\n <div style={{ color: '#64748b', fontSize: 12 }}>No hay catálogo disponible para este filtro.</div>\r\n )}\r\n {filterError && <div style={{ color: '#b91c1c', fontSize: 12 }}>{filterError}</div>}\r\n {appliedFilter && (\r\n <div className=\"zlm-badge\" style={{ alignSelf: 'flex-start' }}>\r\n Activo: {appliedFilter.field} = {appliedFilter.value}\r\n </div>\r\n )}\r\n <div className=\"zlm-filter-actions\" style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>\r\n <button\r\n type=\"button\"\r\n className=\"zlm-panel-toggle\"\r\n disabled={!selectedFilterValue || applyingFilter || !onApplyLayerFilter}\r\n onClick={handleApplyFilter}\r\n >\r\n {applyingFilter ? 'Aplicando…' : 'Aplicar'}\r\n </button>\r\n <button\r\n type=\"button\"\r\n className=\"zlm-panel-toggle\"\r\n disabled={applyingFilter}\r\n onClick={handleClearFilter}\r\n >\r\n Limpiar\r\n </button>\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n )}\r\n {showUploadTab && activeTab === 'upload' && (\r\n <div style={{ color: '#475569', fontSize: 13 }}>\r\n Próximamente podrás subir capas desde este panel.\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n","export { Eye, EyeOff, ChevronDown, ChevronLeft, ChevronRight, Layers, Upload, X, ZoomIn } from 'lucide-react';\r\n","import React from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport { ChevronDown } from '../icons';\r\n\r\nexport interface ZenitSelectOption {\r\n value: string;\r\n label: string;\r\n disabled?: boolean;\r\n}\r\n\r\nexport interface ZenitSelectProps {\r\n id?: string;\r\n value?: string;\r\n placeholder?: string;\r\n options: ZenitSelectOption[];\r\n onValueChange?: (value: string) => void;\r\n disabled?: boolean;\r\n className?: string;\r\n menuZIndex?: number;\r\n maxMenuHeight?: number;\r\n ariaLabel?: string;\r\n useNativeOnMobile?: boolean;\r\n}\r\n\r\nconst DEFAULT_SAFE_MENU_Z_INDEX = 4000;\r\n\r\nfunction readCssMenuZIndex(): number | null {\r\n if (typeof document === 'undefined') return null;\r\n const rootStyles = getComputedStyle(document.documentElement);\r\n const configuredValue =\r\n rootStyles.getPropertyValue('--zenit-select-z-index').trim() ||\r\n rootStyles.getPropertyValue('--zenit-overlay-z-index').trim();\r\n\r\n if (!configuredValue) return null;\r\n const parsed = Number.parseInt(configuredValue, 10);\r\n return Number.isFinite(parsed) ? parsed : null;\r\n}\r\n\r\nfunction shouldUseNativeSelect(): boolean {\r\n if (typeof window === 'undefined' || typeof navigator === 'undefined') return false;\r\n\r\n const hasCoarsePointer = typeof window.matchMedia === 'function'\r\n ? window.matchMedia('(pointer: coarse)').matches\r\n : false;\r\n\r\n return hasCoarsePointer || navigator.maxTouchPoints > 0;\r\n}\r\n\r\nexport const ZenitSelect: React.FC<ZenitSelectProps> = ({\r\n id,\r\n value,\r\n placeholder = 'Seleccionar…',\r\n options,\r\n onValueChange,\r\n disabled = false,\r\n className,\r\n menuZIndex,\r\n maxMenuHeight = 384,\r\n ariaLabel,\r\n useNativeOnMobile = true,\r\n}) => {\r\n const rootRef = React.useRef<HTMLDivElement | null>(null);\r\n const triggerRef = React.useRef<HTMLButtonElement | null>(null);\r\n const menuRef = React.useRef<HTMLDivElement | null>(null);\r\n\r\n // evita dobles triggers touch -> synthetic mouse\r\n const lastTouchTsRef = React.useRef<number>(0);\r\n\r\n const [isOpen, setIsOpen] = React.useState(false);\r\n const [menuPosition, setMenuPosition] = React.useState({ top: 0, left: 0, width: 0 });\r\n\r\n const selectedOption = React.useMemo(\r\n () => options.find((option) => option.value === value),\r\n [options, value]\r\n );\r\n\r\n const effectiveMenuZIndex = React.useMemo(\r\n () => menuZIndex ?? readCssMenuZIndex() ?? DEFAULT_SAFE_MENU_Z_INDEX,\r\n [menuZIndex]\r\n );\r\n\r\n const useNative = React.useMemo(\r\n () => useNativeOnMobile && shouldUseNativeSelect(),\r\n [useNativeOnMobile]\r\n );\r\n\r\n const updateMenuPosition = React.useCallback(() => {\r\n const trigger = triggerRef.current;\r\n if (!trigger) return;\r\n\r\n const rect = trigger.getBoundingClientRect();\r\n const viewportPadding = 8;\r\n const minWidth = 200;\r\n const width = Math.max(rect.width, minWidth);\r\n\r\n const maxLeft = window.innerWidth - width - viewportPadding;\r\n const nextLeft = Math.max(viewportPadding, Math.min(rect.left, maxLeft));\r\n const nextTop = rect.bottom + 4;\r\n\r\n setMenuPosition({ top: nextTop, left: nextLeft, width });\r\n }, []);\r\n\r\n const getEffectiveMaxHeight = React.useCallback(() => {\r\n // Evita que el menú “se salga” en pantallas pequeñas\r\n const available = Math.max(160, window.innerHeight - menuPosition.top - 12);\r\n return Math.min(maxMenuHeight, available);\r\n }, [maxMenuHeight, menuPosition.top]);\r\n\r\n React.useEffect(() => {\r\n if (!isOpen) return;\r\n\r\n updateMenuPosition();\r\n\r\n const isEventInsideSelect = (targetNode: Node) =>\r\n Boolean(rootRef.current?.contains(targetNode) || menuRef.current?.contains(targetNode));\r\n\r\n const handleOutsideTouchStart = (event: TouchEvent) => {\r\n lastTouchTsRef.current = Date.now();\r\n const targetNode = event.target as Node;\r\n if (isEventInsideSelect(targetNode)) return;\r\n setIsOpen(false);\r\n };\r\n\r\n const handleOutsideMouseDown = (event: MouseEvent) => {\r\n if (Date.now() - lastTouchTsRef.current < 500) return;\r\n const targetNode = event.target as Node;\r\n if (isEventInsideSelect(targetNode)) return;\r\n setIsOpen(false);\r\n };\r\n\r\n const handleEscape = (event: KeyboardEvent) => {\r\n if (event.key === 'Escape') {\r\n setIsOpen(false);\r\n triggerRef.current?.focus();\r\n }\r\n };\r\n\r\n const handleWindowChanges = () => updateMenuPosition();\r\n\r\n document.addEventListener('touchstart', handleOutsideTouchStart, { capture: true });\r\n document.addEventListener('mousedown', handleOutsideMouseDown, true);\r\n document.addEventListener('keydown', handleEscape);\r\n window.addEventListener('resize', handleWindowChanges);\r\n window.addEventListener('scroll', handleWindowChanges, true);\r\n\r\n return () => {\r\n document.removeEventListener('touchstart', handleOutsideTouchStart, true);\r\n document.removeEventListener('mousedown', handleOutsideMouseDown, true);\r\n document.removeEventListener('keydown', handleEscape);\r\n window.removeEventListener('resize', handleWindowChanges);\r\n window.removeEventListener('scroll', handleWindowChanges, true);\r\n };\r\n }, [isOpen, updateMenuPosition]);\r\n\r\n const handleTriggerDown = (\r\n event: React.TouchEvent<HTMLButtonElement> | React.MouseEvent<HTMLButtonElement>\r\n ) => {\r\n if (event.type === 'touchstart') {\r\n lastTouchTsRef.current = Date.now();\r\n }\r\n if (event.type === 'mousedown' && Date.now() - lastTouchTsRef.current < 500) {\r\n return;\r\n }\r\n\r\n // prevenir ghost click / cierres raros\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n if (disabled) return;\r\n if (!isOpen) updateMenuPosition();\r\n setIsOpen((prev) => !prev);\r\n };\r\n\r\n const handleTriggerClick = (event: React.MouseEvent<HTMLButtonElement>) => {\r\n // solo teclado\r\n if (event.detail !== 0) return;\r\n event.preventDefault();\r\n event.stopPropagation();\r\n if (disabled) return;\r\n if (!isOpen) updateMenuPosition();\r\n setIsOpen((prev) => !prev);\r\n };\r\n\r\n const selectValue = (nextValue: string, isDisabled?: boolean) => {\r\n if (isDisabled) return;\r\n onValueChange?.(nextValue);\r\n setIsOpen(false);\r\n triggerRef.current?.focus();\r\n };\r\n\r\n if (useNative) {\r\n return (\r\n <div ref={rootRef} className={[className, 'zenit-select-root'].filter(Boolean).join(' ')}>\r\n <style>\r\n {`\r\n .zenit-select-native {\r\n width: 100%;\r\n min-height: 40px;\r\n height: 40px;\r\n border: 1px solid #cbd5e1;\r\n border-radius: 6px;\r\n background: #ffffff;\r\n color: #0f172a;\r\n padding: 0 12px;\r\n font-size: 14px;\r\n line-height: 1.25;\r\n cursor: pointer;\r\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\r\n appearance: none;\r\n -webkit-appearance: none;\r\n }\r\n .zenit-select-native:disabled {\r\n opacity: 0.6;\r\n cursor: not-allowed;\r\n }\r\n .zenit-select-native:focus-visible {\r\n outline: none;\r\n border-color: #60a5fa;\r\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.35);\r\n }\r\n\r\n @media (max-width: 640px) {\r\n .zenit-select-native {\r\n min-height: 38px;\r\n height: 38px;\r\n }\r\n }\r\n `}\r\n </style>\r\n\r\n <select\r\n id={id}\r\n className=\"zenit-select-native\"\r\n value={value ?? ''}\r\n aria-label={ariaLabel}\r\n disabled={disabled}\r\n onChange={(event) => {\r\n onValueChange?.(event.target.value);\r\n }}\r\n >\r\n <option value=\"\" disabled hidden>\r\n {placeholder}\r\n </option>\r\n {options.map((option) => (\r\n <option key={option.value} value={option.value} disabled={option.disabled}>\r\n {option.label}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div ref={rootRef} className={[className, 'zenit-select-root'].filter(Boolean).join(' ')}>\r\n <style>\r\n {`\r\n .zenit-select-trigger {\r\n width: 100%;\r\n min-height: 40px;\r\n height: 40px;\r\n border: 1px solid #cbd5e1;\r\n border-radius: 6px;\r\n background: #ffffff;\r\n color: #0f172a;\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 8px;\r\n padding: 0 12px;\r\n font-size: 14px;\r\n line-height: 1.25;\r\n cursor: pointer;\r\n text-align: left;\r\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\r\n touch-action: manipulation;\r\n -webkit-tap-highlight-color: transparent;\r\n }\r\n .zenit-select-trigger.is-disabled {\r\n opacity: 0.6;\r\n cursor: not-allowed;\r\n }\r\n .zenit-select-trigger:focus-visible {\r\n outline: none;\r\n border-color: #60a5fa;\r\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.35);\r\n }\r\n .zenit-select-label {\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n .zenit-select-label.is-placeholder {\r\n color: #64748b;\r\n }\r\n .zenit-select-chevron {\r\n opacity: 0.5;\r\n flex-shrink: 0;\r\n }\r\n\r\n /* Contenedor: aquí debe GANAR el scroll en móvil */\r\n .zenit-select-content {\r\n position: fixed;\r\n border: 1px solid #cbd5e1;\r\n border-radius: 6px;\r\n background: #ffffff;\r\n box-shadow: 0 10px 25px rgba(15, 23, 42, 0.18);\r\n overflow-y: auto;\r\n padding: 4px;\r\n pointer-events: auto;\r\n\r\n /* Lo importante: permitir pan vertical dentro del menú */\r\n touch-action: pan-y;\r\n overscroll-behavior: contain;\r\n -webkit-overflow-scrolling: touch;\r\n }\r\n\r\n /* Items NO son button: evitamos que WebView “secuestré” el gesto */\r\n .zenit-select-item {\r\n width: 100%;\r\n border-radius: 4px;\r\n text-align: left;\r\n color: #0f172a;\r\n font-size: 14px;\r\n min-height: 34px;\r\n padding: 8px 10px;\r\n cursor: pointer;\r\n -webkit-tap-highlight-color: transparent;\r\n user-select: none;\r\n }\r\n .zenit-select-item:hover {\r\n background: #f1f5f9;\r\n }\r\n .zenit-select-item.is-selected {\r\n background: #e2e8f0;\r\n font-weight: 600;\r\n }\r\n .zenit-select-item.is-disabled {\r\n color: #94a3b8;\r\n cursor: not-allowed;\r\n }\r\n .zenit-select-item:focus-visible {\r\n outline: none;\r\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.35);\r\n }\r\n\r\n @media (max-width: 640px) {\r\n .zenit-select-trigger {\r\n height: 38px;\r\n min-height: 38px;\r\n }\r\n .zenit-select-content {\r\n max-width: calc(100vw - 16px);\r\n }\r\n }\r\n `}\r\n </style>\r\n\r\n <button\r\n id={id}\r\n ref={triggerRef}\r\n type=\"button\"\r\n className={`zenit-select-trigger${disabled ? ' is-disabled' : ''}`}\r\n onTouchStart={handleTriggerDown}\r\n onMouseDown={handleTriggerDown}\r\n onClick={handleTriggerClick}\r\n aria-haspopup=\"listbox\"\r\n aria-expanded={isOpen}\r\n aria-label={ariaLabel}\r\n disabled={disabled}\r\n >\r\n <span className={`zenit-select-label${selectedOption ? '' : ' is-placeholder'}`}>\r\n {selectedOption?.label ?? placeholder}\r\n </span>\r\n <ChevronDown className=\"zenit-select-chevron\" size={16} aria-hidden=\"true\" />\r\n </button>\r\n\r\n {isOpen &&\r\n typeof document !== 'undefined' &&\r\n createPortal(\r\n <div\r\n ref={menuRef}\r\n className=\"zenit-select-content\"\r\n role=\"listbox\"\r\n style={{\r\n top: menuPosition.top,\r\n left: menuPosition.left,\r\n width: menuPosition.width,\r\n zIndex: effectiveMenuZIndex,\r\n maxHeight: getEffectiveMaxHeight(),\r\n }}\r\n >\r\n {options.map((option) => {\r\n const isSelected = option.value === value;\r\n\r\n return (\r\n <div\r\n key={option.value}\r\n role=\"option\"\r\n aria-selected={isSelected}\r\n tabIndex={option.disabled ? -1 : 0}\r\n className={`zenit-select-item${isSelected ? ' is-selected' : ''}${\r\n option.disabled ? ' is-disabled' : ''\r\n }`}\r\n // Selección por click (tap). Sin handlers touch para no romper scroll.\r\n onClick={(event) => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n if (option.disabled) return;\r\n selectValue(option.value, option.disabled);\r\n }}\r\n // teclado\r\n onKeyDown={(event) => {\r\n if (option.disabled) return;\r\n if (event.key === 'Enter' || event.key === ' ') {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n selectValue(option.value, option.disabled);\r\n }\r\n }}\r\n >\r\n {option.label}\r\n </div>\r\n );\r\n })}\r\n </div>,\r\n document.body\r\n )}\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\nimport type { LayerFilters } from '../layers/types';\r\n\r\nexport interface ZenitFeatureFilterPanelProps {\r\n title?: string;\r\n description?: string;\r\n className?: string;\r\n style?: React.CSSProperties;\r\n filters?: LayerFilters;\r\n onChange?: (filters: LayerFilters) => void;\r\n children?: React.ReactNode;\r\n}\r\n\r\nexport const ZenitFeatureFilterPanel: React.FC<ZenitFeatureFilterPanelProps> = ({\r\n title = 'Filtros',\r\n description,\r\n className,\r\n style,\r\n children,\r\n}) => {\r\n return (\r\n <section\r\n className={className}\r\n style={{\r\n border: '1px solid #e2e8f0',\r\n borderRadius: 12,\r\n padding: 16,\r\n background: '#fff',\r\n fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif',\r\n ...style,\r\n }}\r\n >\r\n <header style={{ marginBottom: 12 }}>\r\n <h3 style={{ margin: 0, fontSize: 16 }}>{title}</h3>\r\n {description && (\r\n <p style={{ margin: '6px 0 0', color: '#475569', fontSize: 13 }}>{description}</p>\r\n )}\r\n </header>\r\n <div>{children}</div>\r\n </section>\r\n );\r\n};\r\n","import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport type { ChatRequestDto, ChatResponseDto, SuggestedAction } from '../../ai/types';\r\nimport { useSendMessageStream } from '../hooks/use-chat';\r\nimport type { ChatServiceConfig } from '../../ai/chat.service';\r\nimport { MarkdownRenderer } from '../components/MarkdownRenderer';\r\n\r\ninterface ChatMessage {\r\n id: string;\r\n role: 'user' | 'assistant';\r\n content: string;\r\n response?: ChatResponseDto;\r\n}\r\n\r\nexport interface FloatingChatBoxProps {\r\n mapId?: number;\r\n filteredLayerIds?: number[];\r\n filters?: Record<string, unknown>;\r\n userId?: number | null;\r\n baseUrl?: string;\r\n accessToken?: string;\r\n getAccessToken?: () => string | Promise<string>;\r\n onActionClick?: (action: SuggestedAction) => void;\r\n /** Called when the chat panel opens or closes. */\r\n onOpenChange?: (isOpen: boolean) => void;\r\n /** When true, the floating action button is hidden (panel can still be open). */\r\n hideButton?: boolean;\r\n /**\r\n * Controlled open state. When provided, the component uses this as the source of truth.\r\n * Use with `onOpenChange` to control the chat panel externally.\r\n */\r\n open?: boolean;\r\n}\r\n\r\n// SVG Icons as inline components (no external dependencies)\r\nconst ChatIcon = () => (\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\r\n </svg>\r\n);\r\n\r\nconst CloseIcon = () => (\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\r\n </svg>\r\n);\r\n\r\nconst ExpandIcon = () => (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <polyline points=\"15 3 21 3 21 9\" />\r\n <polyline points=\"9 21 3 21 3 15\" />\r\n <line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\" />\r\n <line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\" />\r\n </svg>\r\n);\r\n\r\nconst CollapseIcon = () => (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <polyline points=\"4 14 10 14 10 20\" />\r\n <polyline points=\"20 10 14 10 14 4\" />\r\n <line x1=\"14\" y1=\"10\" x2=\"21\" y2=\"3\" />\r\n <line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\" />\r\n </svg>\r\n);\r\n\r\nconst SendIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" />\r\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\" />\r\n </svg>\r\n);\r\n\r\nconst LayersIcon = () => (\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <polygon points=\"12 2 2 7 12 12 22 7 12 2\" />\r\n <polyline points=\"2 17 12 22 22 17\" />\r\n <polyline points=\"2 12 12 17 22 12\" />\r\n </svg>\r\n);\r\n\r\nconst styles = {\r\n root: {\r\n fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\r\n } as React.CSSProperties,\r\n\r\n // Floating button (closed state - wide with text, open state - circular with X)\r\n floatingButton: {\r\n position: 'fixed',\r\n bottom: 16,\r\n right: 16,\r\n borderRadius: '999px',\r\n border: 'none',\r\n cursor: 'pointer',\r\n background: 'linear-gradient(135deg, #10b981, #059669)',\r\n color: '#fff',\r\n boxShadow: '0 12px 28px rgba(16, 185, 129, 0.4)',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n fontSize: 14,\r\n fontWeight: 600,\r\n zIndex: 99999,\r\n transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\r\n } as React.CSSProperties,\r\n\r\n floatingButtonClosed: {\r\n padding: '12px 20px',\r\n gap: 8,\r\n } as React.CSSProperties,\r\n\r\n floatingButtonOpen: {\r\n width: 52,\r\n height: 52,\r\n padding: 0,\r\n } as React.CSSProperties,\r\n\r\n floatingButtonMobile: {\r\n width: 52,\r\n height: 52,\r\n padding: 0,\r\n } as React.CSSProperties,\r\n\r\n // Panel (expandable)\r\n panel: {\r\n position: 'fixed',\r\n bottom: 80,\r\n right: 16,\r\n background: '#fff',\r\n borderRadius: 16,\r\n boxShadow: '0 20px 60px rgba(15, 23, 42, 0.3), 0 0 0 1px rgba(15, 23, 42, 0.05)',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n overflow: 'hidden',\r\n zIndex: 99999,\r\n transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\r\n } as React.CSSProperties,\r\n\r\n panelNormal: {\r\n width: 360,\r\n height: 520,\r\n } as React.CSSProperties,\r\n\r\n panelExpanded: {\r\n width: 480,\r\n height: 640,\r\n } as React.CSSProperties,\r\n\r\n panelMobileFullscreen: {\r\n position: 'fixed',\r\n top: 0,\r\n left: 0,\r\n right: 0,\r\n bottom: 0,\r\n width: '100%',\r\n height: '100%',\r\n borderRadius: 0,\r\n margin: 0,\r\n } as React.CSSProperties,\r\n\r\n // Header with green gradient\r\n header: {\r\n padding: '14px 16px',\r\n background: 'linear-gradient(135deg, #10b981, #059669)',\r\n color: '#fff',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'space-between',\r\n } as React.CSSProperties,\r\n\r\n title: {\r\n margin: 0,\r\n fontSize: 15,\r\n fontWeight: 600,\r\n letterSpacing: '-0.01em',\r\n } as React.CSSProperties,\r\n\r\n headerButtons: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: 8,\r\n } as React.CSSProperties,\r\n\r\n headerButton: {\r\n border: 'none',\r\n background: 'rgba(255, 255, 255, 0.15)',\r\n color: '#fff',\r\n width: 30,\r\n height: 30,\r\n borderRadius: 8,\r\n cursor: 'pointer',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n transition: 'background 0.2s',\r\n } as React.CSSProperties,\r\n\r\n // Messages area\r\n messages: {\r\n flex: 1,\r\n padding: '16px',\r\n overflowY: 'auto',\r\n background: '#f8fafc',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: 16,\r\n } as React.CSSProperties,\r\n\r\n // Message bubbles\r\n messageWrapper: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: 8,\r\n } as React.CSSProperties,\r\n\r\n messageBubble: {\r\n maxWidth: '85%',\r\n padding: '10px 12px',\r\n borderRadius: 16,\r\n lineHeight: 1.5,\r\n fontSize: 13,\r\n whiteSpace: 'pre-wrap',\r\n wordBreak: 'break-word',\r\n } as React.CSSProperties,\r\n\r\n userMessage: {\r\n alignSelf: 'flex-end',\r\n background: 'linear-gradient(135deg, #10b981, #059669)',\r\n color: '#fff',\r\n borderBottomRightRadius: 4,\r\n } as React.CSSProperties,\r\n\r\n assistantMessage: {\r\n alignSelf: 'flex-start',\r\n background: '#e2e8f0',\r\n color: '#0f172a',\r\n borderBottomLeftRadius: 4,\r\n } as React.CSSProperties,\r\n\r\n // Streaming cursor\r\n cursor: {\r\n display: 'inline-block',\r\n width: 2,\r\n height: 16,\r\n background: '#0f172a',\r\n marginLeft: 2,\r\n animation: 'zenitBlink 1s infinite',\r\n verticalAlign: 'text-bottom',\r\n } as React.CSSProperties,\r\n\r\n thinkingText: {\r\n fontStyle: 'italic',\r\n opacity: 0.7,\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: 8,\r\n } as React.CSSProperties,\r\n\r\n typingIndicator: {\r\n display: 'flex',\r\n gap: 4,\r\n alignItems: 'center',\r\n } as React.CSSProperties,\r\n\r\n typingDot: {\r\n width: 8,\r\n height: 8,\r\n borderRadius: '50%',\r\n backgroundColor: '#059669',\r\n animation: 'typingDotBounce 1.4s infinite ease-in-out',\r\n } as React.CSSProperties,\r\n\r\n // Metadata section (Referenced Layers)\r\n metadataSection: {\r\n marginTop: 12,\r\n padding: '10px 12px',\r\n background: 'rgba(255, 255, 255, 0.5)',\r\n borderRadius: 10,\r\n fontSize: 12,\r\n } as React.CSSProperties,\r\n\r\n metadataTitle: {\r\n fontWeight: 600,\r\n color: '#059669',\r\n marginBottom: 6,\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: 6,\r\n } as React.CSSProperties,\r\n\r\n metadataList: {\r\n margin: 0,\r\n paddingLeft: 18,\r\n color: '#475569',\r\n } as React.CSSProperties,\r\n\r\n metadataItem: {\r\n marginBottom: 2,\r\n } as React.CSSProperties,\r\n\r\n // Suggested actions\r\n actionsSection: {\r\n marginTop: 12,\r\n } as React.CSSProperties,\r\n\r\n sectionLabel: {\r\n fontSize: 11,\r\n fontWeight: 600,\r\n color: '#64748b',\r\n marginBottom: 8,\r\n textTransform: 'uppercase',\r\n letterSpacing: '0.05em',\r\n } as React.CSSProperties,\r\n\r\n actionsGrid: {\r\n display: 'flex',\r\n flexWrap: 'wrap',\r\n gap: 6,\r\n } as React.CSSProperties,\r\n\r\n actionButton: {\r\n border: '1px solid #d1fae5',\r\n background: '#d1fae5',\r\n color: '#065f46',\r\n borderRadius: 999,\r\n padding: '6px 12px',\r\n fontSize: 12,\r\n fontWeight: 500,\r\n cursor: 'pointer',\r\n transition: 'all 0.2s',\r\n } as React.CSSProperties,\r\n\r\n // Follow-up questions\r\n followUpButton: {\r\n border: '1px solid #cbd5e1',\r\n background: '#fff',\r\n color: '#475569',\r\n borderRadius: 10,\r\n padding: '8px 12px',\r\n fontSize: 12,\r\n fontWeight: 500,\r\n cursor: 'pointer',\r\n textAlign: 'left',\r\n width: '100%',\r\n transition: 'all 0.2s',\r\n } as React.CSSProperties,\r\n\r\n // Input area\r\n inputWrapper: {\r\n borderTop: '1px solid #e2e8f0',\r\n padding: '10px 14px',\r\n display: 'flex',\r\n gap: 10,\r\n alignItems: 'flex-end',\r\n background: '#fff',\r\n } as React.CSSProperties,\r\n\r\n textarea: {\r\n flex: 1,\r\n resize: 'none',\r\n borderRadius: 12,\r\n border: '1.5px solid #cbd5e1',\r\n padding: '8px 10px',\r\n fontSize: 13,\r\n fontFamily: 'inherit',\r\n lineHeight: 1.4,\r\n transition: 'border-color 0.2s',\r\n } as React.CSSProperties,\r\n\r\n textareaFocus: {\r\n borderColor: '#10b981',\r\n outline: 'none',\r\n } as React.CSSProperties,\r\n\r\n sendButton: {\r\n borderRadius: 12,\r\n border: 'none',\r\n padding: '8px 12px',\r\n background: 'linear-gradient(135deg, #10b981, #059669)',\r\n color: '#fff',\r\n cursor: 'pointer',\r\n fontSize: 13,\r\n fontWeight: 600,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n transition: 'opacity 0.2s, transform 0.2s',\r\n minWidth: 40,\r\n height: 40,\r\n } as React.CSSProperties,\r\n\r\n // Status messages\r\n statusNote: {\r\n padding: '0 16px 14px',\r\n fontSize: 12,\r\n color: '#64748b',\r\n textAlign: 'center',\r\n } as React.CSSProperties,\r\n\r\n errorText: {\r\n padding: '0 16px 14px',\r\n fontSize: 12,\r\n color: '#dc2626',\r\n textAlign: 'center',\r\n } as React.CSSProperties,\r\n};\r\n\r\nexport const FloatingChatBox: React.FC<FloatingChatBoxProps> = ({\r\n mapId,\r\n filteredLayerIds,\r\n filters,\r\n userId,\r\n baseUrl,\r\n accessToken,\r\n getAccessToken,\r\n onActionClick,\r\n onOpenChange,\r\n hideButton,\r\n open: openProp,\r\n}) => {\r\n // Controlled vs uncontrolled mode\r\n const isControlled = openProp !== undefined;\r\n const [internalOpen, setInternalOpen] = useState(false);\r\n const open = isControlled ? openProp : internalOpen;\r\n\r\n const setOpen = useCallback((value: boolean | ((prev: boolean) => boolean)) => {\r\n const newValue = typeof value === 'function' ? value(open) : value;\r\n if (!isControlled) {\r\n setInternalOpen(newValue);\r\n }\r\n // Always notify parent so they can update their state\r\n onOpenChange?.(newValue);\r\n }, [isControlled, open, onOpenChange]);\r\n const [expanded, setExpanded] = useState(false);\r\n const [messages, setMessages] = useState<ChatMessage[]>([]);\r\n const [inputValue, setInputValue] = useState('');\r\n const [conversationId, setConversationId] = useState<number | undefined>();\r\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\r\n const [isFocused, setIsFocused] = useState(false);\r\n const [isMobile, setIsMobile] = useState(false);\r\n const messagesEndRef = useRef<HTMLDivElement | null>(null);\r\n const messagesContainerRef = useRef<HTMLDivElement | null>(null);\r\n const chatBoxRef = useRef<HTMLDivElement | null>(null);\r\n\r\n const chatConfig = useMemo<ChatServiceConfig | undefined>(() => {\r\n if (!baseUrl) return undefined;\r\n return { baseUrl, accessToken, getAccessToken };\r\n }, [accessToken, baseUrl, getAccessToken]);\r\n\r\n const { sendMessage, isStreaming, streamingText, completeResponse } = useSendMessageStream(chatConfig);\r\n\r\n const canSend = Boolean(mapId) && Boolean(baseUrl) && inputValue.trim().length > 0 && !isStreaming;\r\n\r\n\r\n // Auto-expand to fullscreen on mobile when opening\r\n useEffect(() => {\r\n if (open && isMobile) {\r\n setExpanded(true);\r\n }\r\n }, [open, isMobile]);\r\n\r\n // Auto-scroll to bottom\r\n const scrollToBottom = useCallback(() => {\r\n if (messagesEndRef.current) {\r\n messagesEndRef.current.scrollIntoView({ behavior: 'smooth' });\r\n }\r\n }, []);\r\n\r\n // Initial welcome message\r\n useEffect(() => {\r\n if (open && messages.length === 0) {\r\n setMessages([\r\n {\r\n id: 'welcome',\r\n role: 'assistant',\r\n content: 'Hola, soy el asistente de IA de ZENIT. Estoy aquí para ayudarte a analizar tu mapa y responder tus preguntas sobre las capas y datos. ¿En qué puedo ayudarte hoy?',\r\n },\r\n ]);\r\n }\r\n }, [open, messages.length]);\r\n\r\n // Auto-scroll on new messages or streaming\r\n useEffect(() => {\r\n scrollToBottom();\r\n }, [messages, streamingText, scrollToBottom]);\r\n\r\n // Close chat when clicking outside (skip on mobile fullscreen — use header close button)\r\n useEffect(() => {\r\n if (!open) return;\r\n if (isMobile && expanded) return;\r\n\r\n const handleClickOutside = (event: MouseEvent) => {\r\n if (\r\n chatBoxRef.current &&\r\n !chatBoxRef.current.contains(event.target as Node)\r\n ) {\r\n setOpen(false);\r\n }\r\n };\r\n\r\n document.addEventListener('mousedown', handleClickOutside);\r\n return () => {\r\n document.removeEventListener('mousedown', handleClickOutside);\r\n };\r\n }, [open, isMobile, expanded]);\r\n\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n const mediaQuery = window.matchMedia('(max-width: 768px)');\r\n const updateMobile = () => setIsMobile(mediaQuery.matches);\r\n updateMobile();\r\n if (mediaQuery.addEventListener) {\r\n mediaQuery.addEventListener('change', updateMobile);\r\n } else {\r\n mediaQuery.addListener(updateMobile);\r\n }\r\n return () => {\r\n if (mediaQuery.removeEventListener) {\r\n mediaQuery.removeEventListener('change', updateMobile);\r\n } else {\r\n mediaQuery.removeListener(updateMobile);\r\n }\r\n };\r\n }, []);\r\n\r\n // Lock body scroll when chat is fullscreen on mobile\r\n useEffect(() => {\r\n if (typeof document === 'undefined') return;\r\n if (!open || !isMobile) return;\r\n document.body.style.overflow = 'hidden';\r\n return () => {\r\n document.body.style.overflow = '';\r\n };\r\n }, [open, isMobile]);\r\n\r\n const addMessage = useCallback((message: ChatMessage) => {\r\n setMessages((prev) => [...prev, message]);\r\n }, []);\r\n\r\n const handleSend = useCallback(async () => {\r\n if (!mapId) {\r\n setErrorMessage('Selecciona un mapa para usar el asistente.');\r\n return;\r\n }\r\n if (!baseUrl) {\r\n setErrorMessage('Configura la baseUrl del SDK para usar Zenit AI.');\r\n return;\r\n }\r\n if (!inputValue.trim()) return;\r\n\r\n const messageText = inputValue.trim();\r\n setInputValue('');\r\n setErrorMessage(null);\r\n\r\n addMessage({\r\n id: `user-${Date.now()}`,\r\n role: 'user',\r\n content: messageText,\r\n });\r\n\r\n const request: ChatRequestDto = {\r\n message: messageText,\r\n conversationId,\r\n filteredLayerIds,\r\n filters,\r\n userId,\r\n };\r\n\r\n try {\r\n const response = await sendMessage(mapId, request);\r\n setConversationId(response.conversationId ?? conversationId);\r\n addMessage({\r\n id: `assistant-${Date.now()}`,\r\n role: 'assistant',\r\n content: response.answer,\r\n response,\r\n });\r\n } catch (error) {\r\n setErrorMessage('Ocurrió un error al generar la respuesta.');\r\n addMessage({\r\n id: `error-${Date.now()}`,\r\n role: 'assistant',\r\n content: '❌ Ocurrió un error al generar la respuesta.',\r\n });\r\n }\r\n }, [\r\n addMessage,\r\n baseUrl,\r\n conversationId,\r\n filteredLayerIds,\r\n filters,\r\n inputValue,\r\n mapId,\r\n sendMessage,\r\n userId,\r\n ]);\r\n\r\n const handleKeyDown = useCallback(\r\n (event: React.KeyboardEvent<HTMLTextAreaElement>) => {\r\n if (event.key === 'Enter' && !event.shiftKey) {\r\n event.preventDefault();\r\n if (canSend) {\r\n void handleSend();\r\n }\r\n }\r\n },\r\n [canSend, handleSend]\r\n );\r\n\r\n const handleFollowUpClick = useCallback((question: string) => {\r\n setInputValue(question);\r\n }, []);\r\n\r\n // Render metadata (Referenced Layers)\r\n const renderMetadata = (response?: ChatResponseDto) => {\r\n if (!response?.metadata) return null;\r\n\r\n const referencedLayers = response.metadata.referencedLayers as Array<{ layerName: string; featureCount: number }> | undefined;\r\n if (!referencedLayers || referencedLayers.length === 0) return null;\r\n\r\n return (\r\n <div style={styles.metadataSection}>\r\n <div style={styles.metadataTitle}>\r\n <LayersIcon />\r\n Capas Analizadas\r\n </div>\r\n <ul style={styles.metadataList}>\r\n {referencedLayers.map((layer, index) => (\r\n <li key={index} style={styles.metadataItem}>\r\n <strong>{layer.layerName}</strong> ({layer.featureCount} {layer.featureCount === 1 ? 'elemento' : 'elementos'})\r\n </li>\r\n ))}\r\n </ul>\r\n </div>\r\n );\r\n };\r\n\r\n // Handle suggested action click: close chat first, then execute action\r\n const handleActionClick = useCallback((action: SuggestedAction) => {\r\n if (isStreaming) return;\r\n // Close chat immediately so map is visible\r\n setOpen(false);\r\n // Execute action in next frame after chat closes\r\n requestAnimationFrame(() => {\r\n onActionClick?.(action);\r\n });\r\n }, [isStreaming, setOpen, onActionClick]);\r\n\r\n // Render suggested actions\r\n const renderActions = (response?: ChatResponseDto) => {\r\n if (!response?.suggestedActions?.length) return null;\r\n\r\n return (\r\n <div style={styles.actionsSection}>\r\n <div style={styles.sectionLabel}>Acciones Sugeridas</div>\r\n <div style={styles.actionsGrid}>\r\n {response.suggestedActions.map((action, index) => (\r\n <button\r\n key={`${action.label ?? action.action ?? 'action'}-${index}`}\r\n type=\"button\"\r\n style={{\r\n ...styles.actionButton,\r\n opacity: isStreaming ? 0.5 : 1,\r\n cursor: isStreaming ? 'not-allowed' : 'pointer',\r\n }}\r\n onClick={() => handleActionClick(action)}\r\n disabled={isStreaming}\r\n onMouseEnter={(e) => {\r\n if (!isStreaming) {\r\n e.currentTarget.style.background = '#a7f3d0';\r\n e.currentTarget.style.borderColor = '#a7f3d0';\r\n }\r\n }}\r\n onMouseLeave={(e) => {\r\n if (!isStreaming) {\r\n e.currentTarget.style.background = '#d1fae5';\r\n e.currentTarget.style.borderColor = '#d1fae5';\r\n }\r\n }}\r\n >\r\n {action.label ?? action.action ?? 'Acción'}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n // Render follow-up questions\r\n const renderFollowUps = (response?: ChatResponseDto) => {\r\n if (!response?.followUpQuestions?.length) return null;\r\n\r\n return (\r\n <div style={styles.actionsSection}>\r\n <div style={styles.sectionLabel}>Preguntas Relacionadas</div>\r\n <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>\r\n {response.followUpQuestions.map((question, index) => (\r\n <button\r\n key={`followup-${index}`}\r\n type=\"button\"\r\n style={{\r\n ...styles.followUpButton,\r\n opacity: isStreaming ? 0.5 : 1,\r\n cursor: isStreaming ? 'not-allowed' : 'pointer',\r\n }}\r\n onClick={() => !isStreaming && handleFollowUpClick(question)}\r\n disabled={isStreaming}\r\n onMouseEnter={(e) => {\r\n if (!isStreaming) {\r\n e.currentTarget.style.background = '#f8fafc';\r\n e.currentTarget.style.borderColor = '#10b981';\r\n }\r\n }}\r\n onMouseLeave={(e) => {\r\n if (!isStreaming) {\r\n e.currentTarget.style.background = '#fff';\r\n e.currentTarget.style.borderColor = '#cbd5e1';\r\n }\r\n }}\r\n >\r\n {question}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n const chatContent = (\r\n <div style={styles.root}>\r\n <style>{`\r\n @keyframes zenitBlink {\r\n 0%, 49% { opacity: 1; }\r\n 50%, 100% { opacity: 0; }\r\n }\r\n @keyframes zenitPulse {\r\n 0% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7); }\r\n 70% { box-shadow: 0 0 0 14px rgba(16, 185, 129, 0); }\r\n 100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0); }\r\n }\r\n @keyframes typingDotBounce {\r\n 0%, 60%, 100% { transform: translateY(0); }\r\n 30% { transform: translateY(-8px); }\r\n }\r\n .zenit-typing-dot:nth-child(1) { animation-delay: 0s; }\r\n .zenit-typing-dot:nth-child(2) { animation-delay: 0.2s; }\r\n .zenit-typing-dot:nth-child(3) { animation-delay: 0.4s; }\r\n .zenit-ai-button:not(.open) {\r\n animation: zenitPulse 2.5s infinite;\r\n }\r\n .zenit-ai-button:hover {\r\n transform: scale(1.05);\r\n }\r\n .zenit-ai-button:active {\r\n transform: scale(0.95);\r\n }\r\n .zenit-send-button:disabled {\r\n opacity: 0.5;\r\n cursor: not-allowed;\r\n }\r\n .zenit-send-button:not(:disabled):hover {\r\n opacity: 0.9;\r\n transform: translateY(-1px);\r\n }\r\n .zenit-send-button:not(:disabled):active {\r\n transform: translateY(0);\r\n }\r\n .zenit-chat-panel {\r\n box-sizing: border-box;\r\n }\r\n @media (max-width: 768px) {\r\n .zenit-chat-panel.zenit-chat-panel--fullscreen .zenit-ai-body {\r\n flex: 1;\r\n min-height: 0;\r\n overflow-y: auto;\r\n -webkit-overflow-scrolling: touch;\r\n }\r\n .zenit-chat-panel.zenit-chat-panel--fullscreen .zenit-ai-input-area {\r\n flex-shrink: 0;\r\n padding-bottom: max(14px, env(safe-area-inset-bottom));\r\n }\r\n .zenit-ai-button.zenit-ai-button--hidden-mobile {\r\n display: none !important;\r\n }\r\n }\r\n `}</style>\r\n\r\n {open && (\r\n <div\r\n ref={chatBoxRef}\r\n className={`zenit-chat-panel${expanded && !isMobile ? ' zenit-chat-panel--expanded' : ''}${\r\n isMobile ? ' zenit-chat-panel--fullscreen' : ''\r\n }`}\r\n style={(() => {\r\n // Split desktop vs mobile styles to prevent fullscreen from being overridden by desktop sizing.\r\n const desktopStyle = expanded ? styles.panelExpanded : styles.panelNormal;\r\n const mobileStyle = styles.panelMobileFullscreen;\r\n return {\r\n ...styles.panel,\r\n ...(isMobile ? mobileStyle : desktopStyle),\r\n };\r\n })()}\r\n >\r\n <header style={styles.header}>\r\n <h3 style={styles.title}>Asistente Zenit AI</h3>\r\n <div style={styles.headerButtons}>\r\n {!isMobile && (\r\n <button\r\n type=\"button\"\r\n style={styles.headerButton}\r\n onClick={() => setExpanded(!expanded)}\r\n onMouseEnter={(e) => {\r\n e.currentTarget.style.background = 'rgba(255, 255, 255, 0.25)';\r\n }}\r\n onMouseLeave={(e) => {\r\n e.currentTarget.style.background = 'rgba(255, 255, 255, 0.15)';\r\n }}\r\n aria-label={expanded ? 'Contraer' : 'Expandir'}\r\n >\r\n {expanded ? <CollapseIcon /> : <ExpandIcon />}\r\n </button>\r\n )}\r\n <button\r\n type=\"button\"\r\n style={styles.headerButton}\r\n onClick={() => setOpen(false)}\r\n onMouseEnter={(e) => {\r\n e.currentTarget.style.background = 'rgba(255, 255, 255, 0.25)';\r\n }}\r\n onMouseLeave={(e) => {\r\n e.currentTarget.style.background = 'rgba(255, 255, 255, 0.15)';\r\n }}\r\n aria-label=\"Cerrar\"\r\n >\r\n <CloseIcon />\r\n </button>\r\n </div>\r\n </header>\r\n\r\n <div ref={messagesContainerRef} className=\"zenit-ai-body\" style={styles.messages}>\r\n {messages.map((message) => (\r\n <div\r\n key={message.id}\r\n style={{\r\n ...styles.messageWrapper,\r\n alignItems: message.role === 'user' ? 'flex-end' : 'flex-start',\r\n }}\r\n >\r\n <div\r\n style={{\r\n ...styles.messageBubble,\r\n ...(message.role === 'user' ? styles.userMessage : styles.assistantMessage),\r\n }}\r\n >\r\n {message.role === 'assistant' ? (\r\n <MarkdownRenderer content={message.content} />\r\n ) : (\r\n message.content\r\n )}\r\n {message.role === 'assistant' && renderMetadata(message.response)}\r\n {message.role === 'assistant' && renderActions(message.response)}\r\n {message.role === 'assistant' && renderFollowUps(message.response)}\r\n </div>\r\n </div>\r\n ))}\r\n\r\n {isStreaming && (\r\n <div\r\n style={{\r\n ...styles.messageWrapper,\r\n alignItems: 'flex-start',\r\n }}\r\n >\r\n <div\r\n style={{\r\n ...styles.messageBubble,\r\n ...styles.assistantMessage,\r\n }}\r\n >\r\n {streamingText ? (\r\n <>\r\n <MarkdownRenderer content={streamingText} />\r\n <span style={styles.cursor} />\r\n </>\r\n ) : (\r\n <div style={styles.thinkingText}>\r\n <span>Pensando</span>\r\n <div style={styles.typingIndicator}>\r\n <div className=\"zenit-typing-dot\" style={styles.typingDot} />\r\n <div className=\"zenit-typing-dot\" style={styles.typingDot} />\r\n <div className=\"zenit-typing-dot\" style={styles.typingDot} />\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n\r\n <div ref={messagesEndRef} />\r\n </div>\r\n\r\n <div className=\"zenit-ai-input-area\" style={styles.inputWrapper}>\r\n <textarea\r\n style={{\r\n ...styles.textarea,\r\n ...(isFocused ? styles.textareaFocus : {}),\r\n }}\r\n rows={2}\r\n value={inputValue}\r\n onChange={(event) => setInputValue(event.target.value)}\r\n onKeyDown={handleKeyDown}\r\n onFocus={() => setIsFocused(true)}\r\n onBlur={() => setIsFocused(false)}\r\n placeholder={\r\n !mapId\r\n ? 'Selecciona un mapa para comenzar'\r\n : isStreaming\r\n ? 'Esperando respuesta...'\r\n : 'Escribe tu pregunta...'\r\n }\r\n disabled={!mapId || !baseUrl || isStreaming}\r\n />\r\n <button\r\n type=\"button\"\r\n className=\"zenit-send-button\"\r\n style={styles.sendButton}\r\n onClick={() => void handleSend()}\r\n disabled={!canSend}\r\n aria-label=\"Enviar mensaje\"\r\n >\r\n <SendIcon />\r\n </button>\r\n </div>\r\n\r\n {errorMessage && (\r\n <div style={styles.errorText}>\r\n {errorMessage}\r\n </div>\r\n )}\r\n\r\n {isStreaming && !errorMessage && (\r\n <div style={styles.statusNote}>\r\n Generando sugerencias...\r\n </div>\r\n )}\r\n\r\n {!mapId && !errorMessage && (\r\n <div style={styles.statusNote}>\r\n Selecciona un mapa para usar el asistente\r\n </div>\r\n )}\r\n\r\n {!baseUrl && !errorMessage && (\r\n <div style={styles.statusNote}>\r\n Configura la baseUrl del SDK\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* Hide FAB when hideButton is true and chat is closed; always show when chat is open so user can close */}\r\n {!(hideButton && !open) && (\r\n <button\r\n type=\"button\"\r\n className={`zenit-ai-button ${open ? 'open' : ''}${\r\n open && isMobile ? ' zenit-ai-button--hidden-mobile' : ''\r\n }`}\r\n style={{\r\n ...styles.floatingButton,\r\n ...(open\r\n ? styles.floatingButtonOpen\r\n : isMobile\r\n ? styles.floatingButtonMobile\r\n : styles.floatingButtonClosed),\r\n zIndex: open ? 100001 : 99999,\r\n }}\r\n onClick={() => setOpen((prev) => !prev)}\r\n aria-label={open ? 'Cerrar asistente' : 'Abrir asistente Zenit AI'}\r\n >\r\n {open ? (\r\n <CloseIcon />\r\n ) : (\r\n <>\r\n <ChatIcon />\r\n {!isMobile && <span>Asistente IA</span>}\r\n </>\r\n )}\r\n </button>\r\n )}\r\n </div>\r\n );\r\n\r\n // Use portal to render at document.body for proper z-index\r\n if (typeof document !== 'undefined') {\r\n return createPortal(chatContent, document.body);\r\n }\r\n\r\n // Fallback for SSR\r\n return chatContent;\r\n};\r\n","import { useCallback, useRef, useState } from 'react';\r\nimport type { ChatRequestDto, ChatResponseDto } from '../../ai/types';\r\nimport type { ChatRequestOptions, ChatServiceConfig } from '../../ai/chat.service';\r\nimport { sendMessage, sendMessageStream } from '../../ai/chat.service';\r\n\r\nexport const useSendMessage = (config?: ChatServiceConfig) => {\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [error, setError] = useState<unknown>(null);\r\n\r\n const send = useCallback(\r\n async (mapId: number, request: ChatRequestDto, options?: ChatRequestOptions) => {\r\n setIsLoading(true);\r\n setError(null);\r\n try {\r\n return await sendMessage(mapId, request, options, config);\r\n } catch (err) {\r\n setError(err);\r\n throw err;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n },\r\n [config]\r\n );\r\n\r\n return { sendMessage: send, isLoading, error };\r\n};\r\n\r\nexport const useSendMessageStream = (config?: ChatServiceConfig) => {\r\n const [isStreaming, setIsStreaming] = useState(false);\r\n const [streamingText, setStreamingText] = useState('');\r\n const [completeResponse, setCompleteResponse] = useState<ChatResponseDto | null>(null);\r\n const [error, setError] = useState<unknown>(null);\r\n const requestIdRef = useRef(0);\r\n\r\n const reset = useCallback(() => {\r\n setIsStreaming(false);\r\n setStreamingText('');\r\n setCompleteResponse(null);\r\n setError(null);\r\n }, []);\r\n\r\n const send = useCallback(\r\n async (mapId: number, request: ChatRequestDto, options?: ChatRequestOptions) => {\r\n const requestId = requestIdRef.current + 1;\r\n requestIdRef.current = requestId;\r\n\r\n setIsStreaming(true);\r\n setStreamingText('');\r\n setCompleteResponse(null);\r\n setError(null);\r\n\r\n try {\r\n const response = await sendMessageStream(\r\n mapId,\r\n request,\r\n {\r\n onChunk: (_chunk, aggregated) => {\r\n if (requestIdRef.current !== requestId) return;\r\n setStreamingText(aggregated);\r\n },\r\n onError: (err) => {\r\n if (requestIdRef.current !== requestId) return;\r\n setError(err);\r\n },\r\n onComplete: (finalResponse) => {\r\n if (requestIdRef.current !== requestId) return;\r\n setCompleteResponse(finalResponse);\r\n },\r\n },\r\n options,\r\n config\r\n );\r\n return response;\r\n } catch (err) {\r\n setError(err);\r\n throw err;\r\n } finally {\r\n if (requestIdRef.current === requestId) {\r\n setIsStreaming(false);\r\n }\r\n }\r\n },\r\n [config]\r\n );\r\n\r\n return {\r\n sendMessage: send,\r\n isStreaming,\r\n streamingText,\r\n completeResponse,\r\n error,\r\n reset,\r\n };\r\n};\r\n","import type { ChatRequestDto, ChatResponseDto } from './types';\r\n\r\nexport interface ChatServiceConfig {\r\n baseUrl: string;\r\n accessToken?: string;\r\n getAccessToken?: () => string | Promise<string>;\r\n}\r\n\r\nexport interface ChatRequestOptions {\r\n baseUrl?: string;\r\n accessToken?: string;\r\n getAccessToken?: () => string | Promise<string>;\r\n signal?: AbortSignal;\r\n}\r\n\r\nexport interface ChatStreamCallbacks {\r\n onChunk?: (chunk: ChatResponseDto, aggregatedText: string) => void;\r\n onComplete?: (response: ChatResponseDto) => void;\r\n onError?: (error: unknown) => void;\r\n}\r\n\r\nconst DEFAULT_ERROR_MESSAGE = 'No fue posible completar la solicitud al asistente.';\r\n\r\nconst normalizeBaseUrl = (baseUrl: string) => baseUrl.replace(/\\/$/, '');\r\n\r\nconst resolveBaseUrl = (config?: ChatServiceConfig, options?: ChatRequestOptions): string => {\r\n const baseUrl = options?.baseUrl ?? config?.baseUrl;\r\n if (!baseUrl) {\r\n throw new Error('baseUrl es requerido para usar el chat de Zenit AI.');\r\n }\r\n return normalizeBaseUrl(baseUrl);\r\n};\r\n\r\nconst resolveAccessToken = async (\r\n config?: ChatServiceConfig,\r\n options?: ChatRequestOptions\r\n): Promise<string | undefined> => {\r\n if (options?.accessToken) return options.accessToken;\r\n if (config?.accessToken) return config.accessToken;\r\n\r\n if (options?.getAccessToken) return await options.getAccessToken();\r\n if (config?.getAccessToken) return await config.getAccessToken();\r\n\r\n return undefined;\r\n};\r\n\r\nconst buildAuthHeaders = (token?: string): Record<string, string> => {\r\n if (!token) return {};\r\n return { Authorization: `Bearer ${token}` };\r\n};\r\n\r\nconst parseError = async (response: Response): Promise<Error> => {\r\n try {\r\n const contentType = response.headers.get('content-type') ?? '';\r\n if (contentType.includes('application/json')) {\r\n const payload = await response.json();\r\n const message = payload?.message ?? DEFAULT_ERROR_MESSAGE;\r\n return new Error(message);\r\n }\r\n\r\n const text = await response.text();\r\n return new Error(text || DEFAULT_ERROR_MESSAGE);\r\n } catch (error) {\r\n return error instanceof Error ? error : new Error(DEFAULT_ERROR_MESSAGE);\r\n }\r\n};\r\n\r\nexport const sendMessage = async (\r\n mapId: number,\r\n request: ChatRequestDto,\r\n options?: ChatRequestOptions,\r\n config?: ChatServiceConfig\r\n): Promise<ChatResponseDto> => {\r\n const baseUrl = resolveBaseUrl(config, options);\r\n const token = await resolveAccessToken(config, options);\r\n const response = await fetch(`${baseUrl}/ai/maps/chat/${mapId}`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n ...buildAuthHeaders(token),\r\n },\r\n body: JSON.stringify(request),\r\n signal: options?.signal,\r\n });\r\n\r\n if (!response.ok) {\r\n throw await parseError(response);\r\n }\r\n\r\n return (await response.json()) as ChatResponseDto;\r\n};\r\n\r\nconst mergeResponse = (\r\n previous: ChatResponseDto | null,\r\n chunk: ChatResponseDto,\r\n aggregatedAnswer: string\r\n): ChatResponseDto => ({\r\n ...(previous ?? chunk),\r\n ...chunk,\r\n answer: aggregatedAnswer,\r\n});\r\n\r\nconst resolveAggregatedAnswer = (current: string, incoming: string): string => {\r\n if (!incoming) return current;\r\n if (incoming.startsWith(current)) return incoming;\r\n return current + incoming;\r\n};\r\n\r\nexport const sendMessageStream = async (\r\n mapId: number,\r\n request: ChatRequestDto,\r\n callbacks: ChatStreamCallbacks = {},\r\n options?: ChatRequestOptions,\r\n config?: ChatServiceConfig\r\n): Promise<ChatResponseDto> => {\r\n const baseUrl = resolveBaseUrl(config, options);\r\n const token = await resolveAccessToken(config, options);\r\n\r\n const response = await fetch(`${baseUrl}/ai/maps/chat/${mapId}/stream`, {\r\n method: 'POST',\r\n headers: {\r\n Accept: 'text/event-stream',\r\n 'Content-Type': 'application/json',\r\n ...buildAuthHeaders(token),\r\n },\r\n body: JSON.stringify(request),\r\n signal: options?.signal,\r\n });\r\n\r\n if (!response.ok) {\r\n const error = await parseError(response);\r\n callbacks.onError?.(error);\r\n throw error;\r\n }\r\n\r\n const reader = response.body?.getReader();\r\n if (!reader) {\r\n const error = new Error('No se pudo iniciar el streaming de Zenit AI.');\r\n callbacks.onError?.(error);\r\n throw error;\r\n }\r\n\r\n const decoder = new TextDecoder('utf-8');\r\n let buffer = '';\r\n let aggregated = '';\r\n let latestResponse: ChatResponseDto | null = null;\r\n\r\n try {\r\n while (true) {\r\n const { value, done } = await reader.read();\r\n if (done) break;\r\n\r\n buffer += decoder.decode(value, { stream: true });\r\n const lines = buffer.split(/\\r?\\n/);\r\n buffer = lines.pop() ?? '';\r\n\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n if (!trimmed || trimmed.startsWith('event:')) continue;\r\n if (!trimmed.startsWith('data:')) continue;\r\n\r\n const payload = trimmed.replace(/^data:\\s*/, '');\r\n if (!payload || payload === '[DONE]') continue;\r\n\r\n try {\r\n const parsed = JSON.parse(payload) as ChatResponseDto;\r\n aggregated = resolveAggregatedAnswer(aggregated, parsed.answer ?? '');\r\n latestResponse = mergeResponse(latestResponse, parsed, aggregated);\r\n if (latestResponse) {\r\n callbacks.onChunk?.(latestResponse, aggregated);\r\n }\r\n } catch (error) {\r\n callbacks.onError?.(error);\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n callbacks.onError?.(error);\r\n throw error;\r\n }\r\n\r\n if (!latestResponse) {\r\n const error = new Error(DEFAULT_ERROR_MESSAGE);\r\n callbacks.onError?.(error);\r\n throw error;\r\n }\r\n\r\n callbacks.onComplete?.(latestResponse);\r\n return latestResponse;\r\n};\r\n\r\nexport const createChatService = (config: ChatServiceConfig) => ({\r\n sendMessage: (mapId: number, request: ChatRequestDto, options?: ChatRequestOptions) =>\r\n sendMessage(mapId, request, options, config),\r\n sendMessageStream: (\r\n mapId: number,\r\n request: ChatRequestDto,\r\n callbacks?: ChatStreamCallbacks,\r\n options?: ChatRequestOptions\r\n ) => sendMessageStream(mapId, request, callbacks, options, config),\r\n});\r\n","import React from 'react';\r\nimport ReactMarkdown from 'react-markdown';\r\nimport remarkGfm from 'remark-gfm';\r\n\r\ninterface MarkdownRendererProps {\r\n content: string;\r\n className?: string;\r\n}\r\n\r\n/**\r\n * Normalizes assistant markdown by removing artifacts and cleaning up formatting\r\n */\r\nfunction normalizeAssistantMarkdown(text: string): string {\r\n if (!text || typeof text !== 'string') return '';\r\n\r\n let normalized = text;\r\n\r\n // 1. Normalize line endings\r\n normalized = normalized.replace(/\\r\\n/g, '\\n');\r\n\r\n // 2. Remove standalone header symbols (lines that are ONLY # symbols with optional whitespace)\r\n normalized = normalized.replace(/^\\s*#{1,6}\\s*$/gm, '');\r\n\r\n // 3. Remove excessive blank lines (more than 2 consecutive newlines)\r\n normalized = normalized.replace(/\\n{3,}/g, '\\n\\n');\r\n\r\n // 4. Trim trailing whitespace from each line\r\n normalized = normalized\r\n .split('\\n')\r\n .map((line) => line.trimEnd())\r\n .join('\\n');\r\n\r\n // 5. Trim the entire string\r\n normalized = normalized.trim();\r\n\r\n return normalized;\r\n}\r\n\r\n/**\r\n * Renders markdown content with GFM support and normalization\r\n */\r\nexport const MarkdownRenderer: React.FC<MarkdownRendererProps> = ({ content, className }) => {\r\n const normalizedContent = normalizeAssistantMarkdown(content);\r\n\r\n if (!normalizedContent) {\r\n return null;\r\n }\r\n\r\n return (\r\n <div className={className} style={{ wordBreak: 'break-word' }}>\r\n <ReactMarkdown\r\n remarkPlugins={[remarkGfm]}\r\n components={{\r\n // Headings with proper spacing\r\n h1: ({ children, ...props }) => (\r\n <h1 style={{ fontSize: '1.5em', fontWeight: 700, marginTop: '1em', marginBottom: '0.5em' }} {...props}>\r\n {children}\r\n </h1>\r\n ),\r\n h2: ({ children, ...props }) => (\r\n <h2 style={{ fontSize: '1.3em', fontWeight: 700, marginTop: '0.9em', marginBottom: '0.45em' }} {...props}>\r\n {children}\r\n </h2>\r\n ),\r\n h3: ({ children, ...props }) => (\r\n <h3 style={{ fontSize: '1.15em', fontWeight: 600, marginTop: '0.75em', marginBottom: '0.4em' }} {...props}>\r\n {children}\r\n </h3>\r\n ),\r\n h4: ({ children, ...props }) => (\r\n <h4 style={{ fontSize: '1.05em', fontWeight: 600, marginTop: '0.6em', marginBottom: '0.35em' }} {...props}>\r\n {children}\r\n </h4>\r\n ),\r\n h5: ({ children, ...props }) => (\r\n <h5 style={{ fontSize: '1em', fontWeight: 600, marginTop: '0.5em', marginBottom: '0.3em' }} {...props}>\r\n {children}\r\n </h5>\r\n ),\r\n h6: ({ children, ...props }) => (\r\n <h6 style={{ fontSize: '0.95em', fontWeight: 600, marginTop: '0.5em', marginBottom: '0.3em' }} {...props}>\r\n {children}\r\n </h6>\r\n ),\r\n // Paragraphs with comfortable line height\r\n p: ({ children, ...props }) => (\r\n <p style={{ marginTop: '0.5em', marginBottom: '0.5em', lineHeight: 1.6 }} {...props}>\r\n {children}\r\n </p>\r\n ),\r\n // Lists with proper indentation\r\n ul: ({ children, ...props }) => (\r\n <ul style={{ paddingLeft: '1.5em', marginTop: '0.5em', marginBottom: '0.5em' }} {...props}>\r\n {children}\r\n </ul>\r\n ),\r\n ol: ({ children, ...props }) => (\r\n <ol style={{ paddingLeft: '1.5em', marginTop: '0.5em', marginBottom: '0.5em' }} {...props}>\r\n {children}\r\n </ol>\r\n ),\r\n li: ({ children, ...props }) => (\r\n <li style={{ marginTop: '0.25em', marginBottom: '0.25em' }} {...props}>\r\n {children}\r\n </li>\r\n ),\r\n // Code blocks\r\n code: ({ inline, children, ...props }: any) => {\r\n if (inline) {\r\n return (\r\n <code\r\n style={{\r\n backgroundColor: 'rgba(0, 0, 0, 0.08)',\r\n padding: '0.15em 0.4em',\r\n borderRadius: '4px',\r\n fontSize: '0.9em',\r\n fontFamily: 'monospace',\r\n }}\r\n {...props}\r\n >\r\n {children}\r\n </code>\r\n );\r\n }\r\n return (\r\n <code\r\n style={{\r\n display: 'block',\r\n backgroundColor: 'rgba(0, 0, 0, 0.08)',\r\n padding: '0.75em',\r\n borderRadius: '6px',\r\n fontSize: '0.9em',\r\n fontFamily: 'monospace',\r\n overflowX: 'auto',\r\n marginTop: '0.5em',\r\n marginBottom: '0.5em',\r\n }}\r\n {...props}\r\n >\r\n {children}\r\n </code>\r\n );\r\n },\r\n // Pre (code block wrapper)\r\n pre: ({ children, ...props }) => (\r\n <pre style={{ margin: 0 }} {...props}>\r\n {children}\r\n </pre>\r\n ),\r\n // Blockquotes\r\n blockquote: ({ children, ...props }) => (\r\n <blockquote\r\n style={{\r\n borderLeft: '4px solid rgba(0, 0, 0, 0.2)',\r\n paddingLeft: '1em',\r\n marginLeft: 0,\r\n marginTop: '0.5em',\r\n marginBottom: '0.5em',\r\n color: 'rgba(0, 0, 0, 0.7)',\r\n }}\r\n {...props}\r\n >\r\n {children}\r\n </blockquote>\r\n ),\r\n // Strong/bold\r\n strong: ({ children, ...props }) => (\r\n <strong style={{ fontWeight: 600 }} {...props}>\r\n {children}\r\n </strong>\r\n ),\r\n // Emphasis/italic\r\n em: ({ children, ...props }) => (\r\n <em style={{ fontStyle: 'italic' }} {...props}>\r\n {children}\r\n </em>\r\n ),\r\n // Horizontal rule\r\n hr: (props) => (\r\n <hr\r\n style={{\r\n border: 'none',\r\n borderTop: '1px solid rgba(0, 0, 0, 0.1)',\r\n marginTop: '1em',\r\n marginBottom: '1em',\r\n }}\r\n {...props}\r\n />\r\n ),\r\n // Tables (GFM)\r\n table: ({ children, ...props }) => (\r\n <div style={{ overflowX: 'auto', marginTop: '0.5em', marginBottom: '0.5em' }}>\r\n <table\r\n style={{\r\n borderCollapse: 'collapse',\r\n width: '100%',\r\n fontSize: '0.9em',\r\n }}\r\n {...props}\r\n >\r\n {children}\r\n </table>\r\n </div>\r\n ),\r\n th: ({ children, ...props }) => (\r\n <th\r\n style={{\r\n border: '1px solid rgba(0, 0, 0, 0.2)',\r\n padding: '0.5em',\r\n backgroundColor: 'rgba(0, 0, 0, 0.05)',\r\n fontWeight: 600,\r\n textAlign: 'left',\r\n }}\r\n {...props}\r\n >\r\n {children}\r\n </th>\r\n ),\r\n td: ({ children, ...props }) => (\r\n <td\r\n style={{\r\n border: '1px solid rgba(0, 0, 0, 0.2)',\r\n padding: '0.5em',\r\n }}\r\n {...props}\r\n >\r\n {children}\r\n </td>\r\n ),\r\n }}\r\n >\r\n {normalizedContent}\r\n </ReactMarkdown>\r\n </div>\r\n );\r\n};\r\n"],"mappings":"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","names":["React","useCallback","useEffect","useMemo","useRef","useState","Marker","L","clampOpacity","clampOpacity","useEffect","useRef","L","useEffect","useRef","L","clampNumber","clampOpacity","Fragment","jsx","jsxs","useRef","useEffect","L","useEffect","useRef","useMap","jsx","jsxs","useState","useRef","useMemo","useEffect","useCallback","clampOpacity","L","zoom","React","Marker","React","useEffect","useMemo","useRef","useState","React","createPortal","jsx","jsxs","React","createPortal","Fragment","jsx","jsxs","getLayerColor","useState","useRef","useMemo","React","useEffect","jsx","jsxs","useCallback","useEffect","useMemo","useRef","useState","createPortal","useCallback","useRef","useState","useState","useCallback","useRef","jsx","Fragment","jsx","jsxs","useState","useCallback","useRef","useMemo","sendMessage","useEffect","createPortal"]}
|