{"version":3,"sources":["webpack:///./src/client/default/js/classes/woosmap/woosmapClustererClass.js","webpack:///./src/client/default/js/components/WoosmapComponent.js","webpack:///./src/client/default/js/classes/woosmap/woosmapClass.js","webpack:///./src/microtemplates/stores/storeCard.ejs","webpack:///./node_modules/kdbush/index.js","webpack:///./node_modules/supercluster/index.js"],"names":["WoosmapClusterer","woosmap","markers","options","this","map","maxZoom","clustererIcon","debounceDelay","clusterRadius","eventHandler","initialize","latLng","lng","lat","cluster","Supercluster","radius","points","marker","index","type","properties","geometry","coordinates","latLngToSuperclusterFormat","position","load","zoom","getZoom","bounds","getBounds","ne","getNorthEast","sw","getSouthWest","getClusters","Math","min","clusters","getPosition","some","set","setMap","onMarkerHidden","debounce","call","listener","remove","newActiveMarkers","Map","activeMarkers","forEach","toggleMarker","key","has","onClickListener","Marker","LatLng","label","text","point_count","color","icon","url","labelOrigin","window","Point","scaledSize","Size","addListener","zoomToCluster","bind","Array","from","values","dispatch","clusterPosition","zoomLevel","flyTo","createClusterer","boundsEvent","updateMap","clearActiveMarkers","PIN_SIZE","height","width","STORETYPES","CLUSTERER_SETTINGS","WoosmapComponent","element","body","document","isMobileApp","$options","appVersion","storeCity","mobileVersionWithoutGeolocPostMessage","parseInt","initSelectors","boundFn","initComponentEvents","initWoosmap","registerMessageHandler","payload","latitude","longitude","currentPosition","appPostMessage","action","storeDetailCta","addressContainer","addressContainerMobile","contentFilterStore","applyFilters","storeLocatorFilters","appliedFilters","clearFilters","storeIndications","storeLocatorIndications","storeLocatorHeader","storeListDestinations","routeDestinationPv","routeDestinationPvPos","routeOriginPvPos","destinationStoreDropdown","findRouteButton","storeLocatorDirectionsList","filterBackButton","filter","storeLocatorTypeSwitcher","filterCheckbox","typeRoute","storeCard","typeRouteChecked","selected","noResults","active","appliedFilter","notFound","wmkey","express","pinExpress","market","pinMarket","iper","pinCarrefour","gas","pinGas","applyDateFilter","Object","keys","SINGLE_SELECTORS","$el","querySelector","MULTIPLE_SELECTORS","querySelectorAll","filtersCheckboxes","storeLocatorFiltersSelector","method","e","console","error","woosmapLoadedBound","woosmapLoaded","storeUrl","addEventListener","$on","getCurrentPositionBound","currentPositionSelector","findRouteBound","findRouteButtonSelector","storeLocatorTypeSwitcherSelectors","btn","storeLocatorSwitchBound","typeRouteSelectors","radio","clickTypeRouteCBBound","storeListDestinationsSelector","classList","toggle","routeDestinationPvSelector","focusoutStoreDestinationCBBound","destinationStoreDropdownSelector","customEventBus","on","selectAddressBound","initFilters","loading","mapSelector","Woosmap","WOOSMAP_KEY","MARKERS","storelocatorType","storeList","StoreList","updateStoresBound","filterSelectors","filterBtn","selectFilterBound","checkbox","selectFilterCBBound","clearFiltersCBBound","clearFiltersSelector","preventDefault","currentTarget","CLASSES","triggerFilterAction","updateStoreList","overlayStores","toggleFilterButton","checked","selectFilter","elem","dataset","value","filterValue","input","node","createElement","add","setAttribute","innerHTML","labels","innerText","appliedFiltersSelector","appendChild","removeFilterBound","removeChild","HTMLButtonElement","find","el","contains","HTMLInputElement","$off","selector","parentNode","children","switch","currentListType","infoWindow","close","isGasFilter","contentFilterStoreSelector","clearAllFilters","deselectFiltersCB","clearInsegneFilters","storeLocatorIndicationsSelector","storeLocatorHeaderSelector","activeMarker","storePosition","activeMarkerName","target","storeName","routeDestinationPvPosSelector","JSON","stringify","clearCBFilters","filterBackButtonSelector","dispatchEvent","Event","selectedDates","Date","filters","openingDate","dirty","a","getCurrentPosition","updateStores","isVolantino","URL","searchParams","append","toString","stores","markerCluster","destroy","store","applyFiltersToStore","i","markerType","setStoreMarker","selectMarker","onMarkerHiddenEventBound","filterStoreTypes","emit","endLoading","doSearch","infoWindowListener","setInfoWindow","maxWidth","setContent","infoWindowTpl","iconUrl","storeLogo","detail","storeDetail","indications","qodaCta","urlVolantiniCta","storeVolantiniCta","isStoreSelector","isstoreselector","storeSelectCta","storeSelectEndpoint","csrfToken","csrfTokenName","isvolantino","isvolantini","infoWindowInitBound","open","storeDetailSelector","selectStoreBound","clickIndicationsCBBound","data","details","autocomplete","location","routeOriginPvPosSelector","isMobile","setPosition","setZoom","setMarker","_stores","filterVisibleStores","showStore","addressContainerSelector","calculateDistances","baseUrl","filterStoreList","sortStores","length","servicesTemplate","volantino","volantinichat","isvolantinichat","addressContainerMobileSelector","appendStoreDestinationList","initCardEvents","SELECTORS","card","selectCardBound","id","parseFloat","selectMarkerBound","setCenter","removeListener","storesSorted","sort","b","distanceKm","storeLimits","maxCount","result","distanceSteps","storeIds","Set","firstThree","slice","push","filteredByType","distance","distanceMatrix","s","wmresponse","success","distances","rows","elements","status","getKmFromDistanceText","distanceText","durationText","duration","storeTypes","split","includes","getAttribute","insegna","descrizione","handleStoreCardClick","getPositionObject","relatedTarget","travelMode","STATUS","isTransit","origin","parse","destination","calcTransitRoute","handleTransitResponseBound","calcRoute","handleRouteResponseBound","setTransitRoutes","res","renderTransitRouteResult","renderTransitResult","setRouteDirection","renderRouteResult","renderResult","directionsRenderer","storeLocatorDirectionsListSelector","error_message","start_location","routes","route","stepEl","legs","step","end_address","steps","summary","findRoute","BaseComponent","DEFAULT_GEOLOCATION","DEFAULT_MAP_CONFIG","gestureHandling","minZoom","defaultMarker","$elm","mapConfig","config","geolocation","initWoosmapScript","initMap","visible","getGeolocation","center","getCenter","directionsService","DirectionsService","DirectionsRenderer","transitService","TransitService","transitRenderer","TransitRenderer","content","InfoWindow","eventName","callback","arguments","event","CustomEvent","removeEventListener","setDirections","setRoutes","cb","then","TravelMode","module","exports","anonymous","locals","escapeFn","include","rethrow","err","str","flnm","lineno","esc","lines","start","max","end","filename","context","line","curr","join","path","message","markup","undefined","String","replace","_MATCH_HTML","encode_char","_ENCODE_HTML_RULES","c","__line","__lines","__filename","__output","__append","urlVolantini","pop","msi","ARRAY_TYPES","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","KDBush","ArrayBuffer","Error","magic","versionAndType","version","ArrayType","nodeSize","numItems","isNaN","IndexArrayType","arrayTypeIndex","indexOf","coordsByteSize","BYTES_PER_ELEMENT","idsByteSize","padCoords","ids","coords","_pos","_finished","x","y","numAdded","left","right","axis","m","k","n","z","log","exp","sd","sqrt","newLeft","floor","newRight","t","j","swapItem","minX","minY","maxX","maxY","stack","qx","qy","r","r2","sqDist","swap","arr","tmp","ax","ay","bx","by","dx","dy","defaultOptions","minPoints","extent","generateId","reduce","props","fround","assign","create","trees","stride","clusterProps","time","timerId","p","lngX","latY","Infinity","tree","_createTree","timeEnd","now","_cluster","bbox","minLng","minLat","maxLng","maxLat","easternHem","westernHem","concat","_limitZoom","range","getClusterJSON","clusterId","originId","_getOriginId","originZoom","_getOriginZoom","errorMsg","pow","within","limit","offset","leaves","_appendLeaves","z2","top","bottom","tile","features","_addTileFeatures","expansionZoom","getChildren","cluster_id","skipped","child","finish","isCluster","tags","px","py","getClusterProperties","f","round","nextData","neighborIds","numPointsOrigin","numPoints","neighborId","clusterProperties","wx","wy","clusterPropIndex","numPoints2","_map","clone","original","yLat","count","abbrev","propIndex","point_count_abbreviated","sin","PI","y2","atan"],"mappings":"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","file":"js/component-WoosmapComponent-js.chunks.js","sourcesContent":["'use strict';\n\n/// <reference types=\"woosmap\" />\n/* global woosmap */\n\nimport Supercluster from 'supercluster';\nimport { debounce } from 'underscore';\n\nconst CLUSTERER_ICON = 'https://images.woosmap.com/marker-red.svg';\n\nexport default class WoosmapClusterer {\n  constructor(woosmap, markers, options = {}) {\n    this.woosmap = woosmap;\n    this.map = woosmap.map;\n    this.markers = markers;\n    this.maxZoom = options.maxZoom || 16;\n    this.clustererIcon = options.clustererIcon || CLUSTERER_ICON;\n    this.debounceDelay = options.debounceDelay || 300;\n    this.clusterRadius = options.clusterRadius || 40; // Raggio in pixel per il clustering (default: 40px)\n    this.eventHandler = options.eventHandler || {};\n\n    this.initialize();\n  }\n\n  latLngToSuperclusterFormat(latLng) {\n    return [latLng.lng(), latLng.lat()];\n  }\n\n  createClusterer() {\n    this.cluster = new Supercluster({\n      radius: this.clusterRadius, // Raggio in pixel\n      maxZoom: this.maxZoom // Zoom massimo per il clustering\n    });\n\n    const points = this.markers.map((marker, index) => ({\n      type: 'Feature',\n      properties: { cluster: false, index },\n      geometry: {\n        type: 'Point',\n        coordinates: this.latLngToSuperclusterFormat(marker.position)\n      }\n    }));\n\n    this.cluster.load(points);\n  }\n\n  getClusters() {\n    const zoom = this.map.getZoom();\n    const bounds = this.map.getBounds();\n    const ne = bounds.getNorthEast();\n    const sw = bounds.getSouthWest();\n\n    return this.cluster.getClusters(\n      [sw.lng(), sw.lat(), ne.lng(), ne.lat()],\n      Math.min(zoom, this.maxZoom) // Limita lo zoom massimo\n    );\n  }\n\n  toggleMarker(marker, clusters, map) {\n    const position = marker.getPosition();\n    const isStillVisible = clusters.some((cluster) => {\n      const [lng, lat] = cluster.geometry.coordinates;\n      return position.lat() === lat && position.lng() === lng;\n    });\n\n    if (!isStillVisible) {\n      marker.setMap(null);\n\n      if (this.eventHandler.onMarkerHidden) {\n        debounce(this.eventHandler.onMarkerHidden.call(this, marker), 1000);\n      }\n\n      if (marker.listener) {\n        marker.listener.remove();\n      }\n    } else {\n      map.set(`${position.lat()},${position.lng()}`, marker);\n    }\n  }\n\n  updateMap() {\n    const clusters = this.getClusters();\n    const newActiveMarkers = new Map();\n\n    // Identifica i marker già attivi che dovrebbero rimanere visibili\n    this.activeMarkers.forEach((marker) => this.toggleMarker(marker, clusters, newActiveMarkers));\n\n    // Aggiorna i marker con i nuovi cluster\n    clusters.forEach((cluster) => {\n      const [lng, lat] = cluster.geometry.coordinates;\n      const key = `${lat},${lng}`;\n\n      if (!newActiveMarkers.has(key)) {\n        let marker;\n\n        if (cluster.properties.cluster) {\n          marker = new woosmap.map.Marker({\n            position: new woosmap.map.LatLng(lat, lng),\n            map: this.map,\n            label: {\n              text: `${cluster.properties.point_count}`,\n              color: 'white'\n            },\n            icon: {\n              url: this.clustererIcon,\n              labelOrigin: new window.woosmap.map.Point(16, 16),\n              scaledSize: new window.woosmap.map.Size(33, 45)\n            }\n          });\n\n          const onClickListener = marker.addListener('click', this.zoomToCluster.bind(this, cluster));\n          marker.listener = onClickListener;\n        } else {\n          marker = this.markers[cluster.properties.index];\n          marker.setMap(this.map);\n        }\n\n        newActiveMarkers.set(key, marker);\n      }\n    });\n\n    // Aggiorna la lista dei marker attivi\n    this.activeMarkers = Array.from(newActiveMarkers.values());\n    this.woosmap.dispatch('update_cluterer', { activeMarkers: this.activeMarkers });\n  }\n\n  zoomToCluster(cluster) {\n    const zoom = this.map.getZoom();\n    const [lng, lat] = cluster.geometry.coordinates;\n    const clusterPosition = new woosmap.map.LatLng(lat, lng);\n    const zoomLevel = zoom < this.maxZoom ? zoom + 2 : this.maxZoom;\n\n    this.woosmap.flyTo(clusterPosition, zoomLevel);\n  }\n\n  // Rimuove tutti i marker attivi dalla mappa\n  clearActiveMarkers() {\n    this.activeMarkers.forEach((marker) => {\n      marker.setMap(null);\n\n      if (this.eventHandler.onMarkerHidden) {\n        debounce(this.eventHandler.onMarkerHidden.call(this, marker), 1000);\n      }\n\n      if (marker.listener) {\n        marker.listener.remove();\n      }\n    });\n    this.activeMarkers = [];\n  }\n\n  // Inizializza il clusterer\n  initialize() {\n    this.activeMarkers = [];\n\n    // Inizializza il clusterer con i marker\n    this.createClusterer();\n\n    this.boundsEvent = this.map.addListener(\n      'bounds_changed',\n      debounce(() => this.updateMap(), this.debounceDelay)\n    );\n\n    // Aggiorna la mappa con i cluster iniziali\n    this.updateMap();\n  }\n\n  destroy() {\n    this.clearActiveMarkers();\n    this.boundsEvent.remove();\n  }\n}\n","'use strict';\n\nimport BaseComponent from '../base/baseComponent';\nimport StoreList from '../classes/storeList';\nimport { appPostMessage } from '../utilities/postMessage';\nimport { registerMessageHandler } from '../utilities/postMessageHandler';\nimport infoWindowTpl from 'MICROTEMPLATES/stores/storeInfoWindow.ejs';\nimport WoosmapClusterer from '../classes/woosmap/woosmapClustererClass';\nimport Woosmap from '../classes/woosmap/woosmapClass';\nimport { distanceMatrix, getKmFromDistanceText, getPositionObject, renderRouteResult, renderTransitRouteResult } from '../utilities/woosmapUtils';\n\nimport servicesTemplate from 'MICROTEMPLATES/stores/storeCard.ejs';\nimport customEventBus from '../libs/Eventbus';\n\nconst PIN_SIZE = { height: 45, width: 33.5 };\nconst STORETYPES = {\n  editorial: 'EDITORIAL',\n  store: 'STORE',\n  gas: 'GAS'\n};\nconst CLUSTERER_SETTINGS = {\n  maxZoom: 20,\n  clusterRadius: 100\n};\n\nexport default class WoosmapComponent extends BaseComponent {\n  get SINGLE_SELECTORS() {\n    return {\n      currentPosition: '.iamhere',\n      map: '#woosmap',\n      storeDetailCta: '.store-detail',\n      addressContainer: '.store-list',\n      addressContainerMobile: '.store-list-mobile',\n      contentFilterStore: '.content-filter-store-recap',\n      applyFilters: '#applyFilters',\n      storeLocatorFilters: '.store-locator-filters',\n      appliedFilters: '.applied-filters',\n      clearFilters: '#emptyFilters',\n      storeIndications: '.js-store-indications',\n      storeLocatorIndications: '.store-locator-indications',\n      storeLocatorHeader: '.store-locator-header',\n      storeListDestinations: '.store-list-destinations',\n      routeDestinationPv: '#route-destination-pv',\n      routeDestinationPvPos: '#route-destination-pv-pos',\n      routeOriginPvPos: '#route-origin-pv-pos',\n      destinationStoreDropdown: '.destination-store-dropdown',\n      findRouteButton: '#btn-find-route',\n      storeLocatorDirectionsList: '.store-locator-directions-list',\n      filterBackButton: '.filter-back-button'\n      // filterhome: '.filter-to-home',\n      // brand: '.dts-bar-store-type',\n      // street: '.dts-bar-street',\n      // km: '.dts-bar-km',\n      // spesaOnline: '.volantini-store-card-first',\n      //\n    };\n  }\n\n  get MULTIPLE_SELECTORS() {\n    return {\n      filter: '.filter-type-map',\n      storeLocatorTypeSwitcher: '.item-switch',\n      filterCheckbox: '.filter-checkbox',\n      typeRoute: 'input[type=\"radio\"][name=\"travelby\"]'\n    };\n  }\n\n  // selectors not initialized in class constructor\n  get SELECTORS() {\n    return {\n      storeCard: '.store-card'\n    };\n  }\n\n  get STATUS() {\n    return {\n      typeRouteChecked: 'input[type=\"radio\"][name=\"travelby\"]:checked'\n    };\n  }\n\n  get CLASSES() {\n    return {\n      selected: 'selected',\n      noResults: 'no-results',\n      active: 'active',\n      appliedFilter: 'applied-filter',\n      filterCheckbox: 'filter-checkbox',\n      notFound: 'not-found'\n    };\n  }\n\n  get WOOSMAP_KEY() {\n    return this.$options.wmkey;\n  }\n\n  get MARKERS() {\n    return {\n      express: {\n        url: this.$options.pinExpress,\n        scaledSize: PIN_SIZE\n      },\n      market: {\n        url: this.$options.pinMarket,\n        scaledSize: PIN_SIZE\n      },\n      iper: {\n        url: this.$options.pinCarrefour,\n        scaledSize: PIN_SIZE\n      },\n      gas: {\n        url: this.$options.pinGas,\n        scaledSize: PIN_SIZE\n      }\n    };\n  }\n\n  get Messages() {\n    return {\n      ['storelocator-date-change']: this.applyDateFilter\n    };\n  }\n\n  constructor(element) {\n    super(element);\n\n    this.body = document.body;\n    this.isMobileApp = this.$options.isMobileApp;\n    this.appVersion = this.$options.appVersion;\n    this.storeCity = this.$options.storeCity;\n    this.mobileVersionWithoutGeolocPostMessage = this.isMobileApp && (!this.appVersion || (this.appVersion && parseInt(this.appVersion) < 18));\n\n    this.initSelectors();\n    this.boundFn();\n    this.initComponentEvents();\n\n    if (!this.isMobileApp || this.mobileVersionWithoutGeolocPostMessage) {\n      this.initWoosmap();\n    } else {\n      //Post message handler for Location Requested\n      registerMessageHandler('SEND_LOCATION', (payload) => {\n        const { latitude, longitude } = payload;\n        this.currentPosition = { lat: latitude, lng: longitude };\n        this.initWoosmap();\n      });\n      //Send Location Request to APP\n      appPostMessage({ action: 'REQUEST_LOCATION' });\n    }\n  }\n\n  initSelectors() {\n    Object.keys(this.SINGLE_SELECTORS).forEach((key) => {\n      this[`${key}Selector`] = this.$el.querySelector(this.SINGLE_SELECTORS[key]);\n    });\n\n    Object.keys(this.MULTIPLE_SELECTORS).forEach((key) => {\n      this[`${key}Selectors`] = this.$el.querySelectorAll(this.MULTIPLE_SELECTORS[key]);\n    });\n\n    this.filtersCheckboxes = this.storeLocatorFiltersSelector?.querySelectorAll(this.MULTIPLE_SELECTORS.filterCheckbox);\n  }\n\n  boundFn() {\n    const methodsToBind = [\n      'updateStores',\n      'selectStore',\n      'infoWindowInit',\n      'getCurrentPosition',\n      'selectFilter',\n      'storeLocatorSwitch',\n      'selectFilterCB',\n      'clearFiltersCB',\n      'removeFilter',\n      'clickIndicationsCB',\n      'findRoute',\n      'focusoutStoreDestinationCB',\n      'onMarkerHiddenEvent',\n      'clickTypeRouteCB',\n      'handleTransitResponse',\n      'handleRouteResponse',\n      'selectCard',\n      'selectAddress'\n    ];\n\n    methodsToBind.forEach((method) => {\n      try {\n        this[`${method}Bound`] = this[method].bind(this);\n      } catch (e) {\n        console.error(`${method} function not found, cannot bound`);\n      }\n    });\n\n    // Binding specifico con parametri\n    this.woosmapLoadedBound = this.woosmapLoaded.bind(this, this.$options.storeUrl);\n  }\n\n  initComponentEvents() {\n    // update stores on map when it's loaded\n    document.body.addEventListener('woosmap:mapLoaded', this.woosmapLoadedBound);\n\n    // set current position on map\n    this.$on('click', this.getCurrentPositionBound, this.currentPositionSelector);\n    this.$on('click', this.findRouteBound, this.findRouteButtonSelector);\n\n    this.storeLocatorTypeSwitcherSelectors?.forEach((btn) => this.$on('click', this.storeLocatorSwitchBound, btn));\n    this.typeRouteSelectors?.forEach((radio) => this.$on('click', this.clickTypeRouteCBBound, radio));\n\n    this.$on('click', () => this.storeListDestinationsSelector.classList.toggle('d-none'), this.routeDestinationPvSelector);\n    this.$on('focusout', this.focusoutStoreDestinationCBBound, this.destinationStoreDropdownSelector);\n\n    customEventBus.on('woosmap:select', this.selectAddressBound);\n    this.initFilters();\n  }\n\n  initWoosmap() {\n    //construct Map\n    this.loading(this.mapSelector);\n    this.woosmap = new Woosmap(this.mapSelector, this.WOOSMAP_KEY, { markers: this.MARKERS });\n  }\n\n  woosmapLoaded(storeUrl) {\n    this.map = this.woosmap.map;\n\n    this.storelocatorType = this.$options.storelocatorType || STORETYPES.store;\n    // Aggiorna gli store markers sulla mappa\n    this.storeList = new StoreList(storeUrl, this.storelocatorType, this.updateStoresBound);\n    // this.doSearch(this.woosmap.currentPosition);\n  }\n\n  initFilters() {\n    this.filterSelectors.forEach((filterBtn) => {\n      this.$on('click', this.selectFilterBound, filterBtn);\n    });\n\n    this.filtersCheckboxes?.forEach((checkbox) => {\n      this.$on('change', this.selectFilterCBBound, checkbox);\n    });\n\n    this.$on('click', this.clearFiltersCBBound, this.clearFiltersSelector);\n  }\n\n  selectFilter(e) {\n    e.preventDefault();\n\n    const { currentTarget } = e;\n    currentTarget.classList.toggle(this.CLASSES.selected);\n\n    this.storeList.triggerFilterAction(currentTarget);\n    this.updateStoreList();\n    this.overlayStores({ applyFilters: true });\n  }\n\n  selectFilterCB(e) {\n    const { currentTarget } = e;\n    this.toggleFilterButton(currentTarget.checked, currentTarget);\n    this.selectFilter(e);\n  }\n\n  toggleFilterButton(toggle, elem) {\n    const type = elem.dataset?.filter;\n    const value = elem.dataset?.filterValue;\n    if (toggle) {\n      let input = /** @type {HTMLInputElement} */ (elem);\n      let node = document.createElement('button');\n      node.type = 'button';\n      node.classList.add(this.CLASSES.appliedFilter);\n      node.classList.add(`${this.CLASSES.appliedFilter}-${type}-${value}`);\n      node.classList.add('icon-close');\n      node.setAttribute('data-filter', type);\n      node.setAttribute('data-filter-value', value);\n      node.innerHTML = `${input.labels[0].innerText}`;\n      this.appliedFiltersSelector.appendChild(node);\n\n      this.$on('click', this.removeFilterBound, node);\n    } else {\n      this.appliedFiltersSelector.removeChild(this.appliedFiltersSelector.querySelector(`.${this.CLASSES.appliedFilter}-${type}-${value}`));\n      if (elem instanceof HTMLButtonElement) {\n        let input = [...this.filtersCheckboxes].find((el) => el.classList.contains(`${this.CLASSES.filterCheckbox}-${type}-${value}`));\n        if (input instanceof HTMLInputElement) input.checked = false;\n        this.$off('click', this.removeFilterBound, elem);\n      }\n    }\n  }\n\n  clearInsegneFilters() {\n    this.filterSelectors.forEach((selector) => selector.classList.remove(this.CLASSES.selected));\n  }\n\n  storeLocatorSwitch(e) {\n    const currentTarget = e.currentTarget;\n\n    Array.from(currentTarget.parentNode.children).forEach((el) => el.classList.toggle(this.CLASSES.active));\n\n    const type = currentTarget.dataset.switch;\n\n    if (!type || type === this.currentListType) return;\n\n    if (this.infoWindow) this.infoWindow.close();\n\n    this.currentListType = type;\n    const isGasFilter = type === STORETYPES.gas;\n\n    this.contentFilterStoreSelector.classList.toggle('d-none', isGasFilter);\n\n    this.storeList.clearAllFilters();\n    this.deselectFiltersCB();\n    this.clearInsegneFilters();\n\n    this.storeList.triggerFilterAction(e.currentTarget);\n    this.updateStoreList();\n    this.overlayStores({ applyFilters: true });\n  }\n\n  clickIndicationsCB(e) {\n    this.storeLocatorIndicationsSelector.classList.toggle('d-none', false);\n    this.storeLocatorHeaderSelector.classList.toggle('d-none', true);\n    this.storeLocatorFiltersSelector?.classList.toggle('d-none', true);\n    this.activeMarker = this.infoWindow.storePosition;\n    this.activeMarkerName = e.target.dataset.storeName;\n    this.routeDestinationPvSelector.value = this.activeMarkerName;\n    this.routeDestinationPvPosSelector.value = JSON.stringify(this.activeMarker);\n  }\n\n  deselectFiltersCB() {\n    this.appliedFiltersSelector.innerHTML = '';\n    this.filtersCheckboxes.forEach((filter) => {\n      if (filter instanceof HTMLInputElement) {\n        filter.checked = false;\n      }\n    });\n  }\n\n  clearFiltersCB() {\n    this.storeList.clearCBFilters();\n\n    this.deselectFiltersCB();\n    this.updateStoreList();\n    this.overlayStores({ applyFilters: true });\n\n    this.filterBackButtonSelector.dispatchEvent(new Event('click'));\n  }\n\n  removeFilter(e) {\n    const currentTarget = e.currentTarget;\n    this.storeList.triggerFilterAction(currentTarget);\n    this.toggleFilterButton(false, currentTarget);\n\n    this.updateStoreList();\n    this.overlayStores({ applyFilters: true });\n  }\n\n  /**\n   * @param {Object} payload\n   * @param {Date[]} payload.selectedDates\n   */\n  applyDateFilter({ selectedDates }) {\n    if (!(selectedDates?.[0] instanceof Date)) return;\n    this.storeList.filters.openingDate = selectedDates[0];\n    this.storeList.dirty = true;\n    this.updateStoreList();\n    this.overlayStores({ applyFilters: true });\n  }\n\n  async getCurrentPosition(e) {\n    e.preventDefault();\n    await this.woosmap.getCurrentPosition();\n    await this.updateStores({ applyFilters: true });\n  }\n\n  getNearestStoresUrl(position, type, isVolantino) {\n    const url = new URL(this.$options.url);\n\n    url.searchParams.append('lat', position.lat);\n    url.searchParams.append('long', position.lng);\n\n    switch (type) {\n      case 'express':\n        url.searchParams.append('isExpress', true);\n        break;\n      case 'market':\n        url.searchParams.append('isMarket', true);\n        break;\n      case 'iper':\n        url.searchParams.append('isCarrefour', true);\n        break;\n    }\n\n    if (isVolantino) {\n      url.searchParams.append('isVolantino', true);\n    }\n\n    return url.toString();\n  }\n\n  overlayStores(options = {}) {\n    let stores = this.storeList.stores;\n\n    if (options.applyFilters) {\n      this.markerCluster?.destroy();\n    }\n\n    this.markers = stores\n      .filter((store) => this.storeList.applyFiltersToStore(store))\n      .map((store, i) => {\n        let markerType = this.MARKERS[store.type] || this.MARKERS.iper;\n        let marker = this.setStoreMarker(store.position, markerType);\n        marker.addListener('click', this.selectMarker.bind(this, store, marker));\n\n        return marker;\n      });\n\n    this.markerCluster = new WoosmapClusterer(this.woosmap, this.markers, {\n      ...CLUSTERER_SETTINGS,\n      eventHandler: {\n        onMarkerHidden: this.onMarkerHiddenEventBound\n      }\n    });\n  }\n\n  async updateStores(options = {}) {\n    if (!options.applyFilters) {\n      this.filterStoreTypes();\n    }\n\n    this.overlayStores(options);\n\n    if (this.storeCity) {\n      customEventBus.emit('woosmap:multisearch:autocomplete', { value: this.storeCity });\n      this.endLoading(this.mapSelector);\n      return;\n    }\n\n    const position = this.woosmap.getPosition();\n    const bounds = this.woosmap.getBounds();\n    await this.doSearch(position, bounds);\n\n    this.endLoading(this.mapSelector);\n  }\n\n  onMarkerHiddenEvent(marker) {\n    if (this.infoWindow && this.infoWindow.getPosition() === marker.getPosition()) {\n      this.infoWindow.close();\n    }\n  }\n\n  selectMarker(store, marker) {\n    if (!marker.map) {\n      marker.setMap(this.map);\n    }\n\n    if (this.infoWindow) {\n      // remove listener of previously info window\n      if (this.infoWindowListener) this.infoWindowListener.remove();\n\n      this.infoWindow.close();\n    }\n\n    this.infoWindow = this.woosmap.setInfoWindow({ maxWidth: 320 });\n    this.infoWindow.setContent(\n      infoWindowTpl({\n        store: {\n          ...store,\n          iconUrl: this.$options.storeLogo,\n          detail: this.$options.storeDetail,\n          indications: this.$options.storeIndications,\n          qodaCta: this.$options.qodaCta,\n          urlVolantiniCta: this.$options.storeVolantiniCta,\n          isStoreSelector: this.$options.isstoreselector,\n          storeSelectCta: this.$options.storeSelectCta,\n          storeSelectEndpoint: this.$options.storeSelectEndpoint,\n          csrfToken: this.$options.csrfToken,\n          csrfTokenName: this.$options.csrfTokenName,\n          isvolantino: this.$options.isvolantini\n        }\n      })\n    );\n\n    this.infoWindow.storePosition = { lat: store.latitude, lng: store.longitude };\n    this.infoWindowListener = this.infoWindow.addListener('domready', this.infoWindowInitBound);\n\n    this.infoWindow.open(this.map, marker);\n  }\n\n  infoWindowInit() {\n    const storeDetailSelector = this.$el.querySelector(this.SINGLE_SELECTORS.storeDetailCta);\n    const storeIndications = this.$el.querySelector(this.SINGLE_SELECTORS.storeIndications);\n\n    if (storeDetailSelector) {\n      this.$off('click', this.selectStoreBound, storeDetailSelector);\n      this.$on('click', this.selectStoreBound, storeDetailSelector);\n    }\n\n    if (storeIndications) {\n      this.$off('click', this.clickIndicationsCBBound, storeIndications);\n      this.$on('click', this.clickIndicationsCBBound, storeIndications);\n    }\n  }\n\n  // funzione da estendere\n  selectStore(e) {}\n\n  async selectAddress(data) {\n    const { details, autocomplete } = data;\n    const { geometry } = details;\n\n    if (!geometry) {\n      console.error(`geometry not found in details`);\n      return;\n    }\n\n    const { location } = geometry;\n\n    if (autocomplete === 'directions') {\n      this.routeOriginPvPosSelector.value = JSON.stringify(location);\n      return;\n    } // break search on map\n\n    const isMobile = window.isMobile();\n    const zoom = isMobile ? 10 : null;\n\n    const bounds = this.woosmap\n      .setPosition(location)\n      .setZoom(zoom)\n      .getBounds();\n\n    this.storeList.dirty = true;\n    await this.doSearch(location, bounds);\n\n    if (isMobile) {\n      this.woosmap.flyTo(location, 12);\n    }\n  }\n\n  setStoreMarker(position, icon) {\n    return this.woosmap.setMarker({ position, icon });\n  }\n\n  async doSearch(position, bounds) {\n    // const nearestURL = this.getNearestStoresUrl(position);\n    // this.storeSearch = new StoreList(nearestURL, this.storelocatorType, this.showStore.bind(this, position));\n    this._stores = this.storeList.stores.filter((store) => this.storeList.filterVisibleStores(store, bounds));\n    await this.showStore(position);\n  }\n\n  async showStore(position) {\n    this.addressContainerSelector.classList.add('d-none');\n    this.$el.classList.add('open');\n    this._stores = await this.calculateDistances(position, this._stores);\n    this.updateStoreList();\n    this.addressContainerSelector.classList.remove('d-none');\n  }\n\n  updateStoreList(stores) {\n    stores = stores || this._stores;\n\n    if (!stores) {\n      return;\n    }\n\n    const baseUrl = this.$options.baseUrl + '?storeId=';\n\n    stores = this.filterStoreList(stores);\n    stores = this.sortStores(stores);\n\n    if (stores.length) {\n      this.addressContainerSelector.classList.remove(this.CLASSES.noResults);\n      this.addressContainerSelector.innerHTML = servicesTemplate({ stores, baseUrl: baseUrl, volantino: this.$options.isvolantini, volantinichat: this.$options.isvolantinichat });\n    } else {\n      this.addressContainerSelector.classList.add(this.CLASSES.noResults);\n      this.addressContainerSelector.innerHTML = `<p>${this.$options.noResults}</p>`;\n    }\n\n    this.addressContainerMobileSelector.innerHTML = this.addressContainerSelector.innerHTML;\n\n    this.appendStoreDestinationList(stores);\n    this.initCardEvents();\n    return stores;\n  }\n\n  initCardEvents() {\n    const cards = this.$el.querySelectorAll(this.SELECTORS.storeCard);\n    cards.forEach((card) => {\n      this.$off('click', this.selectCardBound, card);\n      this.$on('click', this.selectCardBound, card);\n    });\n  }\n\n  selectCard(e) {\n    if (this.$options.isvolantinichat) {\n      return;\n    }\n\n    e.preventDefault();\n\n    let { lat, lng, id } = e.currentTarget.dataset;\n\n    lat = parseFloat(lat);\n    lng = parseFloat(lng);\n\n    const store = this.storeList.stores.find((store) => store.id?.toString() === id);\n\n    if (!store) {\n      console.error(`store ${id} not found`);\n      return;\n    }\n\n    const marker = this.markers.find((marker) => marker.getPosition().lat() === lat && marker.getPosition().lng() === lng);\n\n    if (!marker) {\n      console.error(`marker for store ${id} not found`);\n    }\n\n    const selectMarkerBound = this.selectMarker.bind(this, store, marker);\n\n    this.woosmap.addListener('update_cluterer', selectMarkerBound); // seleziona il market dopo l'update\n\n    this.map.setCenter({ lat, lng });\n    this.map.setZoom(16);\n\n    this.woosmap.removeListener('update_cluterer', selectMarkerBound);\n  }\n\n  filterStoreList(stores) {\n    return stores.filter((store) => this.storeList.applyFiltersToStore(store));\n  }\n\n  sortStores(stores) {\n    let storesSorted = stores.sort((a, b) => a.distanceKm - b.distanceKm);\n\n    // Regole per il numero massimo di risultati per tipo\n    const storeLimits = {\n      market: { maxCount: 10 },\n      iper: { maxCount: 3 },\n      express: { maxCount: 20 },\n      gas: { maxCount: 3 }\n    };\n\n    const result = [];\n\n    // Step progressivi di distanza\n    const distanceSteps = {\n      market: [30],\n      iper: [20],\n      express: [20],\n      gas: [15, 25, 35]\n    };\n\n    const storeIds = new Set(result.map((store) => store.id));\n\n    if (storesSorted.length > 3) {\n      const firstThree = storesSorted.slice(0, 3);\n      result.push(...firstThree);\n    }\n\n    Object.keys(storeLimits).forEach((type) => {\n      let filteredByType = [];\n\n      // cerca i negozi per range di distanza\n      for (let distance of distanceSteps[type]) {\n        // se ha trovato almeno uno store interrompe lo step di ricerca per distanza\n        if (filteredByType.length) break;\n\n        storesSorted = storesSorted.length > 3 ? storesSorted.slice(3) : storesSorted;\n        filteredByType = storesSorted\n          .filter((store) => store.type === type && store.distanceKm <= distance)\n          .filter((store) => !storeIds.has(store.id))\n          .slice(0, storeLimits[type].maxCount);\n      }\n\n      result.push(...filteredByType);\n    });\n\n    return result;\n  }\n\n  /**\n   *\n   * @param {{lat: number, lng: number}} position\n   * @param {Store[]} storeList\n   * @returns {Store[]}\n   */\n  async calculateDistances(position, storeList) {\n    if (!storeList.length) {\n      return storeList;\n    }\n\n    const wmresponse = await distanceMatrix(\n      position,\n      storeList.map((s) => {\n        return {\n          lat: s.latitude,\n          lng: s.longitude\n        };\n      }),\n      this.$options.wmkey\n    );\n\n    // fix error on distances if response is not success, return storeList as fallback\n    if (!wmresponse.success) {\n      return storeList;\n    }\n\n    let distances = wmresponse.rows?.[0]?.elements;\n\n    if (!distances) {\n      return [];\n    }\n\n    return storeList\n      .filter((s, i) => distances[i])\n      .map((s, i) => {\n        s.distanceKm = distances[i].status === 'OK' ? getKmFromDistanceText(distances[i].distance.text) : 9999;\n        s.distanceText = distances[i].status === 'OK' ? distances[i].distance.text : '';\n        s.durationText = distances[i].status === 'OK' ? distances[i].duration.text : '';\n        return s;\n      });\n  }\n\n  filterStoreTypes() {\n    if (this.$options.storeTypes) {\n      let storeTypes = this.$options.storeTypes.split('-');\n      this.filterSelectors.forEach((filterBtn) => {\n        if (storeTypes.includes(filterBtn.getAttribute('data-filter-value'))) {\n          filterBtn.classList.toggle(this.CLASSES.selected);\n          this.storeList.triggerFilterAction(filterBtn);\n        }\n      });\n    }\n  }\n\n  appendStoreDestinationList(stores) {\n    if (!this.storeListDestinationsSelector) return;\n\n    this.storeListDestinationsSelector.innerHTML = '';\n\n    for (let i = 0; stores.length > i; i++) {\n      let store = stores[i];\n\n      let storeCard = document.createElement('div');\n      storeCard.setAttribute('data-lat', store.latitude);\n      storeCard.setAttribute('tabindex', '0');\n      storeCard.setAttribute('data-lng', store.longitude);\n      storeCard.setAttribute('data-insegna', store.insegna);\n      storeCard.setAttribute('data-descrizione', store.descrizione);\n      storeCard.classList.add('destination-store');\n      storeCard.innerHTML = `${store.insegna}, ${store.descrizione}`;\n      this.storeListDestinationsSelector.append(storeCard);\n\n      this.$off('click', this.handleStoreCardClick.bind(this, store), storeCard);\n      this.$on('click', this.handleStoreCardClick.bind(this, store), storeCard);\n    }\n  }\n\n  handleStoreCardClick(store) {\n    this.routeDestinationPvSelector.value = `${store.insegna}, ${store.descrizione}`;\n    this.routeDestinationPvPosSelector.value = JSON.stringify(getPositionObject(store.position));\n    this.activeMarker = store.position;\n    this.activeMarkerName = `${store.insegna}, ${store.descrizione}`;\n    this.storeListDestinationsSelector.classList.toggle('d-none');\n  }\n\n  focusoutStoreDestinationCB(e) {\n    if (e.currentTarget.contains(e.relatedTarget)) return;\n    this.storeListDestinationsSelector.classList.toggle('d-none', true);\n  }\n\n  findRoute(options = {}) {\n    let payload;\n    const travelMode = options.travelMode || this.$el.querySelector(this.STATUS.typeRouteChecked)?.value;\n    const isTransit = travelMode === 'TRANSIT';\n    try {\n      payload = {\n        origin: JSON.parse(this.routeOriginPvPosSelector.value),\n        destination: JSON.parse(this.routeDestinationPvPosSelector.value),\n        details: 'full',\n        travelMode\n      };\n    } catch (e) {\n      // console.warn(e);\n    }\n\n    if (!payload) return;\n\n    if (isTransit) {\n      delete payload.details;\n      delete payload.travelMode;\n\n      // payload.modes = ['bus'];\n\n      this.woosmap.calcTransitRoute(payload, this.handleTransitResponseBound);\n      return;\n    }\n\n    this.woosmap.calcRoute(payload, this.handleRouteResponseBound);\n  }\n\n  handleTransitResponse(result, status) {\n    // if (status === 'OK') {\n    this.woosmap.setTransitRoutes(result);\n    const res = renderTransitRouteResult(result);\n    this.renderTransitResult(res);\n  }\n\n  handleRouteResponse(result, status) {\n    if (status === 'OK') {\n      this.woosmap.setRouteDirection(result);\n      const res = renderRouteResult(result);\n      this.renderResult(res);\n    } else {\n      this.woosmap.directionsRenderer.setMap(null);\n      this.storeLocatorDirectionsListSelector.innerHTML = `<li>${result.error_message}</li>`;\n      console.error('Directions request failed with status :' + status);\n    }\n  }\n\n  renderTransitResult(res) {\n    this.storeLocatorDirectionsListSelector.innerHTML = '';\n\n    const { start_location, routes } = res;\n\n    this.woosmap.setPosition(start_location);\n\n    routes.forEach((route) => {\n      let stepEl = document.createElement('li');\n      stepEl.innerHTML = `<p>Durata: ${route.duration}</p>`;\n      this.storeLocatorDirectionsListSelector.append(stepEl);\n\n      route.legs.forEach((step) => {\n        stepEl = document.createElement('li');\n        stepEl.innerHTML = `${step}`;\n        this.storeLocatorDirectionsListSelector.append(stepEl);\n      });\n    });\n  }\n\n  renderResult(res) {\n    this.storeLocatorDirectionsListSelector.innerHTML = '';\n\n    this.woosmap.setPosition(res.start_location);\n\n    let stepEl = document.createElement('li');\n    stepEl.innerHTML = `<p>${res.end_address}</p>`;\n    stepEl.innerHTML += `<p>Distanza: ${res.distance}</p>`;\n    stepEl.innerHTML += `<p>Durata: ${res.duration}</p>`;\n    this.storeLocatorDirectionsListSelector.append(stepEl);\n    res.steps.forEach((step) => {\n      stepEl = document.createElement('li');\n      stepEl.innerHTML = `${step.summary}`;\n      this.storeLocatorDirectionsListSelector.append(stepEl);\n    });\n  }\n\n  clickTypeRouteCB(e) {\n    this.findRoute({ travelMode: e.target.value });\n  }\n}\n","'use strict';\n\n/// <reference types=\"woosmap\" />\n/* global woosmap */\n\nimport { geolocation, initWoosmapScript } from '../../utilities/woosmapUtils';\n\nconst DEFAULT_GEOLOCATION = { lat: 45.5718999, lng: 9.1483656 }; // Paderno Dugnano\nconst PIN_SIZE = { height: 50, width: 32 };\nconst DEFAULT_MAP_CONFIG = {\n  gestureHandling: 'cooperative',\n  minZoom: 9,\n  zoom: 12\n};\nconst MARKERS = {\n  defaultMarker: {\n    url: 'https://images.woosmap.com/marker.png',\n    scaledSize: PIN_SIZE\n  }\n};\n\nexport default class Woosmap {\n  constructor($elm, wmkey, options = {}) {\n    this.mapConfig = { ...DEFAULT_MAP_CONFIG, ...options.config };\n    this.markers = { ...MARKERS, ...options.markers };\n    this.geolocation = typeof options.geolocation == 'undefined' ? true : options.geolocation;\n    this.wmkey = wmkey;\n    this.$elm = $elm;\n\n    initWoosmapScript(wmkey);\n\n    this.initMap();\n  }\n\n  initMap() {\n    document.body.addEventListener('woosmap:loaded', this.woosmapLoaded.bind(this));\n  }\n\n  async getGeolocation() {\n    const res = await geolocation(this.wmkey);\n\n    if (res && res.success) {\n      this.currentPosition = { lat: res.latitude, lng: res.longitude };\n    } else {\n      this.currentPosition = DEFAULT_GEOLOCATION; //Default position: Paderno Dugnano\n    }\n  }\n\n  setMarker({ position, icon, visible }) {\n    const marker = new woosmap.map.Marker({\n      position,\n      icon: icon || this.markers.defaultMarker,\n      visible\n    });\n\n    if (visible) {\n      marker.setMap(this.map);\n    }\n\n    return marker;\n  }\n\n  async getCurrentPosition() {\n    await this.getGeolocation();\n    this.setPosition(this.currentPosition);\n  }\n\n  // set current position marker\n  setPosition(position) {\n    if (this.defaultMarker) {\n      this.defaultMarker.setMap(null);\n    }\n\n    this.defaultMarker = this.setMarker({\n      position,\n      visible: true\n    });\n\n    this.map.setCenter(position);\n    return this;\n  }\n\n  getPosition() {\n    const center = this.map.getCenter();\n    return { lat: center.lat(), lng: center.lng() };\n  }\n\n  async woosmapLoaded() {\n    //construct Map\n    this.map = new woosmap.map.Map(this.$elm, this.mapConfig);\n    this.directionsService = new woosmap.map.DirectionsService();\n    this.directionsRenderer = new woosmap.map.DirectionsRenderer();\n\n    this.transitService = new woosmap.map.TransitService();\n    this.transitRenderer = new woosmap.map.TransitRenderer();\n\n    if (this.geolocation) {\n      await this.getCurrentPosition();\n    } else {\n      this.setPosition(this.mapConfig.center);\n    }\n\n    document.body.dispatchEvent(new Event('woosmap:mapLoaded'));\n  }\n\n  setInfoWindow(content, options = {}) {\n    return new woosmap.map.InfoWindow({ content, ...options });\n  }\n\n  getBounds() {\n    return this.map.getBounds();\n  }\n\n  flyTo(center, zoom) {\n    return this.map.flyTo({ center, zoom });\n  }\n\n  addListener(eventName, callback) {\n    this.$elm.addEventListener(eventName, callback.call(this, arguments));\n  }\n\n  dispatch(eventName, detail) {\n    const event = new CustomEvent(eventName, { detail });\n    this.$elm.dispatchEvent(event);\n  }\n\n  removeListener(eventName, callback) {\n    this.$elm.removeEventListener(eventName, callback);\n  }\n\n  setZoom(zoom) {\n    this.map.setZoom(zoom || DEFAULT_MAP_CONFIG.zoom);\n    return this;\n  }\n\n  setRouteDirection(result) {\n    this.directionsRenderer.setDirections(result);\n  }\n\n  setTransitRoutes(result) {\n    this.transitRenderer.setRoutes(result.routes);\n  }\n\n  calcTransitRoute(payload, cb) {\n    this.directionsRenderer.setMap(null);\n\n    this.transitRenderer.setMap(this.map);\n    this.transitService.route(payload).then(cb);\n  }\n\n  calcRoute(payload, cb) {\n    this.transitRenderer.setMap(null);\n\n    payload.travelMode = woosmap.map.TravelMode[payload.travelMode];\n\n    this.directionsRenderer.setMap(this.map);\n    this.directionsService.route(payload, cb);\n  }\n}\n","module.exports = function anonymous(locals, escapeFn, include, rethrow) {\n    rethrow = rethrow || function rethrow(err, str, flnm, lineno, esc) {\n        var lines = str.split(\"\\n\");\n        var start = Math.max(lineno - 3, 0);\n        var end = Math.min(lines.length, lineno + 3);\n        var filename = esc(flnm);\n        var context = lines.slice(start, end).map(function(line, i) {\n            var curr = i + start + 1;\n            return (curr == lineno ? \" >> \" : \"    \") + curr + \"| \" + line;\n        }).join(\"\\n\");\n        err.path = filename;\n        err.message = (filename || \"ejs\") + \":\" + lineno + \"\\n\" + context + \"\\n\\n\" + err.message;\n        throw err;\n    };\n    escapeFn = escapeFn || function(markup) {\n        return markup == undefined ? \"\" : String(markup).replace(_MATCH_HTML, encode_char);\n    };\n    var _ENCODE_HTML_RULES = {\n        \"&\": \"&amp;\",\n        \"<\": \"&lt;\",\n        \">\": \"&gt;\",\n        '\"': \"&#34;\",\n        \"'\": \"&#39;\"\n    }, _MATCH_HTML = /[&<>'\"]/g;\n    function encode_char(c) {\n        return _ENCODE_HTML_RULES[c] || c;\n    }\n    var __line = 1, __lines = '<% stores.forEach(function(store){ %>\\n  <% if(volantinichat) { %>\\n    <a href=\"https://wa.me/393666527541?text=Invia%20questo%20messaggio%20e%20ricevi%20subito%20il%20volantino%20%5B<%= store.urlVolantini.split(\\'/\\').pop() %>%5D%20<%= store.insegna %>%20<%=store.descrizione%>\"\\n      class=\"volantini-store-card store-card <%= store.type %> <%= store.type === \\'gas\\' ? store.insegna : \\'\\' %> \"\\n    >\\n      <p class=\"store-details\">\\n          <p class=\"brand-store store-name\" data-id=\"<%= store.id %>\"><%= store.insegna %></p>\\n          <p class=\"address store-address\"><%= store.descrizione %></p>\\n          <p class=\"distance store-distance\"><%= store.distanceText %> <% if (store.durationText) { %>(<%= store.durationText %>)<% } %></p>\\n      </p>\\n      <div class=\"store-chat-url\">\\n        Ricevi su Whatsapp\\n        <i class=\"icon-icon-whatsapp\"></i>\\n      </div>\\n    </a>\\n  <% } else { %>\\n    <a href=\"<%= volantino ? store.urlVolantini : store.url %>\"\\n        class=\"volantini-store-card store-card <%= store.type %> <%= store.type === \\'gas\\' ? store.insegna : \\'\\' %>\"\\n        data-option-url=\"<%= store.urlVolantini %>\"\\n        data-option-brand=\"<%= store.type %>\"\\n        data-option-msi=\"<%= store.msi %>\"\\n        data-option-distance=\"<%= store.distanceText %>\"\\n        data-id=\"<%= store.id %>\"\\n        data-lat=\"<%= store.latitude %>\"\\n        data-lng=\"<%= store.longitude %>\"\\n    >\\n      <p class=\"store-details\">\\n          <p class=\"brand-store store-name\" data-id=\"<%= store.id %>\"><%= store.insegna %></p>\\n          <p class=\"address store-address\"><%= store.descrizione %></p>\\n          <p class=\"distance store-distance\"><%= store.distanceText %> <% if (store.durationText) { %>(<%= store.durationText %>)<% } %></p>\\n      </p>\\n    </a>\\n  <% } %>\\n<% }); %>\\n', __filename = \"src/microtemplates/stores/storeCard.ejs\";\n    try {\n        var __output = \"\";\n        function __append(s) {\n            if (s !== undefined && s !== null) __output += s;\n        }\n        with (locals || {}) {\n            stores.forEach(function(store) {\n                __append(\"\\n  \");\n                __line = 2;\n                if (volantinichat) {\n                    __append('\\n    <a href=\"https://wa.me/393666527541?text=Invia%20questo%20messaggio%20e%20ricevi%20subito%20il%20volantino%20%5B');\n                    __line = 3;\n                    __append(escapeFn(store.urlVolantini.split(\"/\").pop()));\n                    __append(\"%5D%20\");\n                    __append(escapeFn(store.insegna));\n                    __append(\"%20\");\n                    __append(escapeFn(store.descrizione));\n                    __append('\"\\n      class=\"volantini-store-card store-card ');\n                    __line = 4;\n                    __append(escapeFn(store.type));\n                    __append(\" \");\n                    __append(escapeFn(store.type === \"gas\" ? store.insegna : \"\"));\n                    __append(' \"\\n    >\\n      <p class=\"store-details\">\\n          <p class=\"brand-store store-name\" data-id=\"');\n                    __line = 7;\n                    __append(escapeFn(store.id));\n                    __append('\">');\n                    __append(escapeFn(store.insegna));\n                    __append('</p>\\n          <p class=\"address store-address\">');\n                    __line = 8;\n                    __append(escapeFn(store.descrizione));\n                    __append('</p>\\n          <p class=\"distance store-distance\">');\n                    __line = 9;\n                    __append(escapeFn(store.distanceText));\n                    __append(\" \");\n                    if (store.durationText) {\n                        __append(\"(\");\n                        __append(escapeFn(store.durationText));\n                        __append(\")\");\n                    }\n                    __append('</p>\\n      </p>\\n      <div class=\"store-chat-url\">\\n        Ricevi su Whatsapp\\n        <i class=\"icon-icon-whatsapp\"></i>\\n      </div>\\n    </a>\\n  ');\n                    __line = 16;\n                } else {\n                    __append('\\n    <a href=\"');\n                    __line = 17;\n                    __append(escapeFn(volantino ? store.urlVolantini : store.url));\n                    __append('\"\\n        class=\"volantini-store-card store-card ');\n                    __line = 18;\n                    __append(escapeFn(store.type));\n                    __append(\" \");\n                    __append(escapeFn(store.type === \"gas\" ? store.insegna : \"\"));\n                    __append('\"\\n        data-option-url=\"');\n                    __line = 19;\n                    __append(escapeFn(store.urlVolantini));\n                    __append('\"\\n        data-option-brand=\"');\n                    __line = 20;\n                    __append(escapeFn(store.type));\n                    __append('\"\\n        data-option-msi=\"');\n                    __line = 21;\n                    __append(escapeFn(store.msi));\n                    __append('\"\\n        data-option-distance=\"');\n                    __line = 22;\n                    __append(escapeFn(store.distanceText));\n                    __append('\"\\n        data-id=\"');\n                    __line = 23;\n                    __append(escapeFn(store.id));\n                    __append('\"\\n        data-lat=\"');\n                    __line = 24;\n                    __append(escapeFn(store.latitude));\n                    __append('\"\\n        data-lng=\"');\n                    __line = 25;\n                    __append(escapeFn(store.longitude));\n                    __append('\"\\n    >\\n      <p class=\"store-details\">\\n          <p class=\"brand-store store-name\" data-id=\"');\n                    __line = 28;\n                    __append(escapeFn(store.id));\n                    __append('\">');\n                    __append(escapeFn(store.insegna));\n                    __append('</p>\\n          <p class=\"address store-address\">');\n                    __line = 29;\n                    __append(escapeFn(store.descrizione));\n                    __append('</p>\\n          <p class=\"distance store-distance\">');\n                    __line = 30;\n                    __append(escapeFn(store.distanceText));\n                    __append(\" \");\n                    if (store.durationText) {\n                        __append(\"(\");\n                        __append(escapeFn(store.durationText));\n                        __append(\")\");\n                    }\n                    __append(\"</p>\\n      </p>\\n    </a>\\n  \");\n                    __line = 33;\n                }\n                __append(\"\\n\");\n                __line = 34;\n            });\n            __append(\"\\n\");\n            __line = 35;\n        }\n        return __output;\n    } catch (e) {\n        rethrow(e, __lines, __filename, __line, escapeFn);\n    }\n}","\nconst ARRAY_TYPES = [\n    Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array,\n    Int32Array, Uint32Array, Float32Array, Float64Array\n];\n\n/** @typedef {Int8ArrayConstructor | Uint8ArrayConstructor | Uint8ClampedArrayConstructor | Int16ArrayConstructor | Uint16ArrayConstructor | Int32ArrayConstructor | Uint32ArrayConstructor | Float32ArrayConstructor | Float64ArrayConstructor} TypedArrayConstructor */\n\nconst VERSION = 1; // serialized format version\nconst HEADER_SIZE = 8;\n\nexport default class KDBush {\n\n    /**\n     * Creates an index from raw `ArrayBuffer` data.\n     * @param {ArrayBuffer} data\n     */\n    static from(data) {\n        if (!(data instanceof ArrayBuffer)) {\n            throw new Error('Data must be an instance of ArrayBuffer.');\n        }\n        const [magic, versionAndType] = new Uint8Array(data, 0, 2);\n        if (magic !== 0xdb) {\n            throw new Error('Data does not appear to be in a KDBush format.');\n        }\n        const version = versionAndType >> 4;\n        if (version !== VERSION) {\n            throw new Error(`Got v${version} data when expected v${VERSION}.`);\n        }\n        const ArrayType = ARRAY_TYPES[versionAndType & 0x0f];\n        if (!ArrayType) {\n            throw new Error('Unrecognized array type.');\n        }\n        const [nodeSize] = new Uint16Array(data, 2, 1);\n        const [numItems] = new Uint32Array(data, 4, 1);\n\n        return new KDBush(numItems, nodeSize, ArrayType, data);\n    }\n\n    /**\n     * Creates an index that will hold a given number of items.\n     * @param {number} numItems\n     * @param {number} [nodeSize=64] Size of the KD-tree node (64 by default).\n     * @param {TypedArrayConstructor} [ArrayType=Float64Array] The array type used for coordinates storage (`Float64Array` by default).\n     * @param {ArrayBuffer} [data] (For internal use only)\n     */\n    constructor(numItems, nodeSize = 64, ArrayType = Float64Array, data) {\n        if (isNaN(numItems) || numItems < 0) throw new Error(`Unpexpected numItems value: ${numItems}.`);\n\n        this.numItems = +numItems;\n        this.nodeSize = Math.min(Math.max(+nodeSize, 2), 65535);\n        this.ArrayType = ArrayType;\n        this.IndexArrayType = numItems < 65536 ? Uint16Array : Uint32Array;\n\n        const arrayTypeIndex = ARRAY_TYPES.indexOf(this.ArrayType);\n        const coordsByteSize = numItems * 2 * this.ArrayType.BYTES_PER_ELEMENT;\n        const idsByteSize = numItems * this.IndexArrayType.BYTES_PER_ELEMENT;\n        const padCoords = (8 - idsByteSize % 8) % 8;\n\n        if (arrayTypeIndex < 0) {\n            throw new Error(`Unexpected typed array class: ${ArrayType}.`);\n        }\n\n        if (data && (data instanceof ArrayBuffer)) { // reconstruct an index from a buffer\n            this.data = data;\n            this.ids = new this.IndexArrayType(this.data, HEADER_SIZE, numItems);\n            this.coords = new this.ArrayType(this.data, HEADER_SIZE + idsByteSize + padCoords, numItems * 2);\n            this._pos = numItems * 2;\n            this._finished = true;\n        } else { // initialize a new index\n            this.data = new ArrayBuffer(HEADER_SIZE + coordsByteSize + idsByteSize + padCoords);\n            this.ids = new this.IndexArrayType(this.data, HEADER_SIZE, numItems);\n            this.coords = new this.ArrayType(this.data, HEADER_SIZE + idsByteSize + padCoords, numItems * 2);\n            this._pos = 0;\n            this._finished = false;\n\n            // set header\n            new Uint8Array(this.data, 0, 2).set([0xdb, (VERSION << 4) + arrayTypeIndex]);\n            new Uint16Array(this.data, 2, 1)[0] = nodeSize;\n            new Uint32Array(this.data, 4, 1)[0] = numItems;\n        }\n    }\n\n    /**\n     * Add a point to the index.\n     * @param {number} x\n     * @param {number} y\n     * @returns {number} An incremental index associated with the added item (starting from `0`).\n     */\n    add(x, y) {\n        const index = this._pos >> 1;\n        this.ids[index] = index;\n        this.coords[this._pos++] = x;\n        this.coords[this._pos++] = y;\n        return index;\n    }\n\n    /**\n     * Perform indexing of the added points.\n     */\n    finish() {\n        const numAdded = this._pos >> 1;\n        if (numAdded !== this.numItems) {\n            throw new Error(`Added ${numAdded} items when expected ${this.numItems}.`);\n        }\n        // kd-sort both arrays for efficient search\n        sort(this.ids, this.coords, this.nodeSize, 0, this.numItems - 1, 0);\n\n        this._finished = true;\n        return this;\n    }\n\n    /**\n     * Search the index for items within a given bounding box.\n     * @param {number} minX\n     * @param {number} minY\n     * @param {number} maxX\n     * @param {number} maxY\n     * @returns {number[]} An array of indices correponding to the found items.\n     */\n    range(minX, minY, maxX, maxY) {\n        if (!this._finished) throw new Error('Data not yet indexed - call index.finish().');\n\n        const {ids, coords, nodeSize} = this;\n        const stack = [0, ids.length - 1, 0];\n        const result = [];\n\n        // recursively search for items in range in the kd-sorted arrays\n        while (stack.length) {\n            const axis = stack.pop() || 0;\n            const right = stack.pop() || 0;\n            const left = stack.pop() || 0;\n\n            // if we reached \"tree node\", search linearly\n            if (right - left <= nodeSize) {\n                for (let i = left; i <= right; i++) {\n                    const x = coords[2 * i];\n                    const y = coords[2 * i + 1];\n                    if (x >= minX && x <= maxX && y >= minY && y <= maxY) result.push(ids[i]);\n                }\n                continue;\n            }\n\n            // otherwise find the middle index\n            const m = (left + right) >> 1;\n\n            // include the middle item if it's in range\n            const x = coords[2 * m];\n            const y = coords[2 * m + 1];\n            if (x >= minX && x <= maxX && y >= minY && y <= maxY) result.push(ids[m]);\n\n            // queue search in halves that intersect the query\n            if (axis === 0 ? minX <= x : minY <= y) {\n                stack.push(left);\n                stack.push(m - 1);\n                stack.push(1 - axis);\n            }\n            if (axis === 0 ? maxX >= x : maxY >= y) {\n                stack.push(m + 1);\n                stack.push(right);\n                stack.push(1 - axis);\n            }\n        }\n\n        return result;\n    }\n\n    /**\n     * Search the index for items within a given radius.\n     * @param {number} qx\n     * @param {number} qy\n     * @param {number} r Query radius.\n     * @returns {number[]} An array of indices correponding to the found items.\n     */\n    within(qx, qy, r) {\n        if (!this._finished) throw new Error('Data not yet indexed - call index.finish().');\n\n        const {ids, coords, nodeSize} = this;\n        const stack = [0, ids.length - 1, 0];\n        const result = [];\n        const r2 = r * r;\n\n        // recursively search for items within radius in the kd-sorted arrays\n        while (stack.length) {\n            const axis = stack.pop() || 0;\n            const right = stack.pop() || 0;\n            const left = stack.pop() || 0;\n\n            // if we reached \"tree node\", search linearly\n            if (right - left <= nodeSize) {\n                for (let i = left; i <= right; i++) {\n                    if (sqDist(coords[2 * i], coords[2 * i + 1], qx, qy) <= r2) result.push(ids[i]);\n                }\n                continue;\n            }\n\n            // otherwise find the middle index\n            const m = (left + right) >> 1;\n\n            // include the middle item if it's in range\n            const x = coords[2 * m];\n            const y = coords[2 * m + 1];\n            if (sqDist(x, y, qx, qy) <= r2) result.push(ids[m]);\n\n            // queue search in halves that intersect the query\n            if (axis === 0 ? qx - r <= x : qy - r <= y) {\n                stack.push(left);\n                stack.push(m - 1);\n                stack.push(1 - axis);\n            }\n            if (axis === 0 ? qx + r >= x : qy + r >= y) {\n                stack.push(m + 1);\n                stack.push(right);\n                stack.push(1 - axis);\n            }\n        }\n\n        return result;\n    }\n}\n\n/**\n * @param {Uint16Array | Uint32Array} ids\n * @param {InstanceType<TypedArrayConstructor>} coords\n * @param {number} nodeSize\n * @param {number} left\n * @param {number} right\n * @param {number} axis\n */\nfunction sort(ids, coords, nodeSize, left, right, axis) {\n    if (right - left <= nodeSize) return;\n\n    const m = (left + right) >> 1; // middle index\n\n    // sort ids and coords around the middle index so that the halves lie\n    // either left/right or top/bottom correspondingly (taking turns)\n    select(ids, coords, m, left, right, axis);\n\n    // recursively kd-sort first half and second half on the opposite axis\n    sort(ids, coords, nodeSize, left, m - 1, 1 - axis);\n    sort(ids, coords, nodeSize, m + 1, right, 1 - axis);\n}\n\n/**\n * Custom Floyd-Rivest selection algorithm: sort ids and coords so that\n * [left..k-1] items are smaller than k-th item (on either x or y axis)\n * @param {Uint16Array | Uint32Array} ids\n * @param {InstanceType<TypedArrayConstructor>} coords\n * @param {number} k\n * @param {number} left\n * @param {number} right\n * @param {number} axis\n */\nfunction select(ids, coords, k, left, right, axis) {\n\n    while (right > left) {\n        if (right - left > 600) {\n            const n = right - left + 1;\n            const m = k - left + 1;\n            const z = Math.log(n);\n            const s = 0.5 * Math.exp(2 * z / 3);\n            const sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);\n            const newLeft = Math.max(left, Math.floor(k - m * s / n + sd));\n            const newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));\n            select(ids, coords, k, newLeft, newRight, axis);\n        }\n\n        const t = coords[2 * k + axis];\n        let i = left;\n        let j = right;\n\n        swapItem(ids, coords, left, k);\n        if (coords[2 * right + axis] > t) swapItem(ids, coords, left, right);\n\n        while (i < j) {\n            swapItem(ids, coords, i, j);\n            i++;\n            j--;\n            while (coords[2 * i + axis] < t) i++;\n            while (coords[2 * j + axis] > t) j--;\n        }\n\n        if (coords[2 * left + axis] === t) swapItem(ids, coords, left, j);\n        else {\n            j++;\n            swapItem(ids, coords, j, right);\n        }\n\n        if (j <= k) left = j + 1;\n        if (k <= j) right = j - 1;\n    }\n}\n\n/**\n * @param {Uint16Array | Uint32Array} ids\n * @param {InstanceType<TypedArrayConstructor>} coords\n * @param {number} i\n * @param {number} j\n */\nfunction swapItem(ids, coords, i, j) {\n    swap(ids, i, j);\n    swap(coords, 2 * i, 2 * j);\n    swap(coords, 2 * i + 1, 2 * j + 1);\n}\n\n/**\n * @param {InstanceType<TypedArrayConstructor>} arr\n * @param {number} i\n * @param {number} j\n */\nfunction swap(arr, i, j) {\n    const tmp = arr[i];\n    arr[i] = arr[j];\n    arr[j] = tmp;\n}\n\n/**\n * @param {number} ax\n * @param {number} ay\n * @param {number} bx\n * @param {number} by\n */\nfunction sqDist(ax, ay, bx, by) {\n    const dx = ax - bx;\n    const dy = ay - by;\n    return dx * dx + dy * dy;\n}\n","\nimport KDBush from 'kdbush';\n\nconst defaultOptions = {\n    minZoom: 0,   // min zoom to generate clusters on\n    maxZoom: 16,  // max zoom level to cluster the points on\n    minPoints: 2, // minimum points to form a cluster\n    radius: 40,   // cluster radius in pixels\n    extent: 512,  // tile extent (radius is calculated relative to it)\n    nodeSize: 64, // size of the KD-tree leaf node, affects performance\n    log: false,   // whether to log timing info\n\n    // whether to generate numeric ids for input features (in vector tiles)\n    generateId: false,\n\n    // a reduce function for calculating custom cluster properties\n    reduce: null, // (accumulated, props) => { accumulated.sum += props.sum; }\n\n    // properties to use for individual points when running the reducer\n    map: props => props // props => ({sum: props.my_value})\n};\n\nconst fround = Math.fround || (tmp => ((x) => { tmp[0] = +x; return tmp[0]; }))(new Float32Array(1));\n\nconst OFFSET_ZOOM = 2;\nconst OFFSET_ID = 3;\nconst OFFSET_PARENT = 4;\nconst OFFSET_NUM = 5;\nconst OFFSET_PROP = 6;\n\nexport default class Supercluster {\n    constructor(options) {\n        this.options = Object.assign(Object.create(defaultOptions), options);\n        this.trees = new Array(this.options.maxZoom + 1);\n        this.stride = this.options.reduce ? 7 : 6;\n        this.clusterProps = [];\n    }\n\n    load(points) {\n        const {log, minZoom, maxZoom} = this.options;\n\n        if (log) console.time('total time');\n\n        const timerId = `prepare ${  points.length  } points`;\n        if (log) console.time(timerId);\n\n        this.points = points;\n\n        // generate a cluster object for each point and index input points into a KD-tree\n        const data = [];\n\n        for (let i = 0; i < points.length; i++) {\n            const p = points[i];\n            if (!p.geometry) continue;\n\n            const [lng, lat] = p.geometry.coordinates;\n            const x = fround(lngX(lng));\n            const y = fround(latY(lat));\n            // store internal point/cluster data in flat numeric arrays for performance\n            data.push(\n                x, y, // projected point coordinates\n                Infinity, // the last zoom the point was processed at\n                i, // index of the source feature in the original input array\n                -1, // parent cluster id\n                1 // number of points in a cluster\n            );\n            if (this.options.reduce) data.push(0); // noop\n        }\n        let tree = this.trees[maxZoom + 1] = this._createTree(data);\n\n        if (log) console.timeEnd(timerId);\n\n        // cluster points on max zoom, then cluster the results on previous zoom, etc.;\n        // results in a cluster hierarchy across zoom levels\n        for (let z = maxZoom; z >= minZoom; z--) {\n            const now = +Date.now();\n\n            // create a new set of clusters for the zoom and index them with a KD-tree\n            tree = this.trees[z] = this._createTree(this._cluster(tree, z));\n\n            if (log) console.log('z%d: %d clusters in %dms', z, tree.numItems, +Date.now() - now);\n        }\n\n        if (log) console.timeEnd('total time');\n\n        return this;\n    }\n\n    getClusters(bbox, zoom) {\n        let minLng = ((bbox[0] + 180) % 360 + 360) % 360 - 180;\n        const minLat = Math.max(-90, Math.min(90, bbox[1]));\n        let maxLng = bbox[2] === 180 ? 180 : ((bbox[2] + 180) % 360 + 360) % 360 - 180;\n        const maxLat = Math.max(-90, Math.min(90, bbox[3]));\n\n        if (bbox[2] - bbox[0] >= 360) {\n            minLng = -180;\n            maxLng = 180;\n        } else if (minLng > maxLng) {\n            const easternHem = this.getClusters([minLng, minLat, 180, maxLat], zoom);\n            const westernHem = this.getClusters([-180, minLat, maxLng, maxLat], zoom);\n            return easternHem.concat(westernHem);\n        }\n\n        const tree = this.trees[this._limitZoom(zoom)];\n        const ids = tree.range(lngX(minLng), latY(maxLat), lngX(maxLng), latY(minLat));\n        const data = tree.data;\n        const clusters = [];\n        for (const id of ids) {\n            const k = this.stride * id;\n            clusters.push(data[k + OFFSET_NUM] > 1 ? getClusterJSON(data, k, this.clusterProps) : this.points[data[k + OFFSET_ID]]);\n        }\n        return clusters;\n    }\n\n    getChildren(clusterId) {\n        const originId = this._getOriginId(clusterId);\n        const originZoom = this._getOriginZoom(clusterId);\n        const errorMsg = 'No cluster with the specified id.';\n\n        const tree = this.trees[originZoom];\n        if (!tree) throw new Error(errorMsg);\n\n        const data = tree.data;\n        if (originId * this.stride >= data.length) throw new Error(errorMsg);\n\n        const r = this.options.radius / (this.options.extent * Math.pow(2, originZoom - 1));\n        const x = data[originId * this.stride];\n        const y = data[originId * this.stride + 1];\n        const ids = tree.within(x, y, r);\n        const children = [];\n        for (const id of ids) {\n            const k = id * this.stride;\n            if (data[k + OFFSET_PARENT] === clusterId) {\n                children.push(data[k + OFFSET_NUM] > 1 ? getClusterJSON(data, k, this.clusterProps) : this.points[data[k + OFFSET_ID]]);\n            }\n        }\n\n        if (children.length === 0) throw new Error(errorMsg);\n\n        return children;\n    }\n\n    getLeaves(clusterId, limit, offset) {\n        limit = limit || 10;\n        offset = offset || 0;\n\n        const leaves = [];\n        this._appendLeaves(leaves, clusterId, limit, offset, 0);\n\n        return leaves;\n    }\n\n    getTile(z, x, y) {\n        const tree = this.trees[this._limitZoom(z)];\n        const z2 = Math.pow(2, z);\n        const {extent, radius} = this.options;\n        const p = radius / extent;\n        const top = (y - p) / z2;\n        const bottom = (y + 1 + p) / z2;\n\n        const tile = {\n            features: []\n        };\n\n        this._addTileFeatures(\n            tree.range((x - p) / z2, top, (x + 1 + p) / z2, bottom),\n            tree.data, x, y, z2, tile);\n\n        if (x === 0) {\n            this._addTileFeatures(\n                tree.range(1 - p / z2, top, 1, bottom),\n                tree.data, z2, y, z2, tile);\n        }\n        if (x === z2 - 1) {\n            this._addTileFeatures(\n                tree.range(0, top, p / z2, bottom),\n                tree.data, -1, y, z2, tile);\n        }\n\n        return tile.features.length ? tile : null;\n    }\n\n    getClusterExpansionZoom(clusterId) {\n        let expansionZoom = this._getOriginZoom(clusterId) - 1;\n        while (expansionZoom <= this.options.maxZoom) {\n            const children = this.getChildren(clusterId);\n            expansionZoom++;\n            if (children.length !== 1) break;\n            clusterId = children[0].properties.cluster_id;\n        }\n        return expansionZoom;\n    }\n\n    _appendLeaves(result, clusterId, limit, offset, skipped) {\n        const children = this.getChildren(clusterId);\n\n        for (const child of children) {\n            const props = child.properties;\n\n            if (props && props.cluster) {\n                if (skipped + props.point_count <= offset) {\n                    // skip the whole cluster\n                    skipped += props.point_count;\n                } else {\n                    // enter the cluster\n                    skipped = this._appendLeaves(result, props.cluster_id, limit, offset, skipped);\n                    // exit the cluster\n                }\n            } else if (skipped < offset) {\n                // skip a single point\n                skipped++;\n            } else {\n                // add a single point\n                result.push(child);\n            }\n            if (result.length === limit) break;\n        }\n\n        return skipped;\n    }\n\n    _createTree(data) {\n        const tree = new KDBush(data.length / this.stride | 0, this.options.nodeSize, Float32Array);\n        for (let i = 0; i < data.length; i += this.stride) tree.add(data[i], data[i + 1]);\n        tree.finish();\n        tree.data = data;\n        return tree;\n    }\n\n    _addTileFeatures(ids, data, x, y, z2, tile) {\n        for (const i of ids) {\n            const k = i * this.stride;\n            const isCluster = data[k + OFFSET_NUM] > 1;\n\n            let tags, px, py;\n            if (isCluster) {\n                tags = getClusterProperties(data, k, this.clusterProps);\n                px = data[k];\n                py = data[k + 1];\n            } else {\n                const p = this.points[data[k + OFFSET_ID]];\n                tags = p.properties;\n                const [lng, lat] = p.geometry.coordinates;\n                px = lngX(lng);\n                py = latY(lat);\n            }\n\n            const f = {\n                type: 1,\n                geometry: [[\n                    Math.round(this.options.extent * (px * z2 - x)),\n                    Math.round(this.options.extent * (py * z2 - y))\n                ]],\n                tags\n            };\n\n            // assign id\n            let id;\n            if (isCluster || this.options.generateId) {\n                // optionally generate id for points\n                id = data[k + OFFSET_ID];\n            } else {\n                // keep id if already assigned\n                id = this.points[data[k + OFFSET_ID]].id;\n            }\n\n            if (id !== undefined) f.id = id;\n\n            tile.features.push(f);\n        }\n    }\n\n    _limitZoom(z) {\n        return Math.max(this.options.minZoom, Math.min(Math.floor(+z), this.options.maxZoom + 1));\n    }\n\n    _cluster(tree, zoom) {\n        const {radius, extent, reduce, minPoints} = this.options;\n        const r = radius / (extent * Math.pow(2, zoom));\n        const data = tree.data;\n        const nextData = [];\n        const stride = this.stride;\n\n        // loop through each point\n        for (let i = 0; i < data.length; i += stride) {\n            // if we've already visited the point at this zoom level, skip it\n            if (data[i + OFFSET_ZOOM] <= zoom) continue;\n            data[i + OFFSET_ZOOM] = zoom;\n\n            // find all nearby points\n            const x = data[i];\n            const y = data[i + 1];\n            const neighborIds = tree.within(data[i], data[i + 1], r);\n\n            const numPointsOrigin = data[i + OFFSET_NUM];\n            let numPoints = numPointsOrigin;\n\n            // count the number of points in a potential cluster\n            for (const neighborId of neighborIds) {\n                const k = neighborId * stride;\n                // filter out neighbors that are already processed\n                if (data[k + OFFSET_ZOOM] > zoom) numPoints += data[k + OFFSET_NUM];\n            }\n\n            // if there were neighbors to merge, and there are enough points to form a cluster\n            if (numPoints > numPointsOrigin && numPoints >= minPoints) {\n                let wx = x * numPointsOrigin;\n                let wy = y * numPointsOrigin;\n\n                let clusterProperties;\n                let clusterPropIndex = -1;\n\n                // encode both zoom and point index on which the cluster originated -- offset by total length of features\n                const id = ((i / stride | 0) << 5) + (zoom + 1) + this.points.length;\n\n                for (const neighborId of neighborIds) {\n                    const k = neighborId * stride;\n\n                    if (data[k + OFFSET_ZOOM] <= zoom) continue;\n                    data[k + OFFSET_ZOOM] = zoom; // save the zoom (so it doesn't get processed twice)\n\n                    const numPoints2 = data[k + OFFSET_NUM];\n                    wx += data[k] * numPoints2; // accumulate coordinates for calculating weighted center\n                    wy += data[k + 1] * numPoints2;\n\n                    data[k + OFFSET_PARENT] = id;\n\n                    if (reduce) {\n                        if (!clusterProperties) {\n                            clusterProperties = this._map(data, i, true);\n                            clusterPropIndex = this.clusterProps.length;\n                            this.clusterProps.push(clusterProperties);\n                        }\n                        reduce(clusterProperties, this._map(data, k));\n                    }\n                }\n\n                data[i + OFFSET_PARENT] = id;\n                nextData.push(wx / numPoints, wy / numPoints, Infinity, id, -1, numPoints);\n                if (reduce) nextData.push(clusterPropIndex);\n\n            } else { // left points as unclustered\n                for (let j = 0; j < stride; j++) nextData.push(data[i + j]);\n\n                if (numPoints > 1) {\n                    for (const neighborId of neighborIds) {\n                        const k = neighborId * stride;\n                        if (data[k + OFFSET_ZOOM] <= zoom) continue;\n                        data[k + OFFSET_ZOOM] = zoom;\n                        for (let j = 0; j < stride; j++) nextData.push(data[k + j]);\n                    }\n                }\n            }\n        }\n\n        return nextData;\n    }\n\n    // get index of the point from which the cluster originated\n    _getOriginId(clusterId) {\n        return (clusterId - this.points.length) >> 5;\n    }\n\n    // get zoom of the point from which the cluster originated\n    _getOriginZoom(clusterId) {\n        return (clusterId - this.points.length) % 32;\n    }\n\n    _map(data, i, clone) {\n        if (data[i + OFFSET_NUM] > 1) {\n            const props = this.clusterProps[data[i + OFFSET_PROP]];\n            return clone ? Object.assign({}, props) : props;\n        }\n        const original = this.points[data[i + OFFSET_ID]].properties;\n        const result = this.options.map(original);\n        return clone && result === original ? Object.assign({}, result) : result;\n    }\n}\n\nfunction getClusterJSON(data, i, clusterProps) {\n    return {\n        type: 'Feature',\n        id: data[i + OFFSET_ID],\n        properties: getClusterProperties(data, i, clusterProps),\n        geometry: {\n            type: 'Point',\n            coordinates: [xLng(data[i]), yLat(data[i + 1])]\n        }\n    };\n}\n\nfunction getClusterProperties(data, i, clusterProps) {\n    const count = data[i + OFFSET_NUM];\n    const abbrev =\n        count >= 10000 ? `${Math.round(count / 1000)  }k` :\n        count >= 1000 ? `${Math.round(count / 100) / 10  }k` : count;\n    const propIndex = data[i + OFFSET_PROP];\n    const properties = propIndex === -1 ? {} : Object.assign({}, clusterProps[propIndex]);\n    return Object.assign(properties, {\n        cluster: true,\n        cluster_id: data[i + OFFSET_ID],\n        point_count: count,\n        point_count_abbreviated: abbrev\n    });\n}\n\n// longitude/latitude to spherical mercator in [0..1] range\nfunction lngX(lng) {\n    return lng / 360 + 0.5;\n}\nfunction latY(lat) {\n    const sin = Math.sin(lat * Math.PI / 180);\n    const y = (0.5 - 0.25 * Math.log((1 + sin) / (1 - sin)) / Math.PI);\n    return y < 0 ? 0 : y > 1 ? 1 : y;\n}\n\n// spherical mercator to longitude/latitude\nfunction xLng(x) {\n    return (x - 0.5) * 360;\n}\nfunction yLat(y) {\n    const y2 = (180 - y * 360) * Math.PI / 180;\n    return 360 * Math.atan(Math.exp(y2)) / Math.PI - 90;\n}\n"],"sourceRoot":""}