@rsltda/components 1.0.11

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rs-components.es.js","sources":["../src/utils/define.ts","../src/components/rs-map.ts","../src/index.ts"],"sourcesContent":["// Registro seguro para evitar DOMException por doble definición\r\nexport function safeDefine(tag: string, Ctor: CustomElementConstructor) {\r\n if (!customElements.get(tag)) customElements.define(tag, Ctor);\r\n}\r\n","type ZoneKey = 'norte' | 'rm' | 'centro' | 'sur';\ntype ZoneFilter = ZoneKey | 'all';\n\ninterface MapPointPhone {\n id: number;\n dist: number;\n telefono: string;\n nombre: string;\n whatsapp: number;\n orden: number;\n}\n\ninterface MapPointApi {\n id: number;\n titulo: string;\n rut: string;\n direccion: string;\n comuna: number;\n tipo: number;\n lat: string;\n lng: string;\n url: string;\n email: string;\n adicional: string;\n portada: string;\n googlelink: string;\n activo: number;\n marca: number;\n comuna_name: string;\n provincia_name: string;\n region_name: string;\n telefonos: MapPointPhone[];\n}\n\ninterface MapPoint extends MapPointApi {\n zone: ZoneKey;\n}\n\ninterface PointsCacheEntry {\n timestamp: number;\n data: MapPointApi[];\n}\n\ninterface PointsCacheRecord extends PointsCacheEntry {\n key: string;\n}\n\nconst DEFAULT_BRAND_COLOR = '#1e88e5';\nconst FONT_AWESOME_LOCAL_PATH = '/assets/fontawesome/css/all.min.css';\nconst DEFAULT_MARKER_ICON_BASE_URL = 'https://cdn.rsltda.cl/logos/marker/';\nconst DEFAULT_POINTS_API_URL = 'https://ap2.rs-shop.cl/web/PuntosMapas';\nconst BRAND_COLORS: Record<string, string> = {\n ktm: '#ff6600'\n};\nconst TYPE_CODES: Record<string, number> = {\n sucursal: 0,\n distribuidor: 1\n};\nconst ZONE_ORDER: ZoneKey[] = ['norte', 'rm', 'centro', 'sur'];\nconst ZONE_LABELS: Record<ZoneKey, string> = {\n norte: 'Zona Norte',\n rm: 'RM',\n centro: 'Zona Centro',\n sur: 'Zona Sur'\n};\nconst TYPE_LABELS: Record<number, string> = {\n 0: 'Sucursales',\n 1: 'Distribuidores'\n};\nconst DEFAULT_POINTS_CACHE_TTL_MS = 30 * 24 * 60 * 60 * 1000;\nconst POINTS_CACHE_DB_NAME = 'rs-map-cache';\nconst POINTS_CACHE_STORE_NAME = 'points';\nconst REGION_ZONE_MAP: Record<string, ZoneKey> = {\n 'region de arica y parinacota': 'norte',\n 'arica y parinacota': 'norte',\n 'region de tarapaca': 'norte',\n tarapaca: 'norte',\n 'region de antofagasta': 'norte',\n antofagasta: 'norte',\n 'region de atacama': 'norte',\n atacama: 'norte',\n 'region de coquimbo': 'norte',\n coquimbo: 'norte',\n 'region de valparaiso': 'centro',\n valparaiso: 'centro',\n 'region del libertador general bernardo o higgins': 'centro',\n \"region del libertador general bernardo o'higgins\": 'centro',\n \"libertador bernardo o'higgins\": 'centro',\n ohiggins: 'centro',\n 'region del maule': 'centro',\n maule: 'centro',\n 'region de nuble': 'centro',\n nuble: 'centro',\n 'region del biobio': 'centro',\n biobio: 'centro',\n 'region metropolitana de santiago': 'rm',\n 'region metropolitana': 'rm',\n 'rm': 'rm',\n santiago: 'rm',\n 'region de la araucania': 'sur',\n araucania: 'sur',\n 'region de los rios': 'sur',\n 'los rios': 'sur',\n 'region de los lagos': 'sur',\n 'los lagos': 'sur',\n 'region de aysen del general carlos ibanez del campo': 'sur',\n 'region de aysen': 'sur',\n aysen: 'sur',\n 'region de magallanes y la antartica chilena': 'sur',\n magallanes: 'sur'\n};\n\nexport class RsMap extends HTMLElement {\n static tag = 'rs-map';\n private static googleMapsLoaderPromise: Promise<void> | null = null;\n private static pointsCacheDbPromise: Promise<IDBDatabase | null> | null = null;\n private root: ShadowRoot;\n private mapEl!: HTMLDivElement;\n private map: any;\n private markers: any[] = [];\n private marca = '';\n private marcaKey = 'default';\n private tipo = '';\n private tipoCode: number | null = null;\n private pointsController?: AbortController;\n private points: MapPoint[] = [];\n private pointsByZone: Record<ZoneKey, MapPoint[]> = {\n norte: [],\n rm: [],\n centro: [],\n sur: []\n };\n private initialViewApplied = false;\n private zonesContainer!: HTMLElement;\n private componentMessageEl!: HTMLElement;\n private mapLayoutEl!: HTMLElement;\n private zoneButtons: HTMLButtonElement[] = [];\n private nearestButton!: HTMLButtonElement;\n private panelTitleEl!: HTMLElement;\n private activeZone: ZoneFilter = 'all';\n private mapHeight = '';\n private googleMapsApiKey = '';\n private pointsApiUrl = DEFAULT_POINTS_API_URL;\n private markerIconBaseUrl = DEFAULT_MARKER_ICON_BASE_URL;\n private defaultMarkerIconUrl = '';\n private pointsCacheTtlMs = DEFAULT_POINTS_CACHE_TTL_MS;\n private static fontAwesomeAttached = false;\n private panAnimationFrame: number | null = null;\n private highlightTimeout: number | null = null;\n private isSyncingInitialAttributes = false;\n private refreshQueued = false;\n\n static get observedAttributes() {\n return [\n 'marca',\n 'tipo',\n 'height',\n 'google-maps-key',\n 'points-api-url',\n 'cache-days',\n 'marker-icon-base',\n 'marker-icon-default'\n ];\n }\n\n constructor() {\n super();\n RsMap.ensureFontAwesome();\n this.root = this.attachShadow({ mode: 'open' });\n this.root.innerHTML = `\n <link rel=\"stylesheet\" href=\"${FONT_AWESOME_LOCAL_PATH}\" />\n <style>\n :host {\n display: block;\n width: 100%;\n height: var(--map-height, 520px);\n --rs-map-accent: ${DEFAULT_BRAND_COLOR};\n }\n .map-layout {\n display: grid;\n grid-template-columns: minmax(0, 2.5fr) minmax(220px, 1fr);\n gap: 16px;\n width: 100%;\n height: 100%;\n }\n .map-panel,\n #map {\n width: 100%;\n height: 100%;\n animation: mapSlide 90s infinite;\n animation-timing-function: ease-in-out; \n }\n .map-panel {\n border-radius: 8px;\n overflow: hidden;\n border: 2px solid var(--rs-map-accent);\n }\n #map {\n background: #f5f5f5;\n }\n .component-shell {\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n .component-message {\n margin: 0;\n font-size: 1rem;\n color: #555;\n text-align: center;\n padding: 24px 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 1;\n }\n .component-message[hidden] {\n display: none;\n }\n .map-layout[hidden] {\n display: none;\n }\n .points-panel {\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n border-top: 4px solid var(--rs-map-accent);\n padding: 16px;\n font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n background: #fff;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n .panel-message {\n margin: 0;\n font-size: 0.95rem;\n color: #555;\n text-align: center;\n padding: 32px 12px;\n }\n .panel-content[hidden] {\n display: none;\n }\n .points-panel h2 {\n margin: 0 0 8px;\n font-size: 1rem;\n color: var(--rs-map-accent);\n }\n .zone-filters {\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n overflow-x: auto;\n padding-bottom: 8px;\n flex-wrap: nowrap;\n }\n .zone-button {\n border: 1px solid var(--rs-map-accent);\n border-radius: 999px;\n padding: 6px 12px;\n font-size: 0.85rem;\n background: transparent;\n color: var(--rs-map-accent);\n cursor: pointer;\n transition: background 0.2s ease, color 0.2s ease;\n text-align: center;\n white-space: nowrap;\n }\n .zone-button:hover,\n .zone-button:focus-visible {\n background: var(--rs-map-accent);\n color: #fff;\n }\n .zone-button.is-active {\n background: var(--rs-map-accent);\n color: #fff;\n }\n .zone-button--secondary {\n flex-shrink: 0;\n border-color: #444;\n color: #444;\n }\n .zone-button--secondary i {\n margin-right: 6px;\n }\n .panel-header {\n margin-bottom: 12px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n }\n .panel-header h2[data-panel-title] {\n margin: 0;\n font-size: 1.25rem;\n }\n .zones-container {\n display: flex;\n flex-direction: column;\n gap: 16px;\n flex: 1;\n overflow-y: auto;\n }\n .zone-section {\n border-top: 2px solid #eee;\n padding-top: 12px;\n }\n .zone-section[hidden] {\n display: none;\n }\n .zone-section__header {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n margin: 0 0 8px;\n font-weight: 600;\n color: #333;\n }\n .zone-section__empty {\n margin: 0;\n font-size: 0.85rem;\n color: #777;\n }\n .zone-section__list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n }\n .point-card {\n border: 1px solid #e6e6e6;\n border-radius: 8px;\n padding: 10px;\n background: #fff;\n display: flex;\n flex-direction: column;\n gap: 6px;\n overflow: hidden;\n transition: border 0.2s ease, box-shadow 0.2s ease;\n }\n .point-card--highlight {\n border: 2px solid var(--rs-map-accent);\n box-shadow: 0 0 0 2px rgba(30, 136, 229, 0.2);\n animation: highlightFade 3s forwards;\n }\n @keyframes highlightFade {\n 0% {\n border-color: var(--rs-map-accent);\n box-shadow: 0 0 0 2px rgba(30, 136, 229, 0.2);\n }\n 80% {\n border-color: #111;\n box-shadow: 0 0 0 2px rgba(17, 17, 17, 0.2);\n }\n 100% {\n border-color: #e6e6e6;\n box-shadow: none;\n }\n }\n .point-card__title {\n margin: -10px -10px 8px;\n padding: 10px;\n font-size: 0.95rem;\n font-weight: 600;\n text-align: center;\n color: #fff;\n background: var(--rs-map-accent);\n }\n .point-card__focus {\n border: 1px solid var(--rs-map-accent);\n border-radius: 999px;\n padding: 4px 12px;\n font-size: 0.8rem;\n background: transparent;\n color: var(--rs-map-accent);\n cursor: pointer;\n align-self: flex-start;\n margin-top: 8px;\n }\n .point-card__focus:hover,\n .point-card__focus:focus-visible {\n background: var(--rs-map-accent);\n color: #fff;\n }\n @media (max-width: 768px) {\n .map-layout {\n grid-template-columns: 1fr;\n }\n .map-panel {\n display: none;\n }\n .panel-header {\n flex-direction: column;\n align-items: stretch;\n }\n .zone-filters {\n flex-wrap: wrap;\n }\n .point-card__focus {\n display: none;\n }\n }\n .point-card__address,\n .point-card__meta,\n .point-card__contact {\n margin: 0;\n font-size: 0.85rem;\n color: #555;\n }\n .point-card__contact {\n margin: 0 0 6px;\n font-size: 0.85rem;\n color: #555;\n }\n .point-card__contact-title {\n display: flex;\n align-items: center;\n gap: 6px;\n font-weight: 600;\n color: #333;\n margin-bottom: 4px;\n }\n .point-card__phone-list {\n list-style: none;\n padding: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n .point-card__phone-item {\n display: flex;\n gap: 8px;\n align-items: flex-start;\n }\n .point-card__phone-icon {\n width: 16px;\n display: inline-flex;\n justify-content: center;\n color: var(--rs-map-accent);\n font-size: 0.85rem;\n }\n .point-card__phone-content {\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n .point-card__phone-name {\n font-weight: 600;\n color: #333;\n }\n .point-card__phone-number {\n font-family: 'Segoe UI', system-ui, sans-serif;\n font-size: 0.85rem;\n }\n .point-card__phone-number--link {\n color: var(--rs-map-accent);\n text-decoration: none;\n }\n .point-card__phone-number--link:hover,\n .point-card__phone-number--link:focus-visible {\n text-decoration: underline;\n }\n .point-card__address-block {\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n .point-card__details {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-top: 6px;\n }\n .point-card__details[hidden] {\n display: none;\n }\n .point-card__toggle {\n border: 1px solid var(--rs-map-accent);\n border-radius: 16px;\n padding: 4px 10px;\n background: transparent;\n color: var(--rs-map-accent);\n font-size: 0.8rem;\n cursor: pointer;\n align-self: flex-start;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n }\n .point-card__toggle:hover,\n .point-card__toggle:focus-visible {\n background: var(--rs-map-accent);\n color: #fff;\n }\n .point-card__actions {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 6px;\n margin-top: 8px;\n }\n .point-card__action {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 0.8rem;\n }\n .point-card__actions a.point-card__action {\n color: var(--rs-map-accent);\n text-decoration: none;\n border-bottom: 1px solid transparent;\n }\n .point-card__actions a.point-card__action:hover,\n .point-card__actions a.point-card__action:focus-visible {\n border-color: currentColor;\n }\n .point-card__actions .point-card__action i {\n font-size: 0.85rem;\n }\n .point-card__actions .point-card__action--text {\n color: #444;\n }\n .point-card__extra {\n margin: 0;\n font-size: 0.8rem;\n color: #444;\n }\n .point-card__extra a {\n color: var(--rs-map-accent);\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n }\n .point-card__extra a:hover,\n .point-card__extra a:focus-visible {\n color: #444;\n text-decoration: underline;\n }\n .point-card__extra-icon {\n font-size: 0.75rem;\n }\n .empty-state {\n margin: 0;\n font-size: 0.9rem;\n color: #777;\n text-align: center;\n }\n .points-panel p {\n margin: 0;\n color: #666;\n font-size: 0.9rem;\n }\n </style>\n <div class=\"component-shell\">\n <p class=\"component-message\" data-component-message>Cargando puntos...</p>\n <div class=\"map-layout\" data-map-layout hidden>\n <div class=\"map-panel\">\n <div id=\"map\"></div>\n </div>\n <aside class=\"points-panel\" aria-live=\"polite\">\n <div class=\"zone-filters\" role=\"group\" aria-label=\"Filtrar por zona\">\n <button class=\"zone-button\" type=\"button\" data-zone=\"norte\" data-label=\"Zona Norte\" aria-pressed=\"false\">Zona Norte</button>\n <button class=\"zone-button\" type=\"button\" data-zone=\"rm\" data-label=\"RM\" aria-pressed=\"false\">RM</button>\n <button class=\"zone-button\" type=\"button\" data-zone=\"centro\" data-label=\"Zona Centro\" aria-pressed=\"false\">Zona Centro</button>\n <button class=\"zone-button\" type=\"button\" data-zone=\"sur\" data-label=\"Zona Sur\" aria-pressed=\"false\">Zona Sur</button>\n </div>\n <div class=\"panel-header\">\n <h2 data-panel-title>Puntos del mapa</h2>\n <button class=\"zone-button zone-button--secondary\" type=\"button\" data-action=\"nearest\">\n <i class=\"fa-solid fa-location-dot\" aria-hidden=\"true\"></i>\n Buscar tienda cercana\n </button>\n </div>\n <div class=\"zones-container\" data-zone-container></div>\n </aside>\n </div>\n </div>\n `;\n }\n\n connectedCallback() {\n this.mapEl = this.root.querySelector<HTMLDivElement>('#map')!;\n this.panelTitleEl = this.root.querySelector<HTMLElement>('[data-panel-title]')!;\n this.zonesContainer = this.root.querySelector<HTMLElement>('[data-zone-container]')!;\n this.componentMessageEl = this.root.querySelector<HTMLElement>('[data-component-message]')!;\n this.mapLayoutEl = this.root.querySelector<HTMLElement>('[data-map-layout]')!;\n this.zoneButtons = Array.from(this.root.querySelectorAll<HTMLButtonElement>('[data-zone]'));\n this.nearestButton = this.root.querySelector<HTMLButtonElement>('[data-action=\"nearest\"]')!;\n this.zoneButtons.forEach((btn) => btn.addEventListener('click', this.handleZoneButtonClick));\n if (this.nearestButton) {\n this.nearestButton.addEventListener('click', this.handleNearestClick);\n }\n this.updateZoneButtons();\n this.setMapHeight(this.getAttribute('height'));\n this.setComponentState('loading');\n this.syncAttributesToState();\n }\n\n disconnectedCallback() {\n this.pointsController?.abort();\n this.zoneButtons.forEach((btn) => btn.removeEventListener('click', this.handleZoneButtonClick));\n if (this.nearestButton) {\n this.nearestButton.removeEventListener('click', this.handleNearestClick);\n }\n }\n\n attributeChangedCallback(name: string, _oldValue: string | null, newValue: string | null) {\n if (name === 'marca') {\n this.setMarca(newValue ?? '');\n } else if (name === 'tipo') {\n this.setTipo(newValue ?? '');\n } else if (name === 'height') {\n this.setMapHeight(newValue);\n } else if (name === 'google-maps-key') {\n this.setGoogleMapsKey(newValue);\n } else if (name === 'points-api-url') {\n this.setPointsApiUrl(newValue);\n } else if (name === 'cache-days') {\n this.setCacheDays(newValue);\n } else if (name === 'marker-icon-base') {\n this.setMarkerIconBase(newValue);\n } else if (name === 'marker-icon-default') {\n this.setDefaultMarkerIcon(newValue);\n }\n }\n\n private loadGoogleMaps() {\n if ((window as any)._rsGoogleMapsLoaded) {\n return Promise.resolve().then(() => {\n this.initMap();\n });\n }\n\n if (!this.googleMapsApiKey) {\n console.error('Falta la clave de Google Maps. Define el atributo \"google-maps-key\" en <rs-map>.');\n return Promise.resolve();\n }\n\n if (!RsMap.googleMapsLoaderPromise) {\n RsMap.googleMapsLoaderPromise = new Promise<void>((resolve, reject) => {\n const existingScript = document.querySelector<HTMLScriptElement>('script[data-rs-google-maps=\"true\"]');\n if (existingScript) {\n existingScript.addEventListener('load', () => resolve(), { once: true });\n existingScript.addEventListener(\n 'error',\n () => reject(new Error('Error al cargar la API de Google Maps')),\n { once: true }\n );\n return;\n }\n\n const script = document.createElement('script');\n const params = new URLSearchParams({\n key: this.googleMapsApiKey,\n v: 'weekly'\n });\n script.src = `https://maps.googleapis.com/maps/api/js?${params.toString()}`;\n script.async = true;\n script.defer = true;\n script.dataset.rsGoogleMaps = 'true';\n\n script.onload = () => {\n (window as any)._rsGoogleMapsLoaded = true;\n resolve();\n };\n\n script.onerror = () => {\n RsMap.googleMapsLoaderPromise = null;\n reject(new Error('Error al cargar la API de Google Maps'));\n };\n\n document.head.appendChild(script);\n });\n }\n\n return RsMap.googleMapsLoaderPromise\n .then(() => {\n (window as any)._rsGoogleMapsLoaded = true;\n this.initMap();\n })\n .catch((error) => {\n console.error(error instanceof Error ? error.message : 'Error al cargar la API de Google Maps');\n });\n }\n\n private initMap() {\n const g = (window as any).google;\n if (!g) {\n console.error('Google Maps aun no esta disponible.');\n return;\n }\n\n const initialCenter = this.getInitialCenter();\n this.map = new g.maps.Map(this.mapEl, {\n center: initialCenter,\n zoom: 14,\n mapTypeId: 'roadmap'\n });\n if (this.points.length) {\n this.updateMarkers(this.points);\n }\n }\n\n private getInitialCenter() {\n const firstPoint = this.getFirstValidPoint();\n if (firstPoint) {\n return firstPoint;\n }\n return { lat: -33.4489, lng: -70.6693 };\n }\n\n private getFirstValidPoint(): { lat: number; lng: number } | null {\n for (const point of this.points) {\n const lat = Number(point.lat);\n const lng = Number(point.lng);\n if (Number.isFinite(lat) && Number.isFinite(lng)) {\n return { lat, lng };\n }\n }\n return null;\n }\n\n private syncAttributesToState() {\n this.isSyncingInitialAttributes = true;\n this.setMarca(this.getAttribute('marca') ?? '');\n this.setTipo(this.getAttribute('tipo') ?? '');\n this.setGoogleMapsKey(this.getAttribute('google-maps-key'));\n this.setPointsApiUrl(this.getAttribute('points-api-url'));\n this.setCacheDays(this.getAttribute('cache-days'));\n this.setMarkerIconBase(this.getAttribute('marker-icon-base'));\n this.setDefaultMarkerIcon(this.getAttribute('marker-icon-default'));\n this.isSyncingInitialAttributes = false;\n this.queueRefreshPoints();\n }\n\n private setMapHeight(value: string | null) {\n const normalized = (value ?? '').trim();\n if (!normalized) {\n this.mapHeight = '';\n this.style.removeProperty('--map-height');\n return;\n }\n this.mapHeight = normalized;\n this.style.setProperty('--map-height', normalized);\n }\n\n private setGoogleMapsKey(value: string | null) {\n this.googleMapsApiKey = (value ?? '').trim();\n if (this.googleMapsApiKey && this.isConnected) {\n void this.loadGoogleMaps();\n }\n }\n\n private setPointsApiUrl(value: string | null) {\n const normalized = (value ?? '').trim();\n this.pointsApiUrl = normalized || DEFAULT_POINTS_API_URL;\n if (this.pointsApiUrl && this.isConnected && !this.isSyncingInitialAttributes) {\n this.queueRefreshPoints();\n }\n }\n\n private setCacheDays(value: string | null) {\n const normalized = (value ?? '').trim();\n if (!normalized) {\n this.pointsCacheTtlMs = DEFAULT_POINTS_CACHE_TTL_MS;\n return;\n }\n\n const days = Number(normalized);\n if (!Number.isFinite(days) || days < 0) {\n this.pointsCacheTtlMs = DEFAULT_POINTS_CACHE_TTL_MS;\n return;\n }\n\n this.pointsCacheTtlMs = days * 24 * 60 * 60 * 1000;\n }\n\n private setMarkerIconBase(value: string | null) {\n const normalized = (value ?? '').trim();\n if (!normalized) {\n this.markerIconBaseUrl = DEFAULT_MARKER_ICON_BASE_URL;\n return;\n }\n this.markerIconBaseUrl = normalized.endsWith('/') ? normalized : `${normalized}/`;\n }\n\n private setDefaultMarkerIcon(value: string | null) {\n this.defaultMarkerIconUrl = (value ?? '').trim();\n }\n\n private setMarca(value: string) {\n this.marca = value.trim();\n this.marcaKey = this.normalizeBrandKey(this.marca);\n this.applyBrandColor();\n if (!this.isSyncingInitialAttributes) {\n this.queueRefreshPoints();\n }\n }\n\n private setTipo(value: string) {\n this.tipo = value.trim();\n this.tipoCode = this.normalizeTipo(this.tipo);\n this.updatePanelTitle();\n if (!this.isSyncingInitialAttributes) {\n this.queueRefreshPoints();\n }\n }\n\n private queueRefreshPoints() {\n if (this.refreshQueued) {\n return;\n }\n this.refreshQueued = true;\n queueMicrotask(() => {\n this.refreshQueued = false;\n void this.refreshPoints();\n });\n }\n\n get marcaFilter() {\n return this.marca;\n }\n\n get tipoFilter() {\n return this.tipo;\n }\n\n private updatePanelTitle() {\n if (!this.panelTitleEl) {\n return;\n }\n const label = this.getTipoLabel();\n this.panelTitleEl.textContent = label ?? 'Puntos del mapa';\n }\n\n private getTipoLabel() {\n if (this.tipoCode !== null && this.tipoCode in TYPE_LABELS) {\n return TYPE_LABELS[this.tipoCode];\n }\n const normalized = this.tipo.trim().toLowerCase();\n const normalizedCode = normalized && normalized in TYPE_CODES ? TYPE_CODES[normalized] : null;\n if (normalizedCode !== null && normalizedCode in TYPE_LABELS) {\n return TYPE_LABELS[normalizedCode];\n }\n return null;\n }\n\n private applyBrandColor() {\n const color = BRAND_COLORS[this.marcaKey] ?? DEFAULT_BRAND_COLOR;\n this.style.setProperty('--rs-map-accent', color);\n }\n\n private normalizeTipo(value: string): number | null {\n if (!value) {\n return null;\n }\n const normalized = value.trim().toLowerCase();\n if (normalized in TYPE_CODES) {\n return TYPE_CODES[normalized];\n }\n const numeric = Number(normalized);\n if (Number.isFinite(numeric) && (numeric === 0 || numeric === 1)) {\n return numeric;\n }\n return null;\n }\n\n private async refreshPoints() {\n if (!this.isConnected || !this.marca || this.tipoCode === null) {\n return;\n }\n\n if (!this.pointsApiUrl) {\n console.error('Falta la URL de la API de puntos. Define el atributo \"points-api-url\" en <rs-map>.');\n this.setComponentState('error');\n return;\n }\n\n this.pointsController?.abort();\n const controller = new AbortController();\n this.pointsController = controller;\n\n const params = new URLSearchParams({\n marca: this.marca,\n tipo: String(this.tipoCode)\n });\n\n const hasQuery = this.pointsApiUrl.includes('?');\n const needsAmp = hasQuery && !/[?&]$/.test(this.pointsApiUrl);\n const separator = hasQuery ? (needsAmp ? '&' : '') : '?';\n const requestUrl = `${this.pointsApiUrl}${separator}${params.toString()}`;\n const cacheKey = this.getPointsCacheKey(requestUrl);\n const cachedPayload = await this.readPointsCache(cacheKey);\n const hasFreshCache = cachedPayload && Date.now() - cachedPayload.timestamp < this.pointsCacheTtlMs;\n\n if (cachedPayload) {\n this.applyPointsPayload(cachedPayload.data);\n this.setComponentState('ready');\n if (hasFreshCache) {\n return;\n }\n } else {\n this.setComponentState('loading');\n }\n\n try {\n const response = await fetch(requestUrl, {\n signal: controller.signal\n });\n\n if (!response.ok) {\n throw new Error(`Respuesta ${response.status}`);\n }\n\n const payload = await response.json();\n if (!Array.isArray(payload)) {\n throw new Error('La respuesta de puntos no es valida.');\n }\n const typedPayload = payload as MapPointApi[];\n await this.writePointsCache(cacheKey, typedPayload);\n this.applyPointsPayload(typedPayload);\n this.setComponentState('ready');\n } catch (error) {\n if (error instanceof DOMException && error.name === 'AbortError') {\n return;\n }\n if (cachedPayload) {\n console.warn('Se mantienen puntos cacheados por error al refrescar el mapa', error);\n return;\n }\n console.error('No se pudieron cargar los puntos del mapa', error);\n this.setComponentState('error');\n }\n }\n\n private applyPointsPayload(payload: MapPointApi[]) {\n this.points = this.transformPoints(payload);\n this.renderPoints(this.points);\n this.initialViewApplied = false;\n this.updateMarkers(this.points);\n }\n\n private getPointsCacheKey(requestUrl: string) {\n return `rs-map:points:${requestUrl}`;\n }\n\n private async readPointsCache(cacheKey: string): Promise<PointsCacheEntry | null> {\n const dbEntry = await this.readPointsCacheFromIndexedDb(cacheKey);\n if (dbEntry) {\n return dbEntry;\n }\n\n try {\n const raw = window.localStorage.getItem(cacheKey);\n if (!raw) {\n return null;\n }\n const parsed = JSON.parse(raw) as PointsCacheEntry;\n if (!parsed || !Array.isArray(parsed.data) || !Number.isFinite(parsed.timestamp)) {\n window.localStorage.removeItem(cacheKey);\n return null;\n }\n return parsed;\n } catch {\n return null;\n }\n }\n\n private async writePointsCache(cacheKey: string, payload: MapPointApi[]) {\n const entry: PointsCacheEntry = {\n timestamp: Date.now(),\n data: payload\n };\n\n await this.writePointsCacheToIndexedDb(cacheKey, entry);\n\n try {\n window.localStorage.setItem(cacheKey, JSON.stringify(entry));\n } catch {\n // Ignore storage errors and keep runtime behavior.\n }\n }\n\n private async readPointsCacheFromIndexedDb(cacheKey: string): Promise<PointsCacheEntry | null> {\n const db = await RsMap.openPointsCacheDb();\n if (!db) {\n return null;\n }\n\n return new Promise((resolve) => {\n const transaction = db.transaction(POINTS_CACHE_STORE_NAME, 'readonly');\n const store = transaction.objectStore(POINTS_CACHE_STORE_NAME);\n const request = store.get(cacheKey);\n\n request.onsuccess = () => {\n const result = request.result as PointsCacheRecord | undefined;\n if (!result || !Array.isArray(result.data) || !Number.isFinite(result.timestamp)) {\n resolve(null);\n return;\n }\n resolve({\n timestamp: result.timestamp,\n data: result.data\n });\n };\n\n request.onerror = () => resolve(null);\n });\n }\n\n private async writePointsCacheToIndexedDb(cacheKey: string, entry: PointsCacheEntry) {\n const db = await RsMap.openPointsCacheDb();\n if (!db) {\n return;\n }\n\n await new Promise<void>((resolve) => {\n const transaction = db.transaction(POINTS_CACHE_STORE_NAME, 'readwrite');\n const store = transaction.objectStore(POINTS_CACHE_STORE_NAME);\n const request = store.put({\n key: cacheKey,\n timestamp: entry.timestamp,\n data: entry.data\n } satisfies PointsCacheRecord);\n\n request.onsuccess = () => resolve();\n request.onerror = () => resolve();\n });\n }\n\n private static openPointsCacheDb(): Promise<IDBDatabase | null> {\n if (typeof window === 'undefined' || !('indexedDB' in window)) {\n return Promise.resolve(null);\n }\n\n if (!RsMap.pointsCacheDbPromise) {\n RsMap.pointsCacheDbPromise = new Promise((resolve) => {\n const request = window.indexedDB.open(POINTS_CACHE_DB_NAME, 1);\n\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(POINTS_CACHE_STORE_NAME)) {\n db.createObjectStore(POINTS_CACHE_STORE_NAME, { keyPath: 'key' });\n }\n };\n\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => resolve(null);\n });\n }\n\n return RsMap.pointsCacheDbPromise;\n }\n\n private transformPoints(payload: MapPointApi[]): MapPoint[] {\n return payload.map((point) => ({\n ...point,\n zone: this.getZoneForPoint(point)\n }));\n }\n\n private renderPoints(points: MapPoint[]) {\n if (!this.zonesContainer) {\n return;\n }\n\n const grouped = this.groupPoints(points);\n this.pointsByZone = grouped;\n this.updateZoneButtonCounts();\n\n const fragment = document.createDocumentFragment();\n\n ZONE_ORDER.forEach((zoneKey) => {\n const section = document.createElement('section');\n section.className = 'zone-section';\n section.dataset.zoneSection = zoneKey;\n\n const header = document.createElement('div');\n header.className = 'zone-section__header';\n const title = document.createElement('span');\n title.textContent = ZONE_LABELS[zoneKey];\n header.appendChild(title);\n section.appendChild(header);\n\n if (grouped[zoneKey].length === 0) {\n const empty = document.createElement('p');\n empty.className = 'zone-section__empty';\n empty.textContent = 'Sin puntos en esta zona.';\n section.appendChild(empty);\n } else {\n const list = document.createElement('div');\n list.className = 'zone-section__list';\n grouped[zoneKey].forEach((point) => {\n list.appendChild(this.createPointCard(point));\n });\n section.appendChild(list);\n }\n\n fragment.appendChild(section);\n });\n\n this.zonesContainer.replaceChildren(fragment);\n this.updateZoneVisibility();\n }\n\n private groupPoints(points: MapPoint[]): Record<ZoneKey, MapPoint[]> {\n const grouped: Record<ZoneKey, MapPoint[]> = {\n norte: [],\n rm: [],\n centro: [],\n sur: []\n };\n points.forEach((point) => {\n grouped[point.zone].push(point);\n });\n return grouped;\n }\n\n private createPointCard(point: MapPoint) {\n const card = document.createElement('article');\n card.className = 'point-card';\n card.dataset.pointId = String(point.id);\n\n const title = document.createElement('h3');\n title.className = 'point-card__title';\n title.textContent = point.titulo || 'Sin nombre';\n card.appendChild(title);\n\n const addressBlock = document.createElement('div');\n addressBlock.className = 'point-card__address-block';\n\n const address = document.createElement('p');\n address.className = 'point-card__address';\n address.textContent = point.direccion || 'Sin direccion';\n addressBlock.appendChild(address);\n\n if (point.comuna_name) {\n const comuna = document.createElement('p');\n comuna.className = 'point-card__meta';\n comuna.textContent = point.comuna_name;\n addressBlock.appendChild(comuna);\n }\n\n if (point.provincia_name) {\n const provincia = document.createElement('p');\n provincia.className = 'point-card__meta';\n provincia.textContent = point.provincia_name;\n addressBlock.appendChild(provincia);\n }\n\n if (point.region_name) {\n const regionLine = document.createElement('p');\n regionLine.className = 'point-card__meta';\n regionLine.textContent = point.region_name;\n addressBlock.appendChild(regionLine);\n }\n\n card.appendChild(addressBlock);\n\n let focusButton: HTMLButtonElement | null = null;\n const lat = Number(point.lat);\n const lng = Number(point.lng);\n if (Number.isFinite(lat) && Number.isFinite(lng)) {\n focusButton = document.createElement('button');\n focusButton.type = 'button';\n focusButton.className = 'point-card__focus';\n const icon = this.createIconElement('fa-solid fa-location-crosshairs');\n focusButton.appendChild(icon);\n focusButton.appendChild(document.createTextNode(' Ver en el mapa'));\n focusButton.addEventListener('click', () => {\n void this.focusPointWithZoom(lat, lng);\n this.scrollToPointCard(point.id);\n });\n }\n\n const details = document.createElement('div');\n details.className = 'point-card__details';\n details.hidden = true;\n let hasDetails = false;\n\n const actions = document.createElement('div');\n actions.className = 'point-card__actions';\n let mapLinkElement: HTMLAnchorElement | null = null;\n\n if (point.url && point.url !== '#') {\n const siteLink = document.createElement('a');\n siteLink.href = point.url;\n siteLink.target = '_blank';\n siteLink.rel = 'noopener noreferrer';\n siteLink.className = 'point-card__action';\n const icon = this.createIconElement('fa-solid fa-globe');\n siteLink.appendChild(icon);\n siteLink.appendChild(document.createTextNode('Sitio web'));\n actions.appendChild(siteLink);\n }\n\n if (point.email) {\n const emailLink = document.createElement('a');\n emailLink.href = `mailto:${point.email}`;\n emailLink.target = '_blank';\n emailLink.rel = 'noopener noreferrer';\n emailLink.className = 'point-card__action point-card__action--text';\n const icon = this.createIconElement('fa-solid fa-envelope');\n emailLink.appendChild(icon);\n emailLink.appendChild(document.createTextNode(point.email));\n actions.appendChild(emailLink);\n }\n\n if (actions.childElementCount) {\n details.appendChild(actions);\n hasDetails = true;\n }\n\n if (point.telefonos?.length) {\n const contactSection = document.createElement('div');\n contactSection.className = 'point-card__contact';\n const contactTitle = document.createElement('div');\n contactTitle.className = 'point-card__contact-title';\n const icon = this.createIconElement('fa-solid fa-phone');\n contactTitle.appendChild(icon);\n contactTitle.appendChild(document.createTextNode('Telefonos'));\n contactSection.appendChild(contactTitle);\n\n const phoneList = document.createElement('ul');\n phoneList.className = 'point-card__phone-list';\n\n point.telefonos\n .slice()\n .sort((a, b) => a.orden - b.orden)\n .forEach((phone) => {\n const item = document.createElement('li');\n item.className = 'point-card__phone-item';\n\n const iconWrapper = document.createElement('span');\n iconWrapper.className = 'point-card__phone-icon';\n if (phone.whatsapp) {\n const whatsappIcon = this.createIconElement('fa-brands fa-whatsapp');\n iconWrapper.appendChild(whatsappIcon);\n } else {\n iconWrapper.textContent = '-';\n }\n item.appendChild(iconWrapper);\n\n const content = document.createElement('div');\n content.className = 'point-card__phone-content';\n\n const name = document.createElement('span');\n name.className = 'point-card__phone-name';\n name.textContent = phone.nombre;\n content.appendChild(name);\n\n const numberEl = phone.whatsapp ? document.createElement('a') : document.createElement('span');\n numberEl.className = 'point-card__phone-number';\n if (phone.whatsapp) {\n const link = this.getWhatsappLink(phone.telefono);\n if (link) {\n (numberEl as HTMLAnchorElement).href = link;\n (numberEl as HTMLAnchorElement).target = '_blank';\n (numberEl as HTMLAnchorElement).rel = 'noopener noreferrer';\n numberEl.classList.add('point-card__phone-number--link');\n }\n }\n numberEl.textContent = phone.telefono;\n content.appendChild(numberEl);\n\n item.appendChild(content);\n phoneList.appendChild(item);\n });\n\n contactSection.appendChild(phoneList);\n details.appendChild(contactSection);\n hasDetails = true;\n }\n\n if (point.adicional) {\n const extra = document.createElement('p');\n extra.className = 'point-card__extra';\n extra.innerHTML = point.adicional;\n extra.querySelectorAll('a').forEach((link) => {\n link.classList.add('point-card__extra-link');\n const icon = this.createIconElement('fa-solid fa-arrow-up-right-from-square');\n icon.classList.add('point-card__extra-icon');\n link.appendChild(icon);\n });\n details.appendChild(extra);\n hasDetails = true;\n }\n\n if (point.googlelink) {\n mapLinkElement = document.createElement('a');\n mapLinkElement.href = point.googlelink;\n mapLinkElement.target = '_blank';\n mapLinkElement.rel = 'noopener noreferrer';\n mapLinkElement.className = 'point-card__action';\n const icon = this.createIconElement('fa-solid fa-map-location-dot');\n mapLinkElement.appendChild(icon);\n mapLinkElement.appendChild(document.createTextNode('Google Maps'));\n }\n\n if (mapLinkElement) {\n const mapWrapper = document.createElement('div');\n mapWrapper.className = 'point-card__actions';\n mapWrapper.appendChild(mapLinkElement);\n details.appendChild(mapWrapper);\n hasDetails = true;\n }\n\n if (hasDetails) {\n const toggle = document.createElement('button');\n toggle.type = 'button';\n toggle.className = 'point-card__toggle';\n const toggleIcon = this.createIconElement('fa-solid fa-circle-info');\n const toggleText = document.createElement('span');\n toggleText.textContent = 'Mas informacion';\n toggle.appendChild(toggleIcon);\n toggle.appendChild(toggleText);\n toggle.addEventListener('click', () => {\n const isHidden = details.hidden;\n details.hidden = !isHidden;\n toggleText.textContent = isHidden ? 'Ocultar informacion' : 'Mas informacion';\n toggleIcon.className = isHidden ? 'fa-solid fa-circle-xmark' : 'fa-solid fa-circle-info';\n });\n card.appendChild(toggle);\n card.appendChild(details);\n }\n\n if (focusButton) {\n card.appendChild(focusButton);\n }\n\n return card;\n }\n\n private getZoneForPoint(point: MapPointApi): ZoneKey {\n const normalizedRegion = this.normalizeRegionName(point.region_name || '');\n if (normalizedRegion && normalizedRegion in REGION_ZONE_MAP) {\n return REGION_ZONE_MAP[normalizedRegion];\n }\n if (normalizedRegion.includes('metropolitana')) {\n return 'rm';\n }\n if (\n normalizedRegion.includes('araucania') ||\n normalizedRegion.includes('rios') ||\n normalizedRegion.includes('lagos') ||\n normalizedRegion.includes('aysen') ||\n normalizedRegion.includes('magallanes')\n ) {\n return 'sur';\n }\n if (\n normalizedRegion.includes('arica') ||\n normalizedRegion.includes('tarapaca') ||\n normalizedRegion.includes('antofagasta') ||\n normalizedRegion.includes('atacama') ||\n normalizedRegion.includes('coquimbo')\n ) {\n return 'norte';\n }\n return 'centro';\n }\n\n private normalizeRegionName(input: string) {\n return input\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .trim();\n }\n\n private normalizeBrandKey(value: string) {\n if (!value) {\n return 'default';\n }\n const normalized = value\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-z0-9]+/g, '');\n return normalized || 'default';\n }\n\n private getMarkerIcon() {\n const key = this.marcaKey || 'default';\n if (this.markerIconBaseUrl) {\n return `${this.markerIconBaseUrl}${key}.png`;\n }\n if (this.defaultMarkerIconUrl) {\n return this.defaultMarkerIconUrl;\n }\n return null;\n }\n\n private updateMarkers(points: MapPoint[]) {\n const g = (window as any).google;\n if (!g || !this.map) {\n return;\n }\n this.markers.forEach((marker) => marker.setMap(null));\n this.markers = [];\n\n const validPoints = points.filter((point) => {\n const lat = Number(point.lat);\n const lng = Number(point.lng);\n return Number.isFinite(lat) && Number.isFinite(lng);\n });\n\n if (!validPoints.length) {\n return;\n }\n\n const bounds = new g.maps.LatLngBounds();\n const iconUrl = this.getMarkerIcon();\n const icon =\n iconUrl && this.map\n ? {\n url: iconUrl,\n scaledSize: new g.maps.Size(36, 36),\n anchor: new g.maps.Point(18, 36)\n }\n : undefined;\n\n validPoints.forEach((point) => {\n const lat = Number(point.lat);\n const lng = Number(point.lng);\n const marker = new g.maps.Marker({\n map: this.map,\n position: { lat, lng },\n title: point.titulo,\n icon\n });\n this.markers.push(marker);\n const position = marker.getPosition();\n if (position) {\n bounds.extend(position);\n }\n });\n\n if (!this.initialViewApplied && this.markers.length) {\n const position = this.markers[0].getPosition();\n if (position) {\n this.map.setCenter(position);\n this.map.setZoom(14);\n this.initialViewApplied = true;\n return;\n }\n }\n\n if (this.markers.length === 1) {\n const position = this.markers[0].getPosition();\n if (position) {\n this.map.setCenter(position);\n }\n this.map.setZoom(14);\n } else {\n this.map.fitBounds(bounds);\n }\n }\n\n private handleZoneButtonClick = (event: Event) => {\n const button = event.currentTarget as HTMLButtonElement;\n const zone = button.dataset.zone as ZoneKey;\n if (!zone) {\n return;\n }\n this.setActiveZone(zone);\n this.scrollToZoneSection(zone);\n };\n\n private setActiveZone(_zone: ZoneFilter) {}\n\n private scrollToZoneSection(zone: ZoneKey) {\n if (!this.zonesContainer) {\n return;\n }\n const section = this.zonesContainer.querySelector<HTMLElement>(`[data-zone-section=\"${zone}\"]`);\n if (!section) {\n return;\n }\n section.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n\n private updateZoneButtons() {\n this.zoneButtons.forEach((btn) => {\n const zone = btn.dataset.zone as ZoneKey;\n const isActive = this.activeZone === zone;\n btn.classList.toggle('is-active', isActive);\n btn.setAttribute('aria-pressed', String(isActive));\n });\n }\n\n private updateZoneButtonCounts() {\n this.zoneButtons.forEach((btn) => {\n const zone = btn.dataset.zone as ZoneKey;\n const baseLabel = btn.dataset.label || btn.textContent || '';\n btn.textContent = baseLabel;\n });\n }\n\n private updateZoneVisibility() {\n if (!this.zonesContainer) {\n return;\n }\n const sections = this.zonesContainer.querySelectorAll<HTMLElement>('[data-zone-section]');\n sections.forEach((section) => {\n section.removeAttribute('hidden');\n });\n }\n\n private handleNearestClick = () => {\n if (!navigator.geolocation) {\n alert('La geolocalizacion no esta soportada en este navegador.');\n return;\n }\n navigator.geolocation.getCurrentPosition(\n (pos) => {\n const { latitude, longitude } = pos.coords;\n const nearest = this.findNearestPoint(latitude, longitude);\n if (nearest) {\n this.centerMapOnPoint(Number(nearest.lat), Number(nearest.lng));\n this.scrollToPointCard(nearest.id);\n } else {\n alert('No hay puntos disponibles para calcular la tienda cercana.');\n }\n },\n () => {\n alert('No se pudo obtener tu ubicacion.');\n }\n );\n };\n\n private findNearestPoint(lat: number, lng: number): MapPoint | null {\n if (!this.points.length) {\n return null;\n }\n let nearest: MapPoint | null = null;\n let bestDistance = Infinity;\n this.points.forEach((point) => {\n const pointLat = Number(point.lat);\n const pointLng = Number(point.lng);\n if (!Number.isFinite(pointLat) || !Number.isFinite(pointLng)) {\n return;\n }\n const distance = this.haversine(lat, lng, pointLat, pointLng);\n if (distance < bestDistance) {\n bestDistance = distance;\n nearest = point;\n }\n });\n return nearest;\n }\n\n private haversine(lat1: number, lon1: number, lat2: number, lon2: number) {\n const toRad = (deg: number) => (deg * Math.PI) / 180;\n const R = 6371e3;\n const dLat = toRad(lat2 - lat1);\n const dLon = toRad(lon2 - lon1);\n const a =\n Math.sin(dLat / 2) * Math.sin(dLat / 2) +\n Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2);\n const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n return R * c;\n }\n\n private scrollToPointCard(pointId: number) {\n if (!this.zonesContainer) {\n return;\n }\n const card = this.zonesContainer.querySelector<HTMLElement>(`[data-point-id=\"${pointId}\"]`);\n if (!card) {\n return;\n }\n card.scrollIntoView({ behavior: 'smooth', block: 'center' });\n this.highlightPointCard(card);\n }\n\n private highlightPointCard(card: HTMLElement) {\n if (this.highlightTimeout !== null) {\n clearTimeout(this.highlightTimeout);\n this.highlightTimeout = null;\n }\n this.zonesContainer?.querySelectorAll('.point-card--highlight').forEach((el) => {\n el.classList.remove('point-card--highlight');\n });\n card.classList.add('point-card--highlight');\n this.highlightTimeout = window.setTimeout(() => {\n card.classList.remove('point-card--highlight');\n this.highlightTimeout = null;\n }, 3500);\n }\n\n private setComponentState(state: 'loading' | 'ready' | 'error') {\n if (!this.componentMessageEl || !this.mapLayoutEl) {\n return;\n }\n if (state === 'ready') {\n this.componentMessageEl.setAttribute('hidden', '');\n this.mapLayoutEl.removeAttribute('hidden');\n } else {\n const text = state === 'loading' ? 'Cargando puntos...' : 'Mapa temporalmente no disponible';\n this.componentMessageEl.textContent = text;\n this.componentMessageEl.removeAttribute('hidden');\n this.mapLayoutEl.setAttribute('hidden', '');\n }\n }\n\n private centerMapOnPoint(lat: number, lng: number, targetZoom = 14) {\n const g = (window as any).google;\n if (!g || !this.map || !Number.isFinite(lat) || !Number.isFinite(lng)) {\n return;\n }\n const currentZoom = typeof this.map.getZoom === 'function' ? this.map.getZoom() : null;\n const needsZoom = !currentZoom || currentZoom < targetZoom;\n this.animateMapPan(lat, lng, () => {\n if (needsZoom) {\n this.map.setZoom(targetZoom);\n }\n });\n }\n\n private async focusPointWithZoom(lat: number, lng: number) {\n const g = (window as any).google;\n if (!g || !this.map || !Number.isFinite(lat) || !Number.isFinite(lng)) {\n return;\n }\n\n await this.animateZoomTo(8, 800);\n await this.wait(500);\n await new Promise<void>((resolve) => {\n this.animateMapPan(lat, lng, resolve);\n });\n await this.wait(500);\n await this.animateZoomTo(18, 800);\n }\n\n private wait(ms: number) {\n return new Promise<void>((resolve) => {\n window.setTimeout(resolve, ms);\n });\n }\n\n private async animateZoomTo(targetZoom: number, duration = 600) {\n const g = (window as any).google;\n if (\n !g ||\n !this.map ||\n typeof this.map.getZoom !== 'function' ||\n typeof this.map.setZoom !== 'function'\n ) {\n return;\n }\n const startZoom = this.map.getZoom();\n if (!Number.isFinite(startZoom)) {\n this.map.setZoom(targetZoom);\n return;\n }\n const delta = targetZoom - startZoom;\n if (Math.abs(delta) < 0.01) {\n this.map.setZoom(targetZoom);\n return;\n }\n\n await new Promise<void>((resolve) => {\n const startTime = performance.now();\n const ease = (t: number) => 1 - Math.pow(1 - t, 3);\n\n const step = (now: number) => {\n const elapsed = now - startTime;\n const progress = Math.min(elapsed / duration, 1);\n const eased = ease(progress);\n const nextZoom = startZoom + delta * eased;\n this.map.setZoom(Math.round(nextZoom * 100) / 100);\n if (progress < 1) {\n requestAnimationFrame(step);\n } else {\n this.map.setZoom(targetZoom);\n resolve();\n }\n };\n\n requestAnimationFrame(step);\n });\n }\n\n private animateMapPan(targetLat: number, targetLng: number, onComplete?: () => void) {\n const g = (window as any).google;\n if (!g || !this.map) {\n return;\n }\n if (this.panAnimationFrame !== null) {\n cancelAnimationFrame(this.panAnimationFrame);\n this.panAnimationFrame = null;\n }\n const startCenter = this.map.getCenter();\n if (!startCenter) {\n this.map.setCenter({ lat: targetLat, lng: targetLng });\n onComplete?.();\n return;\n }\n const startLat = startCenter.lat();\n const startLng = startCenter.lng();\n const deltaLat = targetLat - startLat;\n const deltaLng = targetLng - startLng;\n const duration = 600;\n const startTime = performance.now();\n\n const ease = (t: number) => 1 - Math.pow(1 - t, 3);\n\n const step = (now: number) => {\n const elapsed = now - startTime;\n const progress = Math.min(elapsed / duration, 1);\n const eased = ease(progress);\n const nextLat = startLat + deltaLat * eased;\n const nextLng = startLng + deltaLng * eased;\n this.map.setCenter({ lat: nextLat, lng: nextLng });\n if (progress < 1) {\n this.panAnimationFrame = requestAnimationFrame(step);\n } else {\n this.panAnimationFrame = null;\n onComplete?.();\n }\n };\n\n this.panAnimationFrame = requestAnimationFrame(step);\n }\n\n private static ensureFontAwesome() {\n if (RsMap.fontAwesomeAttached) {\n return;\n }\n const existing = document.querySelector(`link[href=\"${FONT_AWESOME_LOCAL_PATH}\"]`);\n if (existing) {\n RsMap.fontAwesomeAttached = true;\n return;\n }\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = FONT_AWESOME_LOCAL_PATH;\n link.crossOrigin = 'anonymous';\n link.referrerPolicy = 'no-referrer';\n link.addEventListener('load', () => {\n RsMap.fontAwesomeAttached = true;\n });\n document.head.appendChild(link);\n }\n\n private createIconElement(className: string) {\n const icon = document.createElement('i');\n icon.className = className;\n icon.setAttribute('aria-hidden', 'true');\n return icon;\n }\n\n private getWhatsappLink(phone: string) {\n const digits = phone.replace(/\\D+/g, '');\n if (!digits) {\n return null;\n }\n return `https://wa.me/${digits}`;\n }\n}\n","import { safeDefine } from './utils/define';\nimport { RsMap } from './components/rs-map';\n\n\n// En dev, registramos directamente para probar en el navegador\nsafeDefine(RsMap.tag, RsMap);\n\nexport { RsMap, safeDefine };\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rs-map': RsMap;\n }\n}\n"],"names":["safeDefine","tag","Ctor","DEFAULT_BRAND_COLOR","FONT_AWESOME_LOCAL_PATH","DEFAULT_MARKER_ICON_BASE_URL","DEFAULT_POINTS_API_URL","BRAND_COLORS","TYPE_CODES","ZONE_ORDER","ZONE_LABELS","TYPE_LABELS","DEFAULT_POINTS_CACHE_TTL_MS","POINTS_CACHE_DB_NAME","POINTS_CACHE_STORE_NAME","REGION_ZONE_MAP","_RsMap","__publicField","event","zone","pos","latitude","longitude","nearest","btn","_a","name","_oldValue","newValue","resolve","reject","existingScript","script","params","error","g","initialCenter","firstPoint","point","lat","lng","_b","value","normalized","days","label","normalizedCode","color","numeric","controller","hasQuery","needsAmp","separator","requestUrl","cacheKey","cachedPayload","hasFreshCache","response","payload","typedPayload","dbEntry","raw","parsed","entry","db","request","result","points","grouped","fragment","zoneKey","section","header","title","empty","list","card","addressBlock","address","comuna","provincia","regionLine","focusButton","icon","details","hasDetails","actions","mapLinkElement","siteLink","emailLink","contactSection","contactTitle","phoneList","a","b","phone","item","iconWrapper","whatsappIcon","content","numberEl","link","extra","mapWrapper","toggle","toggleIcon","toggleText","isHidden","normalizedRegion","input","key","marker","validPoints","bounds","iconUrl","position","_zone","isActive","baseLabel","bestDistance","pointLat","pointLng","distance","lat1","lon1","lat2","lon2","toRad","deg","dLat","dLon","pointId","el","state","text","targetZoom","currentZoom","needsZoom","ms","duration","startZoom","delta","startTime","ease","t","step","now","elapsed","progress","eased","nextZoom","targetLat","targetLng","onComplete","startCenter","startLat","startLng","deltaLat","deltaLng","nextLat","nextLng","className","digits","RsMap"],"mappings":"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"}