From c4a1d4a22314ebe91d53e450066d7183490abc1c Mon Sep 17 00:00:00 2001 From: Stefan Froemken Date: Fri, 2 Oct 2026 12:40:58 +0200 Subject: [PATCH] [FEATURE] Add marker clustering for OpenStreetMap Implement marker clustering for OpenStreetMap based on the official Leaflet.markercluster plugin. Only point markers are clustered. The coverage polygon on hover is disabled. Move the site setting maps2.enableMarkerClusterer from the Google Maps site set into the maps2 default site set, so it applies to both map providers. The setting key is unchanged, existing site configurations keep working. Add a FlexForm option in tab "Map Options" to enable or disable clustering per content element for both providers. An empty value falls back to the site setting, so maps rendered via the maps2 API without a FlexForm are configured by TypoScript only. Add the TypoScript setting markerClusterer.styleSheet to replace the cluster theme of Leaflet.markercluster with a custom CSS file. It is the OpenStreetMap counterpart of markerClusterer.imagePath. Replace the outdated MarkerClusterer v1 for Google Maps with the official @googlemaps/markerclusterer library, because v1 does not support AdvancedMarkerElement. The cluster images of imagePath are still used. Both libraries are loaded on demand via AssetCollector. Resolves: #169 Related: #377 Co-Authored-By: Claude Opus 5.5 --- Classes/Helper/SettingsHelper.php | 22 + Configuration/FlexForms/Maps2.xml | 23 + .../Sets/GoogleMaps/settings.definitions.yaml | 6 - .../Sets/GoogleMaps/setup.typoscript | 8 - .../Sets/Maps2/settings.definitions.yaml | 10 + Configuration/Sets/Maps2/setup.typoscript | 3 + .../Sets/OpenStreetMap/setup.typoscript | 9 +- Documentation/ChangeLog/Index.rst | 19 + Documentation/Configuration/Plugins/Index.rst | 17 + .../Configuration/TypoScript/Index.rst | 51 +- .../Private/Build/JavaScript/GoogleMaps2.js | 80 +- .../Build/JavaScript/OpenStreetMap2.js | 146 +- Resources/Private/Build/build.mjs | 26 +- Resources/Private/Build/package-lock.json | 55 + Resources/Private/Build/package.json | 2 + Resources/Private/Language/FlexForms.xlf | 15 + .../Private/Partials/LoadAssets.fluid.html | 28 + .../Css/Leaflet/MarkerCluster.Default.css | 60 + .../Public/Css/Leaflet/MarkerCluster.css | 14 + .../Public/JavaScript/GoogleMaps2.min.js | 2 +- .../Public/JavaScript/GoogleMaps2.min.js.map | 6 +- .../Public/JavaScript/MarkerClusterer.js | 1319 ----------------- .../Public/JavaScript/OpenStreetMap2.min.js | 2 +- .../JavaScript/OpenStreetMap2.min.js.map | 6 +- .../leaflet.markercluster.LICENSE.txt | 20 + .../JavaScript/leaflet.markercluster.min.js | 3 + .../leaflet.markercluster.min.js.map | 7 + .../JavaScript/markerclusterer.LICENSE.txt | 202 +++ .../Public/JavaScript/markerclusterer.min.js | 2 + 29 files changed, 760 insertions(+), 1403 deletions(-) create mode 100755 Resources/Public/Css/Leaflet/MarkerCluster.Default.css create mode 100755 Resources/Public/Css/Leaflet/MarkerCluster.css delete mode 100644 Resources/Public/JavaScript/MarkerClusterer.js create mode 100644 Resources/Public/JavaScript/leaflet.markercluster.LICENSE.txt create mode 100644 Resources/Public/JavaScript/leaflet.markercluster.min.js create mode 100644 Resources/Public/JavaScript/leaflet.markercluster.min.js.map create mode 100644 Resources/Public/JavaScript/markerclusterer.LICENSE.txt create mode 100644 Resources/Public/JavaScript/markerclusterer.min.js diff --git a/Classes/Helper/SettingsHelper.php b/Classes/Helper/SettingsHelper.php index 56026f06b..8659bd6bd 100644 --- a/Classes/Helper/SettingsHelper.php +++ b/Classes/Helper/SettingsHelper.php @@ -60,6 +60,7 @@ public function getPreparedSettings(array $settings, ServerRequestInterface $req $settings['forceZoom'] = (bool)($settings['forceZoom'] ?? false); $this->prepareMapTileForOpenStreetMap($settings); + $this->prepareMarkerClusterer($settings); $this->prepareImagePathForMarkerClusterer($settings, $request); return $settings; @@ -77,6 +78,27 @@ protected function prepareMapTileForOpenStreetMap(array &$settings): void } } + /** + * The FlexForm of the maps2 plugin offers "markerClusterer.override" to enable ("1") or + * disable ("0") marker clustering per content element for all map providers. An empty + * value keeps the value of the site setting / TypoScript, which stays the source of truth. + */ + protected function prepareMarkerClusterer(array &$settings): void + { + if (!is_array($settings['markerClusterer'] ?? null)) { + return; + } + + $override = (string)($settings['markerClusterer']['override'] ?? ''); + unset($settings['markerClusterer']['override']); + + if ($override === '0' || $override === '1') { + $settings['markerClusterer']['enable'] = $override; + } + + $settings['markerClusterer']['enable'] = (int)($settings['markerClusterer']['enable'] ?? 0); + } + protected function prepareImagePathForMarkerClusterer(array &$settings, ServerRequestInterface $request): void { if ( diff --git a/Configuration/FlexForms/Maps2.xml b/Configuration/FlexForms/Maps2.xml index 2eccba840..2330e04d5 100644 --- a/Configuration/FlexForms/Maps2.xml +++ b/Configuration/FlexForms/Maps2.xml @@ -122,6 +122,29 @@ 1 + + + LLL:EXT:maps2/Resources/Private/Language/FlexForms.xlf:markerClusterer.override.description + + select + selectSingle + + + + + + + + + 1 + + + + 0 + + + + diff --git a/Configuration/Sets/GoogleMaps/settings.definitions.yaml b/Configuration/Sets/GoogleMaps/settings.definitions.yaml index 8c1b5ac7e..5e0213b53 100644 --- a/Configuration/Sets/GoogleMaps/settings.definitions.yaml +++ b/Configuration/Sets/GoogleMaps/settings.definitions.yaml @@ -4,12 +4,6 @@ categories: parent: Maps2 settings: - maps2.enableMarkerClusterer: - label: 'Enable Marker Clusterer' - category: Maps2.googlemaps - description: 'If you have a lot of POIs, some POIs will be joined to a single POI with the amount of joined POIs as label' - type: bool - default: false maps2.googleMapsJavaScriptApiKey: label: 'JavaScript API Key' category: Maps2.googlemaps diff --git a/Configuration/Sets/GoogleMaps/setup.typoscript b/Configuration/Sets/GoogleMaps/setup.typoscript index 62d76b861..ce9dda003 100644 --- a/Configuration/Sets/GoogleMaps/setup.typoscript +++ b/Configuration/Sets/GoogleMaps/setup.typoscript @@ -1,11 +1,4 @@ -# Prevent including both static maps of map providers on one page -page.includeJSFooterlibs.markerClustererForMaps2 > - [isRequestToMapProviderAllowed()] - page.includeJSFooterlibs { - markerClustererForMaps2 = EXT:maps2/Resources/Public/JavaScript/MarkerClusterer.js - markerClustererForMaps2.if.isTrue = {$maps2.enableMarkerClusterer} - } [ELSE] # Requests to Google Maps are not allowed. Inform the user about cookies and request permissions for 3rd party. tt_content.maps2_maps2.20.pluginName = Overlay @@ -24,7 +17,6 @@ plugin.tx_maps2 { googleMapsMapId = {$maps2.googleMapsMapId} mapTypeId = google.maps.MapTypeId.ROADMAP markerClusterer { - enable = {$maps2.enableMarkerClusterer} imagePath = EXT:maps2/Resources/Public/Icons/MarkerClusterer/m } } diff --git a/Configuration/Sets/Maps2/settings.definitions.yaml b/Configuration/Sets/Maps2/settings.definitions.yaml index fd3f10ed4..811291526 100644 --- a/Configuration/Sets/Maps2/settings.definitions.yaml +++ b/Configuration/Sets/Maps2/settings.definitions.yaml @@ -10,6 +10,9 @@ categories: Maps2.pages: label: 'Pages' parent: 'Maps2' + Maps2.markerClusterer: + label: 'Marker Clusterer' + parent: 'Maps2' settings: maps2.templateRootPath: @@ -55,3 +58,10 @@ settings: description: 'Folder that stores all POIs' type: int default: 0 + + maps2.enableMarkerClusterer: + label: 'Enable Marker Clusterer' + category: 'Maps2.markerClusterer' + description: 'If you have a lot of POIs, nearby POIs will be joined to a single cluster icon with the amount of joined POIs as label. Applies to Google Maps and OpenStreetMap.' + type: bool + default: false diff --git a/Configuration/Sets/Maps2/setup.typoscript b/Configuration/Sets/Maps2/setup.typoscript index c273aaa48..209b97a6a 100644 --- a/Configuration/Sets/Maps2/setup.typoscript +++ b/Configuration/Sets/Maps2/setup.typoscript @@ -32,6 +32,9 @@ plugin.tx_maps2 { settings { zoom = 10 zoomControl = 1 + markerClusterer { + enable = {$maps2.enableMarkerClusterer} + } overlay { link { addSection = 1 diff --git a/Configuration/Sets/OpenStreetMap/setup.typoscript b/Configuration/Sets/OpenStreetMap/setup.typoscript index 962d25087..c7fd9032b 100644 --- a/Configuration/Sets/OpenStreetMap/setup.typoscript +++ b/Configuration/Sets/OpenStreetMap/setup.typoscript @@ -1,6 +1,3 @@ -# Prevent including both static maps of map providers on one page -page.includeJSFooterlibs.markerClustererForMaps2 > - [isRequestToMapProviderAllowed()] [ELSE] # Requests to OpenStreetMap are not allowed. Inform the user about cookies and request permissions for 3rd party. @@ -14,5 +11,11 @@ plugin.tx_maps2 { mapProvider = osm mapTile = {$maps2.mapTile} mapTileAttribution = {$maps2.mapTileAttribution} + markerClusterer { + # Theme stylesheet for the cluster icons of Leaflet.markercluster. + # Set your own stylesheet or clear the value to style the + # ".marker-cluster" CSS classes within your own site package. + styleSheet = EXT:maps2/Resources/Public/Css/Leaflet/MarkerCluster.Default.css + } } } diff --git a/Documentation/ChangeLog/Index.rst b/Documentation/ChangeLog/Index.rst index 0e0e493b5..8c9b2ae35 100644 --- a/Documentation/ChangeLog/Index.rst +++ b/Documentation/ChangeLog/Index.rst @@ -7,6 +7,25 @@ ChangeLog ========= +Version 13.2.0 +============== + +* FEATURE: Add marker clustering for OpenStreetMap based on + Leaflet.markercluster +* FEATURE: Add FlexForm option to enable or disable marker clustering per + content element for Google Maps and OpenStreetMap +* FEATURE: Add TypoScript setting `markerClusterer.styleSheet` to replace the + cluster icon theme of Leaflet.markercluster +* TASK: Move site setting `maps2.enableMarkerClusterer` from site set + `Maps2 - Google Maps` into `Maps2 - Default Set`. The setting key is + unchanged. +* BUGFIX: Fix marker clustering for Google Maps. The outdated MarkerClusterer + v1 does not support `AdvancedMarkerElement` and was replaced by the official + library `@googlemaps/markerclusterer`. The cluster images of + `markerClusterer.imagePath` are still used. +* TASK: Load the Google Maps marker clusterer on demand via AssetCollector + in partial LoadAssets instead of `page.includeJSFooterlibs` + Version 13.1.1 ============== diff --git a/Documentation/Configuration/Plugins/Index.rst b/Documentation/Configuration/Plugins/Index.rst index c75487d1f..26a654321 100644 --- a/Documentation/Configuration/Plugins/Index.rst +++ b/Documentation/Configuration/Plugins/Index.rst @@ -82,6 +82,23 @@ Default: true Show control to toggle between normal and full screen mode. +.. _plugins-show-map-marker-clusterer: + +markerClusterer.override +------------------------ + +Default: Use default (site settings / TypoScript) + +Enable or disable marker clustering for this content element only. This option +applies to Google Maps and OpenStreetMap. With the default option the value of +site setting `maps2.enableMarkerClusterer` (TypoScript +`plugin.tx_maps2.settings.markerClusterer.enable`) is used. + +The required JavaScript libraries are loaded automatically, if at least one map +on the page uses marker clustering. The cluster icons are configured with +TypoScript `markerClusterer.imagePath` (Google Maps) and +`markerClusterer.styleSheet` (OpenStreetMap). + mapTypeId --------- diff --git a/Documentation/Configuration/TypoScript/Index.rst b/Documentation/Configuration/TypoScript/Index.rst index 27d84c21a..d352ca463 100644 --- a/Documentation/Configuration/TypoScript/Index.rst +++ b/Documentation/Configuration/TypoScript/Index.rst @@ -146,17 +146,36 @@ Set the maximum height of images within the InfoWindow PopUp markerClusterer.enable ---------------------- -Only available for Google Maps +Available for Google Maps and OpenStreetMap Default: 0 Example: `plugin.tx_maps2.settings.markerClusterer.enable = 1` -This value is configurable through TypoScript Constants Editor +This value is configurable through the site setting +`maps2.enableMarkerClusterer` ("Enable Marker Clusterer") of site set +`Maps2 - Default Set`. If you work with a lot of poi collection records you can activate the marker -clusterer. The marker clusterer will merge multiple poi collections to 1 icon -with the contains amount of records. +clusterer. The marker clusterer will merge multiple nearby poi collections to +1 icon showing the amount of contained records. The markers separate as the +visitor zooms in. + +For Google Maps the library `MarkerClusterer` is used. For OpenStreetMap the +official Leaflet plugin +`Leaflet.markercluster `__ +is used. With OpenStreetMap only point markers are clustered. Areas, routes and +radius records are always shown as they are. While editing a marker in +frontend, clustering is not used. + +This TypoScript value is the source of truth. It also applies to maps +which are rendered by foreign extensions through the maps2 Fluid partials. + +.. hint:: + + Editors can override this value per content element in the "Map Options" + tab of the maps2 plugin. See + :ref:`markerClusterer.override `. markerClusterer.imagePath ------------------------- @@ -170,6 +189,30 @@ Example: `plugin.tx_maps2.settings.markerClusterer.imagePath = EXT:my_sitepackag If you don't like the icons of Marker Clusterer you can choose a different path for your own images. +markerClusterer.styleSheet +-------------------------- + +Only available for OpenStreetMap + +Default: `EXT:maps2/Resources/Public/Css/Leaflet/MarkerCluster.Default.css` + +Example: `plugin.tx_maps2.settings.markerClusterer.styleSheet = EXT:my_sitepackage/Resources/Public/Css/MarkerCluster.css` + +Leaflet.markercluster does not work with images like the Google Maps +MarkerClusterer. The cluster icons are HTML elements which are styled by CSS +classes `marker-cluster`, `marker-cluster-small` (less than 10 markers), +`marker-cluster-medium` (less than 100 markers) and `marker-cluster-large`. + +By default, maps2 loads the default theme `MarkerCluster.Default.css` of +Leaflet.markercluster. If you don't like the cluster icons, copy that file to +your site package, adapt it (colors, sizes, background images, ...) and set +the path to your own file here. If you clear this value, no theme stylesheet +will be loaded at all and you can style these CSS classes within the +stylesheets of your site package. + +The required base stylesheet `MarkerCluster.css` (animations) is always loaded, +if marker clustering is enabled. + .. _typoScript-local-lang: diff --git a/Resources/Private/Build/JavaScript/GoogleMaps2.js b/Resources/Private/Build/JavaScript/GoogleMaps2.js index b737808a8..a499f1e12 100644 --- a/Resources/Private/Build/JavaScript/GoogleMaps2.js +++ b/Resources/Private/Build/JavaScript/GoogleMaps2.js @@ -2,6 +2,7 @@ class GoogleMaps2 { allMarkers = []; categorizedMarkers = {}; pointMarkers = []; + markerClusterer = null; bounds = {}; infoWindow = {}; poiCollections = {}; @@ -47,16 +48,7 @@ class GoogleMaps2 { } } else { await this.createPointByCollectionType(element, environment); - if ( - typeof environment.settings.markerClusterer !== 'undefined' - && environment.settings.markerClusterer.enable === 1 - ) { - new MarkerClusterer( - this.map, - this.pointMarkers, - { imagePath: environment.settings.markerClusterer.imagePath } - ); - } + this.createMarkerClusterer(environment.settings); if (this.countObjectProperties(this.categorizedMarkers) > 1) { this.showSwitchableCategories(element, environment); @@ -70,6 +62,66 @@ class GoogleMaps2 { } } + /** + * Cluster the point markers with the official @googlemaps/markerclusterer library + * + * @param {Settings} settings + */ + createMarkerClusterer = settings => { + if ( + this.editable + || typeof settings.markerClusterer === 'undefined' + || settings.markerClusterer.enable !== 1 + || typeof markerClusterer === 'undefined' + ) { + return; + } + + this.markerClusterer = new markerClusterer.MarkerClusterer({ + map: this.map, + markers: this.pointMarkers, + renderer: this.getClusterRenderer(settings.markerClusterer.imagePath), + }); + } + + /** + * Render clusters with the images m1.png to m5.png of the configured imagePath. + * Image sizes and index calculation are taken from the former MarkerClusterer v1. + * + * @param {string} imagePath + * @return {object} + */ + getClusterRenderer = imagePath => { + const imageSizes = [53, 56, 66, 78, 90]; + + return { + render: ({ count, position }) => { + const index = Math.min(String(count).length, imageSizes.length); + const size = imageSizes[index - 1]; + const content = document.createElement('div'); + + content.classList.add('maps2-marker-cluster'); + content.textContent = String(count); + content.style.width = size + 'px'; + content.style.height = size + 'px'; + content.style.lineHeight = size + 'px'; + content.style.backgroundImage = 'url("' + imagePath + index + '.png")'; + content.style.textAlign = 'center'; + content.style.fontSize = '11px'; + content.style.fontWeight = 'bold'; + content.style.color = '#000'; + content.style.cursor = 'pointer'; + content.style.transform = 'translateY(50%)'; + + return new google.maps.marker.AdvancedMarkerElement({ + position: position, + content: content, + zIndex: 1000 + count, + }); + }, + }; + } + /** * Return a MapOptions object which can be assigned to the Map object of Google * @@ -350,7 +402,13 @@ class GoogleMaps2 { let markers = this.getMarkersToChangeVisibilityFor(categoryUid, form, isChecked); markers.forEach((marker) => { - if (typeof marker.setVisible === 'function') { + if (this.markerClusterer !== null && this.pointMarkers.includes(marker)) { + if (isChecked) { + this.markerClusterer.addMarker(marker); + } else { + this.markerClusterer.removeMarker(marker); + } + } else if (typeof marker.setVisible === 'function') { marker.setVisible(isChecked); } else if (typeof marker.setMap === 'function') { marker.setMap(isChecked ? this.map : null); diff --git a/Resources/Private/Build/JavaScript/OpenStreetMap2.js b/Resources/Private/Build/JavaScript/OpenStreetMap2.js index 5064f11d3..96c48e4fd 100644 --- a/Resources/Private/Build/JavaScript/OpenStreetMap2.js +++ b/Resources/Private/Build/JavaScript/OpenStreetMap2.js @@ -8,6 +8,7 @@ class OpenStreetMap2 { categorizedMarkers = {}; poiCollections = []; map = {}; + markerClusterGroup = null; constructor(element, environment) { this.element = element; @@ -18,6 +19,7 @@ class OpenStreetMap2 { this.preparePoiCollection(); this.setMapDimensions(); this.createMap(); + this.markerClusterGroup = this.createMarkerClusterGroup(); this.setMarkersOnMap(); } @@ -59,6 +61,8 @@ class OpenStreetMap2 { createMarkerBasedOnPOICollections() { this.createPointByCollectionType(); + this.markerClusterGroup?.addTo(this.map); + if (this.countObjectProperties(this.categorizedMarkers) > 1) { this.showSwitchableCategories(); } @@ -137,6 +141,50 @@ class OpenStreetMap2 { }).addTo(this.map); } + /** + * Point markers are collected in a cluster group of Leaflet.markercluster, if + * marker clustering is enabled. Clustering is not used while editing a marker. + * + * @returns {L.MarkerClusterGroup|null} + */ + createMarkerClusterGroup() { + if (this.editable || !this.isMarkerClustererEnabled()) { + return null; + } + + // Leaflet.markercluster is only loaded, if clustering is enabled in site settings or plugin + if (typeof L.markerClusterGroup !== "function") { + return null; + } + + // Do not draw the polygon of the cluster bounds on hover + return L.markerClusterGroup({ + showCoverageOnHover: false, + }); + } + + /** + * @returns {boolean} + */ + isMarkerClustererEnabled() { + return parseInt(this.getSettings().markerClusterer?.enable ?? 0, 10) === 1; + } + + /** + * Point markers (L.Marker) are managed by the cluster group, if available. + * Areas, routes and radius layers are always placed on the map directly. + * + * @param {L.Layer} layer + * @returns {L.Map|L.MarkerClusterGroup} + */ + getLayerContainer(layer) { + if (this.markerClusterGroup !== null && layer instanceof L.Marker) { + return this.markerClusterGroup; + } + + return this.map; + } + /** * @returns {{[p: string]: Category}} */ @@ -246,9 +294,9 @@ class OpenStreetMap2 { markers.forEach((marker) => { if (isChecked) { - this.map.addLayer(marker); + this.getLayerContainer(marker).addLayer(marker); } else { - this.map.removeLayer(marker); + this.getLayerContainer(marker).removeLayer(marker); } }); }); @@ -375,7 +423,7 @@ class OpenStreetMap2 { { 'draggable': this.editable } - ).addTo(this.map); + ); if (poiCollection.hasOwnProperty("markerIcon") && poiCollection.markerIcon !== "") { const markerIconWidth = poiCollection.markerIconWidth || this.getExtConf().markerIconWidth; @@ -400,6 +448,7 @@ class OpenStreetMap2 { marker.setIcon(icon); } + this.getLayerContainer(marker).addLayer(marker); this.bounds.extend(marker.getLatLng()); if (this.editable) { @@ -571,49 +620,60 @@ class OpenStreetMap2 { let maps2OpenStreetMaps = []; -document.querySelectorAll(".maps2").forEach((element) => { - const environment = typeof element.dataset.environment !== 'undefined' ? element.dataset.environment : '{}'; - const override = typeof element.dataset.override !== 'undefined' ? element.dataset.override : '{}'; - - // Pass in the objects to merge as arguments. - // For a deep extend, set the first argument to `true`. - const extend = (...args) => { - let extended = {}; - let deep = false; - let i = 0; - let length = args.length; - - // Check for deep merge - if (Object.prototype.toString.call(args[0]) === '[object Boolean]') { - deep = args[0]; - i++; - } +// Initialize maps after all synchronous scripts in body have been executed. If two maps2 +// plugins are on one page, the optional Leaflet.markercluster library may be registered by +// the second plugin and is therefore rendered after this script. +const initializeOpenStreetMaps = () => { + document.querySelectorAll(".maps2").forEach((element) => { + const environment = typeof element.dataset.environment !== 'undefined' ? element.dataset.environment : '{}'; + const override = typeof element.dataset.override !== 'undefined' ? element.dataset.override : '{}'; + + // Pass in the objects to merge as arguments. + // For a deep extend, set the first argument to `true`. + const extend = (...args) => { + let extended = {}; + let deep = false; + let i = 0; + let length = args.length; + + // Check for deep merge + if (Object.prototype.toString.call(args[0]) === '[object Boolean]') { + deep = args[0]; + i++; + } - // Merge the object into the extended object - const merge = function (obj) { - for ( var prop in obj ) { - if ( Object.prototype.hasOwnProperty.call( obj, prop ) ) { - // If deep merge and property is an object, merge properties - if ( deep && Object.prototype.toString.call(obj[prop]) === '[object Object]' ) { - extended[prop] = extend( true, extended[prop], obj[prop] ); - } else { - extended[prop] = obj[prop]; + // Merge the object into the extended object + const merge = function (obj) { + for ( var prop in obj ) { + if ( Object.prototype.hasOwnProperty.call( obj, prop ) ) { + // If deep merge and property is an object, merge properties + if ( deep && Object.prototype.toString.call(obj[prop]) === '[object Object]' ) { + extended[prop] = extend( true, extended[prop], obj[prop] ); + } else { + extended[prop] = obj[prop]; + } } } - } - }; + }; - // Loop through each object and conduct a merge - for ( ; i < length; i++ ) { - var obj = args[i]; - merge(obj); - } + // Loop through each object and conduct a merge + for ( ; i < length; i++ ) { + var obj = args[i]; + merge(obj); + } - return extended; - }; + return extended; + }; - maps2OpenStreetMaps.push(new OpenStreetMap2( - element, - extend(true, JSON.parse(environment), JSON.parse(override)) - )); -}); + maps2OpenStreetMaps.push(new OpenStreetMap2( + element, + extend(true, JSON.parse(environment), JSON.parse(override)) + )); + }); +}; + +if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", initializeOpenStreetMaps); +} else { + initializeOpenStreetMaps(); +} diff --git a/Resources/Private/Build/build.mjs b/Resources/Private/Build/build.mjs index dbccf4086..7ffcd3d7c 100644 --- a/Resources/Private/Build/build.mjs +++ b/Resources/Private/Build/build.mjs @@ -3,20 +3,29 @@ import { mkdirSync, readFileSync, writeFileSync } from 'fs'; import { join } from 'path'; const outDir = '../../Public/JavaScript'; +const cssOutDir = '../../Public/Css/Leaflet'; mkdirSync(outDir, { recursive: true }); +mkdirSync(cssOutDir, { recursive: true }); // Plain global scripts, minified in place. No bundling since none of them use import/require. -async function minifySingleFile(entry, outName) { +async function minifySingleFile(entry, outName, banner = '') { await build({ entryPoints: [entry], outfile: join(outDir, outName), minify: true, sourcemap: true, logLevel: 'info', + banner: { js: banner }, }); } +// Vendor files (stylesheets, licenses) which are shipped unmodified. +function copyVendorFile(source, targetDir, outName) { + writeFileSync(join(targetDir, outName), readFileSync(source)); + console.log(` ${targetDir}/${outName}`); +} + // Vendor scripts are concatenated as plain text first (same behaviour as the former // gulp-concat step) because they rely on sequential global execution, not ESM. async function concatAndMinify(entries, outName) { @@ -41,6 +50,21 @@ await concatAndMinify( 'leaflet.min.js', ); +// Leaflet.markercluster is loaded on demand only, if marker clustering is enabled. +await minifySingleFile( + 'node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.js', + 'leaflet.markercluster.min.js', + '/*! Leaflet.markercluster | (c) 2012-2017, Dave Leaver, smartrak | MIT License' + + ' | https://github.com/Leaflet/Leaflet.markercluster */', +); +copyVendorFile('node_modules/leaflet.markercluster/MIT-LICENCE.txt', outDir, 'leaflet.markercluster.LICENSE.txt'); +copyVendorFile('node_modules/leaflet.markercluster/dist/MarkerCluster.css', cssOutDir, 'MarkerCluster.css'); +copyVendorFile('node_modules/leaflet.markercluster/dist/MarkerCluster.Default.css', cssOutDir, 'MarkerCluster.Default.css'); + +// @googlemaps/markerclusterer ships a minified build exposing the global "markerClusterer". +copyVendorFile('node_modules/@googlemaps/markerclusterer/dist/index.min.js', outDir, 'markerclusterer.min.js'); +copyVendorFile('node_modules/@googlemaps/markerclusterer/LICENSE', outDir, 'markerclusterer.LICENSE.txt'); + await minifySingleFile('JavaScript/Classes.js', 'Classes.js'); await minifySingleFile('JavaScript/GoogleMapsModule.js', 'GoogleMapsModule.min.js'); await minifySingleFile('JavaScript/OpenStreetMapModule.js', 'OpenStreetMapModule.min.js'); diff --git a/Resources/Private/Build/package-lock.json b/Resources/Private/Build/package-lock.json index c6e279d59..f224a8b46 100644 --- a/Resources/Private/Build/package-lock.json +++ b/Resources/Private/Build/package-lock.json @@ -9,12 +9,14 @@ "version": "10.0.8", "license": "GPL-2.0-or-later", "dependencies": { + "@googlemaps/markerclusterer": "^2.6.2", "@types/geojson": "^7946.0.13", "@types/leaflet": "^1.9.8", "@types/leaflet-editable": "^1.2.6", "esbuild": "^0.28.1", "leaflet": "^1.9.4", "leaflet-editable": "^1.2.0", + "leaflet.markercluster": "^1.5.3", "leaflet.path.drag": "^0.0.6" } }, @@ -434,6 +436,17 @@ "node": ">=18" } }, + "node_modules/@googlemaps/markerclusterer": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@googlemaps/markerclusterer/-/markerclusterer-2.6.2.tgz", + "integrity": "sha512-U6uVhq8iWhiIckA89sgRu8OK35mjd6/3CuoZKWakKEf0QmRRWpatlsPb3kqXkoWSmbcZkopRiI4dnW6DQSd7bQ==", + "license": "Apache-2.0", + "dependencies": { + "@types/supercluster": "^7.1.3", + "fast-equals": "^5.2.2", + "supercluster": "^8.0.1" + } + }, "node_modules/@types/geojson": { "version": "7946.0.16", "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", @@ -458,6 +471,15 @@ "@types/leaflet": "^1.9" } }, + "node_modules/@types/supercluster": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.3.tgz", + "integrity": "sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==", + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, "node_modules/esbuild": { "version": "0.28.1", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", @@ -499,6 +521,21 @@ "@esbuild/win32-x64": "0.28.1" } }, + "node_modules/fast-equals": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.4.3.tgz", + "integrity": "sha512-8unmvA0qrfpFWBYUate9BTGtQdKHWBYt+KdAIkag7Vvxe7wz8Q2nJg7fLMC0bJqe0bjP31kca7Ckaawrs4Istg==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/kdbush": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.1.0.tgz", + "integrity": "sha512-e9vurzrXJQrFX6ckpHP3bvj5l+9CnYzkxDNnNQ1h2QTqdWsUAJgXiKdGNcOa1EY85dU8KbQ+z/FdQdB7P+9yfQ==", + "license": "ISC" + }, "node_modules/leaflet": { "version": "1.9.4", "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", @@ -511,11 +548,29 @@ "integrity": "sha512-iDTXR0byKWRiPliNrQrmZtbHHrr/ONZwoFoIzUHP2MQJQwgqzeblc1OKrT0ryOEzf0PFtrClk9SksAbeQpsmXw==", "license": "WTFPL" }, + "node_modules/leaflet.markercluster": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/leaflet.markercluster/-/leaflet.markercluster-1.5.3.tgz", + "integrity": "sha512-vPTw/Bndq7eQHjLBVlWpnGeLa3t+3zGiuM7fJwCkiMFq+nmRuG3RI3f7f4N4TDX7T4NpbAXpR2+NTRSEGfCSeA==", + "license": "MIT", + "peerDependencies": { + "leaflet": "^1.3.1" + } + }, "node_modules/leaflet.path.drag": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/leaflet.path.drag/-/leaflet.path.drag-0.0.6.tgz", "integrity": "sha512-U6jp7sqX4kZss2FCm7bGPltOl8URWd+c4DPcRnEO9mYoZ1hfrteZ3XXVJ6zcEU8zxjnWeu1YywF08EDYbelmFg==", "license": "MIT" + }, + "node_modules/supercluster": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz", + "integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==", + "license": "ISC", + "dependencies": { + "kdbush": "^4.0.2" + } } } } diff --git a/Resources/Private/Build/package.json b/Resources/Private/Build/package.json index 13ac13538..253ab1d8d 100644 --- a/Resources/Private/Build/package.json +++ b/Resources/Private/Build/package.json @@ -1,11 +1,13 @@ { "dependencies": { + "@googlemaps/markerclusterer": "^2.6.2", "@types/geojson": "^7946.0.13", "@types/leaflet": "^1.9.8", "@types/leaflet-editable": "^1.2.6", "esbuild": "^0.28.1", "leaflet": "^1.9.4", "leaflet-editable": "^1.2.0", + "leaflet.markercluster": "^1.5.3", "leaflet.path.drag": "^0.0.6" }, "name": "maps2", diff --git a/Resources/Private/Language/FlexForms.xlf b/Resources/Private/Language/FlexForms.xlf index e310d8e5a..a17fe6276 100644 --- a/Resources/Private/Language/FlexForms.xlf +++ b/Resources/Private/Language/FlexForms.xlf @@ -47,6 +47,21 @@ Show full screen Control + + Marker Clusterer + + + Join nearby markers to a single cluster icon (Google Maps and OpenStreetMap). With the default option, the site setting "Enable Marker Clusterer" (TypoScript: settings.markerClusterer.enable) is used. + + + Use default (site settings / TypoScript) + + + Enabled + + + Disabled + Google Maps diff --git a/Resources/Private/Partials/LoadAssets.fluid.html b/Resources/Private/Partials/LoadAssets.fluid.html index a6b1ee6d0..156faab99 100644 --- a/Resources/Private/Partials/LoadAssets.fluid.html +++ b/Resources/Private/Partials/LoadAssets.fluid.html @@ -9,6 +9,16 @@ ; + + + + + + + + + + + + + {if(this.createMap(e,t),typeof this.poiCollections>"u"||this.poiCollections===null){let s=Number(e.dataset.latitude),o=Number(e.dataset.longitude);s&&o?(await this.createMarkerByLatLng(s,o),this.map.setCenter(new google.maps.LatLng(s,o))):this.map.setCenter(new google.maps.LatLng(t.extConf.defaultLatitude,t.extConf.defaultLongitude))}else await this.createPointByCollectionType(e,t),typeof t.settings.markerClusterer<"u"&&t.settings.markerClusterer.enable===1&&new MarkerClusterer(this.map,this.pointMarkers,{imagePath:t.settings.markerClusterer.imagePath}),this.countObjectProperties(this.categorizedMarkers)>1&&this.showSwitchableCategories(e,t),this.shouldFitBounds(t.settings)?this.map.fitBounds(this.bounds):this.map.setCenter(new google.maps.LatLng(this.poiCollections[0].latitude,this.poiCollections[0].longitude))};getMapOptions=settings=>{let mapOptions={mapTypeId:"",zoom:parseInt(settings.zoom),zoomControl:parseInt(settings.zoomControl)!==0,mapTypeControl:parseInt(settings.mapTypeControl)!==0,scaleControl:parseInt(settings.scaleControl)!==0,streetViewControl:parseInt(settings.streetViewControl)!==0,fullscreenControl:parseInt(settings.fullScreenControl)!==0,scrollwheel:settings.activateScrollWheel,styles:""};switch(settings.styles&&(mapOptions.styles=eval(settings.styles)),settings.mapTypeId){case"google.maps.MapTypeId.HYBRID":case"hybrid":mapOptions.mapTypeId=google.maps.MapTypeId.HYBRID;break;case"google.maps.MapTypeId.ROADMAP":case"roadmap":mapOptions.mapTypeId=google.maps.MapTypeId.ROADMAP;break;case"google.maps.MapTypeId.SATELLITE":case"satellite":mapOptions.mapTypeId=google.maps.MapTypeId.SATELLITE;break;case"google.maps.MapTypeId.TERRAIN":case"terrain":mapOptions.mapTypeId=google.maps.MapTypeId.TERRAIN;break}return mapOptions};getCircleOptions(e,t,s){return{map:e,center:t,radius:s.radius,strokeColor:s.strokeColor,strokeOpacity:s.strokeOpacity,strokeWeight:s.strokeWeight,fillColor:s.fillColor,fillOpacity:s.fillOpacity}}getPolygonOptions(e,t){return{paths:e,strokeColor:t.strokeColor,strokeOpacity:t.strokeOpacity,strokeWeight:t.strokeWeight,fillColor:t.fillColor,fillOpacity:t.fillOpacity}}getPolylineOptions(e,t){return{path:e,strokeColor:t.strokeColor,strokeOpacity:t.strokeOpacity,strokeWeight:t.strokeWeight}}createMap(e,t){let s=this.getMapOptions(t.settings);s.mapId=t.settings.googleMapsMapId||"",this.map=new google.maps.Map(e,s)}canBeInterpretedAsNumber(e){return typeof e=="number"||!isNaN(Number(e))}normalizeDimension(e){let t=String(e);return this.canBeInterpretedAsNumber(t)&&(t+="px"),t}shouldFitBounds(e){return e.forceZoom===!0||this.poiCollections===null?!1:this.poiCollections.length>1||this.poiCollections.length===1&&(this.poiCollections[0].collectionType==="Area"||this.poiCollections[0].collectionType==="Route")}setMapDimensions(e,t){e.style.height=this.normalizeDimension(t.mapHeight),e.style.width=this.normalizeDimension(t.mapWidth)}groupCategories=e=>{let t={},s="0";for(let o=0;o-1&&!t.hasOwnProperty(s)&&(t[s]=this.poiCollections[o].categories[a]);return t};getCategoriesOfCheckboxesWithStatus=(e,t)=>{let s=[];return(t?e.querySelectorAll("input:checked"):e.querySelectorAll("input:not(input:checked)")).forEach(a=>{s.push(parseInt(a.value))}),s};getMarkersToChangeVisibilityFor=(e,t,s)=>{let o=[];if(this.allMarkers.length===0)return o;let a=null,i=null,r=this.getCategoriesOfCheckboxesWithStatus(t,s);for(let n=0;n{let s=this.groupCategories(t),o=document.createElement("form"),a={};o.classList.add("txMaps2Form"),o.setAttribute("id","txMaps2Form-"+t.contentRecord.uid);for(let i in s)if(s.hasOwnProperty(i)){o.appendChild(this.getCheckbox(s[i]));const r=document.createElement("span");r.classList.add("map-category"),r.textContent=s[i].title,o.querySelector("#checkCategory_"+i)?.insertAdjacentElement("afterend",r)}o.querySelectorAll("input").forEach(i=>{i.addEventListener("click",()=>{let r=i.checked,n=i.value;this.getMarkersToChangeVisibilityFor(n,o,r).forEach(l=>{typeof l.setVisible=="function"?l.setVisible(r):typeof l.setMap=="function"?l.setMap(r?this.map:null):l.map=r?this.map:null})})}),e.insertAdjacentElement("afterend",o)};getCheckbox(e){const t=document.createElement("div");t.classList.add("form-group");const s=document.createElement("div");s.classList.add("checkbox");const o=document.createElement("label"),a=document.createElement("input");return a.type="checkbox",a.classList.add("checkCategory"),a.id="checkCategory_"+e.uid,a.checked=!0,a.value=e.uid,o.appendChild(a),s.appendChild(o),t.appendChild(s),t}countObjectProperties=e=>{let t=0;for(let s in e)e.hasOwnProperty(s)&&t++;return t};createPointByCollectionType=async(e,t)=>{let s,o=0;if(this.poiCollections!==null&&this.poiCollections.length)for(const a of this.poiCollections){switch(a.strokeColor===""&&(a.strokeColor=t.extConf.strokeColor),a.strokeOpacity===""&&(a.strokeOpacity=t.extConf.strokeOpacity),a.strokeWeight===""&&(a.strokeWeight=t.extConf.strokeWeight),a.fillColor===""&&(a.fillColor=t.extConf.fillColor),a.fillOpacity===""&&(a.fillOpacity=t.extConf.fillOpacity),s=null,a.collectionType){case"Point":s=await this.createMarker(a,e,t);break;case"Area":s=this.createArea(a,t);break;case"Route":s=this.createRoute(a,t);break;case"Radius":s=this.createRadius(a,t);break}if(s!==null){this.allMarkers.push({marker:s,poiCollection:a}),o=0;for(let i=0;i{const{AdvancedMarkerElement:o}=await google.maps.importLibrary("marker");let a={position:new google.maps.LatLng(e.latitude,e.longitude),map:this.map,gmpDraggable:this.editable};if(e.hasOwnProperty("markerIcon")&&e.markerIcon!==""){const r=document.createElement("img");let n=e.markerIcon;n.startsWith("/")&&(n=n.substring(1)),r.src=s.siteUrl+n;const c=e.markerIconWidth||s.extConf.markerIconWidth,l=e.markerIconHeight||s.extConf.markerIconHeight,p=e.markerIconAnchorPosX||s.extConf.markerIconAnchorPosX,h=e.markerIconAnchorPosY||s.extConf.markerIconAnchorPosY;c&&(r.style.width=c+"px"),l&&(r.style.height=l+"px"),a.content=r,p&&(a.anchorLeft="-"+p+"px"),h&&(a.anchorTop="-"+h+"px")}let i=new o(a);return this.pointMarkers.push(i),this.bounds.extend(i.position),this.editable?this.addEditListeners(t,i,e,s):this.addInfoWindow(i,e,s),i};createArea=(e,t)=>{let s,o=[];for(let i=0;i{let s,o=[];for(let i=0;i{let s=new google.maps.Circle(this.getCircleOptions(this.map,new google.maps.LatLng(e.latitude,e.longitude),e));return this.bounds.union(s.getBounds()),this.addInfoWindow(s,e,t),s};addInfoWindow=(e,t,s)=>{let o=this.infoWindow,a=this.map;google.maps.event.addListener(e,"click",i=>{fetch(s.ajaxUrl,{method:"POST",headers:{"Content-Type":"application/json","ext-maps2":"infoWindowContent"},body:JSON.stringify({poiCollection:t.uid})}).then(r=>r.json()).then(r=>{o.close(),o.setContent(r.content),t.collectionType==="Point"?(o.setPosition(null),o.open({anchor:e,map:a})):(o.setPosition(new google.maps.LatLng(t.latitude,t.longitude)),o.open(a))}).catch(r=>console.error("Error:",r))})};inList=(e,t)=>{let s=","+e+",";return t=","+t+",",s.search(t)};createMarkerByLatLng=async(e,t)=>{const{AdvancedMarkerElement:s}=await google.maps.importLibrary("marker");let o=new s({position:new google.maps.LatLng(e,t),map:this.map});this.bounds.extend(o.position)};addEditListeners=(e,t,s,o)=>{google.maps.event.addListener(t,"dragend",()=>{let a=t.position,i=(typeof a.lat=="function"?a.lat():a.lat).toFixed(6),r=(typeof a.lng=="function"?a.lng():a.lng).toFixed(6);e.prevAll("input.latitude-"+o.contentRecord.uid).val(i),e.prevAll("input.longitude-"+o.contentRecord.uid).val(r)}),google.maps.event.addListener(this.map,"click",a=>{t.position=a.latLng,e.prevAll("input.latitude-"+o.contentRecord.uid).val(a.latLng.lat().toFixed(6)),e.prevAll("input.longitude-"+o.contentRecord.uid).val(a.latLng.lng().toFixed(6))})}}let maps2GoogleMaps=[];function initMap(){document.querySelectorAll(".maps2").forEach(s=>{const o=typeof s.dataset.environment<"u"?s.dataset.environment:"{}",a=typeof s.dataset.override<"u"?s.dataset.override:"{}",i=(...r)=>{let n={},c=!1,l=0,p=r.length;Object.prototype.toString.call(r[0])==="[object Boolean]"&&(c=r[0],l++);const h=function(g){for(var d in g)Object.prototype.hasOwnProperty.call(g,d)&&(c&&Object.prototype.toString.call(g[d])==="[object Object]"?n[d]=i(!0,n[d],g[d]):n[d]=g[d])};for(;l{if(o.keyCode===13)return!1})}} +class GoogleMaps2{allMarkers=[];categorizedMarkers={};pointMarkers=[];markerClusterer=null;bounds={};infoWindow={};poiCollections={};editable={};map={};constructor(e,t){this.allMarkers=[],this.categorizedMarkers={},this.pointMarkers=[],this.bounds=new google.maps.LatLngBounds,this.infoWindow=new google.maps.InfoWindow,this.poiCollections=JSON.parse(e.dataset.pois||"null"),this.editable=e.classList.contains("editMarker"),this.setMapDimensions(e,t.settings),this.initialize(e,t)}initialize=async(e,t)=>{if(this.createMap(e,t),typeof this.poiCollections>"u"||this.poiCollections===null){let s=Number(e.dataset.latitude),a=Number(e.dataset.longitude);s&&a?(await this.createMarkerByLatLng(s,a),this.map.setCenter(new google.maps.LatLng(s,a))):this.map.setCenter(new google.maps.LatLng(t.extConf.defaultLatitude,t.extConf.defaultLongitude))}else await this.createPointByCollectionType(e,t),this.createMarkerClusterer(t.settings),this.countObjectProperties(this.categorizedMarkers)>1&&this.showSwitchableCategories(e,t),this.shouldFitBounds(t.settings)?this.map.fitBounds(this.bounds):this.map.setCenter(new google.maps.LatLng(this.poiCollections[0].latitude,this.poiCollections[0].longitude))};createMarkerClusterer=e=>{this.editable||typeof e.markerClusterer>"u"||e.markerClusterer.enable!==1||typeof markerClusterer>"u"||(this.markerClusterer=new markerClusterer.MarkerClusterer({map:this.map,markers:this.pointMarkers,renderer:this.getClusterRenderer(e.markerClusterer.imagePath)}))};getClusterRenderer=e=>{const t=[53,56,66,78,90];return{render:({count:s,position:a})=>{const r=Math.min(String(s).length,t.length),o=t[r-1],i=document.createElement("div");return i.classList.add("maps2-marker-cluster"),i.textContent=String(s),i.style.width=o+"px",i.style.height=o+"px",i.style.lineHeight=o+"px",i.style.backgroundImage='url("'+e+r+'.png")',i.style.textAlign="center",i.style.fontSize="11px",i.style.fontWeight="bold",i.style.color="#000",i.style.cursor="pointer",i.style.transform="translateY(50%)",new google.maps.marker.AdvancedMarkerElement({position:a,content:i,zIndex:1e3+s})}}};getMapOptions=settings=>{let mapOptions={mapTypeId:"",zoom:parseInt(settings.zoom),zoomControl:parseInt(settings.zoomControl)!==0,mapTypeControl:parseInt(settings.mapTypeControl)!==0,scaleControl:parseInt(settings.scaleControl)!==0,streetViewControl:parseInt(settings.streetViewControl)!==0,fullscreenControl:parseInt(settings.fullScreenControl)!==0,scrollwheel:settings.activateScrollWheel,styles:""};switch(settings.styles&&(mapOptions.styles=eval(settings.styles)),settings.mapTypeId){case"google.maps.MapTypeId.HYBRID":case"hybrid":mapOptions.mapTypeId=google.maps.MapTypeId.HYBRID;break;case"google.maps.MapTypeId.ROADMAP":case"roadmap":mapOptions.mapTypeId=google.maps.MapTypeId.ROADMAP;break;case"google.maps.MapTypeId.SATELLITE":case"satellite":mapOptions.mapTypeId=google.maps.MapTypeId.SATELLITE;break;case"google.maps.MapTypeId.TERRAIN":case"terrain":mapOptions.mapTypeId=google.maps.MapTypeId.TERRAIN;break}return mapOptions};getCircleOptions(e,t,s){return{map:e,center:t,radius:s.radius,strokeColor:s.strokeColor,strokeOpacity:s.strokeOpacity,strokeWeight:s.strokeWeight,fillColor:s.fillColor,fillOpacity:s.fillOpacity}}getPolygonOptions(e,t){return{paths:e,strokeColor:t.strokeColor,strokeOpacity:t.strokeOpacity,strokeWeight:t.strokeWeight,fillColor:t.fillColor,fillOpacity:t.fillOpacity}}getPolylineOptions(e,t){return{path:e,strokeColor:t.strokeColor,strokeOpacity:t.strokeOpacity,strokeWeight:t.strokeWeight}}createMap(e,t){let s=this.getMapOptions(t.settings);s.mapId=t.settings.googleMapsMapId||"",this.map=new google.maps.Map(e,s)}canBeInterpretedAsNumber(e){return typeof e=="number"||!isNaN(Number(e))}normalizeDimension(e){let t=String(e);return this.canBeInterpretedAsNumber(t)&&(t+="px"),t}shouldFitBounds(e){return e.forceZoom===!0||this.poiCollections===null?!1:this.poiCollections.length>1||this.poiCollections.length===1&&(this.poiCollections[0].collectionType==="Area"||this.poiCollections[0].collectionType==="Route")}setMapDimensions(e,t){e.style.height=this.normalizeDimension(t.mapHeight),e.style.width=this.normalizeDimension(t.mapWidth)}groupCategories=e=>{let t={},s="0";for(let a=0;a-1&&!t.hasOwnProperty(s)&&(t[s]=this.poiCollections[a].categories[r]);return t};getCategoriesOfCheckboxesWithStatus=(e,t)=>{let s=[];return(t?e.querySelectorAll("input:checked"):e.querySelectorAll("input:not(input:checked)")).forEach(r=>{s.push(parseInt(r.value))}),s};getMarkersToChangeVisibilityFor=(e,t,s)=>{let a=[];if(this.allMarkers.length===0)return a;let r=null,o=null,i=this.getCategoriesOfCheckboxesWithStatus(t,s);for(let n=0;n{let s=this.groupCategories(t),a=document.createElement("form"),r={};a.classList.add("txMaps2Form"),a.setAttribute("id","txMaps2Form-"+t.contentRecord.uid);for(let o in s)if(s.hasOwnProperty(o)){a.appendChild(this.getCheckbox(s[o]));const i=document.createElement("span");i.classList.add("map-category"),i.textContent=s[o].title,a.querySelector("#checkCategory_"+o)?.insertAdjacentElement("afterend",i)}a.querySelectorAll("input").forEach(o=>{o.addEventListener("click",()=>{let i=o.checked,n=o.value;this.getMarkersToChangeVisibilityFor(n,a,i).forEach(l=>{this.markerClusterer!==null&&this.pointMarkers.includes(l)?i?this.markerClusterer.addMarker(l):this.markerClusterer.removeMarker(l):typeof l.setVisible=="function"?l.setVisible(i):typeof l.setMap=="function"?l.setMap(i?this.map:null):l.map=i?this.map:null})})}),e.insertAdjacentElement("afterend",a)};getCheckbox(e){const t=document.createElement("div");t.classList.add("form-group");const s=document.createElement("div");s.classList.add("checkbox");const a=document.createElement("label"),r=document.createElement("input");return r.type="checkbox",r.classList.add("checkCategory"),r.id="checkCategory_"+e.uid,r.checked=!0,r.value=e.uid,a.appendChild(r),s.appendChild(a),t.appendChild(s),t}countObjectProperties=e=>{let t=0;for(let s in e)e.hasOwnProperty(s)&&t++;return t};createPointByCollectionType=async(e,t)=>{let s,a=0;if(this.poiCollections!==null&&this.poiCollections.length)for(const r of this.poiCollections){switch(r.strokeColor===""&&(r.strokeColor=t.extConf.strokeColor),r.strokeOpacity===""&&(r.strokeOpacity=t.extConf.strokeOpacity),r.strokeWeight===""&&(r.strokeWeight=t.extConf.strokeWeight),r.fillColor===""&&(r.fillColor=t.extConf.fillColor),r.fillOpacity===""&&(r.fillOpacity=t.extConf.fillOpacity),s=null,r.collectionType){case"Point":s=await this.createMarker(r,e,t);break;case"Area":s=this.createArea(r,t);break;case"Route":s=this.createRoute(r,t);break;case"Radius":s=this.createRadius(r,t);break}if(s!==null){this.allMarkers.push({marker:s,poiCollection:r}),a=0;for(let o=0;o{const{AdvancedMarkerElement:a}=await google.maps.importLibrary("marker");let r={position:new google.maps.LatLng(e.latitude,e.longitude),map:this.map,gmpDraggable:this.editable};if(e.hasOwnProperty("markerIcon")&&e.markerIcon!==""){const i=document.createElement("img");let n=e.markerIcon;n.startsWith("/")&&(n=n.substring(1)),i.src=s.siteUrl+n;const c=e.markerIconWidth||s.extConf.markerIconWidth,l=e.markerIconHeight||s.extConf.markerIconHeight,p=e.markerIconAnchorPosX||s.extConf.markerIconAnchorPosX,h=e.markerIconAnchorPosY||s.extConf.markerIconAnchorPosY;c&&(i.style.width=c+"px"),l&&(i.style.height=l+"px"),r.content=i,p&&(r.anchorLeft="-"+p+"px"),h&&(r.anchorTop="-"+h+"px")}let o=new a(r);return this.pointMarkers.push(o),this.bounds.extend(o.position),this.editable?this.addEditListeners(t,o,e,s):this.addInfoWindow(o,e,s),o};createArea=(e,t)=>{let s,a=[];for(let o=0;o{let s,a=[];for(let o=0;o{let s=new google.maps.Circle(this.getCircleOptions(this.map,new google.maps.LatLng(e.latitude,e.longitude),e));return this.bounds.union(s.getBounds()),this.addInfoWindow(s,e,t),s};addInfoWindow=(e,t,s)=>{let a=this.infoWindow,r=this.map;google.maps.event.addListener(e,"click",o=>{fetch(s.ajaxUrl,{method:"POST",headers:{"Content-Type":"application/json","ext-maps2":"infoWindowContent"},body:JSON.stringify({poiCollection:t.uid})}).then(i=>i.json()).then(i=>{a.close(),a.setContent(i.content),t.collectionType==="Point"?(a.setPosition(null),a.open({anchor:e,map:r})):(a.setPosition(new google.maps.LatLng(t.latitude,t.longitude)),a.open(r))}).catch(i=>console.error("Error:",i))})};inList=(e,t)=>{let s=","+e+",";return t=","+t+",",s.search(t)};createMarkerByLatLng=async(e,t)=>{const{AdvancedMarkerElement:s}=await google.maps.importLibrary("marker");let a=new s({position:new google.maps.LatLng(e,t),map:this.map});this.bounds.extend(a.position)};addEditListeners=(e,t,s,a)=>{google.maps.event.addListener(t,"dragend",()=>{let r=t.position,o=(typeof r.lat=="function"?r.lat():r.lat).toFixed(6),i=(typeof r.lng=="function"?r.lng():r.lng).toFixed(6);e.prevAll("input.latitude-"+a.contentRecord.uid).val(o),e.prevAll("input.longitude-"+a.contentRecord.uid).val(i)}),google.maps.event.addListener(this.map,"click",r=>{t.position=r.latLng,e.prevAll("input.latitude-"+a.contentRecord.uid).val(r.latLng.lat().toFixed(6)),e.prevAll("input.longitude-"+a.contentRecord.uid).val(r.latLng.lng().toFixed(6))})}}let maps2GoogleMaps=[];function initMap(){document.querySelectorAll(".maps2").forEach(s=>{const a=typeof s.dataset.environment<"u"?s.dataset.environment:"{}",r=typeof s.dataset.override<"u"?s.dataset.override:"{}",o=(...i)=>{let n={},c=!1,l=0,p=i.length;Object.prototype.toString.call(i[0])==="[object Boolean]"&&(c=i[0],l++);const h=function(g){for(var d in g)Object.prototype.hasOwnProperty.call(g,d)&&(c&&Object.prototype.toString.call(g[d])==="[object Object]"?n[d]=o(!0,n[d],g[d]):n[d]=g[d])};for(;l{if(a.keyCode===13)return!1})}} //# sourceMappingURL=GoogleMaps2.min.js.map diff --git a/Resources/Public/JavaScript/GoogleMaps2.min.js.map b/Resources/Public/JavaScript/GoogleMaps2.min.js.map index 56b41f2e6..af51b3899 100644 --- a/Resources/Public/JavaScript/GoogleMaps2.min.js.map +++ b/Resources/Public/JavaScript/GoogleMaps2.min.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../Private/Build/JavaScript/GoogleMaps2.js"], - "sourcesContent": ["class GoogleMaps2 {\n allMarkers = [];\n categorizedMarkers = {};\n pointMarkers = [];\n bounds = {};\n infoWindow = {};\n poiCollections = {};\n editable = {};\n map = {};\n\n /**\n * @param {HTMLElement} element\n * @param {Environment} environment\n * @constructor\n */\n constructor (element, environment) {\n this.allMarkers = [];\n this.categorizedMarkers = {};\n this.pointMarkers = [];\n this.bounds = new google.maps.LatLngBounds();\n this.infoWindow = new google.maps.InfoWindow();\n this.poiCollections = JSON.parse(element.dataset.pois || \"null\");\n this.editable = element.classList.contains('editMarker');\n\n this.setMapDimensions(element, environment.settings);\n\n this.initialize(element, environment);\n }\n\n /**\n * Initialize Map and Markers asynchronously\n *\n * @param {HTMLElement} element\n * @param {Environment} environment\n */\n initialize = async (element, environment) => {\n this.createMap(element, environment);\n\n if (typeof this.poiCollections === 'undefined' || this.poiCollections === null) {\n let lat = Number(element.dataset.latitude);\n let lng = Number(element.dataset.longitude);\n if (lat && lng) {\n await this.createMarkerByLatLng(lat, lng);\n this.map.setCenter(new google.maps.LatLng(lat, lng));\n } else {\n this.map.setCenter(new google.maps.LatLng(environment.extConf.defaultLatitude, environment.extConf.defaultLongitude));\n }\n } else {\n await this.createPointByCollectionType(element, environment);\n if (\n typeof environment.settings.markerClusterer !== 'undefined'\n && environment.settings.markerClusterer.enable === 1\n ) {\n new MarkerClusterer(\n this.map,\n this.pointMarkers,\n { imagePath: environment.settings.markerClusterer.imagePath }\n );\n }\n\n if (this.countObjectProperties(this.categorizedMarkers) > 1) {\n this.showSwitchableCategories(element, environment);\n }\n\n if (this.shouldFitBounds(environment.settings)) {\n this.map.fitBounds(this.bounds);\n } else {\n this.map.setCenter(new google.maps.LatLng(this.poiCollections[0].latitude, this.poiCollections[0].longitude));\n }\n }\n }\n\n /**\n * Return a MapOptions object which can be assigned to the Map object of Google\n *\n * @param {Settings} settings\n * @return {object}\n */\n getMapOptions = settings => {\n let mapOptions = {\n mapTypeId: '',\n zoom: parseInt(settings.zoom),\n zoomControl: (parseInt(settings.zoomControl) !== 0),\n mapTypeControl: (parseInt(settings.mapTypeControl) !== 0),\n scaleControl: (parseInt(settings.scaleControl) !== 0),\n streetViewControl: (parseInt(settings.streetViewControl) !== 0),\n fullscreenControl: (parseInt(settings.fullScreenControl) !== 0),\n scrollwheel: settings.activateScrollWheel,\n styles: ''\n };\n\n if (settings.styles) {\n mapOptions.styles = eval(settings.styles);\n }\n\n switch (settings.mapTypeId) {\n case 'google.maps.MapTypeId.HYBRID':\n case 'hybrid':\n mapOptions.mapTypeId = google.maps.MapTypeId.HYBRID;\n break;\n case 'google.maps.MapTypeId.ROADMAP':\n case 'roadmap':\n mapOptions.mapTypeId = google.maps.MapTypeId.ROADMAP;\n break;\n case 'google.maps.MapTypeId.SATELLITE':\n case 'satellite':\n mapOptions.mapTypeId = google.maps.MapTypeId.SATELLITE;\n break;\n case 'google.maps.MapTypeId.TERRAIN':\n case 'terrain':\n mapOptions.mapTypeId = google.maps.MapTypeId.TERRAIN;\n break;\n }\n\n return mapOptions;\n }\n\n /**\n * Returns CircleOptions which can be assigned to the Circle object of Google\n *\n * @param {L.Map} map\n * @param {object} centerPosition\n * @param {PoiCollection} poiCollection\n * @return {object}\n */\n getCircleOptions (map, centerPosition, poiCollection) {\n return {\n map: map,\n center: centerPosition,\n radius: poiCollection.radius,\n strokeColor: poiCollection.strokeColor,\n strokeOpacity: poiCollection.strokeOpacity,\n strokeWeight: poiCollection.strokeWeight,\n fillColor: poiCollection.fillColor,\n fillOpacity: poiCollection.fillOpacity\n };\n }\n\n /**\n * Returns PolygonOptions which can be assigned to the Polygon object of Google\n *\n * @param {object} paths\n * @param {PoiCollection} poiCollection\n * @return {object}\n */\n getPolygonOptions (paths, poiCollection) {\n return {\n paths: paths,\n strokeColor: poiCollection.strokeColor,\n strokeOpacity: poiCollection.strokeOpacity,\n strokeWeight: poiCollection.strokeWeight,\n fillColor: poiCollection.fillColor,\n fillOpacity: poiCollection.fillOpacity\n };\n }\n\n /**\n * Return PolylineOptions which can be assigned to the Polyline object of Google\n *\n * @param {object} paths\n * @param {PoiCollection} poiCollection\n * @return {object}\n */\n getPolylineOptions (paths, poiCollection) {\n return {\n path: paths,\n strokeColor: poiCollection.strokeColor,\n strokeOpacity: poiCollection.strokeOpacity,\n strokeWeight: poiCollection.strokeWeight,\n };\n }\n\n /**\n * Create Map\n *\n * @param {HTMLElement} element\n * @param {Environment} environment\n */\n createMap (element, environment) {\n let mapOptions = this.getMapOptions(environment.settings);\n mapOptions.mapId = environment.settings.googleMapsMapId || '';\n\n this.map = new google.maps.Map(element, mapOptions);\n }\n\n /**\n * @param {string | number} value\n * @return {boolean}\n */\n canBeInterpretedAsNumber(value) {\n return typeof value === 'number' || !isNaN(Number(value));\n }\n\n /**\n * @param {string | number} dimension\n * @returns {string}\n */\n normalizeDimension(dimension) {\n let normalizedDimension = String(dimension);\n\n if (this.canBeInterpretedAsNumber(normalizedDimension)) {\n normalizedDimension += 'px';\n }\n\n return normalizedDimension;\n }\n\n /**\n * @param {Settings} settings\n * @returns {boolean}\n */\n shouldFitBounds(settings) {\n if (settings.forceZoom === true) {\n return false;\n }\n\n if (this.poiCollections === null) {\n return false;\n }\n\n if (this.poiCollections.length > 1) {\n return true;\n }\n\n if (\n this.poiCollections.length === 1\n && (\n this.poiCollections[0].collectionType === \"Area\"\n || this.poiCollections[0].collectionType === \"Route\"\n )\n ) {\n return true;\n }\n\n return false;\n }\n\n /**\n * @param {HTMLElement} element\n * @param {Settings} settings\n */\n setMapDimensions(element, settings) {\n element.style.height = this.normalizeDimension(settings.mapHeight);\n element.style.width = this.normalizeDimension(settings.mapWidth);\n }\n\n /**\n * Group Categories\n *\n * @param {Environment} environment\n */\n groupCategories = environment => {\n let groupedCategories = {};\n let categoryUid = \"0\";\n for (let x = 0; x < this.poiCollections.length; x++) {\n for (let y = 0; y < this.poiCollections[x].categories.length; y++) {\n categoryUid = String(this.poiCollections[x].categories[y].uid);\n if (this.inList(environment.settings.categories, categoryUid) > -1 && !groupedCategories.hasOwnProperty(categoryUid)) {\n groupedCategories[categoryUid] = this.poiCollections[x].categories[y];\n }\n }\n }\n\n return groupedCategories;\n };\n\n /**\n * Get categories of all checkboxes with a given status\n *\n * @param {HTMLElement} form The HTML form element containing the checkboxes\n * @param {boolean} isChecked Get checkboxes of this status only\n */\n getCategoriesOfCheckboxesWithStatus = (form, isChecked) => {\n let categories = [];\n let checkboxes = isChecked ? form.querySelectorAll(\"input:checked\") : form.querySelectorAll(\"input:not(input:checked)\");\n\n checkboxes.forEach(checkbox => {\n categories.push(parseInt(checkbox.value));\n });\n\n return categories;\n }\n\n getMarkersToChangeVisibilityFor = (categoryUid, form, isChecked) => {\n let markers = [];\n if (this.allMarkers.length === 0) {\n return markers;\n }\n\n let marker = null;\n let allCategoriesOfMarker = null;\n let categoriesOfCheckboxesWithStatus = this.getCategoriesOfCheckboxesWithStatus(form, isChecked);\n for (let i = 0; i < this.allMarkers.length; i++) {\n marker = this.allMarkers[i];\n allCategoriesOfMarker = marker.poiCollection.categories;\n if (allCategoriesOfMarker.length === 0) {\n continue;\n }\n\n let markerCategoryHasCheckboxWithStatus;\n for (let j = 0; j < allCategoriesOfMarker.length; j++) {\n markerCategoryHasCheckboxWithStatus = false;\n for (let k = 0; k < categoriesOfCheckboxesWithStatus.length; k++) {\n if (allCategoriesOfMarker[j].uid === categoriesOfCheckboxesWithStatus[k]) {\n markerCategoryHasCheckboxWithStatus = true;\n }\n }\n if (markerCategoryHasCheckboxWithStatus === isChecked) {\n break;\n }\n }\n\n if (markerCategoryHasCheckboxWithStatus) {\n markers.push(marker.marker);\n }\n }\n\n return markers;\n }\n\n /**\n * Show switchable categories\n *\n * @param {HTMLElement} element\n * @param {Environment} environment\n */\n showSwitchableCategories = (element, environment) => {\n let categories = this.groupCategories(environment);\n let form = document.createElement(\"form\");\n let span = {};\n\n form.classList.add(\"txMaps2Form\");\n form.setAttribute(\"id\", \"txMaps2Form-\" + environment.contentRecord.uid);\n\n for (let categoryUid in categories) {\n if (categories.hasOwnProperty(categoryUid)) {\n form.appendChild(this.getCheckbox(categories[categoryUid]));\n\n const categoryLabel = document.createElement(\"span\");\n categoryLabel.classList.add(\"map-category\");\n categoryLabel.textContent = categories[categoryUid].title;\n form.querySelector(\"#checkCategory_\" + categoryUid)?.insertAdjacentElement(\"afterend\", categoryLabel);\n }\n }\n\n form.querySelectorAll(\"input\").forEach((checkbox) => {\n checkbox.addEventListener(\"click\", () => {\n let isChecked = (checkbox).checked;\n let categoryUid = (checkbox).value;\n let markers = this.getMarkersToChangeVisibilityFor(categoryUid, form, isChecked);\n\n markers.forEach((marker) => {\n if (typeof marker.setVisible === 'function') {\n marker.setVisible(isChecked);\n } else if (typeof marker.setMap === 'function') {\n marker.setMap(isChecked ? this.map : null);\n } else {\n marker.map = isChecked ? this.map : null;\n }\n });\n });\n });\n\n element.insertAdjacentElement(\"afterend\", form);\n }\n\n /**\n * Get Checkbox for Category\n *\n * @param category\n */\n getCheckbox(category) {\n const div = document.createElement(\"div\");\n div.classList.add(\"form-group\");\n\n const checkboxDiv = document.createElement(\"div\");\n checkboxDiv.classList.add(\"checkbox\");\n\n const label = document.createElement(\"label\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"checkCategory\");\n input.id = \"checkCategory_\" + category.uid;\n input.checked = true;\n input.value = category.uid;\n\n label.appendChild(input);\n checkboxDiv.appendChild(label);\n div.appendChild(checkboxDiv);\n\n return div;\n }\n\n /**\n * Count Object properties\n *\n * @param obj\n */\n countObjectProperties = obj => {\n let count = 0;\n for (let key in obj) {\n if (obj.hasOwnProperty(key)) {\n count++;\n }\n }\n return count;\n }\n\n /**\n * Create Point by CollectionType\n *\n * @param {HTMLElement} element\n * @param {Environment} environment\n */\n createPointByCollectionType = async (element, environment) => {\n let marker;\n let categoryUid = 0;\n\n if (this.poiCollections !== null && this.poiCollections.length) {\n for (const poiCollection of this.poiCollections) {\n if (poiCollection.strokeColor === \"\") {\n poiCollection.strokeColor = environment.extConf.strokeColor;\n }\n if (poiCollection.strokeOpacity === \"\") {\n poiCollection.strokeOpacity = environment.extConf.strokeOpacity;\n }\n if (poiCollection.strokeWeight === \"\") {\n poiCollection.strokeWeight = environment.extConf.strokeWeight;\n }\n if (poiCollection.fillColor === \"\") {\n poiCollection.fillColor = environment.extConf.fillColor;\n }\n if (poiCollection.fillOpacity === \"\") {\n poiCollection.fillOpacity = environment.extConf.fillOpacity;\n }\n\n marker = null;\n switch (poiCollection.collectionType) {\n case \"Point\":\n marker = await this.createMarker(poiCollection, element, environment);\n break;\n case \"Area\":\n marker = this.createArea(poiCollection, environment);\n break;\n case \"Route\":\n marker = this.createRoute(poiCollection, environment);\n break;\n case \"Radius\":\n marker = this.createRadius(poiCollection, environment);\n break;\n }\n\n if (marker !== null) {\n this.allMarkers.push({\n marker: marker,\n poiCollection: poiCollection\n });\n\n categoryUid = 0;\n for (let c = 0; c < poiCollection.categories.length; c++) {\n categoryUid = poiCollection.categories[c].uid;\n if (!this.categorizedMarkers.hasOwnProperty(categoryUid)) {\n this.categorizedMarkers[categoryUid] = [];\n }\n this.categorizedMarkers[categoryUid].push({\n marker: marker,\n relatedCategories: poiCollection.categories\n });\n }\n }\n }\n }\n }\n\n /**\n * Create Marker with InfoWindow\n *\n * @param {PoiCollection} poiCollection\n * @param {HTMLElement} element\n * @param {Environment} environment\n */\n createMarker = async (poiCollection, element, environment) => {\n const { AdvancedMarkerElement } = await google.maps.importLibrary(\"marker\");\n let markerOptions = {\n position: new google.maps.LatLng(poiCollection.latitude, poiCollection.longitude),\n map: this.map,\n gmpDraggable: this.editable\n };\n\n if (poiCollection.hasOwnProperty(\"markerIcon\") && poiCollection.markerIcon !== \"\") {\n const img = document.createElement('img');\n let markerIconPath = poiCollection.markerIcon;\n\n // Remove leading slash if present, to avoid double slashes with siteUrl\n if (markerIconPath.startsWith('/')) {\n markerIconPath = markerIconPath.substring(1);\n }\n\n img.src = environment.siteUrl + markerIconPath;\n\n const markerIconWidth = poiCollection.markerIconWidth || environment.extConf.markerIconWidth;\n const markerIconHeight = poiCollection.markerIconHeight || environment.extConf.markerIconHeight;\n const markerIconAnchorPosX = poiCollection.markerIconAnchorPosX || environment.extConf.markerIconAnchorPosX;\n const markerIconAnchorPosY = poiCollection.markerIconAnchorPosY || environment.extConf.markerIconAnchorPosY;\n\n if (markerIconWidth) img.style.width = markerIconWidth + 'px';\n if (markerIconHeight) img.style.height = markerIconHeight + 'px';\n markerOptions.content = img;\n\n if (markerIconAnchorPosX) {\n markerOptions.anchorLeft = '-' + markerIconAnchorPosX + 'px';\n }\n if (markerIconAnchorPosY) {\n markerOptions.anchorTop = '-' + markerIconAnchorPosY + 'px';\n }\n }\n\n let marker = new AdvancedMarkerElement(markerOptions);\n\n this.pointMarkers.push(marker);\n this.bounds.extend(marker.position);\n\n if (this.editable) {\n this.addEditListeners(element, marker, poiCollection, environment);\n } else {\n this.addInfoWindow(marker, poiCollection, environment);\n }\n\n return marker;\n }\n\n /**\n * Create Area\n *\n * @param poiCollection\n * @param environment\n */\n createArea = (poiCollection, environment) => {\n let latLng;\n let paths = [];\n for (let i = 0; i < poiCollection.pois.length; i++) {\n latLng = new google.maps.LatLng(poiCollection.pois[i].latitude, poiCollection.pois[i].longitude);\n this.bounds.extend(latLng);\n paths.push(latLng);\n }\n\n if (paths.length === 0) {\n paths.push(this.mapPosition);\n }\n\n let area = new google.maps.Polygon(this.getPolygonOptions(paths, poiCollection));\n area.setMap(this.map);\n this.addInfoWindow(area, poiCollection, environment);\n\n return area;\n }\n\n /**\n * Create Route\n *\n * @param poiCollection\n * @param environment\n */\n createRoute = (poiCollection, environment) => {\n let latLng;\n let paths = [];\n for (let i = 0; i < poiCollection.pois.length; i++) {\n latLng = new google.maps.LatLng(poiCollection.pois[i].latitude, poiCollection.pois[i].longitude);\n this.bounds.extend(latLng);\n paths.push(latLng);\n }\n\n if (paths.length === 0) {\n paths.push(this.mapPosition);\n }\n\n let route = new google.maps.Polyline(this.getPolylineOptions(paths, poiCollection));\n route.setMap(this.map);\n this.addInfoWindow(route, poiCollection, environment);\n\n return route;\n }\n\n /**\n * Create Radius\n *\n * @param poiCollection\n * @param environment\n */\n createRadius = (poiCollection, environment) => {\n let circle = new google.maps.Circle(\n this.getCircleOptions(\n this.map,\n new google.maps.LatLng(poiCollection.latitude, poiCollection.longitude),\n poiCollection\n )\n );\n\n this.bounds.union(circle.getBounds());\n this.addInfoWindow(circle, poiCollection, environment);\n\n return circle;\n }\n\n /**\n * Add Info Window to element\n *\n * @param element\n * @param poiCollection\n * @param environment\n */\n addInfoWindow = (element, poiCollection, environment) => {\n let infoWindow = this.infoWindow;\n let map = this.map;\n google.maps.event.addListener(element, \"click\", event => {\n fetch(environment.ajaxUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"ext-maps2\": \"infoWindowContent\"\n },\n body: JSON.stringify({\n poiCollection: poiCollection.uid\n })\n })\n .then(response => response.json())\n .then(data => {\n infoWindow.close();\n infoWindow.setContent(data.content);\n\n if (poiCollection.collectionType === \"Point\") {\n infoWindow.setPosition(null);\n infoWindow.open({\n anchor: element,\n map: map\n });\n } else {\n infoWindow.setPosition(new google.maps.LatLng(poiCollection.latitude, poiCollection.longitude));\n infoWindow.open(map);\n }\n })\n .catch(error => console.error('Error:', error));\n });\n }\n\n /**\n * Check for item in list\n * Check if an item exists in a comma-separated list of items.\n *\n * @param list\n * @param item\n */\n inList = (list, item) => {\n let catSearch = ',' + list + ',';\n item = ',' + item + ',';\n return catSearch.search(item);\n };\n\n /**\n * Create Marker with InfoWindow\n *\n * @param latitude\n * @param longitude\n */\n createMarkerByLatLng = async (latitude, longitude) => {\n const { AdvancedMarkerElement } = await google.maps.importLibrary(\"marker\");\n let marker = new AdvancedMarkerElement({\n position: new google.maps.LatLng(latitude, longitude),\n map: this.map\n });\n this.bounds.extend(marker.position);\n };\n\n /**\n * Add Edit Listeners\n * This will only work for Markers (Point)\n *\n * @param mapContainer\n * @param marker\n * @param poiCollection\n * @param environment\n */\n addEditListeners = (mapContainer, marker, poiCollection, environment) => {\n google.maps.event.addListener(marker, 'dragend', () => {\n let position = marker.position;\n let lat = (typeof position.lat === 'function' ? position.lat() : position.lat).toFixed(6);\n let lng = (typeof position.lng === 'function' ? position.lng() : position.lng).toFixed(6);\n mapContainer.prevAll(\"input.latitude-\" + environment.contentRecord.uid).val(lat);\n mapContainer.prevAll(\"input.longitude-\" + environment.contentRecord.uid).val(lng);\n });\n\n google.maps.event.addListener(this.map, 'click', event => {\n marker.position = event.latLng;\n mapContainer.prevAll(\"input.latitude-\" + environment.contentRecord.uid).val(event.latLng.lat().toFixed(6));\n mapContainer.prevAll(\"input.longitude-\" + environment.contentRecord.uid).val(event.latLng.lng().toFixed(6));\n });\n };\n}\n\nlet maps2GoogleMaps = [];\n\n/**\n * This function will be called by the &callback argument of the Google Maps API library\n */\nfunction initMap () {\n document.querySelectorAll(\".maps2\").forEach(element => {\n const environment = typeof element.dataset.environment !== 'undefined' ? element.dataset.environment : '{}';\n const override = typeof element.dataset.override !== 'undefined' ? element.dataset.override : '{}';\n\n const extend = (...args) => {\n let extended = {};\n let deep = false;\n let i = 0;\n let length = args.length;\n\n if (Object.prototype.toString.call(args[0]) === '[object Boolean]') {\n deep = args[0];\n i++;\n }\n\n const merge = function (obj) {\n for ( var prop in obj ) {\n if ( Object.prototype.hasOwnProperty.call( obj, prop ) ) {\n if ( deep && Object.prototype.toString.call(obj[prop]) === '[object Object]' ) {\n extended[prop] = extend( true, extended[prop], obj[prop] );\n } else {\n extended[prop] = obj[prop];\n }\n }\n }\n };\n\n for ( ; i < length; i++ ) {\n var obj = args[i];\n merge(obj);\n }\n\n return extended;\n };\n\n maps2GoogleMaps.push(new GoogleMaps2(\n element,\n extend(true, JSON.parse(environment), JSON.parse(override))\n ));\n });\n\n let address = document.querySelector('#maps2Address');\n let radius = document.querySelector('#maps2Radius');\n if (address !== null && radius !== null) {\n let autocomplete = new google.maps.places.Autocomplete(address, {\n fields: [\"id\", \"location\", \"formattedAddress\", \"displayName\"]\n });\n\n address.addEventListener(\"keydown\", event => {\n if (event.keyCode === 13) return false;\n });\n }\n}\n"], - "mappings": "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", - "names": ["element", "environment", "lat", "lng", "map", "centerPosition", "poiCollection", "paths", "mapOptions", "value", "dimension", "normalizedDimension", "settings", "groupedCategories", "categoryUid", "x", "y", "form", "isChecked", "categories", "checkbox", "markers", "marker", "allCategoriesOfMarker", "categoriesOfCheckboxesWithStatus", "i", "markerCategoryHasCheckboxWithStatus", "j", "k", "span", "categoryLabel", "category", "div", "checkboxDiv", "label", "input", "obj", "count", "key", "c", "AdvancedMarkerElement", "markerOptions", "img", "markerIconPath", "markerIconWidth", "markerIconHeight", "markerIconAnchorPosX", "markerIconAnchorPosY", "latLng", "area", "route", "circle", "infoWindow", "event", "response", "data", "error", "list", "item", "catSearch", "latitude", "longitude", "mapContainer", "position", "override", "extend", "args", "extended", "deep", "length", "merge", "prop", "address", "radius", "autocomplete"] + "sourcesContent": ["class GoogleMaps2 {\n allMarkers = [];\n categorizedMarkers = {};\n pointMarkers = [];\n markerClusterer = null;\n bounds = {};\n infoWindow = {};\n poiCollections = {};\n editable = {};\n map = {};\n\n /**\n * @param {HTMLElement} element\n * @param {Environment} environment\n * @constructor\n */\n constructor (element, environment) {\n this.allMarkers = [];\n this.categorizedMarkers = {};\n this.pointMarkers = [];\n this.bounds = new google.maps.LatLngBounds();\n this.infoWindow = new google.maps.InfoWindow();\n this.poiCollections = JSON.parse(element.dataset.pois || \"null\");\n this.editable = element.classList.contains('editMarker');\n\n this.setMapDimensions(element, environment.settings);\n\n this.initialize(element, environment);\n }\n\n /**\n * Initialize Map and Markers asynchronously\n *\n * @param {HTMLElement} element\n * @param {Environment} environment\n */\n initialize = async (element, environment) => {\n this.createMap(element, environment);\n\n if (typeof this.poiCollections === 'undefined' || this.poiCollections === null) {\n let lat = Number(element.dataset.latitude);\n let lng = Number(element.dataset.longitude);\n if (lat && lng) {\n await this.createMarkerByLatLng(lat, lng);\n this.map.setCenter(new google.maps.LatLng(lat, lng));\n } else {\n this.map.setCenter(new google.maps.LatLng(environment.extConf.defaultLatitude, environment.extConf.defaultLongitude));\n }\n } else {\n await this.createPointByCollectionType(element, environment);\n this.createMarkerClusterer(environment.settings);\n\n if (this.countObjectProperties(this.categorizedMarkers) > 1) {\n this.showSwitchableCategories(element, environment);\n }\n\n if (this.shouldFitBounds(environment.settings)) {\n this.map.fitBounds(this.bounds);\n } else {\n this.map.setCenter(new google.maps.LatLng(this.poiCollections[0].latitude, this.poiCollections[0].longitude));\n }\n }\n }\n\n /**\n * Cluster the point markers with the official @googlemaps/markerclusterer library\n *\n * @param {Settings} settings\n */\n createMarkerClusterer = settings => {\n if (\n this.editable\n || typeof settings.markerClusterer === 'undefined'\n || settings.markerClusterer.enable !== 1\n || typeof markerClusterer === 'undefined'\n ) {\n return;\n }\n\n this.markerClusterer = new markerClusterer.MarkerClusterer({\n map: this.map,\n markers: this.pointMarkers,\n renderer: this.getClusterRenderer(settings.markerClusterer.imagePath),\n });\n }\n\n /**\n * Render clusters with the images m1.png to m5.png of the configured imagePath.\n * Image sizes and index calculation are taken from the former MarkerClusterer v1.\n *\n * @param {string} imagePath\n * @return {object}\n */\n getClusterRenderer = imagePath => {\n const imageSizes = [53, 56, 66, 78, 90];\n\n return {\n render: ({ count, position }) => {\n const index = Math.min(String(count).length, imageSizes.length);\n const size = imageSizes[index - 1];\n const content = document.createElement('div');\n\n content.classList.add('maps2-marker-cluster');\n content.textContent = String(count);\n content.style.width = size + 'px';\n content.style.height = size + 'px';\n content.style.lineHeight = size + 'px';\n content.style.backgroundImage = 'url(\"' + imagePath + index + '.png\")';\n content.style.textAlign = 'center';\n content.style.fontSize = '11px';\n content.style.fontWeight = 'bold';\n content.style.color = '#000';\n content.style.cursor = 'pointer';\n content.style.transform = 'translateY(50%)';\n\n return new google.maps.marker.AdvancedMarkerElement({\n position: position,\n content: content,\n zIndex: 1000 + count,\n });\n },\n };\n }\n\n /**\n * Return a MapOptions object which can be assigned to the Map object of Google\n *\n * @param {Settings} settings\n * @return {object}\n */\n getMapOptions = settings => {\n let mapOptions = {\n mapTypeId: '',\n zoom: parseInt(settings.zoom),\n zoomControl: (parseInt(settings.zoomControl) !== 0),\n mapTypeControl: (parseInt(settings.mapTypeControl) !== 0),\n scaleControl: (parseInt(settings.scaleControl) !== 0),\n streetViewControl: (parseInt(settings.streetViewControl) !== 0),\n fullscreenControl: (parseInt(settings.fullScreenControl) !== 0),\n scrollwheel: settings.activateScrollWheel,\n styles: ''\n };\n\n if (settings.styles) {\n mapOptions.styles = eval(settings.styles);\n }\n\n switch (settings.mapTypeId) {\n case 'google.maps.MapTypeId.HYBRID':\n case 'hybrid':\n mapOptions.mapTypeId = google.maps.MapTypeId.HYBRID;\n break;\n case 'google.maps.MapTypeId.ROADMAP':\n case 'roadmap':\n mapOptions.mapTypeId = google.maps.MapTypeId.ROADMAP;\n break;\n case 'google.maps.MapTypeId.SATELLITE':\n case 'satellite':\n mapOptions.mapTypeId = google.maps.MapTypeId.SATELLITE;\n break;\n case 'google.maps.MapTypeId.TERRAIN':\n case 'terrain':\n mapOptions.mapTypeId = google.maps.MapTypeId.TERRAIN;\n break;\n }\n\n return mapOptions;\n }\n\n /**\n * Returns CircleOptions which can be assigned to the Circle object of Google\n *\n * @param {L.Map} map\n * @param {object} centerPosition\n * @param {PoiCollection} poiCollection\n * @return {object}\n */\n getCircleOptions (map, centerPosition, poiCollection) {\n return {\n map: map,\n center: centerPosition,\n radius: poiCollection.radius,\n strokeColor: poiCollection.strokeColor,\n strokeOpacity: poiCollection.strokeOpacity,\n strokeWeight: poiCollection.strokeWeight,\n fillColor: poiCollection.fillColor,\n fillOpacity: poiCollection.fillOpacity\n };\n }\n\n /**\n * Returns PolygonOptions which can be assigned to the Polygon object of Google\n *\n * @param {object} paths\n * @param {PoiCollection} poiCollection\n * @return {object}\n */\n getPolygonOptions (paths, poiCollection) {\n return {\n paths: paths,\n strokeColor: poiCollection.strokeColor,\n strokeOpacity: poiCollection.strokeOpacity,\n strokeWeight: poiCollection.strokeWeight,\n fillColor: poiCollection.fillColor,\n fillOpacity: poiCollection.fillOpacity\n };\n }\n\n /**\n * Return PolylineOptions which can be assigned to the Polyline object of Google\n *\n * @param {object} paths\n * @param {PoiCollection} poiCollection\n * @return {object}\n */\n getPolylineOptions (paths, poiCollection) {\n return {\n path: paths,\n strokeColor: poiCollection.strokeColor,\n strokeOpacity: poiCollection.strokeOpacity,\n strokeWeight: poiCollection.strokeWeight,\n };\n }\n\n /**\n * Create Map\n *\n * @param {HTMLElement} element\n * @param {Environment} environment\n */\n createMap (element, environment) {\n let mapOptions = this.getMapOptions(environment.settings);\n mapOptions.mapId = environment.settings.googleMapsMapId || '';\n\n this.map = new google.maps.Map(element, mapOptions);\n }\n\n /**\n * @param {string | number} value\n * @return {boolean}\n */\n canBeInterpretedAsNumber(value) {\n return typeof value === 'number' || !isNaN(Number(value));\n }\n\n /**\n * @param {string | number} dimension\n * @returns {string}\n */\n normalizeDimension(dimension) {\n let normalizedDimension = String(dimension);\n\n if (this.canBeInterpretedAsNumber(normalizedDimension)) {\n normalizedDimension += 'px';\n }\n\n return normalizedDimension;\n }\n\n /**\n * @param {Settings} settings\n * @returns {boolean}\n */\n shouldFitBounds(settings) {\n if (settings.forceZoom === true) {\n return false;\n }\n\n if (this.poiCollections === null) {\n return false;\n }\n\n if (this.poiCollections.length > 1) {\n return true;\n }\n\n if (\n this.poiCollections.length === 1\n && (\n this.poiCollections[0].collectionType === \"Area\"\n || this.poiCollections[0].collectionType === \"Route\"\n )\n ) {\n return true;\n }\n\n return false;\n }\n\n /**\n * @param {HTMLElement} element\n * @param {Settings} settings\n */\n setMapDimensions(element, settings) {\n element.style.height = this.normalizeDimension(settings.mapHeight);\n element.style.width = this.normalizeDimension(settings.mapWidth);\n }\n\n /**\n * Group Categories\n *\n * @param {Environment} environment\n */\n groupCategories = environment => {\n let groupedCategories = {};\n let categoryUid = \"0\";\n for (let x = 0; x < this.poiCollections.length; x++) {\n for (let y = 0; y < this.poiCollections[x].categories.length; y++) {\n categoryUid = String(this.poiCollections[x].categories[y].uid);\n if (this.inList(environment.settings.categories, categoryUid) > -1 && !groupedCategories.hasOwnProperty(categoryUid)) {\n groupedCategories[categoryUid] = this.poiCollections[x].categories[y];\n }\n }\n }\n\n return groupedCategories;\n };\n\n /**\n * Get categories of all checkboxes with a given status\n *\n * @param {HTMLElement} form The HTML form element containing the checkboxes\n * @param {boolean} isChecked Get checkboxes of this status only\n */\n getCategoriesOfCheckboxesWithStatus = (form, isChecked) => {\n let categories = [];\n let checkboxes = isChecked ? form.querySelectorAll(\"input:checked\") : form.querySelectorAll(\"input:not(input:checked)\");\n\n checkboxes.forEach(checkbox => {\n categories.push(parseInt(checkbox.value));\n });\n\n return categories;\n }\n\n getMarkersToChangeVisibilityFor = (categoryUid, form, isChecked) => {\n let markers = [];\n if (this.allMarkers.length === 0) {\n return markers;\n }\n\n let marker = null;\n let allCategoriesOfMarker = null;\n let categoriesOfCheckboxesWithStatus = this.getCategoriesOfCheckboxesWithStatus(form, isChecked);\n for (let i = 0; i < this.allMarkers.length; i++) {\n marker = this.allMarkers[i];\n allCategoriesOfMarker = marker.poiCollection.categories;\n if (allCategoriesOfMarker.length === 0) {\n continue;\n }\n\n let markerCategoryHasCheckboxWithStatus;\n for (let j = 0; j < allCategoriesOfMarker.length; j++) {\n markerCategoryHasCheckboxWithStatus = false;\n for (let k = 0; k < categoriesOfCheckboxesWithStatus.length; k++) {\n if (allCategoriesOfMarker[j].uid === categoriesOfCheckboxesWithStatus[k]) {\n markerCategoryHasCheckboxWithStatus = true;\n }\n }\n if (markerCategoryHasCheckboxWithStatus === isChecked) {\n break;\n }\n }\n\n if (markerCategoryHasCheckboxWithStatus) {\n markers.push(marker.marker);\n }\n }\n\n return markers;\n }\n\n /**\n * Show switchable categories\n *\n * @param {HTMLElement} element\n * @param {Environment} environment\n */\n showSwitchableCategories = (element, environment) => {\n let categories = this.groupCategories(environment);\n let form = document.createElement(\"form\");\n let span = {};\n\n form.classList.add(\"txMaps2Form\");\n form.setAttribute(\"id\", \"txMaps2Form-\" + environment.contentRecord.uid);\n\n for (let categoryUid in categories) {\n if (categories.hasOwnProperty(categoryUid)) {\n form.appendChild(this.getCheckbox(categories[categoryUid]));\n\n const categoryLabel = document.createElement(\"span\");\n categoryLabel.classList.add(\"map-category\");\n categoryLabel.textContent = categories[categoryUid].title;\n form.querySelector(\"#checkCategory_\" + categoryUid)?.insertAdjacentElement(\"afterend\", categoryLabel);\n }\n }\n\n form.querySelectorAll(\"input\").forEach((checkbox) => {\n checkbox.addEventListener(\"click\", () => {\n let isChecked = (checkbox).checked;\n let categoryUid = (checkbox).value;\n let markers = this.getMarkersToChangeVisibilityFor(categoryUid, form, isChecked);\n\n markers.forEach((marker) => {\n if (this.markerClusterer !== null && this.pointMarkers.includes(marker)) {\n if (isChecked) {\n this.markerClusterer.addMarker(marker);\n } else {\n this.markerClusterer.removeMarker(marker);\n }\n } else if (typeof marker.setVisible === 'function') {\n marker.setVisible(isChecked);\n } else if (typeof marker.setMap === 'function') {\n marker.setMap(isChecked ? this.map : null);\n } else {\n marker.map = isChecked ? this.map : null;\n }\n });\n });\n });\n\n element.insertAdjacentElement(\"afterend\", form);\n }\n\n /**\n * Get Checkbox for Category\n *\n * @param category\n */\n getCheckbox(category) {\n const div = document.createElement(\"div\");\n div.classList.add(\"form-group\");\n\n const checkboxDiv = document.createElement(\"div\");\n checkboxDiv.classList.add(\"checkbox\");\n\n const label = document.createElement(\"label\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"checkCategory\");\n input.id = \"checkCategory_\" + category.uid;\n input.checked = true;\n input.value = category.uid;\n\n label.appendChild(input);\n checkboxDiv.appendChild(label);\n div.appendChild(checkboxDiv);\n\n return div;\n }\n\n /**\n * Count Object properties\n *\n * @param obj\n */\n countObjectProperties = obj => {\n let count = 0;\n for (let key in obj) {\n if (obj.hasOwnProperty(key)) {\n count++;\n }\n }\n return count;\n }\n\n /**\n * Create Point by CollectionType\n *\n * @param {HTMLElement} element\n * @param {Environment} environment\n */\n createPointByCollectionType = async (element, environment) => {\n let marker;\n let categoryUid = 0;\n\n if (this.poiCollections !== null && this.poiCollections.length) {\n for (const poiCollection of this.poiCollections) {\n if (poiCollection.strokeColor === \"\") {\n poiCollection.strokeColor = environment.extConf.strokeColor;\n }\n if (poiCollection.strokeOpacity === \"\") {\n poiCollection.strokeOpacity = environment.extConf.strokeOpacity;\n }\n if (poiCollection.strokeWeight === \"\") {\n poiCollection.strokeWeight = environment.extConf.strokeWeight;\n }\n if (poiCollection.fillColor === \"\") {\n poiCollection.fillColor = environment.extConf.fillColor;\n }\n if (poiCollection.fillOpacity === \"\") {\n poiCollection.fillOpacity = environment.extConf.fillOpacity;\n }\n\n marker = null;\n switch (poiCollection.collectionType) {\n case \"Point\":\n marker = await this.createMarker(poiCollection, element, environment);\n break;\n case \"Area\":\n marker = this.createArea(poiCollection, environment);\n break;\n case \"Route\":\n marker = this.createRoute(poiCollection, environment);\n break;\n case \"Radius\":\n marker = this.createRadius(poiCollection, environment);\n break;\n }\n\n if (marker !== null) {\n this.allMarkers.push({\n marker: marker,\n poiCollection: poiCollection\n });\n\n categoryUid = 0;\n for (let c = 0; c < poiCollection.categories.length; c++) {\n categoryUid = poiCollection.categories[c].uid;\n if (!this.categorizedMarkers.hasOwnProperty(categoryUid)) {\n this.categorizedMarkers[categoryUid] = [];\n }\n this.categorizedMarkers[categoryUid].push({\n marker: marker,\n relatedCategories: poiCollection.categories\n });\n }\n }\n }\n }\n }\n\n /**\n * Create Marker with InfoWindow\n *\n * @param {PoiCollection} poiCollection\n * @param {HTMLElement} element\n * @param {Environment} environment\n */\n createMarker = async (poiCollection, element, environment) => {\n const { AdvancedMarkerElement } = await google.maps.importLibrary(\"marker\");\n let markerOptions = {\n position: new google.maps.LatLng(poiCollection.latitude, poiCollection.longitude),\n map: this.map,\n gmpDraggable: this.editable\n };\n\n if (poiCollection.hasOwnProperty(\"markerIcon\") && poiCollection.markerIcon !== \"\") {\n const img = document.createElement('img');\n let markerIconPath = poiCollection.markerIcon;\n\n // Remove leading slash if present, to avoid double slashes with siteUrl\n if (markerIconPath.startsWith('/')) {\n markerIconPath = markerIconPath.substring(1);\n }\n\n img.src = environment.siteUrl + markerIconPath;\n\n const markerIconWidth = poiCollection.markerIconWidth || environment.extConf.markerIconWidth;\n const markerIconHeight = poiCollection.markerIconHeight || environment.extConf.markerIconHeight;\n const markerIconAnchorPosX = poiCollection.markerIconAnchorPosX || environment.extConf.markerIconAnchorPosX;\n const markerIconAnchorPosY = poiCollection.markerIconAnchorPosY || environment.extConf.markerIconAnchorPosY;\n\n if (markerIconWidth) img.style.width = markerIconWidth + 'px';\n if (markerIconHeight) img.style.height = markerIconHeight + 'px';\n markerOptions.content = img;\n\n if (markerIconAnchorPosX) {\n markerOptions.anchorLeft = '-' + markerIconAnchorPosX + 'px';\n }\n if (markerIconAnchorPosY) {\n markerOptions.anchorTop = '-' + markerIconAnchorPosY + 'px';\n }\n }\n\n let marker = new AdvancedMarkerElement(markerOptions);\n\n this.pointMarkers.push(marker);\n this.bounds.extend(marker.position);\n\n if (this.editable) {\n this.addEditListeners(element, marker, poiCollection, environment);\n } else {\n this.addInfoWindow(marker, poiCollection, environment);\n }\n\n return marker;\n }\n\n /**\n * Create Area\n *\n * @param poiCollection\n * @param environment\n */\n createArea = (poiCollection, environment) => {\n let latLng;\n let paths = [];\n for (let i = 0; i < poiCollection.pois.length; i++) {\n latLng = new google.maps.LatLng(poiCollection.pois[i].latitude, poiCollection.pois[i].longitude);\n this.bounds.extend(latLng);\n paths.push(latLng);\n }\n\n if (paths.length === 0) {\n paths.push(this.mapPosition);\n }\n\n let area = new google.maps.Polygon(this.getPolygonOptions(paths, poiCollection));\n area.setMap(this.map);\n this.addInfoWindow(area, poiCollection, environment);\n\n return area;\n }\n\n /**\n * Create Route\n *\n * @param poiCollection\n * @param environment\n */\n createRoute = (poiCollection, environment) => {\n let latLng;\n let paths = [];\n for (let i = 0; i < poiCollection.pois.length; i++) {\n latLng = new google.maps.LatLng(poiCollection.pois[i].latitude, poiCollection.pois[i].longitude);\n this.bounds.extend(latLng);\n paths.push(latLng);\n }\n\n if (paths.length === 0) {\n paths.push(this.mapPosition);\n }\n\n let route = new google.maps.Polyline(this.getPolylineOptions(paths, poiCollection));\n route.setMap(this.map);\n this.addInfoWindow(route, poiCollection, environment);\n\n return route;\n }\n\n /**\n * Create Radius\n *\n * @param poiCollection\n * @param environment\n */\n createRadius = (poiCollection, environment) => {\n let circle = new google.maps.Circle(\n this.getCircleOptions(\n this.map,\n new google.maps.LatLng(poiCollection.latitude, poiCollection.longitude),\n poiCollection\n )\n );\n\n this.bounds.union(circle.getBounds());\n this.addInfoWindow(circle, poiCollection, environment);\n\n return circle;\n }\n\n /**\n * Add Info Window to element\n *\n * @param element\n * @param poiCollection\n * @param environment\n */\n addInfoWindow = (element, poiCollection, environment) => {\n let infoWindow = this.infoWindow;\n let map = this.map;\n google.maps.event.addListener(element, \"click\", event => {\n fetch(environment.ajaxUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"ext-maps2\": \"infoWindowContent\"\n },\n body: JSON.stringify({\n poiCollection: poiCollection.uid\n })\n })\n .then(response => response.json())\n .then(data => {\n infoWindow.close();\n infoWindow.setContent(data.content);\n\n if (poiCollection.collectionType === \"Point\") {\n infoWindow.setPosition(null);\n infoWindow.open({\n anchor: element,\n map: map\n });\n } else {\n infoWindow.setPosition(new google.maps.LatLng(poiCollection.latitude, poiCollection.longitude));\n infoWindow.open(map);\n }\n })\n .catch(error => console.error('Error:', error));\n });\n }\n\n /**\n * Check for item in list\n * Check if an item exists in a comma-separated list of items.\n *\n * @param list\n * @param item\n */\n inList = (list, item) => {\n let catSearch = ',' + list + ',';\n item = ',' + item + ',';\n return catSearch.search(item);\n };\n\n /**\n * Create Marker with InfoWindow\n *\n * @param latitude\n * @param longitude\n */\n createMarkerByLatLng = async (latitude, longitude) => {\n const { AdvancedMarkerElement } = await google.maps.importLibrary(\"marker\");\n let marker = new AdvancedMarkerElement({\n position: new google.maps.LatLng(latitude, longitude),\n map: this.map\n });\n this.bounds.extend(marker.position);\n };\n\n /**\n * Add Edit Listeners\n * This will only work for Markers (Point)\n *\n * @param mapContainer\n * @param marker\n * @param poiCollection\n * @param environment\n */\n addEditListeners = (mapContainer, marker, poiCollection, environment) => {\n google.maps.event.addListener(marker, 'dragend', () => {\n let position = marker.position;\n let lat = (typeof position.lat === 'function' ? position.lat() : position.lat).toFixed(6);\n let lng = (typeof position.lng === 'function' ? position.lng() : position.lng).toFixed(6);\n mapContainer.prevAll(\"input.latitude-\" + environment.contentRecord.uid).val(lat);\n mapContainer.prevAll(\"input.longitude-\" + environment.contentRecord.uid).val(lng);\n });\n\n google.maps.event.addListener(this.map, 'click', event => {\n marker.position = event.latLng;\n mapContainer.prevAll(\"input.latitude-\" + environment.contentRecord.uid).val(event.latLng.lat().toFixed(6));\n mapContainer.prevAll(\"input.longitude-\" + environment.contentRecord.uid).val(event.latLng.lng().toFixed(6));\n });\n };\n}\n\nlet maps2GoogleMaps = [];\n\n/**\n * This function will be called by the &callback argument of the Google Maps API library\n */\nfunction initMap () {\n document.querySelectorAll(\".maps2\").forEach(element => {\n const environment = typeof element.dataset.environment !== 'undefined' ? element.dataset.environment : '{}';\n const override = typeof element.dataset.override !== 'undefined' ? element.dataset.override : '{}';\n\n const extend = (...args) => {\n let extended = {};\n let deep = false;\n let i = 0;\n let length = args.length;\n\n if (Object.prototype.toString.call(args[0]) === '[object Boolean]') {\n deep = args[0];\n i++;\n }\n\n const merge = function (obj) {\n for ( var prop in obj ) {\n if ( Object.prototype.hasOwnProperty.call( obj, prop ) ) {\n if ( deep && Object.prototype.toString.call(obj[prop]) === '[object Object]' ) {\n extended[prop] = extend( true, extended[prop], obj[prop] );\n } else {\n extended[prop] = obj[prop];\n }\n }\n }\n };\n\n for ( ; i < length; i++ ) {\n var obj = args[i];\n merge(obj);\n }\n\n return extended;\n };\n\n maps2GoogleMaps.push(new GoogleMaps2(\n element,\n extend(true, JSON.parse(environment), JSON.parse(override))\n ));\n });\n\n let address = document.querySelector('#maps2Address');\n let radius = document.querySelector('#maps2Radius');\n if (address !== null && radius !== null) {\n let autocomplete = new google.maps.places.Autocomplete(address, {\n fields: [\"id\", \"location\", \"formattedAddress\", \"displayName\"]\n });\n\n address.addEventListener(\"keydown\", event => {\n if (event.keyCode === 13) return false;\n });\n }\n}\n"], + "mappings": "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", + "names": ["element", "environment", "lat", "lng", "settings", "imagePath", "imageSizes", "count", "position", "index", "size", "content", "map", "centerPosition", "poiCollection", "paths", "mapOptions", "value", "dimension", "normalizedDimension", "groupedCategories", "categoryUid", "x", "y", "form", "isChecked", "categories", "checkbox", "markers", "marker", "allCategoriesOfMarker", "categoriesOfCheckboxesWithStatus", "i", "markerCategoryHasCheckboxWithStatus", "j", "k", "span", "categoryLabel", "category", "div", "checkboxDiv", "label", "input", "obj", "key", "c", "AdvancedMarkerElement", "markerOptions", "img", "markerIconPath", "markerIconWidth", "markerIconHeight", "markerIconAnchorPosX", "markerIconAnchorPosY", "latLng", "area", "route", "circle", "infoWindow", "event", "response", "data", "error", "list", "item", "catSearch", "latitude", "longitude", "mapContainer", "override", "extend", "args", "extended", "deep", "length", "merge", "prop", "address", "radius", "autocomplete"] } diff --git a/Resources/Public/JavaScript/MarkerClusterer.js b/Resources/Public/JavaScript/MarkerClusterer.js deleted file mode 100644 index f53d70d84..000000000 --- a/Resources/Public/JavaScript/MarkerClusterer.js +++ /dev/null @@ -1,1319 +0,0 @@ -// ==ClosureCompiler== -// @compilation_level ADVANCED_OPTIMIZATIONS -// @externs_url http://closure-compiler.googlecode.com/svn/trunk/contrib/externs/maps/google_maps_api_v3_3.js -// ==/ClosureCompiler== - -/** - * @name MarkerClusterer for Google Maps v3 - * @version version 1.0.1 - * @author Luke Mahe - * @fileoverview - * The library creates and manages per-zoom-level clusters for large amounts of - * markers. - */ - -/** - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -/** - * A Marker Clusterer that clusters markers. - * - * @param {google.maps.Map} map The Google map to attach to. - * @param {Array.=} opt_markers Optional markers to add to - * the cluster. - * @param {Object=} opt_options support the following options: - * 'gridSize': (number) The grid size of a cluster in pixels. - * 'maxZoom': (number) The maximum zoom level that a marker can be part of a - * cluster. - * 'zoomOnClick': (boolean) Whether the default behaviour of clicking on a - * cluster is to zoom into it. - * 'imagePath': (string) The base URL where the images representing - * clusters will be found. The full URL will be: - * {imagePath}[1-5].{imageExtension} - * Default: '../images/m'. - * 'imageExtension': (string) The suffix for images URL representing - * clusters will be found. See _imagePath_ for details. - * Default: 'png'. - * 'averageCenter': (boolean) Whether the center of each cluster should be - * the average of all markers in the cluster. - * 'minimumClusterSize': (number) The minimum number of markers to be in a - * cluster before the markers are hidden and a count - * is shown. - * 'styles': (object) An object that has style properties: - * 'url': (string) The image url. - * 'height': (number) The image height. - * 'width': (number) The image width. - * 'anchor': (Array) The anchor position of the label text. - * 'textColor': (string) The text color. - * 'textSize': (number) The text size. - * 'backgroundPosition': (string) The position of the backgound x, y. - * @constructor - * @extends google.maps.OverlayView - */ -function MarkerClusterer(map, opt_markers, opt_options) { - // MarkerClusterer implements google.maps.OverlayView interface. We use the - // extend function to extend MarkerClusterer with google.maps.OverlayView - // because it might not always be available when the code is defined so we - // look for it at the last possible moment. If it doesn't exist now then - // there is no point going ahead :) - this.extend(MarkerClusterer, google.maps.OverlayView); - this.map_ = map; - - /** - * @type {Array.} - * @private - */ - this.markers_ = []; - - /** - * @type {Array.} - */ - this.clusters_ = []; - - this.sizes = [53, 56, 66, 78, 90]; - - /** - * @private - */ - this.styles_ = []; - - /** - * @type {boolean} - * @private - */ - this.ready_ = false; - - var options = opt_options || {}; - - /** - * @type {number} - * @private - */ - this.gridSize_ = options['gridSize'] || 60; - - /** - * @private - */ - this.minClusterSize_ = options['minimumClusterSize'] || 2; - - - /** - * @type {?number} - * @private - */ - this.maxZoom_ = options['maxZoom'] || null; - - this.styles_ = options['styles'] || []; - - /** - * @type {string} - * @private - */ - this.imagePath_ = options['imagePath'] || - this.MARKER_CLUSTER_IMAGE_PATH_; - - /** - * @type {string} - * @private - */ - this.imageExtension_ = options['imageExtension'] || - this.MARKER_CLUSTER_IMAGE_EXTENSION_; - - /** - * @type {boolean} - * @private - */ - this.zoomOnClick_ = true; - - if (options['zoomOnClick'] != undefined) { - this.zoomOnClick_ = options['zoomOnClick']; - } - - /** - * @type {boolean} - * @private - */ - this.averageCenter_ = false; - - if (options['averageCenter'] != undefined) { - this.averageCenter_ = options['averageCenter']; - } - - this.setupStyles_(); - - this.setMap(map); - - /** - * @type {number} - * @private - */ - this.prevZoom_ = this.map_.getZoom(); - - // Add the map event listeners - var that = this; - google.maps.event.addListener(this.map_, 'zoom_changed', function() { - // Determines map type and prevent illegal zoom levels - var zoom = that.map_.getZoom(); - var minZoom = that.map_.minZoom || 0; - var maxZoom = Math.min(that.map_.maxZoom || 100, - that.map_.mapTypes[that.map_.getMapTypeId()].maxZoom); - zoom = Math.min(Math.max(zoom,minZoom),maxZoom); - - if (that.prevZoom_ != zoom) { - that.prevZoom_ = zoom; - that.resetViewport(); - } - }); - - google.maps.event.addListener(this.map_, 'idle', function() { - that.redraw(); - }); - - // Finally, add the markers - if (opt_markers && (opt_markers.length || Object.keys(opt_markers).length)) { - this.addMarkers(opt_markers, false); - } -} - - -/** - * The marker cluster image path. - * - * @type {string} - * @private - */ -MarkerClusterer.prototype.MARKER_CLUSTER_IMAGE_PATH_ = '../images/m'; - - -/** - * The marker cluster image path. - * - * @type {string} - * @private - */ -MarkerClusterer.prototype.MARKER_CLUSTER_IMAGE_EXTENSION_ = 'png'; - - -/** - * Extends a objects prototype by anothers. - * - * @param {Object} obj1 The object to be extended. - * @param {Object} obj2 The object to extend with. - * @return {Object} The new extended object. - * @ignore - */ -MarkerClusterer.prototype.extend = function(obj1, obj2) { - return (function(object) { - for (var property in object.prototype) { - this.prototype[property] = object.prototype[property]; - } - return this; - }).apply(obj1, [obj2]); -}; - - -/** - * Implementaion of the interface method. - * @ignore - */ -MarkerClusterer.prototype.onAdd = function() { - this.setReady_(true); -}; - -/** - * Implementaion of the interface method. - * @ignore - */ -MarkerClusterer.prototype.draw = function() {}; - -/** - * Sets up the styles object. - * - * @private - */ -MarkerClusterer.prototype.setupStyles_ = function() { - if (this.styles_.length) { - return; - } - - for (var i = 0, size; size = this.sizes[i]; i++) { - this.styles_.push({ - url: this.imagePath_ + (i + 1) + '.' + this.imageExtension_, - height: size, - width: size - }); - } -}; - -/** - * Fit the map to the bounds of the markers in the clusterer. - */ -MarkerClusterer.prototype.fitMapToMarkers = function() { - var markers = this.getMarkers(); - var bounds = new google.maps.LatLngBounds(); - for (var i = 0, marker; marker = markers[i]; i++) { - bounds.extend(marker.getPosition()); - } - - this.map_.fitBounds(bounds); -}; - - -/** - * Sets the styles. - * - * @param {Object} styles The style to set. - */ -MarkerClusterer.prototype.setStyles = function(styles) { - this.styles_ = styles; -}; - - -/** - * Gets the styles. - * - * @return {Object} The styles object. - */ -MarkerClusterer.prototype.getStyles = function() { - return this.styles_; -}; - - -/** - * Whether zoom on click is set. - * - * @return {boolean} True if zoomOnClick_ is set. - */ -MarkerClusterer.prototype.isZoomOnClick = function() { - return this.zoomOnClick_; -}; - -/** - * Whether average center is set. - * - * @return {boolean} True if averageCenter_ is set. - */ -MarkerClusterer.prototype.isAverageCenter = function() { - return this.averageCenter_; -}; - - -/** - * Returns the array of markers in the clusterer. - * - * @return {Array.} The markers. - */ -MarkerClusterer.prototype.getMarkers = function() { - return this.markers_; -}; - - -/** - * Returns the number of markers in the clusterer - * - * @return {Number} The number of markers. - */ -MarkerClusterer.prototype.getTotalMarkers = function() { - return this.markers_.length; -}; - - -/** - * Sets the max zoom for the clusterer. - * - * @param {number} maxZoom The max zoom level. - */ -MarkerClusterer.prototype.setMaxZoom = function(maxZoom) { - this.maxZoom_ = maxZoom; -}; - - -/** - * Gets the max zoom for the clusterer. - * - * @return {number} The max zoom level. - */ -MarkerClusterer.prototype.getMaxZoom = function() { - return this.maxZoom_; -}; - - -/** - * The function for calculating the cluster icon image. - * - * @param {Array.} markers The markers in the clusterer. - * @param {number} numStyles The number of styles available. - * @return {Object} A object properties: 'text' (string) and 'index' (number). - * @private - */ -MarkerClusterer.prototype.calculator_ = function(markers, numStyles) { - var index = 0; - var count = markers.length; - var dv = count; - while (dv !== 0) { - dv = parseInt(dv / 10, 10); - index++; - } - - index = Math.min(index, numStyles); - return { - text: count, - index: index - }; -}; - - -/** - * Set the calculator function. - * - * @param {function(Array, number)} calculator The function to set as the - * calculator. The function should return a object properties: - * 'text' (string) and 'index' (number). - * - */ -MarkerClusterer.prototype.setCalculator = function(calculator) { - this.calculator_ = calculator; -}; - - -/** - * Get the calculator function. - * - * @return {function(Array, number)} the calculator function. - */ -MarkerClusterer.prototype.getCalculator = function() { - return this.calculator_; -}; - - -/** - * Add an array of markers to the clusterer. - * - * @param {Array.} markers The markers to add. - * @param {boolean=} opt_nodraw Whether to redraw the clusters. - */ -MarkerClusterer.prototype.addMarkers = function(markers, opt_nodraw) { - if (markers.length) { - for (var i = 0, marker; marker = markers[i]; i++) { - this.pushMarkerTo_(marker); - } - } else if (Object.keys(markers).length) { - for (var marker in markers) { - this.pushMarkerTo_(markers[marker]); - } - } - if (!opt_nodraw) { - this.redraw(); - } -}; - - -/** - * Pushes a marker to the clusterer. - * - * @param {google.maps.Marker} marker The marker to add. - * @private - */ -MarkerClusterer.prototype.pushMarkerTo_ = function(marker) { - marker.isAdded = false; - if (marker['draggable']) { - // If the marker is draggable add a listener so we update the clusters on - // the drag end. - var that = this; - google.maps.event.addListener(marker, 'dragend', function() { - marker.isAdded = false; - that.repaint(); - }); - } - this.markers_.push(marker); -}; - - -/** - * Adds a marker to the clusterer and redraws if needed. - * - * @param {google.maps.Marker} marker The marker to add. - * @param {boolean=} opt_nodraw Whether to redraw the clusters. - */ -MarkerClusterer.prototype.addMarker = function(marker, opt_nodraw) { - this.pushMarkerTo_(marker); - if (!opt_nodraw) { - this.redraw(); - } -}; - - -/** - * Removes a marker and returns true if removed, false if not - * - * @param {google.maps.Marker} marker The marker to remove - * @return {boolean} Whether the marker was removed or not - * @private - */ -MarkerClusterer.prototype.removeMarker_ = function(marker) { - var index = -1; - if (this.markers_.indexOf) { - index = this.markers_.indexOf(marker); - } else { - for (var i = 0, m; m = this.markers_[i]; i++) { - if (m == marker) { - index = i; - break; - } - } - } - - if (index == -1) { - // Marker is not in our list of markers. - return false; - } - - marker.setMap(null); - - this.markers_.splice(index, 1); - - return true; -}; - - -/** - * Remove a marker from the cluster. - * - * @param {google.maps.Marker} marker The marker to remove. - * @param {boolean=} opt_nodraw Optional boolean to force no redraw. - * @return {boolean} True if the marker was removed. - */ -MarkerClusterer.prototype.removeMarker = function(marker, opt_nodraw) { - var removed = this.removeMarker_(marker); - - if (!opt_nodraw && removed) { - this.resetViewport(); - this.redraw(); - return true; - } else { - return false; - } -}; - - -/** - * Removes an array of markers from the cluster. - * - * @param {Array.} markers The markers to remove. - * @param {boolean=} opt_nodraw Optional boolean to force no redraw. - */ -MarkerClusterer.prototype.removeMarkers = function(markers, opt_nodraw) { - // create a local copy of markers if required - // (removeMarker_ modifies the getMarkers() array in place) - var markersCopy = markers === this.getMarkers() ? markers.slice() : markers; - var removed = false; - - for (var i = 0, marker; marker = markersCopy[i]; i++) { - var r = this.removeMarker_(marker); - removed = removed || r; - } - - if (!opt_nodraw && removed) { - this.resetViewport(); - this.redraw(); - return true; - } -}; - - -/** - * Sets the clusterer's ready state. - * - * @param {boolean} ready The state. - * @private - */ -MarkerClusterer.prototype.setReady_ = function(ready) { - if (!this.ready_) { - this.ready_ = ready; - this.createClusters_(); - } -}; - - -/** - * Returns the number of clusters in the clusterer. - * - * @return {number} The number of clusters. - */ -MarkerClusterer.prototype.getTotalClusters = function() { - return this.clusters_.length; -}; - - -/** - * Returns the google map that the clusterer is associated with. - * - * @return {google.maps.Map} The map. - */ -MarkerClusterer.prototype.getMap = function() { - return this.map_; -}; - - -/** - * Sets the google map that the clusterer is associated with. - * - * @param {google.maps.Map} map The map. - */ -MarkerClusterer.prototype.setMap = function(map) { - this.map_ = map; -}; - - -/** - * Returns the size of the grid. - * - * @return {number} The grid size. - */ -MarkerClusterer.prototype.getGridSize = function() { - return this.gridSize_; -}; - - -/** - * Sets the size of the grid. - * - * @param {number} size The grid size. - */ -MarkerClusterer.prototype.setGridSize = function(size) { - this.gridSize_ = size; -}; - - -/** - * Returns the min cluster size. - * - * @return {number} The grid size. - */ -MarkerClusterer.prototype.getMinClusterSize = function() { - return this.minClusterSize_; -}; - -/** - * Sets the min cluster size. - * - * @param {number} size The grid size. - */ -MarkerClusterer.prototype.setMinClusterSize = function(size) { - this.minClusterSize_ = size; -}; - - -/** - * Extends a bounds object by the grid size. - * - * @param {google.maps.LatLngBounds} bounds The bounds to extend. - * @return {google.maps.LatLngBounds} The extended bounds. - */ -MarkerClusterer.prototype.getExtendedBounds = function(bounds) { - var projection = this.getProjection(); - - // Turn the bounds into latlng. - var tr = new google.maps.LatLng(bounds.getNorthEast().lat(), - bounds.getNorthEast().lng()); - var bl = new google.maps.LatLng(bounds.getSouthWest().lat(), - bounds.getSouthWest().lng()); - - // Convert the points to pixels and the extend out by the grid size. - var trPix = projection.fromLatLngToDivPixel(tr); - trPix.x += this.gridSize_; - trPix.y -= this.gridSize_; - - var blPix = projection.fromLatLngToDivPixel(bl); - blPix.x -= this.gridSize_; - blPix.y += this.gridSize_; - - // Convert the pixel points back to LatLng - var ne = projection.fromDivPixelToLatLng(trPix); - var sw = projection.fromDivPixelToLatLng(blPix); - - // Extend the bounds to contain the new bounds. - bounds.extend(ne); - bounds.extend(sw); - - return bounds; -}; - - -/** - * Determins if a marker is contained in a bounds. - * - * @param {google.maps.Marker} marker The marker to check. - * @param {google.maps.LatLngBounds} bounds The bounds to check against. - * @return {boolean} True if the marker is in the bounds. - * @private - */ -MarkerClusterer.prototype.isMarkerInBounds_ = function(marker, bounds) { - return bounds.contains(marker.getPosition()); -}; - - -/** - * Clears all clusters and markers from the clusterer. - */ -MarkerClusterer.prototype.clearMarkers = function() { - this.resetViewport(true); - - // Set the markers a empty array. - this.markers_ = []; -}; - - -/** - * Clears all existing clusters and recreates them. - * @param {boolean} opt_hide To also hide the marker. - */ -MarkerClusterer.prototype.resetViewport = function(opt_hide) { - // Remove all the clusters - for (var i = 0, cluster; cluster = this.clusters_[i]; i++) { - cluster.remove(); - } - - // Reset the markers to not be added and to be invisible. - for (var i = 0, marker; marker = this.markers_[i]; i++) { - marker.isAdded = false; - if (opt_hide) { - marker.setMap(null); - } - } - - this.clusters_ = []; -}; - -/** - * - */ -MarkerClusterer.prototype.repaint = function() { - var oldClusters = this.clusters_.slice(); - this.clusters_.length = 0; - this.resetViewport(); - this.redraw(); - - // Remove the old clusters. - // Do it in a timeout so the other clusters have been drawn first. - window.setTimeout(function() { - for (var i = 0, cluster; cluster = oldClusters[i]; i++) { - cluster.remove(); - } - }, 0); -}; - - -/** - * Redraws the clusters. - */ -MarkerClusterer.prototype.redraw = function() { - this.createClusters_(); -}; - - -/** - * Calculates the distance between two latlng locations in km. - * @see http://www.movable-type.co.uk/scripts/latlong.html - * - * @param {google.maps.LatLng} p1 The first lat lng point. - * @param {google.maps.LatLng} p2 The second lat lng point. - * @return {number} The distance between the two points in km. - * @private - */ -MarkerClusterer.prototype.distanceBetweenPoints_ = function(p1, p2) { - if (!p1 || !p2) { - return 0; - } - - var R = 6371; // Radius of the Earth in km - var dLat = (p2.lat() - p1.lat()) * Math.PI / 180; - var dLon = (p2.lng() - p1.lng()) * Math.PI / 180; - var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + - Math.cos(p1.lat() * Math.PI / 180) * Math.cos(p2.lat() * Math.PI / 180) * - Math.sin(dLon / 2) * Math.sin(dLon / 2); - var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); - var d = R * c; - return d; -}; - - -/** - * Add a marker to a cluster, or creates a new cluster. - * - * @param {google.maps.Marker} marker The marker to add. - * @private - */ -MarkerClusterer.prototype.addToClosestCluster_ = function(marker) { - var distance = 40000; // Some large number - var clusterToAddTo = null; - var pos = marker.getPosition(); - for (var i = 0, cluster; cluster = this.clusters_[i]; i++) { - var center = cluster.getCenter(); - if (center) { - var d = this.distanceBetweenPoints_(center, marker.getPosition()); - if (d < distance) { - distance = d; - clusterToAddTo = cluster; - } - } - } - - if (clusterToAddTo && clusterToAddTo.isMarkerInClusterBounds(marker)) { - clusterToAddTo.addMarker(marker); - } else { - var cluster = new Cluster(this); - cluster.addMarker(marker); - this.clusters_.push(cluster); - } -}; - - -/** - * Creates the clusters. - * - * @private - */ -MarkerClusterer.prototype.createClusters_ = function() { - if (!this.ready_) { - return; - } - - // Get our current map view bounds. - // Create a new bounds object so we don't affect the map. - var mapBounds = new google.maps.LatLngBounds(this.map_.getBounds().getSouthWest(), - this.map_.getBounds().getNorthEast()); - var bounds = this.getExtendedBounds(mapBounds); - - for (var i = 0, marker; marker = this.markers_[i]; i++) { - if (!marker.isAdded && this.isMarkerInBounds_(marker, bounds)) { - this.addToClosestCluster_(marker); - } - } -}; - - -/** - * A cluster that contains markers. - * - * @param {MarkerClusterer} markerClusterer The markerclusterer that this - * cluster is associated with. - * @constructor - * @ignore - */ -function Cluster(markerClusterer) { - this.markerClusterer_ = markerClusterer; - this.map_ = markerClusterer.getMap(); - this.gridSize_ = markerClusterer.getGridSize(); - this.minClusterSize_ = markerClusterer.getMinClusterSize(); - this.averageCenter_ = markerClusterer.isAverageCenter(); - this.center_ = null; - this.markers_ = []; - this.bounds_ = null; - this.clusterIcon_ = new ClusterIcon(this, markerClusterer.getStyles(), - markerClusterer.getGridSize()); -} - -/** - * Determins if a marker is already added to the cluster. - * - * @param {google.maps.Marker} marker The marker to check. - * @return {boolean} True if the marker is already added. - */ -Cluster.prototype.isMarkerAlreadyAdded = function(marker) { - if (this.markers_.indexOf) { - return this.markers_.indexOf(marker) != -1; - } else { - for (var i = 0, m; m = this.markers_[i]; i++) { - if (m == marker) { - return true; - } - } - } - return false; -}; - - -/** - * Add a marker the cluster. - * - * @param {google.maps.Marker} marker The marker to add. - * @return {boolean} True if the marker was added. - */ -Cluster.prototype.addMarker = function(marker) { - if (this.isMarkerAlreadyAdded(marker)) { - return false; - } - - if (!this.center_) { - this.center_ = marker.getPosition(); - this.calculateBounds_(); - } else { - if (this.averageCenter_) { - var l = this.markers_.length + 1; - var lat = (this.center_.lat() * (l-1) + marker.getPosition().lat()) / l; - var lng = (this.center_.lng() * (l-1) + marker.getPosition().lng()) / l; - this.center_ = new google.maps.LatLng(lat, lng); - this.calculateBounds_(); - } - } - - marker.isAdded = true; - this.markers_.push(marker); - - var len = this.markers_.length; - if (len < this.minClusterSize_ && marker.getMap() != this.map_) { - // Min cluster size not reached so show the marker. - marker.setMap(this.map_); - } - - if (len == this.minClusterSize_) { - // Hide the markers that were showing. - for (var i = 0; i < len; i++) { - this.markers_[i].setMap(null); - } - } - - if (len >= this.minClusterSize_) { - marker.setMap(null); - } - - this.updateIcon(); - return true; -}; - - -/** - * Returns the marker clusterer that the cluster is associated with. - * - * @return {MarkerClusterer} The associated marker clusterer. - */ -Cluster.prototype.getMarkerClusterer = function() { - return this.markerClusterer_; -}; - - -/** - * Returns the bounds of the cluster. - * - * @return {google.maps.LatLngBounds} the cluster bounds. - */ -Cluster.prototype.getBounds = function() { - var bounds = new google.maps.LatLngBounds(this.center_, this.center_); - var markers = this.getMarkers(); - for (var i = 0, marker; marker = markers[i]; i++) { - bounds.extend(marker.getPosition()); - } - return bounds; -}; - - -/** - * Removes the cluster - */ -Cluster.prototype.remove = function() { - this.clusterIcon_.remove(); - this.markers_.length = 0; - delete this.markers_; -}; - - -/** - * Returns the number of markers in the cluster. - * - * @return {number} The number of markers in the cluster. - */ -Cluster.prototype.getSize = function() { - return this.markers_.length; -}; - - -/** - * Returns a list of the markers in the cluster. - * - * @return {Array.} The markers in the cluster. - */ -Cluster.prototype.getMarkers = function() { - return this.markers_; -}; - - -/** - * Returns the center of the cluster. - * - * @return {google.maps.LatLng} The cluster center. - */ -Cluster.prototype.getCenter = function() { - return this.center_; -}; - - -/** - * Calculated the extended bounds of the cluster with the grid. - * - * @private - */ -Cluster.prototype.calculateBounds_ = function() { - var bounds = new google.maps.LatLngBounds(this.center_, this.center_); - this.bounds_ = this.markerClusterer_.getExtendedBounds(bounds); -}; - - -/** - * Determines if a marker lies in the clusters bounds. - * - * @param {google.maps.Marker} marker The marker to check. - * @return {boolean} True if the marker lies in the bounds. - */ -Cluster.prototype.isMarkerInClusterBounds = function(marker) { - return this.bounds_.contains(marker.getPosition()); -}; - - -/** - * Returns the map that the cluster is associated with. - * - * @return {google.maps.Map} The map. - */ -Cluster.prototype.getMap = function() { - return this.map_; -}; - - -/** - * Updates the cluster icon - */ -Cluster.prototype.updateIcon = function() { - var zoom = this.map_.getZoom(); - var mz = this.markerClusterer_.getMaxZoom(); - - if (mz && zoom > mz) { - // The zoom is greater than our max zoom so show all the markers in cluster. - for (var i = 0, marker; marker = this.markers_[i]; i++) { - marker.setMap(this.map_); - } - return; - } - - if (this.markers_.length < this.minClusterSize_) { - // Min cluster size not yet reached. - this.clusterIcon_.hide(); - return; - } - - var numStyles = this.markerClusterer_.getStyles().length; - var sums = this.markerClusterer_.getCalculator()(this.markers_, numStyles); - this.clusterIcon_.setCenter(this.center_); - this.clusterIcon_.setSums(sums); - this.clusterIcon_.show(); -}; - - -/** - * A cluster icon - * - * @param {Cluster} cluster The cluster to be associated with. - * @param {Object} styles An object that has style properties: - * 'url': (string) The image url. - * 'height': (number) The image height. - * 'width': (number) The image width. - * 'anchor': (Array) The anchor position of the label text. - * 'textColor': (string) The text color. - * 'textSize': (number) The text size. - * 'backgroundPosition: (string) The background postition x, y. - * @param {number=} opt_padding Optional padding to apply to the cluster icon. - * @constructor - * @extends google.maps.OverlayView - * @ignore - */ -function ClusterIcon(cluster, styles, opt_padding) { - cluster.getMarkerClusterer().extend(ClusterIcon, google.maps.OverlayView); - - this.styles_ = styles; - this.padding_ = opt_padding || 0; - this.cluster_ = cluster; - this.center_ = null; - this.map_ = cluster.getMap(); - this.div_ = null; - this.sums_ = null; - this.visible_ = false; - - this.setMap(this.map_); -} - - -/** - * Triggers the clusterclick event and zoom's if the option is set. - */ -ClusterIcon.prototype.triggerClusterClick = function() { - var markerClusterer = this.cluster_.getMarkerClusterer(); - - // Trigger the clusterclick event. - google.maps.event.trigger(markerClusterer.map_, 'clusterclick', this.cluster_); - - if (markerClusterer.isZoomOnClick()) { - // Zoom into the cluster. - this.map_.fitBounds(this.cluster_.getBounds()); - } -}; - - -/** - * Adding the cluster icon to the dom. - * @ignore - */ -ClusterIcon.prototype.onAdd = function() { - this.div_ = document.createElement('DIV'); - if (this.visible_) { - var pos = this.getPosFromLatLng_(this.center_); - this.div_.style.cssText = this.createCss(pos); - this.div_.innerHTML = this.sums_.text; - } - - var panes = this.getPanes(); - panes.overlayMouseTarget.appendChild(this.div_); - - var that = this; - google.maps.event.addDomListener(this.div_, 'click', function() { - that.triggerClusterClick(); - }); -}; - - -/** - * Returns the position to place the div dending on the latlng. - * - * @param {google.maps.LatLng} latlng The position in latlng. - * @return {google.maps.Point} The position in pixels. - * @private - */ -ClusterIcon.prototype.getPosFromLatLng_ = function(latlng) { - var pos = this.getProjection().fromLatLngToDivPixel(latlng); - pos.x -= parseInt(this.width_ / 2, 10); - pos.y -= parseInt(this.height_ / 2, 10); - return pos; -}; - - -/** - * Draw the icon. - * @ignore - */ -ClusterIcon.prototype.draw = function() { - if (this.visible_) { - var pos = this.getPosFromLatLng_(this.center_); - this.div_.style.top = pos.y + 'px'; - this.div_.style.left = pos.x + 'px'; - this.div_.style.zIndex = google.maps.Marker.MAX_ZINDEX + 1; - } -}; - - -/** - * Hide the icon. - */ -ClusterIcon.prototype.hide = function() { - if (this.div_) { - this.div_.style.display = 'none'; - } - this.visible_ = false; -}; - - -/** - * Position and show the icon. - */ -ClusterIcon.prototype.show = function() { - if (this.div_) { - var pos = this.getPosFromLatLng_(this.center_); - this.div_.style.cssText = this.createCss(pos); - this.div_.style.display = ''; - } - this.visible_ = true; -}; - - -/** - * Remove the icon from the map - */ -ClusterIcon.prototype.remove = function() { - this.setMap(null); -}; - - -/** - * Implementation of the onRemove interface. - * @ignore - */ -ClusterIcon.prototype.onRemove = function() { - if (this.div_ && this.div_.parentNode) { - this.hide(); - this.div_.parentNode.removeChild(this.div_); - this.div_ = null; - } -}; - - -/** - * Set the sums of the icon. - * - * @param {Object} sums The sums containing: - * 'text': (string) The text to display in the icon. - * 'index': (number) The style index of the icon. - */ -ClusterIcon.prototype.setSums = function(sums) { - this.sums_ = sums; - this.text_ = sums.text; - this.index_ = sums.index; - if (this.div_) { - this.div_.innerHTML = sums.text; - } - - this.useStyle(); -}; - - -/** - * Sets the icon to the the styles. - */ -ClusterIcon.prototype.useStyle = function() { - var index = Math.max(0, this.sums_.index - 1); - index = Math.min(this.styles_.length - 1, index); - var style = this.styles_[index]; - this.url_ = style['url']; - this.height_ = style['height']; - this.width_ = style['width']; - this.textColor_ = style['textColor']; - this.anchor_ = style['anchor']; - this.textSize_ = style['textSize']; - this.backgroundPosition_ = style['backgroundPosition']; -}; - - -/** - * Sets the center of the icon. - * - * @param {google.maps.LatLng} center The latlng to set as the center. - */ -ClusterIcon.prototype.setCenter = function(center) { - this.center_ = center; -}; - - -/** - * Create the css text based on the position of the icon. - * - * @param {google.maps.Point} pos The position. - * @return {string} The css style text. - */ -ClusterIcon.prototype.createCss = function(pos) { - var style = []; - style.push('background-image:url(' + this.url_ + ');'); - var backgroundPosition = this.backgroundPosition_ ? this.backgroundPosition_ : '0 0'; - style.push('background-position:' + backgroundPosition + ';'); - - if (typeof this.anchor_ === 'object') { - if (typeof this.anchor_[0] === 'number' && this.anchor_[0] > 0 && - this.anchor_[0] < this.height_) { - style.push('height:' + (this.height_ - this.anchor_[0]) + - 'px; padding-top:' + this.anchor_[0] + 'px;'); - } else { - style.push('height:' + this.height_ + 'px; line-height:' + this.height_ + - 'px;'); - } - if (typeof this.anchor_[1] === 'number' && this.anchor_[1] > 0 && - this.anchor_[1] < this.width_) { - style.push('width:' + (this.width_ - this.anchor_[1]) + - 'px; padding-left:' + this.anchor_[1] + 'px;'); - } else { - style.push('width:' + this.width_ + 'px; text-align:center;'); - } - } else { - style.push('height:' + this.height_ + 'px; line-height:' + - this.height_ + 'px; width:' + this.width_ + 'px; text-align:center;'); - } - - var txtColor = this.textColor_ ? this.textColor_ : 'black'; - var txtSize = this.textSize_ ? this.textSize_ : 11; - - style.push('cursor:pointer; top:' + pos.y + 'px; left:' + - pos.x + 'px; color:' + txtColor + '; position:absolute; font-size:' + - txtSize + 'px; font-family:Arial,sans-serif; font-weight:bold'); - return style.join(''); -}; - - -// Export Symbols for Closure -// If you are not going to compile with closure then you can remove the -// code below. -var window = window || {}; -window['MarkerClusterer'] = MarkerClusterer; -MarkerClusterer.prototype['addMarker'] = MarkerClusterer.prototype.addMarker; -MarkerClusterer.prototype['addMarkers'] = MarkerClusterer.prototype.addMarkers; -MarkerClusterer.prototype['clearMarkers'] = - MarkerClusterer.prototype.clearMarkers; -MarkerClusterer.prototype['fitMapToMarkers'] = - MarkerClusterer.prototype.fitMapToMarkers; -MarkerClusterer.prototype['getCalculator'] = - MarkerClusterer.prototype.getCalculator; -MarkerClusterer.prototype['getGridSize'] = - MarkerClusterer.prototype.getGridSize; -MarkerClusterer.prototype['getExtendedBounds'] = - MarkerClusterer.prototype.getExtendedBounds; -MarkerClusterer.prototype['getMap'] = MarkerClusterer.prototype.getMap; -MarkerClusterer.prototype['getMarkers'] = MarkerClusterer.prototype.getMarkers; -MarkerClusterer.prototype['getMaxZoom'] = MarkerClusterer.prototype.getMaxZoom; -MarkerClusterer.prototype['getStyles'] = MarkerClusterer.prototype.getStyles; -MarkerClusterer.prototype['getTotalClusters'] = - MarkerClusterer.prototype.getTotalClusters; -MarkerClusterer.prototype['getTotalMarkers'] = - MarkerClusterer.prototype.getTotalMarkers; -MarkerClusterer.prototype['redraw'] = MarkerClusterer.prototype.redraw; -MarkerClusterer.prototype['removeMarker'] = - MarkerClusterer.prototype.removeMarker; -MarkerClusterer.prototype['removeMarkers'] = - MarkerClusterer.prototype.removeMarkers; -MarkerClusterer.prototype['resetViewport'] = - MarkerClusterer.prototype.resetViewport; -MarkerClusterer.prototype['repaint'] = - MarkerClusterer.prototype.repaint; -MarkerClusterer.prototype['setCalculator'] = - MarkerClusterer.prototype.setCalculator; -MarkerClusterer.prototype['setGridSize'] = - MarkerClusterer.prototype.setGridSize; -MarkerClusterer.prototype['setMaxZoom'] = - MarkerClusterer.prototype.setMaxZoom; -MarkerClusterer.prototype['onAdd'] = MarkerClusterer.prototype.onAdd; -MarkerClusterer.prototype['draw'] = MarkerClusterer.prototype.draw; - -Cluster.prototype['getCenter'] = Cluster.prototype.getCenter; -Cluster.prototype['getSize'] = Cluster.prototype.getSize; -Cluster.prototype['getMarkers'] = Cluster.prototype.getMarkers; - -ClusterIcon.prototype['onAdd'] = ClusterIcon.prototype.onAdd; -ClusterIcon.prototype['draw'] = ClusterIcon.prototype.draw; -ClusterIcon.prototype['onRemove'] = ClusterIcon.prototype.onRemove; - -Object.keys = Object.keys || function(o) { - var result = []; - for(var name in o) { - if (o.hasOwnProperty(name)) - result.push(name); - } - return result; -}; - -var module = module || {}; -module.exports = MarkerClusterer; \ No newline at end of file diff --git a/Resources/Public/JavaScript/OpenStreetMap2.min.js b/Resources/Public/JavaScript/OpenStreetMap2.min.js index 453b78d08..a5361adcf 100644 --- a/Resources/Public/JavaScript/OpenStreetMap2.min.js +++ b/Resources/Public/JavaScript/OpenStreetMap2.min.js @@ -1,2 +1,2 @@ -class OpenStreetMap2{element={};environment={};editable=!1;bounds={};allMarkers=[];categorizedMarkers={};poiCollections=[];map={};constructor(t,e){this.element=t,this.environment=e,this.editable=this.element.classList.contains("editMarker"),this.bounds=new L.LatLngBounds,this.preparePoiCollection(),this.setMapDimensions(),this.createMap(),this.setMarkersOnMap()}preparePoiCollection(){this.poiCollections=JSON.parse(this.element.getAttribute("data-pois"))??[]}setMarkersOnMap(){this.isPOICollectionsEmpty()?this.createMarkerBasedOnDataAttributes():this.createMarkerBasedOnPOICollections()}isPOICollectionsEmpty(){return this.poiCollections.length===0}createMarkerBasedOnDataAttributes(){const t=this.getAttributeAsFloat("data-latitude"),e=this.getAttributeAsFloat("data-longitude");!isNaN(t)&&!isNaN(e)&&this.createMarkerByLatLng(t,e)}getAttributeAsFloat(t){return parseFloat(this.element.getAttribute(t)||"")}createMarkerBasedOnPOICollections(){this.createPointByCollectionType(),this.countObjectProperties(this.categorizedMarkers)>1&&this.showSwitchableCategories(),this.adjustMapZoom()}adjustMapZoom(){this.shouldFitBounds()?this.map.fitBounds(this.bounds):this.map.panTo([this.poiCollections[0].latitude,this.poiCollections[0].longitude])}shouldFitBounds(){return this.getSettings().forceZoom===!0||this.poiCollections===null?!1:this.poiCollections.length>1||this.poiCollections.length===1&&(this.poiCollections[0].collectionType==="Area"||this.poiCollections[0].collectionType==="Route")}setMapDimensions(){this.element.style.height=this.normalizeDimension(this.getSettings().mapHeight),this.element.style.width=this.normalizeDimension(this.getSettings().mapWidth)}normalizeDimension(t){let e=String(t);return this.canBeInterpretedAsNumber(e)&&(e+="px"),e}createMap(){this.map=L.map(this.element,{center:[this.getExtConf().defaultLatitude,this.getExtConf().defaultLongitude],zoom:this.getSettings().zoom?this.getSettings().zoom:12,editable:this.editable,scrollWheelZoom:this.getSettings().activateScrollWheel!=="0"}),L.tileLayer(this.getSettings().mapTile,{attribution:this.getSettings().mapTileAttribution,maxZoom:20}).addTo(this.map)}groupCategories(){const t={};return this.poiCollections.forEach(e=>{e.categories.map(i=>String(i.uid)).filter(i=>this.getSettings().categories.includes(i)).forEach(i=>{t.hasOwnProperty(i)||(t[i]=e.categories.find(s=>String(s.uid)===i))})}),t}getCategoriesOfCheckboxesWithStatus(t,e){let r=[];return Array.from(e?t.querySelectorAll("input:checked"):t.querySelectorAll("input:not(:checked)")).forEach(s=>{r.push(parseInt(s.value))}),r}getMarkersToChangeVisibilityFor(t,e,r){let i=[];if(this.allMarkers.length===0)return i;let s=null,n=null,a=this.getCategoriesOfCheckboxesWithStatus(e,r);for(let o=0;o{r.addEventListener("click",()=>{let i=r.checked,s=r.value;this.getMarkersToChangeVisibilityFor(s,e,i).forEach(a=>{i?this.map.addLayer(a):this.map.removeLayer(a)})})}),this.element.insertAdjacentElement("afterend",e)}getCheckbox(t){const e=document.createElement("div");e.classList.add("form-group");const r=document.createElement("div");r.classList.add("checkbox");const i=document.createElement("label"),s=document.createElement("input");return s.type="checkbox",s.classList.add("checkCategory"),s.id="checkCategory_"+t.uid,s.checked=!0,s.value=t.uid,i.appendChild(s),r.appendChild(i),e.appendChild(r),e}countObjectProperties(t){let e=0;for(let r in t)t.hasOwnProperty(r)&&e++;return e}createPointByCollectionType(){let t,e=0;this.poiCollections!==null&&this.poiCollections.length&&this.poiCollections.forEach(r=>{switch(r.strokeColor===""&&(r.strokeColor=this.getExtConf().strokeColor),r.strokeOpacity===""&&(r.strokeOpacity=this.getExtConf().strokeOpacity),r.strokeWeight===""&&(r.strokeWeight=this.getExtConf().strokeWeight),r.fillColor===""&&(r.fillColor=this.getExtConf().fillColor),r.fillOpacity===""&&(r.fillOpacity=this.getExtConf().fillOpacity),t=null,r.collectionType){case"Point":t=this.createMarker(r);break;case"Area":t=this.createArea(r);break;case"Route":t=this.createRoute(r);break;case"Radius":t=this.createRadius(r);break}this.allMarkers.push({marker:t,poiCollection:r}),e=0;for(let i=0;i{let o=t.markerIcon;return o.startsWith("/")&&(o=o.substring(1)),this.environment.siteUrl+o})(),iconSize:[r,i],iconAnchor:[s,n]});e.setIcon(a)}return this.bounds.extend(e.getLatLng()),this.editable?this.addEditListeners(this.element,e,t):this.addInfoWindow(e,t),e}createArea(t){let e=[];t.pois.forEach(i=>{let s=[i.latitude,i.longitude];this.bounds.extend(s),e.push(s)});let r=L.polygon(e,{color:t.strokeColor,opacity:t.strokeOpacity,weight:t.strokeWeight,fillColor:t.fillColor,fillOpacity:t.fillOpacity}).addTo(this.map);return this.addInfoWindow(r,t),r}createRoute(t){let e=[];t.pois.forEach(i=>{let s=[i.latitude,i.longitude];this.bounds.extend(s),e.push(s)});let r=L.polyline(e,{color:t.strokeColor,opacity:t.strokeOpacity,weight:t.strokeWeight,fillColor:t.fillColor,fillOpacity:t.fillOpacity}).addTo(this.map);return this.addInfoWindow(r,t),r}createRadius(t){let e=L.circle([t.latitude,t.longitude],{color:t.strokeColor,opacity:t.strokeOpacity,weight:t.strokeWeight,fillColor:t.fillColor,fillOpacity:t.fillOpacity,radius:t.radius}).addTo(this.map);return this.bounds.extend(e.getBounds()),this.addInfoWindow(e,t),e}addInfoWindow(t,e){t.addEventListener("click",()=>{fetch(this.environment.ajaxUrl,{method:"POST",headers:{"Content-Type":"application/json","ext-maps2":"infoWindowContent"},body:JSON.stringify({poiCollection:e.uid})}).then(r=>r.json()).then(r=>{t.bindPopup(r.content).openPopup()}).catch(r=>console.error("Error:",r))})}addEditListeners(t,e,r){e.on("dragend",()=>{let i=e.getLatLng().lat.toFixed(6),s=e.getLatLng().lng.toFixed(6);t.previousElementSibling?.querySelector(`input.latitude-${this.getContentRecord().uid}`).setAttribute("value",i),t.previousElementSibling?.querySelector(`input.longitude-${this.getContentRecord().uid}`).setAttribute("value",s)}),this.map.on("click",i=>{e.setLatLng(i.latlng),t.previousElementSibling?.querySelector(`input.latitude-${this.getContentRecord().uid}`).setAttribute("value",i.latlng.lat.toFixed(6)),t.previousElementSibling?.querySelector(`input.longitude-${this.getContentRecord().uid}`).setAttribute("value",i.latlng.lng.toFixed(6))})}canBeInterpretedAsNumber(t){return typeof t=="number"||!isNaN(Number(t))}getContentRecord(){return this.environment.contentRecord}getExtConf(){return this.environment.extConf}getSettings(){return this.environment.settings}}let maps2OpenStreetMaps=[];document.querySelectorAll(".maps2").forEach(c=>{const t=typeof c.dataset.environment<"u"?c.dataset.environment:"{}",e=typeof c.dataset.override<"u"?c.dataset.override:"{}",r=(...i)=>{let s={},n=!1,a=0,o=i.length;Object.prototype.toString.call(i[0])==="[object Boolean]"&&(n=i[0],a++);const d=function(l){for(var h in l)Object.prototype.hasOwnProperty.call(l,h)&&(n&&Object.prototype.toString.call(l[h])==="[object Object]"?s[h]=r(!0,s[h],l[h]):s[h]=l[h])};for(;a1&&this.showSwitchableCategories(),this.adjustMapZoom()}adjustMapZoom(){this.shouldFitBounds()?this.map.fitBounds(this.bounds):this.map.panTo([this.poiCollections[0].latitude,this.poiCollections[0].longitude])}shouldFitBounds(){return this.getSettings().forceZoom===!0||this.poiCollections===null?!1:this.poiCollections.length>1||this.poiCollections.length===1&&(this.poiCollections[0].collectionType==="Area"||this.poiCollections[0].collectionType==="Route")}setMapDimensions(){this.element.style.height=this.normalizeDimension(this.getSettings().mapHeight),this.element.style.width=this.normalizeDimension(this.getSettings().mapWidth)}normalizeDimension(e){let t=String(e);return this.canBeInterpretedAsNumber(t)&&(t+="px"),t}createMap(){this.map=L.map(this.element,{center:[this.getExtConf().defaultLatitude,this.getExtConf().defaultLongitude],zoom:this.getSettings().zoom?this.getSettings().zoom:12,editable:this.editable,scrollWheelZoom:this.getSettings().activateScrollWheel!=="0"}),L.tileLayer(this.getSettings().mapTile,{attribution:this.getSettings().mapTileAttribution,maxZoom:20}).addTo(this.map)}createMarkerClusterGroup(){return this.editable||!this.isMarkerClustererEnabled()||typeof L.markerClusterGroup!="function"?null:L.markerClusterGroup({showCoverageOnHover:!1})}isMarkerClustererEnabled(){return parseInt(this.getSettings().markerClusterer?.enable??0,10)===1}getLayerContainer(e){return this.markerClusterGroup!==null&&e instanceof L.Marker?this.markerClusterGroup:this.map}groupCategories(){const e={};return this.poiCollections.forEach(t=>{t.categories.map(i=>String(i.uid)).filter(i=>this.getSettings().categories.includes(i)).forEach(i=>{e.hasOwnProperty(i)||(e[i]=t.categories.find(s=>String(s.uid)===i))})}),e}getCategoriesOfCheckboxesWithStatus(e,t){let r=[];return Array.from(t?e.querySelectorAll("input:checked"):e.querySelectorAll("input:not(:checked)")).forEach(s=>{r.push(parseInt(s.value))}),r}getMarkersToChangeVisibilityFor(e,t,r){let i=[];if(this.allMarkers.length===0)return i;let s=null,n=null,a=this.getCategoriesOfCheckboxesWithStatus(t,r);for(let o=0;o{r.addEventListener("click",()=>{let i=r.checked,s=r.value;this.getMarkersToChangeVisibilityFor(s,t,i).forEach(a=>{i?this.getLayerContainer(a).addLayer(a):this.getLayerContainer(a).removeLayer(a)})})}),this.element.insertAdjacentElement("afterend",t)}getCheckbox(e){const t=document.createElement("div");t.classList.add("form-group");const r=document.createElement("div");r.classList.add("checkbox");const i=document.createElement("label"),s=document.createElement("input");return s.type="checkbox",s.classList.add("checkCategory"),s.id="checkCategory_"+e.uid,s.checked=!0,s.value=e.uid,i.appendChild(s),r.appendChild(i),t.appendChild(r),t}countObjectProperties(e){let t=0;for(let r in e)e.hasOwnProperty(r)&&t++;return t}createPointByCollectionType(){let e,t=0;this.poiCollections!==null&&this.poiCollections.length&&this.poiCollections.forEach(r=>{switch(r.strokeColor===""&&(r.strokeColor=this.getExtConf().strokeColor),r.strokeOpacity===""&&(r.strokeOpacity=this.getExtConf().strokeOpacity),r.strokeWeight===""&&(r.strokeWeight=this.getExtConf().strokeWeight),r.fillColor===""&&(r.fillColor=this.getExtConf().fillColor),r.fillOpacity===""&&(r.fillOpacity=this.getExtConf().fillOpacity),e=null,r.collectionType){case"Point":e=this.createMarker(r);break;case"Area":e=this.createArea(r);break;case"Route":e=this.createRoute(r);break;case"Radius":e=this.createRadius(r);break}this.allMarkers.push({marker:e,poiCollection:r}),t=0;for(let i=0;i{let o=e.markerIcon;return o.startsWith("/")&&(o=o.substring(1)),this.environment.siteUrl+o})(),iconSize:[r,i],iconAnchor:[s,n]});t.setIcon(a)}return this.getLayerContainer(t).addLayer(t),this.bounds.extend(t.getLatLng()),this.editable?this.addEditListeners(this.element,t,e):this.addInfoWindow(t,e),t}createArea(e){let t=[];e.pois.forEach(i=>{let s=[i.latitude,i.longitude];this.bounds.extend(s),t.push(s)});let r=L.polygon(t,{color:e.strokeColor,opacity:e.strokeOpacity,weight:e.strokeWeight,fillColor:e.fillColor,fillOpacity:e.fillOpacity}).addTo(this.map);return this.addInfoWindow(r,e),r}createRoute(e){let t=[];e.pois.forEach(i=>{let s=[i.latitude,i.longitude];this.bounds.extend(s),t.push(s)});let r=L.polyline(t,{color:e.strokeColor,opacity:e.strokeOpacity,weight:e.strokeWeight,fillColor:e.fillColor,fillOpacity:e.fillOpacity}).addTo(this.map);return this.addInfoWindow(r,e),r}createRadius(e){let t=L.circle([e.latitude,e.longitude],{color:e.strokeColor,opacity:e.strokeOpacity,weight:e.strokeWeight,fillColor:e.fillColor,fillOpacity:e.fillOpacity,radius:e.radius}).addTo(this.map);return this.bounds.extend(t.getBounds()),this.addInfoWindow(t,e),t}addInfoWindow(e,t){e.addEventListener("click",()=>{fetch(this.environment.ajaxUrl,{method:"POST",headers:{"Content-Type":"application/json","ext-maps2":"infoWindowContent"},body:JSON.stringify({poiCollection:t.uid})}).then(r=>r.json()).then(r=>{e.bindPopup(r.content).openPopup()}).catch(r=>console.error("Error:",r))})}addEditListeners(e,t,r){t.on("dragend",()=>{let i=t.getLatLng().lat.toFixed(6),s=t.getLatLng().lng.toFixed(6);e.previousElementSibling?.querySelector(`input.latitude-${this.getContentRecord().uid}`).setAttribute("value",i),e.previousElementSibling?.querySelector(`input.longitude-${this.getContentRecord().uid}`).setAttribute("value",s)}),this.map.on("click",i=>{t.setLatLng(i.latlng),e.previousElementSibling?.querySelector(`input.latitude-${this.getContentRecord().uid}`).setAttribute("value",i.latlng.lat.toFixed(6)),e.previousElementSibling?.querySelector(`input.longitude-${this.getContentRecord().uid}`).setAttribute("value",i.latlng.lng.toFixed(6))})}canBeInterpretedAsNumber(e){return typeof e=="number"||!isNaN(Number(e))}getContentRecord(){return this.environment.contentRecord}getExtConf(){return this.environment.extConf}getSettings(){return this.environment.settings}}let maps2OpenStreetMaps=[];const initializeOpenStreetMaps=()=>{document.querySelectorAll(".maps2").forEach(d=>{const e=typeof d.dataset.environment<"u"?d.dataset.environment:"{}",t=typeof d.dataset.override<"u"?d.dataset.override:"{}",r=(...i)=>{let s={},n=!1,a=0,o=i.length;Object.prototype.toString.call(i[0])==="[object Boolean]"&&(n=i[0],a++);const c=function(l){for(var h in l)Object.prototype.hasOwnProperty.call(l,h)&&(n&&Object.prototype.toString.call(l[h])==="[object Object]"?s[h]=r(!0,s[h],l[h]):s[h]=l[h])};for(;a 1) {\n this.showSwitchableCategories();\n }\n this.adjustMapZoom();\n }\n\n adjustMapZoom() {\n if (this.shouldFitBounds()) {\n this.map.fitBounds(this.bounds);\n } else {\n this.map.panTo([this.poiCollections[0].latitude, this.poiCollections[0].longitude]);\n }\n }\n\n /**\n * @returns {boolean}\n */\n shouldFitBounds() {\n if (this.getSettings().forceZoom === true) {\n return false;\n }\n\n if (this.poiCollections === null) {\n return false;\n }\n\n if (this.poiCollections.length > 1) {\n return true;\n }\n\n if (\n this.poiCollections.length === 1\n && (\n this.poiCollections[0].collectionType === \"Area\"\n || this.poiCollections[0].collectionType === \"Route\"\n )\n ) {\n return true;\n }\n\n return false;\n }\n\n setMapDimensions() {\n this.element.style.height = this.normalizeDimension(this.getSettings().mapHeight);\n this.element.style.width = this.normalizeDimension(this.getSettings().mapWidth);\n }\n\n /**\n * @param {string | number} dimension\n * @returns {string}\n */\n normalizeDimension(dimension) {\n let normalizedDimension = String(dimension);\n\n if (this.canBeInterpretedAsNumber(normalizedDimension)) {\n normalizedDimension += 'px';\n }\n\n return normalizedDimension;\n }\n\n createMap() {\n this.map = L.map(\n this.element, {\n center: [this.getExtConf().defaultLatitude, this.getExtConf().defaultLongitude],\n zoom: this.getSettings().zoom ? this.getSettings().zoom : 12,\n editable: this.editable,\n scrollWheelZoom: this.getSettings().activateScrollWheel !== \"0\"\n }\n );\n\n L.tileLayer(this.getSettings().mapTile, {\n attribution: this.getSettings().mapTileAttribution,\n maxZoom: 20\n }).addTo(this.map);\n }\n\n /**\n * @returns {{[p: string]: Category}}\n */\n groupCategories() {\n const groupedCategories = {};\n\n this.poiCollections.forEach((poiCollection) => {\n const categoryUids = poiCollection.categories.map((category) => String(category.uid));\n\n categoryUids\n .filter((categoryUid) => this.getSettings().categories.includes(categoryUid))\n .forEach((categoryUid) => {\n if (!groupedCategories.hasOwnProperty(categoryUid)) {\n groupedCategories[categoryUid] = poiCollection.categories.find((category) => String(category.uid) === categoryUid);\n }\n });\n });\n\n return groupedCategories;\n }\n\n /**\n * @param {HTMLElement} form\n * @param {boolean} isChecked\n * @returns {number[]}\n */\n getCategoriesOfCheckboxesWithStatus(form, isChecked) {\n let categories = [];\n let checkboxes = isChecked\n ? Array.from(form.querySelectorAll(\"input:checked\"))\n : Array.from(form.querySelectorAll(\"input:not(:checked)\"));\n\n checkboxes.forEach((checkbox) => {\n categories.push(parseInt((checkbox).value));\n });\n\n return categories;\n }\n\n /**\n * @param {string} categoryUid\n * @param {HTMLElement} form\n * @param { boolean} isChecked\n * @returns {*[]}\n */\n getMarkersToChangeVisibilityFor(categoryUid, form, isChecked) {\n let markers = [];\n if (this.allMarkers.length === 0) {\n return markers;\n }\n\n let marker = null;\n let allCategoriesOfMarker = null;\n let categoriesOfCheckboxesWithStatus = this.getCategoriesOfCheckboxesWithStatus(form, isChecked);\n for (let i = 0; i < this.allMarkers.length; i++) {\n marker = this.allMarkers[i];\n allCategoriesOfMarker = marker.poiCollection.categories;\n if (allCategoriesOfMarker.length === 0) {\n continue;\n }\n\n let markerCategoryHasCheckboxWithStatus;\n for (let j = 0; j < allCategoriesOfMarker.length; j++) {\n markerCategoryHasCheckboxWithStatus = false;\n for (let k = 0; k < categoriesOfCheckboxesWithStatus.length; k++) {\n if (allCategoriesOfMarker[j].uid === categoriesOfCheckboxesWithStatus[k]) {\n markerCategoryHasCheckboxWithStatus = true;\n }\n }\n if (markerCategoryHasCheckboxWithStatus === isChecked) {\n break;\n }\n }\n\n if (markerCategoryHasCheckboxWithStatus) {\n markers.push(marker.marker);\n }\n }\n\n return markers;\n }\n\n showSwitchableCategories() {\n let categories = this.groupCategories();\n let form = document.createElement(\"form\");\n form.classList.add(\"txMaps2Form\");\n form.setAttribute(\"id\", \"txMaps2Form-\" + this.getContentRecord().uid);\n\n // Add checkbox for category\n for (let categoryUid in categories) {\n if (categories.hasOwnProperty(categoryUid)) {\n form.appendChild(this.getCheckbox(categories[categoryUid]));\n\n const categoryLabel = document.createElement(\"span\");\n categoryLabel.classList.add(\"map-category\");\n categoryLabel.textContent = categories[categoryUid].title;\n form.querySelector(\"#checkCategory_\" + categoryUid)?.insertAdjacentElement(\"afterend\", categoryLabel);\n }\n }\n\n // Add listener for checkboxes\n form.querySelectorAll(\"input\").forEach((checkbox) => {\n checkbox.addEventListener(\"click\", () => {\n let isChecked = (checkbox).checked;\n let categoryUid = (checkbox).value;\n let markers = this.getMarkersToChangeVisibilityFor(categoryUid, form, isChecked);\n\n markers.forEach((marker) => {\n if (isChecked) {\n this.map.addLayer(marker);\n } else {\n this.map.removeLayer(marker);\n }\n });\n });\n });\n\n this.element.insertAdjacentElement(\"afterend\", form);\n }\n\n /**\n * @param {Category} category\n * @returns {HTMLElement}\n */\n getCheckbox(category) {\n const div = document.createElement(\"div\");\n div.classList.add(\"form-group\");\n\n const checkboxDiv = document.createElement(\"div\");\n checkboxDiv.classList.add(\"checkbox\");\n\n const label = document.createElement(\"label\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"checkCategory\");\n input.id = \"checkCategory_\" + category.uid;\n input.checked = true;\n input.value = category.uid;\n\n label.appendChild(input);\n checkboxDiv.appendChild(label);\n div.appendChild(checkboxDiv);\n\n return div;\n }\n\n /**\n * @param {object} obj\n * @returns {number}\n */\n countObjectProperties(obj) {\n let count = 0;\n for (let key in obj) {\n if (obj.hasOwnProperty(key)) {\n count++;\n }\n }\n return count;\n }\n\n createPointByCollectionType() {\n let marker;\n let categoryUid = 0;\n\n if (this.poiCollections !== null && this.poiCollections.length) {\n this.poiCollections.forEach(poiCollection => {\n if (poiCollection.strokeColor === \"\") {\n poiCollection.strokeColor = this.getExtConf().strokeColor;\n }\n if (poiCollection.strokeOpacity === \"\") {\n poiCollection.strokeOpacity = this.getExtConf().strokeOpacity;\n }\n if (poiCollection.strokeWeight === \"\") {\n poiCollection.strokeWeight = this.getExtConf().strokeWeight;\n }\n if (poiCollection.fillColor === \"\") {\n poiCollection.fillColor = this.getExtConf().fillColor;\n }\n if (poiCollection.fillOpacity === \"\") {\n poiCollection.fillOpacity = this.getExtConf().fillOpacity;\n }\n\n marker = null;\n switch (poiCollection.collectionType) {\n case \"Point\":\n marker = this.createMarker(poiCollection);\n break;\n case \"Area\":\n marker = this.createArea(poiCollection);\n break;\n case \"Route\":\n marker = this.createRoute(poiCollection);\n break;\n case \"Radius\":\n marker = this.createRadius(poiCollection);\n break;\n }\n\n this.allMarkers.push({\n marker: marker,\n poiCollection: poiCollection\n });\n\n categoryUid = 0;\n for (let c = 0; c < poiCollection.categories.length; c++) {\n categoryUid = poiCollection.categories[c].uid;\n if (!this.categorizedMarkers.hasOwnProperty(categoryUid)) {\n this.categorizedMarkers[categoryUid] = [];\n }\n this.categorizedMarkers[categoryUid].push(marker);\n }\n });\n }\n }\n\n /**\n * @param {number} latitude\n * @param {number} longitude\n */\n createMarkerByLatLng(latitude, longitude) {\n let marker = L.marker(\n [latitude, longitude]\n ).addTo(this.map);\n\n this.bounds.extend(marker.getLatLng());\n }\n\n /**\n * @param {PoiCollection} poiCollection\n * @returns {Marker}\n */\n createMarker(poiCollection) {\n let marker = L.marker(\n [poiCollection.latitude, poiCollection.longitude],\n {\n 'draggable': this.editable\n }\n ).addTo(this.map);\n\n if (poiCollection.hasOwnProperty(\"markerIcon\") && poiCollection.markerIcon !== \"\") {\n const markerIconWidth = poiCollection.markerIconWidth || this.getExtConf().markerIconWidth;\n const markerIconHeight = poiCollection.markerIconHeight || this.getExtConf().markerIconHeight;\n const markerIconAnchorPosX = poiCollection.markerIconAnchorPosX || this.getExtConf().markerIconAnchorPosX;\n const markerIconAnchorPosY = poiCollection.markerIconAnchorPosY || this.getExtConf().markerIconAnchorPosY;\n\n let icon = L.icon({\n iconUrl: (() => {\n let markerIconPath = poiCollection.markerIcon;\n\n // Remove leading slash if present, to avoid double slashes with siteUrl\n if (markerIconPath.startsWith('/')) {\n markerIconPath = markerIconPath.substring(1);\n }\n\n return this.environment.siteUrl + markerIconPath;\n })(),\n iconSize: [markerIconWidth, markerIconHeight],\n iconAnchor: [markerIconAnchorPosX, markerIconAnchorPosY]\n });\n marker.setIcon(icon);\n }\n\n this.bounds.extend(marker.getLatLng());\n\n if (this.editable) {\n this.addEditListeners(this.element, marker, poiCollection);\n } else {\n this.addInfoWindow(marker, poiCollection);\n }\n\n return marker;\n }\n\n /**\n * @param {PoiCollection} poiCollection\n * @returns {Polygon}\n */\n createArea(poiCollection) {\n let latlngs = [];\n\n poiCollection.pois.forEach(poi => {\n let latLng = [poi.latitude, poi.longitude];\n this.bounds.extend(latLng);\n latlngs.push(latLng);\n });\n\n let marker = L.polygon(latlngs, {\n color: poiCollection.strokeColor,\n opacity: poiCollection.strokeOpacity,\n weight: poiCollection.strokeWeight,\n fillColor: poiCollection.fillColor,\n fillOpacity: poiCollection.fillOpacity\n }).addTo(this.map);\n\n this.addInfoWindow(marker, poiCollection);\n\n return marker;\n }\n\n /**\n * @param {PoiCollection} poiCollection\n * @returns {Polyline}\n */\n createRoute(poiCollection) {\n let latlngs = [];\n\n poiCollection.pois.forEach(poi => {\n let latLng = [poi.latitude, poi.longitude];\n this.bounds.extend(latLng);\n latlngs.push(latLng);\n });\n\n let marker = L.polyline(latlngs, {\n color: poiCollection.strokeColor,\n opacity: poiCollection.strokeOpacity,\n weight: poiCollection.strokeWeight,\n fillColor: poiCollection.fillColor,\n fillOpacity: poiCollection.fillOpacity\n }).addTo(this.map);\n\n this.addInfoWindow(marker, poiCollection);\n\n return marker;\n }\n\n /**\n * @param {PoiCollection} poiCollection\n * @returns {Circle}\n */\n createRadius(poiCollection) {\n let marker = L.circle([poiCollection.latitude, poiCollection.longitude], {\n color: poiCollection.strokeColor,\n opacity: poiCollection.strokeOpacity,\n weight: poiCollection.strokeWeight,\n fillColor: poiCollection.fillColor,\n fillOpacity: poiCollection.fillOpacity,\n radius: poiCollection.radius\n }).addTo(this.map);\n\n this.bounds.extend(marker.getBounds());\n\n this.addInfoWindow(marker, poiCollection);\n\n return marker;\n }\n\n /**\n * @param {HTMLElement} element\n * @param {PoiCollection} poiCollection\n */\n addInfoWindow(element, poiCollection) {\n element.addEventListener(\"click\", () => {\n fetch(this.environment.ajaxUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"ext-maps2\": \"infoWindowContent\"\n },\n body: JSON.stringify({\n poiCollection: poiCollection.uid\n })\n })\n .then(response => response.json())\n .then(data => {\n element.bindPopup(data.content).openPopup();\n })\n .catch(error => console.error('Error:', error));\n });\n }\n\n /**\n * @param {HTMLElement} mapContainer\n * @param {L.Marker} marker\n * @param {PoiCollection} poiCollection\n */\n addEditListeners(mapContainer, marker, poiCollection) {\n marker.on('dragend', () => {\n let lat = marker.getLatLng().lat.toFixed(6);\n let lng = marker.getLatLng().lng.toFixed(6);\n mapContainer\n .previousElementSibling\n ?.querySelector(`input.latitude-${this.getContentRecord().uid}`)\n .setAttribute(\"value\", lat);\n mapContainer\n .previousElementSibling\n ?.querySelector(`input.longitude-${this.getContentRecord().uid}`)\n .setAttribute(\"value\", lng);\n });\n\n this.map.on('click', (event) => {\n marker.setLatLng(event.latlng);\n mapContainer\n .previousElementSibling\n ?.querySelector(`input.latitude-${this.getContentRecord().uid}`)\n .setAttribute(\"value\", event.latlng.lat.toFixed(6));\n mapContainer\n .previousElementSibling\n ?.querySelector(`input.longitude-${this.getContentRecord().uid}`)\n .setAttribute(\"value\", event.latlng.lng.toFixed(6));\n });\n }\n\n /**\n * return {boolean}\n */\n canBeInterpretedAsNumber(value) {\n return typeof value === 'number' || !isNaN(Number(value));\n }\n\n /**\n * return {ContentRecord}\n */\n getContentRecord() {\n return this.environment.contentRecord;\n }\n\n /**\n * return {ExtConf}\n */\n getExtConf() {\n return this.environment.extConf;\n }\n\n /**\n * return {Settings}\n */\n getSettings() {\n return this.environment.settings;\n }\n}\n\nlet maps2OpenStreetMaps = [];\n\ndocument.querySelectorAll(\".maps2\").forEach((element) => {\n const environment = typeof element.dataset.environment !== 'undefined' ? element.dataset.environment : '{}';\n const override = typeof element.dataset.override !== 'undefined' ? element.dataset.override : '{}';\n\n // Pass in the objects to merge as arguments.\n // For a deep extend, set the first argument to `true`.\n const extend = (...args) => {\n let extended = {};\n let deep = false;\n let i = 0;\n let length = args.length;\n\n // Check for deep merge\n if (Object.prototype.toString.call(args[0]) === '[object Boolean]') {\n deep = args[0];\n i++;\n }\n\n // Merge the object into the extended object\n const merge = function (obj) {\n for ( var prop in obj ) {\n if ( Object.prototype.hasOwnProperty.call( obj, prop ) ) {\n // If deep merge and property is an object, merge properties\n if ( deep && Object.prototype.toString.call(obj[prop]) === '[object Object]' ) {\n extended[prop] = extend( true, extended[prop], obj[prop] );\n } else {\n extended[prop] = obj[prop];\n }\n }\n }\n };\n\n // Loop through each object and conduct a merge\n for ( ; i < length; i++ ) {\n var obj = args[i];\n merge(obj);\n }\n\n return extended;\n };\n\n maps2OpenStreetMaps.push(new OpenStreetMap2(\n element,\n extend(true, JSON.parse(environment), JSON.parse(override))\n ));\n});\n"], - "mappings": "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", - "names": ["element", "environment", "latitude", "longitude", "attributeName", "dimension", "normalizedDimension", "groupedCategories", "poiCollection", "category", "categoryUid", "form", "isChecked", "categories", "checkbox", "markers", "marker", "allCategoriesOfMarker", "categoriesOfCheckboxesWithStatus", "i", "markerCategoryHasCheckboxWithStatus", "j", "k", "categoryLabel", "div", "checkboxDiv", "label", "input", "obj", "count", "key", "c", "markerIconWidth", "markerIconHeight", "markerIconAnchorPosX", "markerIconAnchorPosY", "icon", "markerIconPath", "latlngs", "poi", "latLng", "response", "data", "error", "mapContainer", "lat", "lng", "event", "value", "override", "extend", "args", "extended", "deep", "length", "merge", "prop"] + "sourcesContent": ["class OpenStreetMap2 {\n element = {};\n environment = {};\n editable = false;\n bounds = {};\n\n allMarkers = [];\n categorizedMarkers = {};\n poiCollections = [];\n map = {};\n markerClusterGroup = null;\n\n constructor(element, environment) {\n this.element = element;\n this.environment = environment;\n this.editable = this.element.classList.contains(\"editMarker\");\n this.bounds = new L.LatLngBounds();\n\n this.preparePoiCollection();\n this.setMapDimensions();\n this.createMap();\n this.markerClusterGroup = this.createMarkerClusterGroup();\n this.setMarkersOnMap();\n }\n\n preparePoiCollection() {\n this.poiCollections = JSON.parse(this.element.getAttribute(\"data-pois\")) ?? [];\n }\n\n setMarkersOnMap() {\n if (this.isPOICollectionsEmpty()) {\n this.createMarkerBasedOnDataAttributes();\n } else {\n this.createMarkerBasedOnPOICollections();\n }\n }\n\n /**\n * @returns {boolean}\n */\n isPOICollectionsEmpty() {\n return this.poiCollections.length === 0;\n }\n\n createMarkerBasedOnDataAttributes() {\n const latitude = this.getAttributeAsFloat(\"data-latitude\");\n const longitude = this.getAttributeAsFloat(\"data-longitude\");\n\n if (!isNaN(latitude) && !isNaN(longitude)) {\n this.createMarkerByLatLng(latitude, longitude);\n }\n }\n\n /**\n * @param {string} attributeName\n * @returns {number}\n */\n getAttributeAsFloat(attributeName) {\n return parseFloat(this.element.getAttribute(attributeName) || \"\");\n }\n\n createMarkerBasedOnPOICollections() {\n this.createPointByCollectionType();\n this.markerClusterGroup?.addTo(this.map);\n\n if (this.countObjectProperties(this.categorizedMarkers) > 1) {\n this.showSwitchableCategories();\n }\n this.adjustMapZoom();\n }\n\n adjustMapZoom() {\n if (this.shouldFitBounds()) {\n this.map.fitBounds(this.bounds);\n } else {\n this.map.panTo([this.poiCollections[0].latitude, this.poiCollections[0].longitude]);\n }\n }\n\n /**\n * @returns {boolean}\n */\n shouldFitBounds() {\n if (this.getSettings().forceZoom === true) {\n return false;\n }\n\n if (this.poiCollections === null) {\n return false;\n }\n\n if (this.poiCollections.length > 1) {\n return true;\n }\n\n if (\n this.poiCollections.length === 1\n && (\n this.poiCollections[0].collectionType === \"Area\"\n || this.poiCollections[0].collectionType === \"Route\"\n )\n ) {\n return true;\n }\n\n return false;\n }\n\n setMapDimensions() {\n this.element.style.height = this.normalizeDimension(this.getSettings().mapHeight);\n this.element.style.width = this.normalizeDimension(this.getSettings().mapWidth);\n }\n\n /**\n * @param {string | number} dimension\n * @returns {string}\n */\n normalizeDimension(dimension) {\n let normalizedDimension = String(dimension);\n\n if (this.canBeInterpretedAsNumber(normalizedDimension)) {\n normalizedDimension += 'px';\n }\n\n return normalizedDimension;\n }\n\n createMap() {\n this.map = L.map(\n this.element, {\n center: [this.getExtConf().defaultLatitude, this.getExtConf().defaultLongitude],\n zoom: this.getSettings().zoom ? this.getSettings().zoom : 12,\n editable: this.editable,\n scrollWheelZoom: this.getSettings().activateScrollWheel !== \"0\"\n }\n );\n\n L.tileLayer(this.getSettings().mapTile, {\n attribution: this.getSettings().mapTileAttribution,\n maxZoom: 20\n }).addTo(this.map);\n }\n\n /**\n * Point markers are collected in a cluster group of Leaflet.markercluster, if\n * marker clustering is enabled. Clustering is not used while editing a marker.\n *\n * @returns {L.MarkerClusterGroup|null}\n */\n createMarkerClusterGroup() {\n if (this.editable || !this.isMarkerClustererEnabled()) {\n return null;\n }\n\n // Leaflet.markercluster is only loaded, if clustering is enabled in site settings or plugin\n if (typeof L.markerClusterGroup !== \"function\") {\n return null;\n }\n\n // Do not draw the polygon of the cluster bounds on hover\n return L.markerClusterGroup({\n showCoverageOnHover: false,\n });\n }\n\n /**\n * @returns {boolean}\n */\n isMarkerClustererEnabled() {\n return parseInt(this.getSettings().markerClusterer?.enable ?? 0, 10) === 1;\n }\n\n /**\n * Point markers (L.Marker) are managed by the cluster group, if available.\n * Areas, routes and radius layers are always placed on the map directly.\n *\n * @param {L.Layer} layer\n * @returns {L.Map|L.MarkerClusterGroup}\n */\n getLayerContainer(layer) {\n if (this.markerClusterGroup !== null && layer instanceof L.Marker) {\n return this.markerClusterGroup;\n }\n\n return this.map;\n }\n\n /**\n * @returns {{[p: string]: Category}}\n */\n groupCategories() {\n const groupedCategories = {};\n\n this.poiCollections.forEach((poiCollection) => {\n const categoryUids = poiCollection.categories.map((category) => String(category.uid));\n\n categoryUids\n .filter((categoryUid) => this.getSettings().categories.includes(categoryUid))\n .forEach((categoryUid) => {\n if (!groupedCategories.hasOwnProperty(categoryUid)) {\n groupedCategories[categoryUid] = poiCollection.categories.find((category) => String(category.uid) === categoryUid);\n }\n });\n });\n\n return groupedCategories;\n }\n\n /**\n * @param {HTMLElement} form\n * @param {boolean} isChecked\n * @returns {number[]}\n */\n getCategoriesOfCheckboxesWithStatus(form, isChecked) {\n let categories = [];\n let checkboxes = isChecked\n ? Array.from(form.querySelectorAll(\"input:checked\"))\n : Array.from(form.querySelectorAll(\"input:not(:checked)\"));\n\n checkboxes.forEach((checkbox) => {\n categories.push(parseInt((checkbox).value));\n });\n\n return categories;\n }\n\n /**\n * @param {string} categoryUid\n * @param {HTMLElement} form\n * @param { boolean} isChecked\n * @returns {*[]}\n */\n getMarkersToChangeVisibilityFor(categoryUid, form, isChecked) {\n let markers = [];\n if (this.allMarkers.length === 0) {\n return markers;\n }\n\n let marker = null;\n let allCategoriesOfMarker = null;\n let categoriesOfCheckboxesWithStatus = this.getCategoriesOfCheckboxesWithStatus(form, isChecked);\n for (let i = 0; i < this.allMarkers.length; i++) {\n marker = this.allMarkers[i];\n allCategoriesOfMarker = marker.poiCollection.categories;\n if (allCategoriesOfMarker.length === 0) {\n continue;\n }\n\n let markerCategoryHasCheckboxWithStatus;\n for (let j = 0; j < allCategoriesOfMarker.length; j++) {\n markerCategoryHasCheckboxWithStatus = false;\n for (let k = 0; k < categoriesOfCheckboxesWithStatus.length; k++) {\n if (allCategoriesOfMarker[j].uid === categoriesOfCheckboxesWithStatus[k]) {\n markerCategoryHasCheckboxWithStatus = true;\n }\n }\n if (markerCategoryHasCheckboxWithStatus === isChecked) {\n break;\n }\n }\n\n if (markerCategoryHasCheckboxWithStatus) {\n markers.push(marker.marker);\n }\n }\n\n return markers;\n }\n\n showSwitchableCategories() {\n let categories = this.groupCategories();\n let form = document.createElement(\"form\");\n form.classList.add(\"txMaps2Form\");\n form.setAttribute(\"id\", \"txMaps2Form-\" + this.getContentRecord().uid);\n\n // Add checkbox for category\n for (let categoryUid in categories) {\n if (categories.hasOwnProperty(categoryUid)) {\n form.appendChild(this.getCheckbox(categories[categoryUid]));\n\n const categoryLabel = document.createElement(\"span\");\n categoryLabel.classList.add(\"map-category\");\n categoryLabel.textContent = categories[categoryUid].title;\n form.querySelector(\"#checkCategory_\" + categoryUid)?.insertAdjacentElement(\"afterend\", categoryLabel);\n }\n }\n\n // Add listener for checkboxes\n form.querySelectorAll(\"input\").forEach((checkbox) => {\n checkbox.addEventListener(\"click\", () => {\n let isChecked = (checkbox).checked;\n let categoryUid = (checkbox).value;\n let markers = this.getMarkersToChangeVisibilityFor(categoryUid, form, isChecked);\n\n markers.forEach((marker) => {\n if (isChecked) {\n this.getLayerContainer(marker).addLayer(marker);\n } else {\n this.getLayerContainer(marker).removeLayer(marker);\n }\n });\n });\n });\n\n this.element.insertAdjacentElement(\"afterend\", form);\n }\n\n /**\n * @param {Category} category\n * @returns {HTMLElement}\n */\n getCheckbox(category) {\n const div = document.createElement(\"div\");\n div.classList.add(\"form-group\");\n\n const checkboxDiv = document.createElement(\"div\");\n checkboxDiv.classList.add(\"checkbox\");\n\n const label = document.createElement(\"label\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"checkCategory\");\n input.id = \"checkCategory_\" + category.uid;\n input.checked = true;\n input.value = category.uid;\n\n label.appendChild(input);\n checkboxDiv.appendChild(label);\n div.appendChild(checkboxDiv);\n\n return div;\n }\n\n /**\n * @param {object} obj\n * @returns {number}\n */\n countObjectProperties(obj) {\n let count = 0;\n for (let key in obj) {\n if (obj.hasOwnProperty(key)) {\n count++;\n }\n }\n return count;\n }\n\n createPointByCollectionType() {\n let marker;\n let categoryUid = 0;\n\n if (this.poiCollections !== null && this.poiCollections.length) {\n this.poiCollections.forEach(poiCollection => {\n if (poiCollection.strokeColor === \"\") {\n poiCollection.strokeColor = this.getExtConf().strokeColor;\n }\n if (poiCollection.strokeOpacity === \"\") {\n poiCollection.strokeOpacity = this.getExtConf().strokeOpacity;\n }\n if (poiCollection.strokeWeight === \"\") {\n poiCollection.strokeWeight = this.getExtConf().strokeWeight;\n }\n if (poiCollection.fillColor === \"\") {\n poiCollection.fillColor = this.getExtConf().fillColor;\n }\n if (poiCollection.fillOpacity === \"\") {\n poiCollection.fillOpacity = this.getExtConf().fillOpacity;\n }\n\n marker = null;\n switch (poiCollection.collectionType) {\n case \"Point\":\n marker = this.createMarker(poiCollection);\n break;\n case \"Area\":\n marker = this.createArea(poiCollection);\n break;\n case \"Route\":\n marker = this.createRoute(poiCollection);\n break;\n case \"Radius\":\n marker = this.createRadius(poiCollection);\n break;\n }\n\n this.allMarkers.push({\n marker: marker,\n poiCollection: poiCollection\n });\n\n categoryUid = 0;\n for (let c = 0; c < poiCollection.categories.length; c++) {\n categoryUid = poiCollection.categories[c].uid;\n if (!this.categorizedMarkers.hasOwnProperty(categoryUid)) {\n this.categorizedMarkers[categoryUid] = [];\n }\n this.categorizedMarkers[categoryUid].push(marker);\n }\n });\n }\n }\n\n /**\n * @param {number} latitude\n * @param {number} longitude\n */\n createMarkerByLatLng(latitude, longitude) {\n let marker = L.marker(\n [latitude, longitude]\n ).addTo(this.map);\n\n this.bounds.extend(marker.getLatLng());\n }\n\n /**\n * @param {PoiCollection} poiCollection\n * @returns {Marker}\n */\n createMarker(poiCollection) {\n let marker = L.marker(\n [poiCollection.latitude, poiCollection.longitude],\n {\n 'draggable': this.editable\n }\n );\n\n if (poiCollection.hasOwnProperty(\"markerIcon\") && poiCollection.markerIcon !== \"\") {\n const markerIconWidth = poiCollection.markerIconWidth || this.getExtConf().markerIconWidth;\n const markerIconHeight = poiCollection.markerIconHeight || this.getExtConf().markerIconHeight;\n const markerIconAnchorPosX = poiCollection.markerIconAnchorPosX || this.getExtConf().markerIconAnchorPosX;\n const markerIconAnchorPosY = poiCollection.markerIconAnchorPosY || this.getExtConf().markerIconAnchorPosY;\n\n let icon = L.icon({\n iconUrl: (() => {\n let markerIconPath = poiCollection.markerIcon;\n\n // Remove leading slash if present, to avoid double slashes with siteUrl\n if (markerIconPath.startsWith('/')) {\n markerIconPath = markerIconPath.substring(1);\n }\n\n return this.environment.siteUrl + markerIconPath;\n })(),\n iconSize: [markerIconWidth, markerIconHeight],\n iconAnchor: [markerIconAnchorPosX, markerIconAnchorPosY]\n });\n marker.setIcon(icon);\n }\n\n this.getLayerContainer(marker).addLayer(marker);\n this.bounds.extend(marker.getLatLng());\n\n if (this.editable) {\n this.addEditListeners(this.element, marker, poiCollection);\n } else {\n this.addInfoWindow(marker, poiCollection);\n }\n\n return marker;\n }\n\n /**\n * @param {PoiCollection} poiCollection\n * @returns {Polygon}\n */\n createArea(poiCollection) {\n let latlngs = [];\n\n poiCollection.pois.forEach(poi => {\n let latLng = [poi.latitude, poi.longitude];\n this.bounds.extend(latLng);\n latlngs.push(latLng);\n });\n\n let marker = L.polygon(latlngs, {\n color: poiCollection.strokeColor,\n opacity: poiCollection.strokeOpacity,\n weight: poiCollection.strokeWeight,\n fillColor: poiCollection.fillColor,\n fillOpacity: poiCollection.fillOpacity\n }).addTo(this.map);\n\n this.addInfoWindow(marker, poiCollection);\n\n return marker;\n }\n\n /**\n * @param {PoiCollection} poiCollection\n * @returns {Polyline}\n */\n createRoute(poiCollection) {\n let latlngs = [];\n\n poiCollection.pois.forEach(poi => {\n let latLng = [poi.latitude, poi.longitude];\n this.bounds.extend(latLng);\n latlngs.push(latLng);\n });\n\n let marker = L.polyline(latlngs, {\n color: poiCollection.strokeColor,\n opacity: poiCollection.strokeOpacity,\n weight: poiCollection.strokeWeight,\n fillColor: poiCollection.fillColor,\n fillOpacity: poiCollection.fillOpacity\n }).addTo(this.map);\n\n this.addInfoWindow(marker, poiCollection);\n\n return marker;\n }\n\n /**\n * @param {PoiCollection} poiCollection\n * @returns {Circle}\n */\n createRadius(poiCollection) {\n let marker = L.circle([poiCollection.latitude, poiCollection.longitude], {\n color: poiCollection.strokeColor,\n opacity: poiCollection.strokeOpacity,\n weight: poiCollection.strokeWeight,\n fillColor: poiCollection.fillColor,\n fillOpacity: poiCollection.fillOpacity,\n radius: poiCollection.radius\n }).addTo(this.map);\n\n this.bounds.extend(marker.getBounds());\n\n this.addInfoWindow(marker, poiCollection);\n\n return marker;\n }\n\n /**\n * @param {HTMLElement} element\n * @param {PoiCollection} poiCollection\n */\n addInfoWindow(element, poiCollection) {\n element.addEventListener(\"click\", () => {\n fetch(this.environment.ajaxUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"ext-maps2\": \"infoWindowContent\"\n },\n body: JSON.stringify({\n poiCollection: poiCollection.uid\n })\n })\n .then(response => response.json())\n .then(data => {\n element.bindPopup(data.content).openPopup();\n })\n .catch(error => console.error('Error:', error));\n });\n }\n\n /**\n * @param {HTMLElement} mapContainer\n * @param {L.Marker} marker\n * @param {PoiCollection} poiCollection\n */\n addEditListeners(mapContainer, marker, poiCollection) {\n marker.on('dragend', () => {\n let lat = marker.getLatLng().lat.toFixed(6);\n let lng = marker.getLatLng().lng.toFixed(6);\n mapContainer\n .previousElementSibling\n ?.querySelector(`input.latitude-${this.getContentRecord().uid}`)\n .setAttribute(\"value\", lat);\n mapContainer\n .previousElementSibling\n ?.querySelector(`input.longitude-${this.getContentRecord().uid}`)\n .setAttribute(\"value\", lng);\n });\n\n this.map.on('click', (event) => {\n marker.setLatLng(event.latlng);\n mapContainer\n .previousElementSibling\n ?.querySelector(`input.latitude-${this.getContentRecord().uid}`)\n .setAttribute(\"value\", event.latlng.lat.toFixed(6));\n mapContainer\n .previousElementSibling\n ?.querySelector(`input.longitude-${this.getContentRecord().uid}`)\n .setAttribute(\"value\", event.latlng.lng.toFixed(6));\n });\n }\n\n /**\n * return {boolean}\n */\n canBeInterpretedAsNumber(value) {\n return typeof value === 'number' || !isNaN(Number(value));\n }\n\n /**\n * return {ContentRecord}\n */\n getContentRecord() {\n return this.environment.contentRecord;\n }\n\n /**\n * return {ExtConf}\n */\n getExtConf() {\n return this.environment.extConf;\n }\n\n /**\n * return {Settings}\n */\n getSettings() {\n return this.environment.settings;\n }\n}\n\nlet maps2OpenStreetMaps = [];\n\n// Initialize maps after all synchronous scripts in body have been executed. If two maps2\n// plugins are on one page, the optional Leaflet.markercluster library may be registered by\n// the second plugin and is therefore rendered after this script.\nconst initializeOpenStreetMaps = () => {\n document.querySelectorAll(\".maps2\").forEach((element) => {\n const environment = typeof element.dataset.environment !== 'undefined' ? element.dataset.environment : '{}';\n const override = typeof element.dataset.override !== 'undefined' ? element.dataset.override : '{}';\n\n // Pass in the objects to merge as arguments.\n // For a deep extend, set the first argument to `true`.\n const extend = (...args) => {\n let extended = {};\n let deep = false;\n let i = 0;\n let length = args.length;\n\n // Check for deep merge\n if (Object.prototype.toString.call(args[0]) === '[object Boolean]') {\n deep = args[0];\n i++;\n }\n\n // Merge the object into the extended object\n const merge = function (obj) {\n for ( var prop in obj ) {\n if ( Object.prototype.hasOwnProperty.call( obj, prop ) ) {\n // If deep merge and property is an object, merge properties\n if ( deep && Object.prototype.toString.call(obj[prop]) === '[object Object]' ) {\n extended[prop] = extend( true, extended[prop], obj[prop] );\n } else {\n extended[prop] = obj[prop];\n }\n }\n }\n };\n\n // Loop through each object and conduct a merge\n for ( ; i < length; i++ ) {\n var obj = args[i];\n merge(obj);\n }\n\n return extended;\n };\n\n maps2OpenStreetMaps.push(new OpenStreetMap2(\n element,\n extend(true, JSON.parse(environment), JSON.parse(override))\n ));\n });\n};\n\nif (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", initializeOpenStreetMaps);\n} else {\n initializeOpenStreetMaps();\n}\n"], + "mappings": "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", + "names": ["element", "environment", "latitude", "longitude", "attributeName", "dimension", "normalizedDimension", "layer", "groupedCategories", "poiCollection", "category", "categoryUid", "form", "isChecked", "categories", "checkbox", "markers", "marker", "allCategoriesOfMarker", "categoriesOfCheckboxesWithStatus", "i", "markerCategoryHasCheckboxWithStatus", "j", "k", "categoryLabel", "div", "checkboxDiv", "label", "input", "obj", "count", "key", "c", "markerIconWidth", "markerIconHeight", "markerIconAnchorPosX", "markerIconAnchorPosY", "icon", "markerIconPath", "latlngs", "poi", "latLng", "response", "data", "error", "mapContainer", "lat", "lng", "event", "value", "override", "extend", "args", "extended", "deep", "length", "merge", "prop"] } diff --git a/Resources/Public/JavaScript/leaflet.markercluster.LICENSE.txt b/Resources/Public/JavaScript/leaflet.markercluster.LICENSE.txt new file mode 100644 index 000000000..19af06829 --- /dev/null +++ b/Resources/Public/JavaScript/leaflet.markercluster.LICENSE.txt @@ -0,0 +1,20 @@ +Copyright 2012 David Leaver + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Resources/Public/JavaScript/leaflet.markercluster.min.js b/Resources/Public/JavaScript/leaflet.markercluster.min.js new file mode 100644 index 000000000..aa8926bba --- /dev/null +++ b/Resources/Public/JavaScript/leaflet.markercluster.min.js @@ -0,0 +1,3 @@ +/*! Leaflet.markercluster | (c) 2012-2017, Dave Leaver, smartrak | MIT License | https://github.com/Leaflet/Leaflet.markercluster */ +(function(c,m){typeof exports=="object"&&typeof module<"u"?m(exports):typeof define=="function"&&define.amd?define(["exports"],m):(c=c||self,m((c.Leaflet=c.Leaflet||{},c.Leaflet.markercluster={})))})(this,function(c){"use strict";var m=L.MarkerClusterGroup=L.FeatureGroup.extend({options:{maxClusterRadius:80,iconCreateFunction:null,clusterPane:L.Marker.prototype.options.pane,spiderfyOnEveryZoom:!1,spiderfyOnMaxZoom:!0,showCoverageOnHover:!0,zoomToBoundsOnClick:!0,singleMarkerMode:!1,disableClusteringAtZoom:null,removeOutsideVisibleBounds:!0,animate:!0,animateAddingMarkers:!1,spiderfyShapePositions:null,spiderfyDistanceMultiplier:1,spiderLegPolylineOptions:{weight:1.5,color:"#222",opacity:.5},chunkedLoading:!1,chunkInterval:200,chunkDelay:50,chunkProgress:null,polygonOptions:{}},initialize:function(t){L.Util.setOptions(this,t),this.options.iconCreateFunction||(this.options.iconCreateFunction=this._defaultIconCreateFunction),this._featureGroup=L.featureGroup(),this._featureGroup.addEventParent(this),this._nonPointGroup=L.featureGroup(),this._nonPointGroup.addEventParent(this),this._inZoomAnimation=0,this._needsClustering=[],this._needsRemoving=[],this._currentShownBounds=null,this._queue=[],this._childMarkerEventHandlers={dragstart:this._childMarkerDragStart,move:this._childMarkerMoved,dragend:this._childMarkerDragEnd};var e=L.DomUtil.TRANSITION&&this.options.animate;L.extend(this,e?this._withAnimation:this._noAnimation),this._markerCluster=e?L.MarkerCluster:L.MarkerClusterNonAnimated},addLayer:function(t){if(t instanceof L.LayerGroup)return this.addLayers([t]);if(!t.getLatLng)return this._nonPointGroup.addLayer(t),this.fire("layeradd",{layer:t}),this;if(!this._map)return this._needsClustering.push(t),this.fire("layeradd",{layer:t}),this;if(this.hasLayer(t))return this;this._unspiderfy&&this._unspiderfy(),this._addLayer(t,this._maxZoom),this.fire("layeradd",{layer:t}),this._topClusterLevel._recalculateBounds(),this._refreshClustersIcons();var e=t,i=this._zoom;if(t.__parent)for(;e.__parent._zoom>=i;)e=e.__parent;return this._currentShownBounds.contains(e.getLatLng())&&(this.options.animateAddingMarkers?this._animationAddLayer(t,e):this._animationAddLayerNonAnimated(t,e)),this},removeLayer:function(t){return t instanceof L.LayerGroup?this.removeLayers([t]):t.getLatLng?this._map?t.__parent?(this._unspiderfy&&(this._unspiderfy(),this._unspiderfyLayer(t)),this._removeLayer(t,!0),this.fire("layerremove",{layer:t}),this._topClusterLevel._recalculateBounds(),this._refreshClustersIcons(),t.off(this._childMarkerEventHandlers,this),this._featureGroup.hasLayer(t)&&(this._featureGroup.removeLayer(t),t.clusterShow&&t.clusterShow()),this):this:(!this._arraySplice(this._needsClustering,t)&&this.hasLayer(t)&&this._needsRemoving.push({layer:t,latlng:t._latlng}),this.fire("layerremove",{layer:t}),this):(this._nonPointGroup.removeLayer(t),this.fire("layerremove",{layer:t}),this)},addLayers:function(t,e){if(!L.Util.isArray(t))return this.addLayer(t);var i=this._featureGroup,n=this._nonPointGroup,s=this.options.chunkedLoading,o=this.options.chunkInterval,r=this.options.chunkProgress,h=t.length,a=0,u=!0,_;if(this._map){var d=new Date().getTime(),l=L.bind(function(){var p=new Date().getTime();for(this._map&&this._unspiderfy&&this._unspiderfy();ao)break}if(_=t[a],_ instanceof L.LayerGroup){u&&(t=t.slice(),u=!1),this._extractNonGroupLayers(_,t),h=t.length;continue}if(!_.getLatLng){n.addLayer(_),e||this.fire("layeradd",{layer:_});continue}if(!this.hasLayer(_)&&(this._addLayer(_,this._maxZoom),e||this.fire("layeradd",{layer:_}),_.__parent&&_.__parent.getChildCount()===2)){var g=_.__parent.getAllChildMarkers(),y=g[0]===_?g[1]:g[0];i.removeLayer(y)}}r&&r(a,h,new Date().getTime()-d),a===h?(this._topClusterLevel._recalculateBounds(),this._refreshClustersIcons(),this._topClusterLevel._recursivelyAddChildrenToMap(null,this._zoom,this._currentShownBounds)):setTimeout(l,this.options.chunkDelay)},this);l()}else for(var f=this._needsClustering;a=0;e--)t.extend(this._needsClustering[e].getLatLng());return t.extend(this._nonPointGroup.getBounds()),t},eachLayer:function(t,e){var i=this._needsClustering.slice(),n=this._needsRemoving,s,o,r;for(this._topClusterLevel&&this._topClusterLevel.getAllChildMarkers(i),o=i.length-1;o>=0;o--){for(s=!0,r=n.length-1;r>=0;r--)if(n[r].layer===i[o]){s=!1;break}s&&t.call(e,i[o])}this._nonPointGroup.eachLayer(t,e)},getLayers:function(){var t=[];return this.eachLayer(function(e){t.push(e)}),t},getLayer:function(t){var e=null;return t=parseInt(t,10),this.eachLayer(function(i){L.stamp(i)===t&&(e=i)}),e},hasLayer:function(t){if(!t)return!1;var e,i=this._needsClustering;for(e=i.length-1;e>=0;e--)if(i[e]===t)return!0;for(i=this._needsRemoving,e=i.length-1;e>=0;e--)if(i[e].layer===t)return!1;return!!(t.__parent&&t.__parent._group===this)||this._nonPointGroup.hasLayer(t)},zoomToShowLayer:function(t,e){var i=this._map;typeof e!="function"&&(e=function(){});var n=function(){(i.hasLayer(t)||i.hasLayer(t.__parent))&&!this._inZoomAnimation&&(this._map.off("moveend",n,this),this.off("animationend",n,this),i.hasLayer(t)?e():t.__parent._icon&&(this.once("spiderfied",e,this),t.__parent.spiderfy()))};t._icon&&this._map.getBounds().contains(t.getLatLng())?e():t.__parent._zoom=0;i--)if(t[i]===e)return t.splice(i,1),!0},_removeFromGridUnclustered:function(t,e){for(var i=this._map,n=this._gridUnclustered,s=Math.floor(this._map.getMinZoom());e>=s&&n[e].removeObject(t,i.project(t.getLatLng(),e));e--);},_childMarkerDragStart:function(t){t.target.__dragStart=t.target._latlng},_childMarkerMoved:function(t){if(!this._ignoreMove&&!t.target.__dragStart){var e=t.target._popup&&t.target._popup.isOpen();this._moveChild(t.target,t.oldLatLng,t.latlng),e&&t.target.openPopup()}},_moveChild:function(t,e,i){t._latlng=e,this.removeLayer(t),t._latlng=i,this.addLayer(t)},_childMarkerDragEnd:function(t){var e=t.target.__dragStart;delete t.target.__dragStart,e&&this._moveChild(t.target,e,t.target._latlng)},_removeLayer:function(t,e,i){var n=this._gridClusters,s=this._gridUnclustered,o=this._featureGroup,r=this._map,h=Math.floor(this._map.getMinZoom());e&&this._removeFromGridUnclustered(t,this._maxZoom);var a=t.__parent,u=a._markers,_;for(this._arraySplice(u,t);a&&(a._childCount--,a._boundsNeedUpdate=!0,!(a._zoom"+e+"",className:"marker-cluster"+i,iconSize:new L.Point(40,40)})},_bindEvents:function(){var t=this._map,e=this.options.spiderfyOnMaxZoom,i=this.options.showCoverageOnHover,n=this.options.zoomToBoundsOnClick,s=this.options.spiderfyOnEveryZoom;(e||n||s)&&this.on("clusterclick clusterkeypress",this._zoomOrSpiderfy,this),i&&(this.on("clustermouseover",this._showCoverage,this),this.on("clustermouseout",this._hideCoverage,this),t.on("zoomend",this._hideCoverage,this))},_zoomOrSpiderfy:function(t){var e=t.layer,i=e;if(!(t.type==="clusterkeypress"&&t.originalEvent&&t.originalEvent.keyCode!==13)){for(;i._childClusters.length===1;)i=i._childClusters[0];i._zoom===this._maxZoom&&i._childCount===e._childCount&&this.options.spiderfyOnMaxZoom?e.spiderfy():this.options.zoomToBoundsOnClick&&e.zoomToBounds(),this.options.spiderfyOnEveryZoom&&e.spiderfy(),t.originalEvent&&t.originalEvent.keyCode===13&&this._map._container.focus()}},_showCoverage:function(t){var e=this._map;this._inZoomAnimation||(this._shownPolygon&&e.removeLayer(this._shownPolygon),t.layer.getChildCount()>2&&t.layer!==this._spiderfied&&(this._shownPolygon=new L.Polygon(t.layer.getConvexHull(),this.options.polygonOptions),e.addLayer(this._shownPolygon)))},_hideCoverage:function(){this._shownPolygon&&(this._map.removeLayer(this._shownPolygon),this._shownPolygon=null)},_unbindEvents:function(){var t=this.options.spiderfyOnMaxZoom,e=this.options.showCoverageOnHover,i=this.options.zoomToBoundsOnClick,n=this.options.spiderfyOnEveryZoom,s=this._map;(t||i||n)&&this.off("clusterclick clusterkeypress",this._zoomOrSpiderfy,this),e&&(this.off("clustermouseover",this._showCoverage,this),this.off("clustermouseout",this._hideCoverage,this),s.off("zoomend",this._hideCoverage,this))},_zoomEnd:function(){this._map&&(this._mergeSplitClusters(),this._zoom=Math.round(this._map._zoom),this._currentShownBounds=this._getExpandedVisibleBounds())},_moveEnd:function(){if(!this._inZoomAnimation){var t=this._getExpandedVisibleBounds();this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds,Math.floor(this._map.getMinZoom()),this._zoom,t),this._topClusterLevel._recursivelyAddChildrenToMap(null,Math.round(this._map._zoom),t),this._currentShownBounds=t}},_generateInitialClusters:function(){var t=Math.ceil(this._map.getMaxZoom()),e=Math.floor(this._map.getMinZoom()),i=this.options.maxClusterRadius,n=i;typeof i!="function"&&(n=function(){return i}),this.options.disableClusteringAtZoom!==null&&(t=this.options.disableClusteringAtZoom-1),this._maxZoom=t,this._gridClusters={},this._gridUnclustered={};for(var s=t;s>=e;s--)this._gridClusters[s]=new L.DistanceGrid(n(s)),this._gridUnclustered[s]=new L.DistanceGrid(n(s));this._topClusterLevel=new this._markerCluster(this,e-1)},_addLayer:function(t,e){var i=this._gridClusters,n=this._gridUnclustered,s=Math.floor(this._map.getMinZoom()),o,r;for(this.options.singleMarkerMode&&this._overrideMarkerIcon(t),t.on(this._childMarkerEventHandlers,this);e>=s;e--){o=this._map.project(t.getLatLng(),e);var h=i[e].getNearObject(o);if(h){h._addChild(t),t.__parent=h;return}if(h=n[e].getNearObject(o),h){var a=h.__parent;a&&this._removeLayer(h,!1);var u=new this._markerCluster(this,e,h,t);i[e].addObject(u,this._map.project(u._cLatLng,e)),h.__parent=u,t.__parent=u;var _=u;for(r=e-1;r>a._zoom;r--)_=new this._markerCluster(this,r,_),i[r].addObject(_,this._map.project(h.getLatLng(),r));a._addChild(_),this._removeFromGridUnclustered(h,e);return}n[e].addObject(t,o)}this._topClusterLevel._addChild(t),t.__parent=this._topClusterLevel},_refreshClustersIcons:function(){this._featureGroup.eachLayer(function(t){t instanceof L.MarkerCluster&&t._iconNeedsUpdate&&t._updateIcon()})},_enqueue:function(t){this._queue.push(t),this._queueTimeout||(this._queueTimeout=setTimeout(L.bind(this._processQueue,this),300))},_processQueue:function(){for(var t=0;tt?(this._animationStart(),this._animationZoomOut(this._zoom,t)):this._moveEnd()},_getExpandedVisibleBounds:function(){if(this.options.removeOutsideVisibleBounds){if(L.Browser.mobile)return this._checkBoundsMaxLat(this._map.getBounds())}else return this._mapBoundsInfinite;return this._checkBoundsMaxLat(this._map.getBounds().pad(1))},_checkBoundsMaxLat:function(t){var e=this._maxLat;return e!==void 0&&(t.getNorth()>=e&&(t._northEast.lat=1/0),t.getSouth()<=-e&&(t._southWest.lat=-1/0)),t},_animationAddLayerNonAnimated:function(t,e){if(e===t)this._featureGroup.addLayer(t);else if(e._childCount===2){e._addToMap();var i=e.getAllChildMarkers();this._featureGroup.removeLayer(i[0]),this._featureGroup.removeLayer(i[1])}else e._updateIcon()},_extractNonGroupLayers:function(t,e){var i=t.getLayers(),n=0,s;for(e=e||[];n=0;o--)u=a[o],i.contains(u._latlng)||n.removeLayer(u)}),this._forceLayout(),this._topClusterLevel._recursivelyBecomeVisible(i,e),n.eachLayer(function(r){!(r instanceof L.MarkerCluster)&&r._icon&&r.clusterShow()}),this._topClusterLevel._recursively(i,t,e,function(r){r._recursivelyRestoreChildPositions(e)}),this._ignoreMove=!1,this._enqueue(function(){this._topClusterLevel._recursively(i,t,s,function(r){n.removeLayer(r),r.clusterShow()}),this._animationEnd()})},_animationZoomOut:function(t,e){this._animationZoomOutSingle(this._topClusterLevel,t-1,e),this._topClusterLevel._recursivelyAddChildrenToMap(null,e,this._getExpandedVisibleBounds()),this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds,Math.floor(this._map.getMinZoom()),t,this._getExpandedVisibleBounds())},_animationAddLayer:function(t,e){var i=this,n=this._featureGroup;n.addLayer(t),e!==t&&(e._childCount>2?(e._updateIcon(),this._forceLayout(),this._animationStart(),t._setPos(this._map.latLngToLayerPoint(e.getLatLng())),t.clusterHide(),this._enqueue(function(){n.removeLayer(t),t.clusterShow(),i._animationEnd()})):(this._forceLayout(),i._animationStart(),i._animationZoomOutSingle(e,this._map.getMaxZoom(),this._zoom)))}},_animationZoomOutSingle:function(t,e,i){var n=this._getExpandedVisibleBounds(),s=Math.floor(this._map.getMinZoom());t._recursivelyAnimateChildrenInAndAddSelfToMap(n,s,e+1,i);var o=this;this._forceLayout(),t._recursivelyBecomeVisible(n,i),this._enqueue(function(){if(t._childCount===1){var r=t._markers[0];this._ignoreMove=!0,r.setLatLng(r.getLatLng()),this._ignoreMove=!1,r.clusterShow&&r.clusterShow()}else t._recursively(n,i,s,function(h){h._recursivelyRemoveChildrenFromMap(n,s,e+1)});o._animationEnd()})},_animationEnd:function(){this._map&&(this._map._mapPane.className=this._map._mapPane.className.replace(" leaflet-cluster-anim","")),this._inZoomAnimation--,this.fire("animationend")},_forceLayout:function(){L.Util.falseFn(document.body.offsetWidth)}}),L.markerClusterGroup=function(t){return new L.MarkerClusterGroup(t)};var C=L.MarkerCluster=L.Marker.extend({options:L.Icon.prototype.options,initialize:function(t,e,i,n){L.Marker.prototype.initialize.call(this,i?i._cLatLng||i.getLatLng():new L.LatLng(0,0),{icon:this,pane:t.options.clusterPane}),this._group=t,this._zoom=e,this._markers=[],this._childClusters=[],this._childCount=0,this._iconNeedsUpdate=!0,this._boundsNeedUpdate=!0,this._bounds=new L.LatLngBounds,i&&this._addChild(i),n&&this._addChild(n)},getAllChildMarkers:function(t,e){t=t||[];for(var i=this._childClusters.length-1;i>=0;i--)this._childClusters[i].getAllChildMarkers(t,e);for(var n=this._markers.length-1;n>=0;n--)e&&this._markers[n].__dragStart||t.push(this._markers[n]);return t},getChildCount:function(){return this._childCount},zoomToBounds:function(t){for(var e=this._childClusters.slice(),i=this._group._map,n=i.getBoundsZoom(this._bounds),s=this._zoom+1,o=i.getZoom(),r;e.length>0&&n>s;){s++;var h=[];for(r=0;rs?this._group._map.setView(this._latlng,s):n<=o?this._group._map.setView(this._latlng,o+1):this._group._map.fitBounds(this._bounds,t)},getBounds:function(){var t=new L.LatLngBounds;return t.extend(this._bounds),t},_updateIcon:function(){this._iconNeedsUpdate=!0,this._icon&&this.setIcon(this)},createIcon:function(){return this._iconNeedsUpdate&&(this._iconObj=this._group.options.iconCreateFunction(this),this._iconNeedsUpdate=!1),this._iconObj.createIcon()},createShadow:function(){return this._iconObj.createShadow()},_addChild:function(t,e){this._iconNeedsUpdate=!0,this._boundsNeedUpdate=!0,this._setClusterCenter(t),t instanceof L.MarkerCluster?(e||(this._childClusters.push(t),t.__parent=this),this._childCount+=t._childCount):(e||this._markers.push(t),this._childCount++),this.__parent&&this.__parent._addChild(t,!0)},_setClusterCenter:function(t){this._cLatLng||(this._cLatLng=t._cLatLng||t._latlng)},_resetBounds:function(){var t=this._bounds;t._southWest&&(t._southWest.lat=1/0,t._southWest.lng=1/0),t._northEast&&(t._northEast.lat=-1/0,t._northEast.lng=-1/0)},_recalculateBounds:function(){var t=this._markers,e=this._childClusters,i=0,n=0,s=this._childCount,o,r,h,a;if(s!==0){for(this._resetBounds(),o=0;o=0;o--)r=s[o],r._icon&&(r._setPos(e),r.clusterHide())},function(n){var s=n._childClusters,o,r;for(o=s.length-1;o>=0;o--)r=s[o],r._icon&&(r._setPos(e),r.clusterHide())})},_recursivelyAnimateChildrenInAndAddSelfToMap:function(t,e,i,n){this._recursively(t,n,e,function(s){s._recursivelyAnimateChildrenIn(t,s._group._map.latLngToLayerPoint(s.getLatLng()).round(),i),s._isSingleParent()&&i-1===n?(s.clusterShow(),s._recursivelyRemoveChildrenFromMap(t,e,i)):s.clusterHide(),s._addToMap()})},_recursivelyBecomeVisible:function(t,e){this._recursively(t,this._group._map.getMinZoom(),e,null,function(i){i.clusterShow()})},_recursivelyAddChildrenToMap:function(t,e,i){this._recursively(i,this._group._map.getMinZoom()-1,e,function(n){if(e!==n._zoom)for(var s=n._markers.length-1;s>=0;s--){var o=n._markers[s];i.contains(o._latlng)&&(t&&(o._backupLatlng=o.getLatLng(),o.setLatLng(t),o.clusterHide&&o.clusterHide()),n._group._featureGroup.addLayer(o))}},function(n){n._addToMap(t)})},_recursivelyRestoreChildPositions:function(t){for(var e=this._markers.length-1;e>=0;e--){var i=this._markers[e];i._backupLatlng&&(i.setLatLng(i._backupLatlng),delete i._backupLatlng)}if(t-1===this._zoom)for(var n=this._childClusters.length-1;n>=0;n--)this._childClusters[n]._restorePosition();else for(var s=this._childClusters.length-1;s>=0;s--)this._childClusters[s]._recursivelyRestoreChildPositions(t)},_restorePosition:function(){this._backupLatlng&&(this.setLatLng(this._backupLatlng),delete this._backupLatlng)},_recursivelyRemoveChildrenFromMap:function(t,e,i,n){var s,o;this._recursively(t,e-1,i-1,function(r){for(o=r._markers.length-1;o>=0;o--)s=r._markers[o],(!n||!n.contains(s._latlng))&&(r._group._featureGroup.removeLayer(s),s.clusterShow&&s.clusterShow())},function(r){for(o=r._childClusters.length-1;o>=0;o--)s=r._childClusters[o],(!n||!n.contains(s._latlng))&&(r._group._featureGroup.removeLayer(s),s.clusterShow&&s.clusterShow())})},_recursively:function(t,e,i,n,s){var o=this._childClusters,r=this._zoom,h,a;if(e<=r&&(n&&n(this),s&&r===i&&s(this)),r=0;h--)a=o[h],a._boundsNeedUpdate&&a._recalculateBounds(),t.intersects(a._bounds)&&a._recursively(t,e,i,n,s)},_isSingleParent:function(){return this._childClusters.length>0&&this._childClusters[0]._childCount===this._childCount}});L.Marker.include({clusterHide:function(){var t=this.options.opacity;return this.setOpacity(0),this.options.opacity=t,this},clusterShow:function(){return this.setOpacity(this.options.opacity)}}),L.DistanceGrid=function(t){this._cellSize=t,this._sqCellSize=t*t,this._grid={},this._objectPoint={}},L.DistanceGrid.prototype={addObject:function(t,e){var i=this._getCoord(e.x),n=this._getCoord(e.y),s=this._grid,o=s[n]=s[n]||{},r=o[i]=o[i]||[],h=L.Util.stamp(t);this._objectPoint[h]=e,r.push(t)},updateObject:function(t,e){this.removeObject(t),this.addObject(t,e)},removeObject:function(t,e){var i=this._getCoord(e.x),n=this._getCoord(e.y),s=this._grid,o=s[n]=s[n]||{},r=o[i]=o[i]||[],h,a;for(delete this._objectPoint[L.Util.stamp(t)],h=0,a=r.length;h=0;o--){if(r=e[o],h=this.getDistant(r,t),h>0)s.push(r);else continue;h>i&&(i=h,n=r)}return{maxPoint:n,newPoints:s}},buildConvexHull:function(t,e){var i=[],n=this.findMostDistantPointFromBaseLine(t,e);return n.maxPoint?(i=i.concat(this.buildConvexHull([t[0],n.maxPoint],n.newPoints)),i=i.concat(this.buildConvexHull([n.maxPoint,t[1]],n.newPoints)),i):[t[0]]},getConvexHull:function(t){var e=!1,i=!1,n=!1,s=!1,o=null,r=null,h=null,a=null,u=null,_=null,d;for(d=t.length-1;d>=0;d--){var l=t[d];(e===!1||l.lat>e)&&(o=l,e=l.lat),(i===!1||l.latn)&&(h=l,n=l.lng),(s===!1||l.lng=0;n--)i=t[n].getLatLng(),e.push(i);return L.QuickHull.getConvexHull(e)}}),L.MarkerCluster.include({_2PI:Math.PI*2,_circleFootSeparation:25,_circleStartAngle:0,_spiralFootSeparation:28,_spiralLengthStart:11,_spiralLengthFactor:5,_circleSpiralSwitchover:9,spiderfy:function(){if(!(this._group._spiderfied===this||this._group._inZoomAnimation)){var t=this.getAllChildMarkers(null,!0),e=this._group,i=e._map,n=i.latLngToLayerPoint(this._latlng),s;this._group._unspiderfy(),this._group._spiderfied=this,this._group.options.spiderfyShapePositions?s=this._group.options.spiderfyShapePositions(t.length,n):t.length>=this._circleSpiralSwitchover?s=this._generatePointsSpiral(t.length,n):(n.y+=10,s=this._generatePointsCircle(t.length,n)),this._animationSpiderfy(t,s)}},unspiderfy:function(t){this._group._inZoomAnimation||(this._animationUnspiderfy(t),this._group._spiderfied=null)},_generatePointsCircle:function(t,e){var i=this._group.options.spiderfyDistanceMultiplier*this._circleFootSeparation*(2+t),n=i/this._2PI,s=this._2PI/t,o=[],r,h;for(n=Math.max(n,35),o.length=t,r=0;r=0;a--)a=0;o--)s=n[o],i.removeLayer(s),s._preSpiderfyLatlng&&(s.setLatLng(s._preSpiderfyLatlng),delete s._preSpiderfyLatlng),s.setZIndexOffset&&s.setZIndexOffset(0),s._spiderLeg&&(e.removeLayer(s._spiderLeg),delete s._spiderLeg);t.fire("unspiderfied",{cluster:this,markers:n}),t._ignoreMove=!1,t._spiderfied=null}}),L.MarkerClusterNonAnimated=L.MarkerCluster.extend({_animationSpiderfy:function(t,e){var i=this._group,n=i._map,s=i._featureGroup,o=this._group.options.spiderLegPolylineOptions,r,h,a,u;for(i._ignoreMove=!0,r=0;r=0;d--)g=s.layerPointToLatLng(e[d]),l=t[d],l._preSpiderfyLatlng=l._latlng,l.setLatLng(g),l.clusterShow&&l.clusterShow(),a&&(f=l._spiderLeg,p=f._path,p.style.strokeDashoffset=0,f.setStyle({opacity:_}));this.setOpacity(.3),n._ignoreMove=!1,setTimeout(function(){n._animationEnd(),n.fire("spiderfied",{cluster:i,markers:t})},200)},_animationUnspiderfy:function(t){var e=this,i=this._group,n=i._map,s=i._featureGroup,o=t?n._latLngToNewLayerPoint(this._latlng,t.zoom,t.center):n.latLngToLayerPoint(this._latlng),r=this.getAllChildMarkers(null,!0),h=L.Path.SVG,a,u,_,d,l,f;for(i._ignoreMove=!0,i._animationStart(),this.setOpacity(1),u=r.length-1;u>=0;u--)a=r[u],a._preSpiderfyLatlng&&(a.closePopup(),a.setLatLng(a._preSpiderfyLatlng),delete a._preSpiderfyLatlng,f=!0,a._setPos&&(a._setPos(o),f=!1),a.clusterHide&&(a.clusterHide(),f=!1),f&&s.removeLayer(a),h&&(_=a._spiderLeg,d=_._path,l=d.getTotalLength()+.1,d.style.strokeDashoffset=l,_.setStyle({opacity:0})));i._ignoreMove=!1,setTimeout(function(){var p=0;for(u=r.length-1;u>=0;u--)a=r[u],a._spiderLeg&&p++;for(u=r.length-1;u>=0;u--)a=r[u],a._spiderLeg&&(a.clusterShow&&a.clusterShow(),a.setZIndexOffset&&a.setZIndexOffset(0),p>1&&s.removeLayer(a),n.removeLayer(a._spiderLeg),delete a._spiderLeg);i._animationEnd(),i.fire("unspiderfied",{cluster:e,markers:r})},200)}}),L.MarkerClusterGroup.include({_spiderfied:null,unspiderfy:function(){this._unspiderfy.apply(this,arguments)},_spiderfierOnAdd:function(){this._map.on("click",this._unspiderfyWrapper,this),this._map.options.zoomAnimation&&this._map.on("zoomstart",this._unspiderfyZoomStart,this),this._map.on("zoomend",this._noanimationUnspiderfy,this),L.Browser.touch||this._map.getRenderer(this)},_spiderfierOnRemove:function(){this._map.off("click",this._unspiderfyWrapper,this),this._map.off("zoomstart",this._unspiderfyZoomStart,this),this._map.off("zoomanim",this._unspiderfyZoomAnim,this),this._map.off("zoomend",this._noanimationUnspiderfy,this),this._noanimationUnspiderfy()},_unspiderfyZoomStart:function(){this._map&&this._map.on("zoomanim",this._unspiderfyZoomAnim,this)},_unspiderfyZoomAnim:function(t){L.DomUtil.hasClass(this._map._mapPane,"leaflet-touching")||(this._map.off("zoomanim",this._unspiderfyZoomAnim,this),this._unspiderfy(t))},_unspiderfyWrapper:function(){this._unspiderfy()},_unspiderfy:function(t){this._spiderfied&&this._spiderfied.unspiderfy(t)},_noanimationUnspiderfy:function(){this._spiderfied&&this._spiderfied._noanimationUnspiderfy()},_unspiderfyLayer:function(t){t._spiderLeg&&(this._featureGroup.removeLayer(t),t.clusterShow&&t.clusterShow(),t.setZIndexOffset&&t.setZIndexOffset(0),this._map.removeLayer(t._spiderLeg),delete t._spiderLeg)}}),L.MarkerClusterGroup.include({refreshClusters:function(t){return t?t instanceof L.MarkerClusterGroup?t=t._topClusterLevel.getAllChildMarkers():t instanceof L.LayerGroup?t=t._layers:t instanceof L.MarkerCluster?t=t.getAllChildMarkers():t instanceof L.Marker&&(t=[t]):t=this._topClusterLevel.getAllChildMarkers(),this._flagParentsIconsNeedUpdate(t),this._refreshClustersIcons(),this.options.singleMarkerMode&&this._refreshSingleMarkerModeMarkers(t),this},_flagParentsIconsNeedUpdate:function(t){var e,i;for(e in t)for(i=t[e].__parent;i;)i._iconNeedsUpdate=!0,i=i.__parent},_refreshSingleMarkerModeMarkers:function(t){var e,i;for(e in t)i=t[e],this.hasLayer(i)&&i.setIcon(this._overrideMarkerIcon(i))}}),L.Marker.include({refreshIconOptions:function(t,e){var i=this.options.icon;return L.setOptions(i,t),this.setIcon(i),e&&this.__parent&&this.__parent._group.refreshClusters(this),this}}),c.MarkerClusterGroup=m,c.MarkerCluster=C,Object.defineProperty(c,"__esModule",{value:!0})}); +//# sourceMappingURL=leaflet.markercluster.min.js.map diff --git a/Resources/Public/JavaScript/leaflet.markercluster.min.js.map b/Resources/Public/JavaScript/leaflet.markercluster.min.js.map new file mode 100644 index 000000000..59bf556e8 --- /dev/null +++ b/Resources/Public/JavaScript/leaflet.markercluster.min.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["../../Private/Build/node_modules/leaflet.markercluster/src/MarkerClusterGroup.js", "../../Private/Build/node_modules/leaflet.markercluster/src/MarkerCluster.js", "../../Private/Build/node_modules/leaflet.markercluster/src/MarkerOpacity.js", "../../Private/Build/node_modules/leaflet.markercluster/src/DistanceGrid.js", "../../Private/Build/node_modules/leaflet.markercluster/src/MarkerCluster.QuickHull.js", "../../Private/Build/node_modules/leaflet.markercluster/src/MarkerCluster.Spiderfier.js", "../../Private/Build/node_modules/leaflet.markercluster/src/MarkerClusterGroup.Refresh.js"], + "sourcesContent": ["/*\n * L.MarkerClusterGroup extends L.FeatureGroup by clustering the markers contained within\n */\n\nexport var MarkerClusterGroup = L.MarkerClusterGroup = L.FeatureGroup.extend({\n\n\toptions: {\n\t\tmaxClusterRadius: 80, //A cluster will cover at most this many pixels from its center\n\t\ticonCreateFunction: null,\n\t\tclusterPane: L.Marker.prototype.options.pane,\n\n\t\tspiderfyOnEveryZoom: false,\n\t\tspiderfyOnMaxZoom: true,\n\t\tshowCoverageOnHover: true,\n\t\tzoomToBoundsOnClick: true,\n\t\tsingleMarkerMode: false,\n\n\t\tdisableClusteringAtZoom: null,\n\n\t\t// Setting this to false prevents the removal of any clusters outside of the viewpoint, which\n\t\t// is the default behaviour for performance reasons.\n\t\tremoveOutsideVisibleBounds: true,\n\n\t\t// Set to false to disable all animations (zoom and spiderfy).\n\t\t// If false, option animateAddingMarkers below has no effect.\n\t\t// If L.DomUtil.TRANSITION is falsy, this option has no effect.\n\t\tanimate: true,\n\n\t\t//Whether to animate adding markers after adding the MarkerClusterGroup to the map\n\t\t// If you are adding individual markers set to true, if adding bulk markers leave false for massive performance gains.\n\t\tanimateAddingMarkers: false,\n\n\t\t// Make it possible to provide custom function to calculate spiderfy shape positions\n\t\tspiderfyShapePositions: null,\n\n\t\t//Increase to increase the distance away that spiderfied markers appear from the center\n\t\tspiderfyDistanceMultiplier: 1,\n\n\t\t// Make it possible to specify a polyline options on a spider leg\n\t\tspiderLegPolylineOptions: { weight: 1.5, color: '#222', opacity: 0.5 },\n\n\t\t// When bulk adding layers, adds markers in chunks. Means addLayers may not add all the layers in the call, others will be loaded during setTimeouts\n\t\tchunkedLoading: false,\n\t\tchunkInterval: 200, // process markers for a maximum of ~ n milliseconds (then trigger the chunkProgress callback)\n\t\tchunkDelay: 50, // at the end of each interval, give n milliseconds back to system/browser\n\t\tchunkProgress: null, // progress callback: function(processed, total, elapsed) (e.g. for a progress indicator)\n\n\t\t//Options to pass to the L.Polygon constructor\n\t\tpolygonOptions: {}\n\t},\n\n\tinitialize: function (options) {\n\t\tL.Util.setOptions(this, options);\n\t\tif (!this.options.iconCreateFunction) {\n\t\t\tthis.options.iconCreateFunction = this._defaultIconCreateFunction;\n\t\t}\n\n\t\tthis._featureGroup = L.featureGroup();\n\t\tthis._featureGroup.addEventParent(this);\n\n\t\tthis._nonPointGroup = L.featureGroup();\n\t\tthis._nonPointGroup.addEventParent(this);\n\n\t\tthis._inZoomAnimation = 0;\n\t\tthis._needsClustering = [];\n\t\tthis._needsRemoving = []; //Markers removed while we aren't on the map need to be kept track of\n\t\t//The bounds of the currently shown area (from _getExpandedVisibleBounds) Updated on zoom/move\n\t\tthis._currentShownBounds = null;\n\n\t\tthis._queue = [];\n\n\t\tthis._childMarkerEventHandlers = {\n\t\t\t'dragstart': this._childMarkerDragStart,\n\t\t\t'move': this._childMarkerMoved,\n\t\t\t'dragend': this._childMarkerDragEnd,\n\t\t};\n\n\t\t// Hook the appropriate animation methods.\n\t\tvar animate = L.DomUtil.TRANSITION && this.options.animate;\n\t\tL.extend(this, animate ? this._withAnimation : this._noAnimation);\n\t\t// Remember which MarkerCluster class to instantiate (animated or not).\n\t\tthis._markerCluster = animate ? L.MarkerCluster : L.MarkerClusterNonAnimated;\n\t},\n\n\taddLayer: function (layer) {\n\n\t\tif (layer instanceof L.LayerGroup) {\n\t\t\treturn this.addLayers([layer]);\n\t\t}\n\n\t\t//Don't cluster non point data\n\t\tif (!layer.getLatLng) {\n\t\t\tthis._nonPointGroup.addLayer(layer);\n\t\t\tthis.fire('layeradd', { layer: layer });\n\t\t\treturn this;\n\t\t}\n\n\t\tif (!this._map) {\n\t\t\tthis._needsClustering.push(layer);\n\t\t\tthis.fire('layeradd', { layer: layer });\n\t\t\treturn this;\n\t\t}\n\n\t\tif (this.hasLayer(layer)) {\n\t\t\treturn this;\n\t\t}\n\n\n\t\t//If we have already clustered we'll need to add this one to a cluster\n\n\t\tif (this._unspiderfy) {\n\t\t\tthis._unspiderfy();\n\t\t}\n\n\t\tthis._addLayer(layer, this._maxZoom);\n\t\tthis.fire('layeradd', { layer: layer });\n\n\t\t// Refresh bounds and weighted positions.\n\t\tthis._topClusterLevel._recalculateBounds();\n\n\t\tthis._refreshClustersIcons();\n\n\t\t//Work out what is visible\n\t\tvar visibleLayer = layer,\n\t\t currentZoom = this._zoom;\n\t\tif (layer.__parent) {\n\t\t\twhile (visibleLayer.__parent._zoom >= currentZoom) {\n\t\t\t\tvisibleLayer = visibleLayer.__parent;\n\t\t\t}\n\t\t}\n\n\t\tif (this._currentShownBounds.contains(visibleLayer.getLatLng())) {\n\t\t\tif (this.options.animateAddingMarkers) {\n\t\t\t\tthis._animationAddLayer(layer, visibleLayer);\n\t\t\t} else {\n\t\t\t\tthis._animationAddLayerNonAnimated(layer, visibleLayer);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t},\n\n\tremoveLayer: function (layer) {\n\n\t\tif (layer instanceof L.LayerGroup) {\n\t\t\treturn this.removeLayers([layer]);\n\t\t}\n\n\t\t//Non point layers\n\t\tif (!layer.getLatLng) {\n\t\t\tthis._nonPointGroup.removeLayer(layer);\n\t\t\tthis.fire('layerremove', { layer: layer });\n\t\t\treturn this;\n\t\t}\n\n\t\tif (!this._map) {\n\t\t\tif (!this._arraySplice(this._needsClustering, layer) && this.hasLayer(layer)) {\n\t\t\t\tthis._needsRemoving.push({ layer: layer, latlng: layer._latlng });\n\t\t\t}\n\t\t\tthis.fire('layerremove', { layer: layer });\n\t\t\treturn this;\n\t\t}\n\n\t\tif (!layer.__parent) {\n\t\t\treturn this;\n\t\t}\n\n\t\tif (this._unspiderfy) {\n\t\t\tthis._unspiderfy();\n\t\t\tthis._unspiderfyLayer(layer);\n\t\t}\n\n\t\t//Remove the marker from clusters\n\t\tthis._removeLayer(layer, true);\n\t\tthis.fire('layerremove', { layer: layer });\n\n\t\t// Refresh bounds and weighted positions.\n\t\tthis._topClusterLevel._recalculateBounds();\n\n\t\tthis._refreshClustersIcons();\n\n\t\tlayer.off(this._childMarkerEventHandlers, this);\n\n\t\tif (this._featureGroup.hasLayer(layer)) {\n\t\t\tthis._featureGroup.removeLayer(layer);\n\t\t\tif (layer.clusterShow) {\n\t\t\t\tlayer.clusterShow();\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\t//Takes an array of markers and adds them in bulk\n\taddLayers: function (layersArray, skipLayerAddEvent) {\n\t\tif (!L.Util.isArray(layersArray)) {\n\t\t\treturn this.addLayer(layersArray);\n\t\t}\n\n\t\tvar fg = this._featureGroup,\n\t\t npg = this._nonPointGroup,\n\t\t chunked = this.options.chunkedLoading,\n\t\t chunkInterval = this.options.chunkInterval,\n\t\t chunkProgress = this.options.chunkProgress,\n\t\t l = layersArray.length,\n\t\t offset = 0,\n\t\t originalArray = true,\n\t\t m;\n\n\t\tif (this._map) {\n\t\t\tvar started = (new Date()).getTime();\n\t\t\tvar process = L.bind(function () {\n\t\t\t\tvar start = (new Date()).getTime();\n\n\t\t\t\t// Make sure to unspiderfy before starting to add some layers\n\t\t\t\tif (this._map && this._unspiderfy) {\n\t\t\t\t\tthis._unspiderfy();\n\t\t\t\t}\n\n\t\t\t\tfor (; offset < l; offset++) {\n\t\t\t\t\tif (chunked && offset % 200 === 0) {\n\t\t\t\t\t\t// every couple hundred markers, instrument the time elapsed since processing started:\n\t\t\t\t\t\tvar elapsed = (new Date()).getTime() - start;\n\t\t\t\t\t\tif (elapsed > chunkInterval) {\n\t\t\t\t\t\t\tbreak; // been working too hard, time to take a break :-)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tm = layersArray[offset];\n\n\t\t\t\t\t// Group of layers, append children to layersArray and skip.\n\t\t\t\t\t// Side effects:\n\t\t\t\t\t// - Total increases, so chunkProgress ratio jumps backward.\n\t\t\t\t\t// - Groups are not included in this group, only their non-group child layers (hasLayer).\n\t\t\t\t\t// Changing array length while looping does not affect performance in current browsers:\n\t\t\t\t\t// http://jsperf.com/for-loop-changing-length/6\n\t\t\t\t\tif (m instanceof L.LayerGroup) {\n\t\t\t\t\t\tif (originalArray) {\n\t\t\t\t\t\t\tlayersArray = layersArray.slice();\n\t\t\t\t\t\t\toriginalArray = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis._extractNonGroupLayers(m, layersArray);\n\t\t\t\t\t\tl = layersArray.length;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\t//Not point data, can't be clustered\n\t\t\t\t\tif (!m.getLatLng) {\n\t\t\t\t\t\tnpg.addLayer(m);\n\t\t\t\t\t\tif (!skipLayerAddEvent) {\n\t\t\t\t\t\t\tthis.fire('layeradd', { layer: m });\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this.hasLayer(m)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis._addLayer(m, this._maxZoom);\n\t\t\t\t\tif (!skipLayerAddEvent) {\n\t\t\t\t\t\tthis.fire('layeradd', { layer: m });\n\t\t\t\t\t}\n\n\t\t\t\t\t//If we just made a cluster of size 2 then we need to remove the other marker from the map (if it is) or we never will\n\t\t\t\t\tif (m.__parent) {\n\t\t\t\t\t\tif (m.__parent.getChildCount() === 2) {\n\t\t\t\t\t\t\tvar markers = m.__parent.getAllChildMarkers(),\n\t\t\t\t\t\t\t otherMarker = markers[0] === m ? markers[1] : markers[0];\n\t\t\t\t\t\t\tfg.removeLayer(otherMarker);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (chunkProgress) {\n\t\t\t\t\t// report progress and time elapsed:\n\t\t\t\t\tchunkProgress(offset, l, (new Date()).getTime() - started);\n\t\t\t\t}\n\n\t\t\t\t// Completed processing all markers.\n\t\t\t\tif (offset === l) {\n\n\t\t\t\t\t// Refresh bounds and weighted positions.\n\t\t\t\t\tthis._topClusterLevel._recalculateBounds();\n\n\t\t\t\t\tthis._refreshClustersIcons();\n\n\t\t\t\t\tthis._topClusterLevel._recursivelyAddChildrenToMap(null, this._zoom, this._currentShownBounds);\n\t\t\t\t} else {\n\t\t\t\t\tsetTimeout(process, this.options.chunkDelay);\n\t\t\t\t}\n\t\t\t}, this);\n\n\t\t\tprocess();\n\t\t} else {\n\t\t\tvar needsClustering = this._needsClustering;\n\n\t\t\tfor (; offset < l; offset++) {\n\t\t\t\tm = layersArray[offset];\n\n\t\t\t\t// Group of layers, append children to layersArray and skip.\n\t\t\t\tif (m instanceof L.LayerGroup) {\n\t\t\t\t\tif (originalArray) {\n\t\t\t\t\t\tlayersArray = layersArray.slice();\n\t\t\t\t\t\toriginalArray = false;\n\t\t\t\t\t}\n\t\t\t\t\tthis._extractNonGroupLayers(m, layersArray);\n\t\t\t\t\tl = layersArray.length;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t//Not point data, can't be clustered\n\t\t\t\tif (!m.getLatLng) {\n\t\t\t\t\tnpg.addLayer(m);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (this.hasLayer(m)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tneedsClustering.push(m);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t},\n\n\t//Takes an array of markers and removes them in bulk\n\tremoveLayers: function (layersArray) {\n\t\tvar i, m,\n\t\t l = layersArray.length,\n\t\t fg = this._featureGroup,\n\t\t npg = this._nonPointGroup,\n\t\t originalArray = true;\n\n\t\tif (!this._map) {\n\t\t\tfor (i = 0; i < l; i++) {\n\t\t\t\tm = layersArray[i];\n\n\t\t\t\t// Group of layers, append children to layersArray and skip.\n\t\t\t\tif (m instanceof L.LayerGroup) {\n\t\t\t\t\tif (originalArray) {\n\t\t\t\t\t\tlayersArray = layersArray.slice();\n\t\t\t\t\t\toriginalArray = false;\n\t\t\t\t\t}\n\t\t\t\t\tthis._extractNonGroupLayers(m, layersArray);\n\t\t\t\t\tl = layersArray.length;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tthis._arraySplice(this._needsClustering, m);\n\t\t\t\tnpg.removeLayer(m);\n\t\t\t\tif (this.hasLayer(m)) {\n\t\t\t\t\tthis._needsRemoving.push({ layer: m, latlng: m._latlng });\n\t\t\t\t}\n\t\t\t\tthis.fire('layerremove', { layer: m });\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\tif (this._unspiderfy) {\n\t\t\tthis._unspiderfy();\n\n\t\t\t// Work on a copy of the array, so that next loop is not affected.\n\t\t\tvar layersArray2 = layersArray.slice(),\n\t\t\t l2 = l;\n\t\t\tfor (i = 0; i < l2; i++) {\n\t\t\t\tm = layersArray2[i];\n\n\t\t\t\t// Group of layers, append children to layersArray and skip.\n\t\t\t\tif (m instanceof L.LayerGroup) {\n\t\t\t\t\tthis._extractNonGroupLayers(m, layersArray2);\n\t\t\t\t\tl2 = layersArray2.length;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tthis._unspiderfyLayer(m);\n\t\t\t}\n\t\t}\n\n\t\tfor (i = 0; i < l; i++) {\n\t\t\tm = layersArray[i];\n\n\t\t\t// Group of layers, append children to layersArray and skip.\n\t\t\tif (m instanceof L.LayerGroup) {\n\t\t\t\tif (originalArray) {\n\t\t\t\t\tlayersArray = layersArray.slice();\n\t\t\t\t\toriginalArray = false;\n\t\t\t\t}\n\t\t\t\tthis._extractNonGroupLayers(m, layersArray);\n\t\t\t\tl = layersArray.length;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!m.__parent) {\n\t\t\t\tnpg.removeLayer(m);\n\t\t\t\tthis.fire('layerremove', { layer: m });\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tthis._removeLayer(m, true, true);\n\t\t\tthis.fire('layerremove', { layer: m });\n\n\t\t\tif (fg.hasLayer(m)) {\n\t\t\t\tfg.removeLayer(m);\n\t\t\t\tif (m.clusterShow) {\n\t\t\t\t\tm.clusterShow();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Refresh bounds and weighted positions.\n\t\tthis._topClusterLevel._recalculateBounds();\n\n\t\tthis._refreshClustersIcons();\n\n\t\t//Fix up the clusters and markers on the map\n\t\tthis._topClusterLevel._recursivelyAddChildrenToMap(null, this._zoom, this._currentShownBounds);\n\n\t\treturn this;\n\t},\n\n\t//Removes all layers from the MarkerClusterGroup\n\tclearLayers: function () {\n\t\t//Need our own special implementation as the LayerGroup one doesn't work for us\n\n\t\t//If we aren't on the map (yet), blow away the markers we know of\n\t\tif (!this._map) {\n\t\t\tthis._needsClustering = [];\n\t\t\tthis._needsRemoving = [];\n\t\t\tdelete this._gridClusters;\n\t\t\tdelete this._gridUnclustered;\n\t\t}\n\n\t\tif (this._noanimationUnspiderfy) {\n\t\t\tthis._noanimationUnspiderfy();\n\t\t}\n\n\t\t//Remove all the visible layers\n\t\tthis._featureGroup.clearLayers();\n\t\tthis._nonPointGroup.clearLayers();\n\n\t\tthis.eachLayer(function (marker) {\n\t\t\tmarker.off(this._childMarkerEventHandlers, this);\n\t\t\tdelete marker.__parent;\n\t\t}, this);\n\n\t\tif (this._map) {\n\t\t\t//Reset _topClusterLevel and the DistanceGrids\n\t\t\tthis._generateInitialClusters();\n\t\t}\n\n\t\treturn this;\n\t},\n\n\t//Override FeatureGroup.getBounds as it doesn't work\n\tgetBounds: function () {\n\t\tvar bounds = new L.LatLngBounds();\n\n\t\tif (this._topClusterLevel) {\n\t\t\tbounds.extend(this._topClusterLevel._bounds);\n\t\t}\n\n\t\tfor (var i = this._needsClustering.length - 1; i >= 0; i--) {\n\t\t\tbounds.extend(this._needsClustering[i].getLatLng());\n\t\t}\n\n\t\tbounds.extend(this._nonPointGroup.getBounds());\n\n\t\treturn bounds;\n\t},\n\n\t//Overrides LayerGroup.eachLayer\n\teachLayer: function (method, context) {\n\t\tvar markers = this._needsClustering.slice(),\n\t\t\tneedsRemoving = this._needsRemoving,\n\t\t\tthisNeedsRemoving, i, j;\n\n\t\tif (this._topClusterLevel) {\n\t\t\tthis._topClusterLevel.getAllChildMarkers(markers);\n\t\t}\n\n\t\tfor (i = markers.length - 1; i >= 0; i--) {\n\t\t\tthisNeedsRemoving = true;\n\n\t\t\tfor (j = needsRemoving.length - 1; j >= 0; j--) {\n\t\t\t\tif (needsRemoving[j].layer === markers[i]) {\n\t\t\t\t\tthisNeedsRemoving = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (thisNeedsRemoving) {\n\t\t\t\tmethod.call(context, markers[i]);\n\t\t\t}\n\t\t}\n\n\t\tthis._nonPointGroup.eachLayer(method, context);\n\t},\n\n\t//Overrides LayerGroup.getLayers\n\tgetLayers: function () {\n\t\tvar layers = [];\n\t\tthis.eachLayer(function (l) {\n\t\t\tlayers.push(l);\n\t\t});\n\t\treturn layers;\n\t},\n\n\t//Overrides LayerGroup.getLayer, WARNING: Really bad performance\n\tgetLayer: function (id) {\n\t\tvar result = null;\n\n\t\tid = parseInt(id, 10);\n\n\t\tthis.eachLayer(function (l) {\n\t\t\tif (L.stamp(l) === id) {\n\t\t\t\tresult = l;\n\t\t\t}\n\t\t});\n\n\t\treturn result;\n\t},\n\n\t//Returns true if the given layer is in this MarkerClusterGroup\n\thasLayer: function (layer) {\n\t\tif (!layer) {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar i, anArray = this._needsClustering;\n\n\t\tfor (i = anArray.length - 1; i >= 0; i--) {\n\t\t\tif (anArray[i] === layer) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tanArray = this._needsRemoving;\n\t\tfor (i = anArray.length - 1; i >= 0; i--) {\n\t\t\tif (anArray[i].layer === layer) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn !!(layer.__parent && layer.__parent._group === this) || this._nonPointGroup.hasLayer(layer);\n\t},\n\n\t//Zoom down to show the given layer (spiderfying if necessary) then calls the callback\n\tzoomToShowLayer: function (layer, callback) {\n\n\t\tvar map = this._map;\n\n\t\tif (typeof callback !== 'function') {\n\t\t\tcallback = function () {};\n\t\t}\n\n\t\tvar showMarker = function () {\n\t\t\t// Assumes that map.hasLayer checks for direct appearance on map, not recursively calling\n\t\t\t// hasLayer on Layer Groups that are on map (typically not calling this MarkerClusterGroup.hasLayer, which would always return true)\n\t\t\tif ((map.hasLayer(layer) || map.hasLayer(layer.__parent)) && !this._inZoomAnimation) {\n\t\t\t\tthis._map.off('moveend', showMarker, this);\n\t\t\t\tthis.off('animationend', showMarker, this);\n\n\t\t\t\tif (map.hasLayer(layer)) {\n\t\t\t\t\tcallback();\n\t\t\t\t} else if (layer.__parent._icon) {\n\t\t\t\t\tthis.once('spiderfied', callback, this);\n\t\t\t\t\tlayer.__parent.spiderfy();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tif (layer._icon && this._map.getBounds().contains(layer.getLatLng())) {\n\t\t\t//Layer is visible ond on screen, immediate return\n\t\t\tcallback();\n\t\t} else if (layer.__parent._zoom < Math.round(this._map._zoom)) {\n\t\t\t//Layer should be visible at this zoom level. It must not be on screen so just pan over to it\n\t\t\tthis._map.on('moveend', showMarker, this);\n\t\t\tthis._map.panTo(layer.getLatLng());\n\t\t} else {\n\t\t\tthis._map.on('moveend', showMarker, this);\n\t\t\tthis.on('animationend', showMarker, this);\n\t\t\tlayer.__parent.zoomToBounds();\n\t\t}\n\t},\n\n\t//Overrides FeatureGroup.onAdd\n\tonAdd: function (map) {\n\t\tthis._map = map;\n\t\tvar i, l, layer;\n\n\t\tif (!isFinite(this._map.getMaxZoom())) {\n\t\t\tthrow \"Map has no maxZoom specified\";\n\t\t}\n\n\t\tthis._featureGroup.addTo(map);\n\t\tthis._nonPointGroup.addTo(map);\n\n\t\tif (!this._gridClusters) {\n\t\t\tthis._generateInitialClusters();\n\t\t}\n\n\t\tthis._maxLat = map.options.crs.projection.MAX_LATITUDE;\n\n\t\t//Restore all the positions as they are in the MCG before removing them\n\t\tfor (i = 0, l = this._needsRemoving.length; i < l; i++) {\n\t\t\tlayer = this._needsRemoving[i];\n\t\t\tlayer.newlatlng = layer.layer._latlng;\n\t\t\tlayer.layer._latlng = layer.latlng;\n\t\t}\n\t\t//Remove them, then restore their new positions\n\t\tfor (i = 0, l = this._needsRemoving.length; i < l; i++) {\n\t\t\tlayer = this._needsRemoving[i];\n\t\t\tthis._removeLayer(layer.layer, true);\n\t\t\tlayer.layer._latlng = layer.newlatlng;\n\t\t}\n\t\tthis._needsRemoving = [];\n\n\t\t//Remember the current zoom level and bounds\n\t\tthis._zoom = Math.round(this._map._zoom);\n\t\tthis._currentShownBounds = this._getExpandedVisibleBounds();\n\n\t\tthis._map.on('zoomend', this._zoomEnd, this);\n\t\tthis._map.on('moveend', this._moveEnd, this);\n\n\t\tif (this._spiderfierOnAdd) { //TODO FIXME: Not sure how to have spiderfier add something on here nicely\n\t\t\tthis._spiderfierOnAdd();\n\t\t}\n\n\t\tthis._bindEvents();\n\n\t\t//Actually add our markers to the map:\n\t\tl = this._needsClustering;\n\t\tthis._needsClustering = [];\n\t\tthis.addLayers(l, true);\n\t},\n\n\t//Overrides FeatureGroup.onRemove\n\tonRemove: function (map) {\n\t\tmap.off('zoomend', this._zoomEnd, this);\n\t\tmap.off('moveend', this._moveEnd, this);\n\n\t\tthis._unbindEvents();\n\n\t\t//In case we are in a cluster animation\n\t\tthis._map._mapPane.className = this._map._mapPane.className.replace(' leaflet-cluster-anim', '');\n\n\t\tif (this._spiderfierOnRemove) { //TODO FIXME: Not sure how to have spiderfier add something on here nicely\n\t\t\tthis._spiderfierOnRemove();\n\t\t}\n\n\t\tdelete this._maxLat;\n\n\t\t//Clean up all the layers we added to the map\n\t\tthis._hideCoverage();\n\t\tthis._featureGroup.remove();\n\t\tthis._nonPointGroup.remove();\n\n\t\tthis._featureGroup.clearLayers();\n\n\t\tthis._map = null;\n\t},\n\n\tgetVisibleParent: function (marker) {\n\t\tvar vMarker = marker;\n\t\twhile (vMarker && !vMarker._icon) {\n\t\t\tvMarker = vMarker.__parent;\n\t\t}\n\t\treturn vMarker || null;\n\t},\n\n\t//Remove the given object from the given array\n\t_arraySplice: function (anArray, obj) {\n\t\tfor (var i = anArray.length - 1; i >= 0; i--) {\n\t\t\tif (anArray[i] === obj) {\n\t\t\t\tanArray.splice(i, 1);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t},\n\n\t/**\n\t * Removes a marker from all _gridUnclustered zoom levels, starting at the supplied zoom.\n\t * @param marker to be removed from _gridUnclustered.\n\t * @param z integer bottom start zoom level (included)\n\t * @private\n\t */\n\t_removeFromGridUnclustered: function (marker, z) {\n\t\tvar map = this._map,\n\t\t gridUnclustered = this._gridUnclustered,\n\t\t\tminZoom = Math.floor(this._map.getMinZoom());\n\n\t\tfor (; z >= minZoom; z--) {\n\t\t\tif (!gridUnclustered[z].removeObject(marker, map.project(marker.getLatLng(), z))) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t},\n\n\t_childMarkerDragStart: function (e) {\n\t\te.target.__dragStart = e.target._latlng;\n\t},\n\n\t_childMarkerMoved: function (e) {\n\t\tif (!this._ignoreMove && !e.target.__dragStart) {\n\t\t\tvar isPopupOpen = e.target._popup && e.target._popup.isOpen();\n\n\t\t\tthis._moveChild(e.target, e.oldLatLng, e.latlng);\n\n\t\t\tif (isPopupOpen) {\n\t\t\t\te.target.openPopup();\n\t\t\t}\n\t\t}\n\t},\n\n\t_moveChild: function (layer, from, to) {\n\t\tlayer._latlng = from;\n\t\tthis.removeLayer(layer);\n\n\t\tlayer._latlng = to;\n\t\tthis.addLayer(layer);\n\t},\n\n\t_childMarkerDragEnd: function (e) {\n\t\tvar dragStart = e.target.__dragStart;\n\t\tdelete e.target.__dragStart;\n\t\tif (dragStart) {\n\t\t\tthis._moveChild(e.target, dragStart, e.target._latlng);\n\t\t}\t\t\n\t},\n\n\n\t//Internal function for removing a marker from everything.\n\t//dontUpdateMap: set to true if you will handle updating the map manually (for bulk functions)\n\t_removeLayer: function (marker, removeFromDistanceGrid, dontUpdateMap) {\n\t\tvar gridClusters = this._gridClusters,\n\t\t\tgridUnclustered = this._gridUnclustered,\n\t\t\tfg = this._featureGroup,\n\t\t\tmap = this._map,\n\t\t\tminZoom = Math.floor(this._map.getMinZoom());\n\n\t\t//Remove the marker from distance clusters it might be in\n\t\tif (removeFromDistanceGrid) {\n\t\t\tthis._removeFromGridUnclustered(marker, this._maxZoom);\n\t\t}\n\n\t\t//Work our way up the clusters removing them as we go if required\n\t\tvar cluster = marker.__parent,\n\t\t\tmarkers = cluster._markers,\n\t\t\totherMarker;\n\n\t\t//Remove the marker from the immediate parents marker list\n\t\tthis._arraySplice(markers, marker);\n\n\t\twhile (cluster) {\n\t\t\tcluster._childCount--;\n\t\t\tcluster._boundsNeedUpdate = true;\n\n\t\t\tif (cluster._zoom < minZoom) {\n\t\t\t\t//Top level, do nothing\n\t\t\t\tbreak;\n\t\t\t} else if (removeFromDistanceGrid && cluster._childCount <= 1) { //Cluster no longer required\n\t\t\t\t//We need to push the other marker up to the parent\n\t\t\t\totherMarker = cluster._markers[0] === marker ? cluster._markers[1] : cluster._markers[0];\n\n\t\t\t\t//Update distance grid\n\t\t\t\tgridClusters[cluster._zoom].removeObject(cluster, map.project(cluster._cLatLng, cluster._zoom));\n\t\t\t\tgridUnclustered[cluster._zoom].addObject(otherMarker, map.project(otherMarker.getLatLng(), cluster._zoom));\n\n\t\t\t\t//Move otherMarker up to parent\n\t\t\t\tthis._arraySplice(cluster.__parent._childClusters, cluster);\n\t\t\t\tcluster.__parent._markers.push(otherMarker);\n\t\t\t\totherMarker.__parent = cluster.__parent;\n\n\t\t\t\tif (cluster._icon) {\n\t\t\t\t\t//Cluster is currently on the map, need to put the marker on the map instead\n\t\t\t\t\tfg.removeLayer(cluster);\n\t\t\t\t\tif (!dontUpdateMap) {\n\t\t\t\t\t\tfg.addLayer(otherMarker);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcluster._iconNeedsUpdate = true;\n\t\t\t}\n\n\t\t\tcluster = cluster.__parent;\n\t\t}\n\n\t\tdelete marker.__parent;\n\t},\n\n\t_isOrIsParent: function (el, oel) {\n\t\twhile (oel) {\n\t\t\tif (el === oel) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\toel = oel.parentNode;\n\t\t}\n\t\treturn false;\n\t},\n\n\t//Override L.Evented.fire\n\tfire: function (type, data, propagate) {\n\t\tif (data && data.layer instanceof L.MarkerCluster) {\n\t\t\t//Prevent multiple clustermouseover/off events if the icon is made up of stacked divs (Doesn't work in ie <= 8, no relatedTarget)\n\t\t\tif (data.originalEvent && this._isOrIsParent(data.layer._icon, data.originalEvent.relatedTarget)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttype = 'cluster' + type;\n\t\t}\n\n\t\tL.FeatureGroup.prototype.fire.call(this, type, data, propagate);\n\t},\n\n\t//Override L.Evented.listens\n\tlistens: function (type, propagate) {\n\t\treturn L.FeatureGroup.prototype.listens.call(this, type, propagate) || L.FeatureGroup.prototype.listens.call(this, 'cluster' + type, propagate);\n\t},\n\n\t//Default functionality\n\t_defaultIconCreateFunction: function (cluster) {\n\t\tvar childCount = cluster.getChildCount();\n\n\t\tvar c = ' marker-cluster-';\n\t\tif (childCount < 10) {\n\t\t\tc += 'small';\n\t\t} else if (childCount < 100) {\n\t\t\tc += 'medium';\n\t\t} else {\n\t\t\tc += 'large';\n\t\t}\n\n\t\treturn new L.DivIcon({ html: '
' + childCount + '
', className: 'marker-cluster' + c, iconSize: new L.Point(40, 40) });\n\t},\n\n\t_bindEvents: function () {\n\t\tvar map = this._map,\n\t\t spiderfyOnMaxZoom = this.options.spiderfyOnMaxZoom,\n\t\t showCoverageOnHover = this.options.showCoverageOnHover,\n\t\t zoomToBoundsOnClick = this.options.zoomToBoundsOnClick,\n\t\t spiderfyOnEveryZoom = this.options.spiderfyOnEveryZoom;\n\n\t\t//Zoom on cluster click or spiderfy if we are at the lowest level\n\t\tif (spiderfyOnMaxZoom || zoomToBoundsOnClick || spiderfyOnEveryZoom) {\n\t\t\tthis.on('clusterclick clusterkeypress', this._zoomOrSpiderfy, this);\n\t\t}\n\n\t\t//Show convex hull (boundary) polygon on mouse over\n\t\tif (showCoverageOnHover) {\n\t\t\tthis.on('clustermouseover', this._showCoverage, this);\n\t\t\tthis.on('clustermouseout', this._hideCoverage, this);\n\t\t\tmap.on('zoomend', this._hideCoverage, this);\n\t\t}\n\t},\n\n\t_zoomOrSpiderfy: function (e) {\n\t\tvar cluster = e.layer,\n\t\t bottomCluster = cluster;\n\n\t\tif (e.type === 'clusterkeypress' && e.originalEvent && e.originalEvent.keyCode !== 13) {\n\t\t\treturn;\n\t\t}\n\n\t\twhile (bottomCluster._childClusters.length === 1) {\n\t\t\tbottomCluster = bottomCluster._childClusters[0];\n\t\t}\n\n\t\tif (bottomCluster._zoom === this._maxZoom &&\n\t\t\tbottomCluster._childCount === cluster._childCount &&\n\t\t\tthis.options.spiderfyOnMaxZoom) {\n\n\t\t\t// All child markers are contained in a single cluster from this._maxZoom to this cluster.\n\t\t\tcluster.spiderfy();\n\t\t} else if (this.options.zoomToBoundsOnClick) {\n\t\t\tcluster.zoomToBounds();\n\t\t}\n\n\t\tif (this.options.spiderfyOnEveryZoom) {\n\t\t\tcluster.spiderfy();\n\t\t}\n\n\t\t// Focus the map again for keyboard users.\n\t\tif (e.originalEvent && e.originalEvent.keyCode === 13) {\n\t\t\tthis._map._container.focus();\n\t\t}\n\t},\n\n\t_showCoverage: function (e) {\n\t\tvar map = this._map;\n\t\tif (this._inZoomAnimation) {\n\t\t\treturn;\n\t\t}\n\t\tif (this._shownPolygon) {\n\t\t\tmap.removeLayer(this._shownPolygon);\n\t\t}\n\t\tif (e.layer.getChildCount() > 2 && e.layer !== this._spiderfied) {\n\t\t\tthis._shownPolygon = new L.Polygon(e.layer.getConvexHull(), this.options.polygonOptions);\n\t\t\tmap.addLayer(this._shownPolygon);\n\t\t}\n\t},\n\n\t_hideCoverage: function () {\n\t\tif (this._shownPolygon) {\n\t\t\tthis._map.removeLayer(this._shownPolygon);\n\t\t\tthis._shownPolygon = null;\n\t\t}\n\t},\n\n\t_unbindEvents: function () {\n\t\tvar spiderfyOnMaxZoom = this.options.spiderfyOnMaxZoom,\n\t\t\tshowCoverageOnHover = this.options.showCoverageOnHover,\n\t\t\tzoomToBoundsOnClick = this.options.zoomToBoundsOnClick,\n\t\t\tspiderfyOnEveryZoom = this.options.spiderfyOnEveryZoom,\n\t\t\tmap = this._map;\n\n\t\tif (spiderfyOnMaxZoom || zoomToBoundsOnClick || spiderfyOnEveryZoom) {\n\t\t\tthis.off('clusterclick clusterkeypress', this._zoomOrSpiderfy, this);\n\t\t}\n\t\tif (showCoverageOnHover) {\n\t\t\tthis.off('clustermouseover', this._showCoverage, this);\n\t\t\tthis.off('clustermouseout', this._hideCoverage, this);\n\t\t\tmap.off('zoomend', this._hideCoverage, this);\n\t\t}\n\t},\n\n\t_zoomEnd: function () {\n\t\tif (!this._map) { //May have been removed from the map by a zoomEnd handler\n\t\t\treturn;\n\t\t}\n\t\tthis._mergeSplitClusters();\n\n\t\tthis._zoom = Math.round(this._map._zoom);\n\t\tthis._currentShownBounds = this._getExpandedVisibleBounds();\n\t},\n\n\t_moveEnd: function () {\n\t\tif (this._inZoomAnimation) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar newBounds = this._getExpandedVisibleBounds();\n\n\t\tthis._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, Math.floor(this._map.getMinZoom()), this._zoom, newBounds);\n\t\tthis._topClusterLevel._recursivelyAddChildrenToMap(null, Math.round(this._map._zoom), newBounds);\n\n\t\tthis._currentShownBounds = newBounds;\n\t\treturn;\n\t},\n\n\t_generateInitialClusters: function () {\n\t\tvar maxZoom = Math.ceil(this._map.getMaxZoom()),\n\t\t\tminZoom = Math.floor(this._map.getMinZoom()),\n\t\t\tradius = this.options.maxClusterRadius,\n\t\t\tradiusFn = radius;\n\n\t\t//If we just set maxClusterRadius to a single number, we need to create\n\t\t//a simple function to return that number. Otherwise, we just have to\n\t\t//use the function we've passed in.\n\t\tif (typeof radius !== \"function\") {\n\t\t\tradiusFn = function () { return radius; };\n\t\t}\n\n\t\tif (this.options.disableClusteringAtZoom !== null) {\n\t\t\tmaxZoom = this.options.disableClusteringAtZoom - 1;\n\t\t}\n\t\tthis._maxZoom = maxZoom;\n\t\tthis._gridClusters = {};\n\t\tthis._gridUnclustered = {};\n\n\t\t//Set up DistanceGrids for each zoom\n\t\tfor (var zoom = maxZoom; zoom >= minZoom; zoom--) {\n\t\t\tthis._gridClusters[zoom] = new L.DistanceGrid(radiusFn(zoom));\n\t\t\tthis._gridUnclustered[zoom] = new L.DistanceGrid(radiusFn(zoom));\n\t\t}\n\n\t\t// Instantiate the appropriate L.MarkerCluster class (animated or not).\n\t\tthis._topClusterLevel = new this._markerCluster(this, minZoom - 1);\n\t},\n\n\t//Zoom: Zoom to start adding at (Pass this._maxZoom to start at the bottom)\n\t_addLayer: function (layer, zoom) {\n\t\tvar gridClusters = this._gridClusters,\n\t\t gridUnclustered = this._gridUnclustered,\n\t\t\tminZoom = Math.floor(this._map.getMinZoom()),\n\t\t markerPoint, z;\n\n\t\tif (this.options.singleMarkerMode) {\n\t\t\tthis._overrideMarkerIcon(layer);\n\t\t}\n\n\t\tlayer.on(this._childMarkerEventHandlers, this);\n\n\t\t//Find the lowest zoom level to slot this one in\n\t\tfor (; zoom >= minZoom; zoom--) {\n\t\t\tmarkerPoint = this._map.project(layer.getLatLng(), zoom); // calculate pixel position\n\n\t\t\t//Try find a cluster close by\n\t\t\tvar closest = gridClusters[zoom].getNearObject(markerPoint);\n\t\t\tif (closest) {\n\t\t\t\tclosest._addChild(layer);\n\t\t\t\tlayer.__parent = closest;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t//Try find a marker close by to form a new cluster with\n\t\t\tclosest = gridUnclustered[zoom].getNearObject(markerPoint);\n\t\t\tif (closest) {\n\t\t\t\tvar parent = closest.__parent;\n\t\t\t\tif (parent) {\n\t\t\t\t\tthis._removeLayer(closest, false);\n\t\t\t\t}\n\n\t\t\t\t//Create new cluster with these 2 in it\n\n\t\t\t\tvar newCluster = new this._markerCluster(this, zoom, closest, layer);\n\t\t\t\tgridClusters[zoom].addObject(newCluster, this._map.project(newCluster._cLatLng, zoom));\n\t\t\t\tclosest.__parent = newCluster;\n\t\t\t\tlayer.__parent = newCluster;\n\n\t\t\t\t//First create any new intermediate parent clusters that don't exist\n\t\t\t\tvar lastParent = newCluster;\n\t\t\t\tfor (z = zoom - 1; z > parent._zoom; z--) {\n\t\t\t\t\tlastParent = new this._markerCluster(this, z, lastParent);\n\t\t\t\t\tgridClusters[z].addObject(lastParent, this._map.project(closest.getLatLng(), z));\n\t\t\t\t}\n\t\t\t\tparent._addChild(lastParent);\n\n\t\t\t\t//Remove closest from this zoom level and any above that it is in, replace with newCluster\n\t\t\t\tthis._removeFromGridUnclustered(closest, zoom);\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t//Didn't manage to cluster in at this zoom, record us as a marker here and continue upwards\n\t\t\tgridUnclustered[zoom].addObject(layer, markerPoint);\n\t\t}\n\n\t\t//Didn't get in anything, add us to the top\n\t\tthis._topClusterLevel._addChild(layer);\n\t\tlayer.__parent = this._topClusterLevel;\n\t\treturn;\n\t},\n\n\t/**\n\t * Refreshes the icon of all \"dirty\" visible clusters.\n\t * Non-visible \"dirty\" clusters will be updated when they are added to the map.\n\t * @private\n\t */\n\t_refreshClustersIcons: function () {\n\t\tthis._featureGroup.eachLayer(function (c) {\n\t\t\tif (c instanceof L.MarkerCluster && c._iconNeedsUpdate) {\n\t\t\t\tc._updateIcon();\n\t\t\t}\n\t\t});\n\t},\n\n\t//Enqueue code to fire after the marker expand/contract has happened\n\t_enqueue: function (fn) {\n\t\tthis._queue.push(fn);\n\t\tif (!this._queueTimeout) {\n\t\t\tthis._queueTimeout = setTimeout(L.bind(this._processQueue, this), 300);\n\t\t}\n\t},\n\t_processQueue: function () {\n\t\tfor (var i = 0; i < this._queue.length; i++) {\n\t\t\tthis._queue[i].call(this);\n\t\t}\n\t\tthis._queue.length = 0;\n\t\tclearTimeout(this._queueTimeout);\n\t\tthis._queueTimeout = null;\n\t},\n\n\t//Merge and split any existing clusters that are too big or small\n\t_mergeSplitClusters: function () {\n\t\tvar mapZoom = Math.round(this._map._zoom);\n\n\t\t//In case we are starting to split before the animation finished\n\t\tthis._processQueue();\n\n\t\tif (this._zoom < mapZoom && this._currentShownBounds.intersects(this._getExpandedVisibleBounds())) { //Zoom in, split\n\t\t\tthis._animationStart();\n\t\t\t//Remove clusters now off screen\n\t\t\tthis._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, Math.floor(this._map.getMinZoom()), this._zoom, this._getExpandedVisibleBounds());\n\n\t\t\tthis._animationZoomIn(this._zoom, mapZoom);\n\n\t\t} else if (this._zoom > mapZoom) { //Zoom out, merge\n\t\t\tthis._animationStart();\n\n\t\t\tthis._animationZoomOut(this._zoom, mapZoom);\n\t\t} else {\n\t\t\tthis._moveEnd();\n\t\t}\n\t},\n\n\t//Gets the maps visible bounds expanded in each direction by the size of the screen (so the user cannot see an area we do not cover in one pan)\n\t_getExpandedVisibleBounds: function () {\n\t\tif (!this.options.removeOutsideVisibleBounds) {\n\t\t\treturn this._mapBoundsInfinite;\n\t\t} else if (L.Browser.mobile) {\n\t\t\treturn this._checkBoundsMaxLat(this._map.getBounds());\n\t\t}\n\n\t\treturn this._checkBoundsMaxLat(this._map.getBounds().pad(1)); // Padding expands the bounds by its own dimensions but scaled with the given factor.\n\t},\n\n\t/**\n\t * Expands the latitude to Infinity (or -Infinity) if the input bounds reach the map projection maximum defined latitude\n\t * (in the case of Web/Spherical Mercator, it is 85.0511287798 / see https://en.wikipedia.org/wiki/Web_Mercator#Formulas).\n\t * Otherwise, the removeOutsideVisibleBounds option will remove markers beyond that limit, whereas the same markers without\n\t * this option (or outside MCG) will have their position floored (ceiled) by the projection and rendered at that limit,\n\t * making the user think that MCG \"eats\" them and never displays them again.\n\t * @param bounds L.LatLngBounds\n\t * @returns {L.LatLngBounds}\n\t * @private\n\t */\n\t_checkBoundsMaxLat: function (bounds) {\n\t\tvar maxLat = this._maxLat;\n\n\t\tif (maxLat !== undefined) {\n\t\t\tif (bounds.getNorth() >= maxLat) {\n\t\t\t\tbounds._northEast.lat = Infinity;\n\t\t\t}\n\t\t\tif (bounds.getSouth() <= -maxLat) {\n\t\t\t\tbounds._southWest.lat = -Infinity;\n\t\t\t}\n\t\t}\n\n\t\treturn bounds;\n\t},\n\n\t//Shared animation code\n\t_animationAddLayerNonAnimated: function (layer, newCluster) {\n\t\tif (newCluster === layer) {\n\t\t\tthis._featureGroup.addLayer(layer);\n\t\t} else if (newCluster._childCount === 2) {\n\t\t\tnewCluster._addToMap();\n\n\t\t\tvar markers = newCluster.getAllChildMarkers();\n\t\t\tthis._featureGroup.removeLayer(markers[0]);\n\t\t\tthis._featureGroup.removeLayer(markers[1]);\n\t\t} else {\n\t\t\tnewCluster._updateIcon();\n\t\t}\n\t},\n\n\t/**\n\t * Extracts individual (i.e. non-group) layers from a Layer Group.\n\t * @param group to extract layers from.\n\t * @param output {Array} in which to store the extracted layers.\n\t * @returns {*|Array}\n\t * @private\n\t */\n\t_extractNonGroupLayers: function (group, output) {\n\t\tvar layers = group.getLayers(),\n\t\t i = 0,\n\t\t layer;\n\n\t\toutput = output || [];\n\n\t\tfor (; i < layers.length; i++) {\n\t\t\tlayer = layers[i];\n\n\t\t\tif (layer instanceof L.LayerGroup) {\n\t\t\t\tthis._extractNonGroupLayers(layer, output);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\toutput.push(layer);\n\t\t}\n\n\t\treturn output;\n\t},\n\n\t/**\n\t * Implements the singleMarkerMode option.\n\t * @param layer Marker to re-style using the Clusters iconCreateFunction.\n\t * @returns {L.Icon} The newly created icon.\n\t * @private\n\t */\n\t_overrideMarkerIcon: function (layer) {\n\t\tvar icon = layer.options.icon = this.options.iconCreateFunction({\n\t\t\tgetChildCount: function () {\n\t\t\t\treturn 1;\n\t\t\t},\n\t\t\tgetAllChildMarkers: function () {\n\t\t\t\treturn [layer];\n\t\t\t}\n\t\t});\n\n\t\treturn icon;\n\t}\n});\n\n// Constant bounds used in case option \"removeOutsideVisibleBounds\" is set to false.\nL.MarkerClusterGroup.include({\n\t_mapBoundsInfinite: new L.LatLngBounds(new L.LatLng(-Infinity, -Infinity), new L.LatLng(Infinity, Infinity))\n});\n\nL.MarkerClusterGroup.include({\n\t_noAnimation: {\n\t\t//Non Animated versions of everything\n\t\t_animationStart: function () {\n\t\t\t//Do nothing...\n\t\t},\n\t\t_animationZoomIn: function (previousZoomLevel, newZoomLevel) {\n\t\t\tthis._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, Math.floor(this._map.getMinZoom()), previousZoomLevel);\n\t\t\tthis._topClusterLevel._recursivelyAddChildrenToMap(null, newZoomLevel, this._getExpandedVisibleBounds());\n\n\t\t\t//We didn't actually animate, but we use this event to mean \"clustering animations have finished\"\n\t\t\tthis.fire('animationend');\n\t\t},\n\t\t_animationZoomOut: function (previousZoomLevel, newZoomLevel) {\n\t\t\tthis._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, Math.floor(this._map.getMinZoom()), previousZoomLevel);\n\t\t\tthis._topClusterLevel._recursivelyAddChildrenToMap(null, newZoomLevel, this._getExpandedVisibleBounds());\n\n\t\t\t//We didn't actually animate, but we use this event to mean \"clustering animations have finished\"\n\t\t\tthis.fire('animationend');\n\t\t},\n\t\t_animationAddLayer: function (layer, newCluster) {\n\t\t\tthis._animationAddLayerNonAnimated(layer, newCluster);\n\t\t}\n\t},\n\n\t_withAnimation: {\n\t\t//Animated versions here\n\t\t_animationStart: function () {\n\t\t\tthis._map._mapPane.className += ' leaflet-cluster-anim';\n\t\t\tthis._inZoomAnimation++;\n\t\t},\n\n\t\t_animationZoomIn: function (previousZoomLevel, newZoomLevel) {\n\t\t\tvar bounds = this._getExpandedVisibleBounds(),\n\t\t\t fg = this._featureGroup,\n\t\t\t\tminZoom = Math.floor(this._map.getMinZoom()),\n\t\t\t i;\n\n\t\t\tthis._ignoreMove = true;\n\n\t\t\t//Add all children of current clusters to map and remove those clusters from map\n\t\t\tthis._topClusterLevel._recursively(bounds, previousZoomLevel, minZoom, function (c) {\n\t\t\t\tvar startPos = c._latlng,\n\t\t\t\t markers = c._markers,\n\t\t\t\t m;\n\n\t\t\t\tif (!bounds.contains(startPos)) {\n\t\t\t\t\tstartPos = null;\n\t\t\t\t}\n\n\t\t\t\tif (c._isSingleParent() && previousZoomLevel + 1 === newZoomLevel) { //Immediately add the new child and remove us\n\t\t\t\t\tfg.removeLayer(c);\n\t\t\t\t\tc._recursivelyAddChildrenToMap(null, newZoomLevel, bounds);\n\t\t\t\t} else {\n\t\t\t\t\t//Fade out old cluster\n\t\t\t\t\tc.clusterHide();\n\t\t\t\t\tc._recursivelyAddChildrenToMap(startPos, newZoomLevel, bounds);\n\t\t\t\t}\n\n\t\t\t\t//Remove all markers that aren't visible any more\n\t\t\t\t//TODO: Do we actually need to do this on the higher levels too?\n\t\t\t\tfor (i = markers.length - 1; i >= 0; i--) {\n\t\t\t\t\tm = markers[i];\n\t\t\t\t\tif (!bounds.contains(m._latlng)) {\n\t\t\t\t\t\tfg.removeLayer(m);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t});\n\n\t\t\tthis._forceLayout();\n\n\t\t\t//Update opacities\n\t\t\tthis._topClusterLevel._recursivelyBecomeVisible(bounds, newZoomLevel);\n\t\t\t//TODO Maybe? Update markers in _recursivelyBecomeVisible\n\t\t\tfg.eachLayer(function (n) {\n\t\t\t\tif (!(n instanceof L.MarkerCluster) && n._icon) {\n\t\t\t\t\tn.clusterShow();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t//update the positions of the just added clusters/markers\n\t\t\tthis._topClusterLevel._recursively(bounds, previousZoomLevel, newZoomLevel, function (c) {\n\t\t\t\tc._recursivelyRestoreChildPositions(newZoomLevel);\n\t\t\t});\n\n\t\t\tthis._ignoreMove = false;\n\n\t\t\t//Remove the old clusters and close the zoom animation\n\t\t\tthis._enqueue(function () {\n\t\t\t\t//update the positions of the just added clusters/markers\n\t\t\t\tthis._topClusterLevel._recursively(bounds, previousZoomLevel, minZoom, function (c) {\n\t\t\t\t\tfg.removeLayer(c);\n\t\t\t\t\tc.clusterShow();\n\t\t\t\t});\n\n\t\t\t\tthis._animationEnd();\n\t\t\t});\n\t\t},\n\n\t\t_animationZoomOut: function (previousZoomLevel, newZoomLevel) {\n\t\t\tthis._animationZoomOutSingle(this._topClusterLevel, previousZoomLevel - 1, newZoomLevel);\n\n\t\t\t//Need to add markers for those that weren't on the map before but are now\n\t\t\tthis._topClusterLevel._recursivelyAddChildrenToMap(null, newZoomLevel, this._getExpandedVisibleBounds());\n\t\t\t//Remove markers that were on the map before but won't be now\n\t\t\tthis._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, Math.floor(this._map.getMinZoom()), previousZoomLevel, this._getExpandedVisibleBounds());\n\t\t},\n\n\t\t_animationAddLayer: function (layer, newCluster) {\n\t\t\tvar me = this,\n\t\t\t fg = this._featureGroup;\n\n\t\t\tfg.addLayer(layer);\n\t\t\tif (newCluster !== layer) {\n\t\t\t\tif (newCluster._childCount > 2) { //Was already a cluster\n\n\t\t\t\t\tnewCluster._updateIcon();\n\t\t\t\t\tthis._forceLayout();\n\t\t\t\t\tthis._animationStart();\n\n\t\t\t\t\tlayer._setPos(this._map.latLngToLayerPoint(newCluster.getLatLng()));\n\t\t\t\t\tlayer.clusterHide();\n\n\t\t\t\t\tthis._enqueue(function () {\n\t\t\t\t\t\tfg.removeLayer(layer);\n\t\t\t\t\t\tlayer.clusterShow();\n\n\t\t\t\t\t\tme._animationEnd();\n\t\t\t\t\t});\n\n\t\t\t\t} else { //Just became a cluster\n\t\t\t\t\tthis._forceLayout();\n\n\t\t\t\t\tme._animationStart();\n\t\t\t\t\tme._animationZoomOutSingle(newCluster, this._map.getMaxZoom(), this._zoom);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Private methods for animated versions.\n\t_animationZoomOutSingle: function (cluster, previousZoomLevel, newZoomLevel) {\n\t\tvar bounds = this._getExpandedVisibleBounds(),\n\t\t\tminZoom = Math.floor(this._map.getMinZoom());\n\n\t\t//Animate all of the markers in the clusters to move to their cluster center point\n\t\tcluster._recursivelyAnimateChildrenInAndAddSelfToMap(bounds, minZoom, previousZoomLevel + 1, newZoomLevel);\n\n\t\tvar me = this;\n\n\t\t//Update the opacity (If we immediately set it they won't animate)\n\t\tthis._forceLayout();\n\t\tcluster._recursivelyBecomeVisible(bounds, newZoomLevel);\n\n\t\t//TODO: Maybe use the transition timing stuff to make this more reliable\n\t\t//When the animations are done, tidy up\n\t\tthis._enqueue(function () {\n\n\t\t\t//This cluster stopped being a cluster before the timeout fired\n\t\t\tif (cluster._childCount === 1) {\n\t\t\t\tvar m = cluster._markers[0];\n\t\t\t\t//If we were in a cluster animation at the time then the opacity and position of our child could be wrong now, so fix it\n\t\t\t\tthis._ignoreMove = true;\n\t\t\t\tm.setLatLng(m.getLatLng());\n\t\t\t\tthis._ignoreMove = false;\n\t\t\t\tif (m.clusterShow) {\n\t\t\t\t\tm.clusterShow();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcluster._recursively(bounds, newZoomLevel, minZoom, function (c) {\n\t\t\t\t\tc._recursivelyRemoveChildrenFromMap(bounds, minZoom, previousZoomLevel + 1);\n\t\t\t\t});\n\t\t\t}\n\t\t\tme._animationEnd();\n\t\t});\n\t},\n\n\t_animationEnd: function () {\n\t\tif (this._map) {\n\t\t\tthis._map._mapPane.className = this._map._mapPane.className.replace(' leaflet-cluster-anim', '');\n\t\t}\n\t\tthis._inZoomAnimation--;\n\t\tthis.fire('animationend');\n\t},\n\n\t//Force a browser layout of stuff in the map\n\t// Should apply the current opacity and location to all elements so we can update them again for an animation\n\t_forceLayout: function () {\n\t\t//In my testing this works, infact offsetWidth of any element seems to work.\n\t\t//Could loop all this._layers and do this for each _icon if it stops working\n\n\t\tL.Util.falseFn(document.body.offsetWidth);\n\t}\n});\n\nL.markerClusterGroup = function (options) {\n\treturn new L.MarkerClusterGroup(options);\n};\n", "export var MarkerCluster = L.MarkerCluster = L.Marker.extend({\n\toptions: L.Icon.prototype.options,\n\n\tinitialize: function (group, zoom, a, b) {\n\n\t\tL.Marker.prototype.initialize.call(this, a ? (a._cLatLng || a.getLatLng()) : new L.LatLng(0, 0),\n { icon: this, pane: group.options.clusterPane });\n\n\t\tthis._group = group;\n\t\tthis._zoom = zoom;\n\n\t\tthis._markers = [];\n\t\tthis._childClusters = [];\n\t\tthis._childCount = 0;\n\t\tthis._iconNeedsUpdate = true;\n\t\tthis._boundsNeedUpdate = true;\n\n\t\tthis._bounds = new L.LatLngBounds();\n\n\t\tif (a) {\n\t\t\tthis._addChild(a);\n\t\t}\n\t\tif (b) {\n\t\t\tthis._addChild(b);\n\t\t}\n\t},\n\n\t//Recursively retrieve all child markers of this cluster\n\tgetAllChildMarkers: function (storageArray, ignoreDraggedMarker) {\n\t\tstorageArray = storageArray || [];\n\n\t\tfor (var i = this._childClusters.length - 1; i >= 0; i--) {\n\t\t\tthis._childClusters[i].getAllChildMarkers(storageArray, ignoreDraggedMarker);\n\t\t}\n\n\t\tfor (var j = this._markers.length - 1; j >= 0; j--) {\n\t\t\tif (ignoreDraggedMarker && this._markers[j].__dragStart) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tstorageArray.push(this._markers[j]);\n\t\t}\n\n\t\treturn storageArray;\n\t},\n\n\t//Returns the count of how many child markers we have\n\tgetChildCount: function () {\n\t\treturn this._childCount;\n\t},\n\n\t//Zoom to the minimum of showing all of the child markers, or the extents of this cluster\n\tzoomToBounds: function (fitBoundsOptions) {\n\t\tvar childClusters = this._childClusters.slice(),\n\t\t\tmap = this._group._map,\n\t\t\tboundsZoom = map.getBoundsZoom(this._bounds),\n\t\t\tzoom = this._zoom + 1,\n\t\t\tmapZoom = map.getZoom(),\n\t\t\ti;\n\n\t\t//calculate how far we need to zoom down to see all of the markers\n\t\twhile (childClusters.length > 0 && boundsZoom > zoom) {\n\t\t\tzoom++;\n\t\t\tvar newClusters = [];\n\t\t\tfor (i = 0; i < childClusters.length; i++) {\n\t\t\t\tnewClusters = newClusters.concat(childClusters[i]._childClusters);\n\t\t\t}\n\t\t\tchildClusters = newClusters;\n\t\t}\n\n\t\tif (boundsZoom > zoom) {\n\t\t\tthis._group._map.setView(this._latlng, zoom);\n\t\t} else if (boundsZoom <= mapZoom) { //If fitBounds wouldn't zoom us down, zoom us down instead\n\t\t\tthis._group._map.setView(this._latlng, mapZoom + 1);\n\t\t} else {\n\t\t\tthis._group._map.fitBounds(this._bounds, fitBoundsOptions);\n\t\t}\n\t},\n\n\tgetBounds: function () {\n\t\tvar bounds = new L.LatLngBounds();\n\t\tbounds.extend(this._bounds);\n\t\treturn bounds;\n\t},\n\n\t_updateIcon: function () {\n\t\tthis._iconNeedsUpdate = true;\n\t\tif (this._icon) {\n\t\t\tthis.setIcon(this);\n\t\t}\n\t},\n\n\t//Cludge for Icon, we pretend to be an icon for performance\n\tcreateIcon: function () {\n\t\tif (this._iconNeedsUpdate) {\n\t\t\tthis._iconObj = this._group.options.iconCreateFunction(this);\n\t\t\tthis._iconNeedsUpdate = false;\n\t\t}\n\t\treturn this._iconObj.createIcon();\n\t},\n\tcreateShadow: function () {\n\t\treturn this._iconObj.createShadow();\n\t},\n\n\n\t_addChild: function (new1, isNotificationFromChild) {\n\n\t\tthis._iconNeedsUpdate = true;\n\n\t\tthis._boundsNeedUpdate = true;\n\t\tthis._setClusterCenter(new1);\n\n\t\tif (new1 instanceof L.MarkerCluster) {\n\t\t\tif (!isNotificationFromChild) {\n\t\t\t\tthis._childClusters.push(new1);\n\t\t\t\tnew1.__parent = this;\n\t\t\t}\n\t\t\tthis._childCount += new1._childCount;\n\t\t} else {\n\t\t\tif (!isNotificationFromChild) {\n\t\t\t\tthis._markers.push(new1);\n\t\t\t}\n\t\t\tthis._childCount++;\n\t\t}\n\n\t\tif (this.__parent) {\n\t\t\tthis.__parent._addChild(new1, true);\n\t\t}\n\t},\n\n\t/**\n\t * Makes sure the cluster center is set. If not, uses the child center if it is a cluster, or the marker position.\n\t * @param child L.MarkerCluster|L.Marker that will be used as cluster center if not defined yet.\n\t * @private\n\t */\n\t_setClusterCenter: function (child) {\n\t\tif (!this._cLatLng) {\n\t\t\t// when clustering, take position of the first point as the cluster center\n\t\t\tthis._cLatLng = child._cLatLng || child._latlng;\n\t\t}\n\t},\n\n\t/**\n\t * Assigns impossible bounding values so that the next extend entirely determines the new bounds.\n\t * This method avoids having to trash the previous L.LatLngBounds object and to create a new one, which is much slower for this class.\n\t * As long as the bounds are not extended, most other methods would probably fail, as they would with bounds initialized but not extended.\n\t * @private\n\t */\n\t_resetBounds: function () {\n\t\tvar bounds = this._bounds;\n\n\t\tif (bounds._southWest) {\n\t\t\tbounds._southWest.lat = Infinity;\n\t\t\tbounds._southWest.lng = Infinity;\n\t\t}\n\t\tif (bounds._northEast) {\n\t\t\tbounds._northEast.lat = -Infinity;\n\t\t\tbounds._northEast.lng = -Infinity;\n\t\t}\n\t},\n\n\t_recalculateBounds: function () {\n\t\tvar markers = this._markers,\n\t\t childClusters = this._childClusters,\n\t\t latSum = 0,\n\t\t lngSum = 0,\n\t\t totalCount = this._childCount,\n\t\t i, child, childLatLng, childCount;\n\n\t\t// Case where all markers are removed from the map and we are left with just an empty _topClusterLevel.\n\t\tif (totalCount === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Reset rather than creating a new object, for performance.\n\t\tthis._resetBounds();\n\n\t\t// Child markers.\n\t\tfor (i = 0; i < markers.length; i++) {\n\t\t\tchildLatLng = markers[i]._latlng;\n\n\t\t\tthis._bounds.extend(childLatLng);\n\n\t\t\tlatSum += childLatLng.lat;\n\t\t\tlngSum += childLatLng.lng;\n\t\t}\n\n\t\t// Child clusters.\n\t\tfor (i = 0; i < childClusters.length; i++) {\n\t\t\tchild = childClusters[i];\n\n\t\t\t// Re-compute child bounds and weighted position first if necessary.\n\t\t\tif (child._boundsNeedUpdate) {\n\t\t\t\tchild._recalculateBounds();\n\t\t\t}\n\n\t\t\tthis._bounds.extend(child._bounds);\n\n\t\t\tchildLatLng = child._wLatLng;\n\t\t\tchildCount = child._childCount;\n\n\t\t\tlatSum += childLatLng.lat * childCount;\n\t\t\tlngSum += childLatLng.lng * childCount;\n\t\t}\n\n\t\tthis._latlng = this._wLatLng = new L.LatLng(latSum / totalCount, lngSum / totalCount);\n\n\t\t// Reset dirty flag.\n\t\tthis._boundsNeedUpdate = false;\n\t},\n\n\t//Set our markers position as given and add it to the map\n\t_addToMap: function (startPos) {\n\t\tif (startPos) {\n\t\t\tthis._backupLatlng = this._latlng;\n\t\t\tthis.setLatLng(startPos);\n\t\t}\n\t\tthis._group._featureGroup.addLayer(this);\n\t},\n\n\t_recursivelyAnimateChildrenIn: function (bounds, center, maxZoom) {\n\t\tthis._recursively(bounds, this._group._map.getMinZoom(), maxZoom - 1,\n\t\t\tfunction (c) {\n\t\t\t\tvar markers = c._markers,\n\t\t\t\t\ti, m;\n\t\t\t\tfor (i = markers.length - 1; i >= 0; i--) {\n\t\t\t\t\tm = markers[i];\n\n\t\t\t\t\t//Only do it if the icon is still on the map\n\t\t\t\t\tif (m._icon) {\n\t\t\t\t\t\tm._setPos(center);\n\t\t\t\t\t\tm.clusterHide();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tfunction (c) {\n\t\t\t\tvar childClusters = c._childClusters,\n\t\t\t\t\tj, cm;\n\t\t\t\tfor (j = childClusters.length - 1; j >= 0; j--) {\n\t\t\t\t\tcm = childClusters[j];\n\t\t\t\t\tif (cm._icon) {\n\t\t\t\t\t\tcm._setPos(center);\n\t\t\t\t\t\tcm.clusterHide();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t},\n\n\t_recursivelyAnimateChildrenInAndAddSelfToMap: function (bounds, mapMinZoom, previousZoomLevel, newZoomLevel) {\n\t\tthis._recursively(bounds, newZoomLevel, mapMinZoom,\n\t\t\tfunction (c) {\n\t\t\t\tc._recursivelyAnimateChildrenIn(bounds, c._group._map.latLngToLayerPoint(c.getLatLng()).round(), previousZoomLevel);\n\n\t\t\t\t//TODO: depthToAnimateIn affects _isSingleParent, if there is a multizoom we may/may not be.\n\t\t\t\t//As a hack we only do a animation free zoom on a single level zoom, if someone does multiple levels then we always animate\n\t\t\t\tif (c._isSingleParent() && previousZoomLevel - 1 === newZoomLevel) {\n\t\t\t\t\tc.clusterShow();\n\t\t\t\t\tc._recursivelyRemoveChildrenFromMap(bounds, mapMinZoom, previousZoomLevel); //Immediately remove our children as we are replacing them. TODO previousBounds not bounds\n\t\t\t\t} else {\n\t\t\t\t\tc.clusterHide();\n\t\t\t\t}\n\n\t\t\t\tc._addToMap();\n\t\t\t}\n\t\t);\n\t},\n\n\t_recursivelyBecomeVisible: function (bounds, zoomLevel) {\n\t\tthis._recursively(bounds, this._group._map.getMinZoom(), zoomLevel, null, function (c) {\n\t\t\tc.clusterShow();\n\t\t});\n\t},\n\n\t_recursivelyAddChildrenToMap: function (startPos, zoomLevel, bounds) {\n\t\tthis._recursively(bounds, this._group._map.getMinZoom() - 1, zoomLevel,\n\t\t\tfunction (c) {\n\t\t\t\tif (zoomLevel === c._zoom) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t//Add our child markers at startPos (so they can be animated out)\n\t\t\t\tfor (var i = c._markers.length - 1; i >= 0; i--) {\n\t\t\t\t\tvar nm = c._markers[i];\n\n\t\t\t\t\tif (!bounds.contains(nm._latlng)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (startPos) {\n\t\t\t\t\t\tnm._backupLatlng = nm.getLatLng();\n\n\t\t\t\t\t\tnm.setLatLng(startPos);\n\t\t\t\t\t\tif (nm.clusterHide) {\n\t\t\t\t\t\t\tnm.clusterHide();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tc._group._featureGroup.addLayer(nm);\n\t\t\t\t}\n\t\t\t},\n\t\t\tfunction (c) {\n\t\t\t\tc._addToMap(startPos);\n\t\t\t}\n\t\t);\n\t},\n\n\t_recursivelyRestoreChildPositions: function (zoomLevel) {\n\t\t//Fix positions of child markers\n\t\tfor (var i = this._markers.length - 1; i >= 0; i--) {\n\t\t\tvar nm = this._markers[i];\n\t\t\tif (nm._backupLatlng) {\n\t\t\t\tnm.setLatLng(nm._backupLatlng);\n\t\t\t\tdelete nm._backupLatlng;\n\t\t\t}\n\t\t}\n\n\t\tif (zoomLevel - 1 === this._zoom) {\n\t\t\t//Reposition child clusters\n\t\t\tfor (var j = this._childClusters.length - 1; j >= 0; j--) {\n\t\t\t\tthis._childClusters[j]._restorePosition();\n\t\t\t}\n\t\t} else {\n\t\t\tfor (var k = this._childClusters.length - 1; k >= 0; k--) {\n\t\t\t\tthis._childClusters[k]._recursivelyRestoreChildPositions(zoomLevel);\n\t\t\t}\n\t\t}\n\t},\n\n\t_restorePosition: function () {\n\t\tif (this._backupLatlng) {\n\t\t\tthis.setLatLng(this._backupLatlng);\n\t\t\tdelete this._backupLatlng;\n\t\t}\n\t},\n\n\t//exceptBounds: If set, don't remove any markers/clusters in it\n\t_recursivelyRemoveChildrenFromMap: function (previousBounds, mapMinZoom, zoomLevel, exceptBounds) {\n\t\tvar m, i;\n\t\tthis._recursively(previousBounds, mapMinZoom - 1, zoomLevel - 1,\n\t\t\tfunction (c) {\n\t\t\t\t//Remove markers at every level\n\t\t\t\tfor (i = c._markers.length - 1; i >= 0; i--) {\n\t\t\t\t\tm = c._markers[i];\n\t\t\t\t\tif (!exceptBounds || !exceptBounds.contains(m._latlng)) {\n\t\t\t\t\t\tc._group._featureGroup.removeLayer(m);\n\t\t\t\t\t\tif (m.clusterShow) {\n\t\t\t\t\t\t\tm.clusterShow();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tfunction (c) {\n\t\t\t\t//Remove child clusters at just the bottom level\n\t\t\t\tfor (i = c._childClusters.length - 1; i >= 0; i--) {\n\t\t\t\t\tm = c._childClusters[i];\n\t\t\t\t\tif (!exceptBounds || !exceptBounds.contains(m._latlng)) {\n\t\t\t\t\t\tc._group._featureGroup.removeLayer(m);\n\t\t\t\t\t\tif (m.clusterShow) {\n\t\t\t\t\t\t\tm.clusterShow();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t},\n\n\t//Run the given functions recursively to this and child clusters\n\t// boundsToApplyTo: a L.LatLngBounds representing the bounds of what clusters to recurse in to\n\t// zoomLevelToStart: zoom level to start running functions (inclusive)\n\t// zoomLevelToStop: zoom level to stop running functions (inclusive)\n\t// runAtEveryLevel: function that takes an L.MarkerCluster as an argument that should be applied on every level\n\t// runAtBottomLevel: function that takes an L.MarkerCluster as an argument that should be applied at only the bottom level\n\t_recursively: function (boundsToApplyTo, zoomLevelToStart, zoomLevelToStop, runAtEveryLevel, runAtBottomLevel) {\n\t\tvar childClusters = this._childClusters,\n\t\t zoom = this._zoom,\n\t\t i, c;\n\n\t\tif (zoomLevelToStart <= zoom) {\n\t\t\tif (runAtEveryLevel) {\n\t\t\t\trunAtEveryLevel(this);\n\t\t\t}\n\t\t\tif (runAtBottomLevel && zoom === zoomLevelToStop) {\n\t\t\t\trunAtBottomLevel(this);\n\t\t\t}\n\t\t}\n\n\t\tif (zoom < zoomLevelToStart || zoom < zoomLevelToStop) {\n\t\t\tfor (i = childClusters.length - 1; i >= 0; i--) {\n\t\t\t\tc = childClusters[i];\n\t\t\t\tif (c._boundsNeedUpdate) {\n\t\t\t\t\tc._recalculateBounds();\n\t\t\t\t}\n\t\t\t\tif (boundsToApplyTo.intersects(c._bounds)) {\n\t\t\t\t\tc._recursively(boundsToApplyTo, zoomLevelToStart, zoomLevelToStop, runAtEveryLevel, runAtBottomLevel);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t//Returns true if we are the parent of only one cluster and that cluster is the same as us\n\t_isSingleParent: function () {\n\t\t//Don't need to check this._markers as the rest won't work if there are any\n\t\treturn this._childClusters.length > 0 && this._childClusters[0]._childCount === this._childCount;\n\t}\n});\n\n", "/*\n* Extends L.Marker to include two extra methods: clusterHide and clusterShow.\n* \n* They work as setOpacity(0) and setOpacity(1) respectively, but\n* don't overwrite the options.opacity\n* \n*/\n\nL.Marker.include({\n\tclusterHide: function () {\n\t\tvar backup = this.options.opacity;\n\t\tthis.setOpacity(0);\n\t\tthis.options.opacity = backup;\n\t\treturn this;\n\t},\n\t\n\tclusterShow: function () {\n\t\treturn this.setOpacity(this.options.opacity);\n\t}\n});\n\n\n", "\nL.DistanceGrid = function (cellSize) {\n\tthis._cellSize = cellSize;\n\tthis._sqCellSize = cellSize * cellSize;\n\tthis._grid = {};\n\tthis._objectPoint = { };\n};\n\nL.DistanceGrid.prototype = {\n\n\taddObject: function (obj, point) {\n\t\tvar x = this._getCoord(point.x),\n\t\t y = this._getCoord(point.y),\n\t\t grid = this._grid,\n\t\t row = grid[y] = grid[y] || {},\n\t\t cell = row[x] = row[x] || [],\n\t\t stamp = L.Util.stamp(obj);\n\n\t\tthis._objectPoint[stamp] = point;\n\n\t\tcell.push(obj);\n\t},\n\n\tupdateObject: function (obj, point) {\n\t\tthis.removeObject(obj);\n\t\tthis.addObject(obj, point);\n\t},\n\n\t//Returns true if the object was found\n\tremoveObject: function (obj, point) {\n\t\tvar x = this._getCoord(point.x),\n\t\t y = this._getCoord(point.y),\n\t\t grid = this._grid,\n\t\t row = grid[y] = grid[y] || {},\n\t\t cell = row[x] = row[x] || [],\n\t\t i, len;\n\n\t\tdelete this._objectPoint[L.Util.stamp(obj)];\n\n\t\tfor (i = 0, len = cell.length; i < len; i++) {\n\t\t\tif (cell[i] === obj) {\n\n\t\t\t\tcell.splice(i, 1);\n\n\t\t\t\tif (len === 1) {\n\t\t\t\t\tdelete row[x];\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t},\n\n\teachObject: function (fn, context) {\n\t\tvar i, j, k, len, row, cell, removed,\n\t\t grid = this._grid;\n\n\t\tfor (i in grid) {\n\t\t\trow = grid[i];\n\n\t\t\tfor (j in row) {\n\t\t\t\tcell = row[j];\n\n\t\t\t\tfor (k = 0, len = cell.length; k < len; k++) {\n\t\t\t\t\tremoved = fn.call(context, cell[k]);\n\t\t\t\t\tif (removed) {\n\t\t\t\t\t\tk--;\n\t\t\t\t\t\tlen--;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tgetNearObject: function (point) {\n\t\tvar x = this._getCoord(point.x),\n\t\t y = this._getCoord(point.y),\n\t\t i, j, k, row, cell, len, obj, dist,\n\t\t objectPoint = this._objectPoint,\n\t\t closestDistSq = this._sqCellSize,\n\t\t closest = null;\n\n\t\tfor (i = y - 1; i <= y + 1; i++) {\n\t\t\trow = this._grid[i];\n\t\t\tif (row) {\n\n\t\t\t\tfor (j = x - 1; j <= x + 1; j++) {\n\t\t\t\t\tcell = row[j];\n\t\t\t\t\tif (cell) {\n\n\t\t\t\t\t\tfor (k = 0, len = cell.length; k < len; k++) {\n\t\t\t\t\t\t\tobj = cell[k];\n\t\t\t\t\t\t\tdist = this._sqDist(objectPoint[L.Util.stamp(obj)], point);\n\t\t\t\t\t\t\tif (dist < closestDistSq ||\n\t\t\t\t\t\t\t\tdist <= closestDistSq && closest === null) {\n\t\t\t\t\t\t\t\tclosestDistSq = dist;\n\t\t\t\t\t\t\t\tclosest = obj;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn closest;\n\t},\n\n\t_getCoord: function (x) {\n\t\tvar coord = Math.floor(x / this._cellSize);\n\t\treturn isFinite(coord) ? coord : x;\n\t},\n\n\t_sqDist: function (p, p2) {\n\t\tvar dx = p2.x - p.x,\n\t\t dy = p2.y - p.y;\n\t\treturn dx * dx + dy * dy;\n\t}\n};\n", "/* Copyright (c) 2012 the authors listed at the following URL, and/or\nthe authors of referenced articles or incorporated external code:\nhttp://en.literateprograms.org/Quickhull_(Javascript)?action=history&offset=20120410175256\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nRetrieved from: http://en.literateprograms.org/Quickhull_(Javascript)?oldid=18434\n*/\n\n(function () {\n\tL.QuickHull = {\n\n\t\t/*\n\t\t * @param {Object} cpt a point to be measured from the baseline\n\t\t * @param {Array} bl the baseline, as represented by a two-element\n\t\t * array of latlng objects.\n\t\t * @returns {Number} an approximate distance measure\n\t\t */\n\t\tgetDistant: function (cpt, bl) {\n\t\t\tvar vY = bl[1].lat - bl[0].lat,\n\t\t\t\tvX = bl[0].lng - bl[1].lng;\n\t\t\treturn (vX * (cpt.lat - bl[0].lat) + vY * (cpt.lng - bl[0].lng));\n\t\t},\n\n\t\t/*\n\t\t * @param {Array} baseLine a two-element array of latlng objects\n\t\t * representing the baseline to project from\n\t\t * @param {Array} latLngs an array of latlng objects\n\t\t * @returns {Object} the maximum point and all new points to stay\n\t\t * in consideration for the hull.\n\t\t */\n\t\tfindMostDistantPointFromBaseLine: function (baseLine, latLngs) {\n\t\t\tvar maxD = 0,\n\t\t\t\tmaxPt = null,\n\t\t\t\tnewPoints = [],\n\t\t\t\ti, pt, d;\n\n\t\t\tfor (i = latLngs.length - 1; i >= 0; i--) {\n\t\t\t\tpt = latLngs[i];\n\t\t\t\td = this.getDistant(pt, baseLine);\n\n\t\t\t\tif (d > 0) {\n\t\t\t\t\tnewPoints.push(pt);\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (d > maxD) {\n\t\t\t\t\tmaxD = d;\n\t\t\t\t\tmaxPt = pt;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { maxPoint: maxPt, newPoints: newPoints };\n\t\t},\n\n\n\t\t/*\n\t\t * Given a baseline, compute the convex hull of latLngs as an array\n\t\t * of latLngs.\n\t\t *\n\t\t * @param {Array} latLngs\n\t\t * @returns {Array}\n\t\t */\n\t\tbuildConvexHull: function (baseLine, latLngs) {\n\t\t\tvar convexHullBaseLines = [],\n\t\t\t\tt = this.findMostDistantPointFromBaseLine(baseLine, latLngs);\n\n\t\t\tif (t.maxPoint) { // if there is still a point \"outside\" the base line\n\t\t\t\tconvexHullBaseLines =\n\t\t\t\t\tconvexHullBaseLines.concat(\n\t\t\t\t\t\tthis.buildConvexHull([baseLine[0], t.maxPoint], t.newPoints)\n\t\t\t\t\t);\n\t\t\t\tconvexHullBaseLines =\n\t\t\t\t\tconvexHullBaseLines.concat(\n\t\t\t\t\t\tthis.buildConvexHull([t.maxPoint, baseLine[1]], t.newPoints)\n\t\t\t\t\t);\n\t\t\t\treturn convexHullBaseLines;\n\t\t\t} else { // if there is no more point \"outside\" the base line, the current base line is part of the convex hull\n\t\t\t\treturn [baseLine[0]];\n\t\t\t}\n\t\t},\n\n\t\t/*\n\t\t * Given an array of latlngs, compute a convex hull as an array\n\t\t * of latlngs\n\t\t *\n\t\t * @param {Array} latLngs\n\t\t * @returns {Array}\n\t\t */\n\t\tgetConvexHull: function (latLngs) {\n\t\t\t// find first baseline\n\t\t\tvar maxLat = false, minLat = false,\n\t\t\t\tmaxLng = false, minLng = false,\n\t\t\t\tmaxLatPt = null, minLatPt = null,\n\t\t\t\tmaxLngPt = null, minLngPt = null,\n\t\t\t\tmaxPt = null, minPt = null,\n\t\t\t\ti;\n\n\t\t\tfor (i = latLngs.length - 1; i >= 0; i--) {\n\t\t\t\tvar pt = latLngs[i];\n\t\t\t\tif (maxLat === false || pt.lat > maxLat) {\n\t\t\t\t\tmaxLatPt = pt;\n\t\t\t\t\tmaxLat = pt.lat;\n\t\t\t\t}\n\t\t\t\tif (minLat === false || pt.lat < minLat) {\n\t\t\t\t\tminLatPt = pt;\n\t\t\t\t\tminLat = pt.lat;\n\t\t\t\t}\n\t\t\t\tif (maxLng === false || pt.lng > maxLng) {\n\t\t\t\t\tmaxLngPt = pt;\n\t\t\t\t\tmaxLng = pt.lng;\n\t\t\t\t}\n\t\t\t\tif (minLng === false || pt.lng < minLng) {\n\t\t\t\t\tminLngPt = pt;\n\t\t\t\t\tminLng = pt.lng;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tif (minLat !== maxLat) {\n\t\t\t\tminPt = minLatPt;\n\t\t\t\tmaxPt = maxLatPt;\n\t\t\t} else {\n\t\t\t\tminPt = minLngPt;\n\t\t\t\tmaxPt = maxLngPt;\n\t\t\t}\n\n\t\t\tvar ch = [].concat(this.buildConvexHull([minPt, maxPt], latLngs),\n\t\t\t\t\t\t\t\tthis.buildConvexHull([maxPt, minPt], latLngs));\n\t\t\treturn ch;\n\t\t}\n\t};\n}());\n\nL.MarkerCluster.include({\n\tgetConvexHull: function () {\n\t\tvar childMarkers = this.getAllChildMarkers(),\n\t\t\tpoints = [],\n\t\t\tp, i;\n\n\t\tfor (i = childMarkers.length - 1; i >= 0; i--) {\n\t\t\tp = childMarkers[i].getLatLng();\n\t\t\tpoints.push(p);\n\t\t}\n\n\t\treturn L.QuickHull.getConvexHull(points);\n\t}\n});\n", "//This code is 100% based on https://github.com/jawj/OverlappingMarkerSpiderfier-Leaflet\n//Huge thanks to jawj for implementing it first to make my job easy :-)\n\nL.MarkerCluster.include({\n\n\t_2PI: Math.PI * 2,\n\t_circleFootSeparation: 25, //related to circumference of circle\n\t_circleStartAngle: 0,\n\n\t_spiralFootSeparation: 28, //related to size of spiral (experiment!)\n\t_spiralLengthStart: 11,\n\t_spiralLengthFactor: 5,\n\n\t_circleSpiralSwitchover: 9, //show spiral instead of circle from this marker count upwards.\n\t\t\t\t\t\t\t\t// 0 -> always spiral; Infinity -> always circle\n\n\tspiderfy: function () {\n\t\tif (this._group._spiderfied === this || this._group._inZoomAnimation) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar childMarkers = this.getAllChildMarkers(null, true),\n\t\t\tgroup = this._group,\n\t\t\tmap = group._map,\n\t\t\tcenter = map.latLngToLayerPoint(this._latlng),\n\t\t\tpositions;\n\n\t\tthis._group._unspiderfy();\n\t\tthis._group._spiderfied = this;\n\n\t\t//TODO Maybe: childMarkers order by distance to center\n\n\t\tif (this._group.options.spiderfyShapePositions) {\n\t\t\tpositions = this._group.options.spiderfyShapePositions(childMarkers.length, center);\n\t\t} else if (childMarkers.length >= this._circleSpiralSwitchover) {\n\t\t\tpositions = this._generatePointsSpiral(childMarkers.length, center);\n\t\t} else {\n\t\t\tcenter.y += 10; // Otherwise circles look wrong => hack for standard blue icon, renders differently for other icons.\n\t\t\tpositions = this._generatePointsCircle(childMarkers.length, center);\n\t\t}\n\n\t\tthis._animationSpiderfy(childMarkers, positions);\n\t},\n\n\tunspiderfy: function (zoomDetails) {\n\t\t/// Argument from zoomanim if being called in a zoom animation or null otherwise\n\t\tif (this._group._inZoomAnimation) {\n\t\t\treturn;\n\t\t}\n\t\tthis._animationUnspiderfy(zoomDetails);\n\n\t\tthis._group._spiderfied = null;\n\t},\n\n\t_generatePointsCircle: function (count, centerPt) {\n\t\tvar circumference = this._group.options.spiderfyDistanceMultiplier * this._circleFootSeparation * (2 + count),\n\t\t\tlegLength = circumference / this._2PI, //radius from circumference\n\t\t\tangleStep = this._2PI / count,\n\t\t\tres = [],\n\t\t\ti, angle;\n\n\t\tlegLength = Math.max(legLength, 35); // Minimum distance to get outside the cluster icon.\n\n\t\tres.length = count;\n\n\t\tfor (i = 0; i < count; i++) { // Clockwise, like spiral.\n\t\t\tangle = this._circleStartAngle + i * angleStep;\n\t\t\tres[i] = new L.Point(centerPt.x + legLength * Math.cos(angle), centerPt.y + legLength * Math.sin(angle))._round();\n\t\t}\n\n\t\treturn res;\n\t},\n\n\t_generatePointsSpiral: function (count, centerPt) {\n\t\tvar spiderfyDistanceMultiplier = this._group.options.spiderfyDistanceMultiplier,\n\t\t\tlegLength = spiderfyDistanceMultiplier * this._spiralLengthStart,\n\t\t\tseparation = spiderfyDistanceMultiplier * this._spiralFootSeparation,\n\t\t\tlengthFactor = spiderfyDistanceMultiplier * this._spiralLengthFactor * this._2PI,\n\t\t\tangle = 0,\n\t\t\tres = [],\n\t\t\ti;\n\n\t\tres.length = count;\n\n\t\t// Higher index, closer position to cluster center.\n\t\tfor (i = count; i >= 0; i--) {\n\t\t\t// Skip the first position, so that we are already farther from center and we avoid\n\t\t\t// being under the default cluster icon (especially important for Circle Markers).\n\t\t\tif (i < count) {\n\t\t\t\tres[i] = new L.Point(centerPt.x + legLength * Math.cos(angle), centerPt.y + legLength * Math.sin(angle))._round();\n\t\t\t}\n\t\t\tangle += separation / legLength + i * 0.0005;\n\t\t\tlegLength += lengthFactor / angle;\n\t\t}\n\t\treturn res;\n\t},\n\n\t_noanimationUnspiderfy: function () {\n\t\tvar group = this._group,\n\t\t\tmap = group._map,\n\t\t\tfg = group._featureGroup,\n\t\t\tchildMarkers = this.getAllChildMarkers(null, true),\n\t\t\tm, i;\n\n\t\tgroup._ignoreMove = true;\n\n\t\tthis.setOpacity(1);\n\t\tfor (i = childMarkers.length - 1; i >= 0; i--) {\n\t\t\tm = childMarkers[i];\n\n\t\t\tfg.removeLayer(m);\n\n\t\t\tif (m._preSpiderfyLatlng) {\n\t\t\t\tm.setLatLng(m._preSpiderfyLatlng);\n\t\t\t\tdelete m._preSpiderfyLatlng;\n\t\t\t}\n\t\t\tif (m.setZIndexOffset) {\n\t\t\t\tm.setZIndexOffset(0);\n\t\t\t}\n\n\t\t\tif (m._spiderLeg) {\n\t\t\t\tmap.removeLayer(m._spiderLeg);\n\t\t\t\tdelete m._spiderLeg;\n\t\t\t}\n\t\t}\n\n\t\tgroup.fire('unspiderfied', {\n\t\t\tcluster: this,\n\t\t\tmarkers: childMarkers\n\t\t});\n\t\tgroup._ignoreMove = false;\n\t\tgroup._spiderfied = null;\n\t}\n});\n\n//Non Animated versions of everything\nL.MarkerClusterNonAnimated = L.MarkerCluster.extend({\n\t_animationSpiderfy: function (childMarkers, positions) {\n\t\tvar group = this._group,\n\t\t\tmap = group._map,\n\t\t\tfg = group._featureGroup,\n\t\t\tlegOptions = this._group.options.spiderLegPolylineOptions,\n\t\t\ti, m, leg, newPos;\n\n\t\tgroup._ignoreMove = true;\n\n\t\t// Traverse in ascending order to make sure that inner circleMarkers are on top of further legs. Normal markers are re-ordered by newPosition.\n\t\t// The reverse order trick no longer improves performance on modern browsers.\n\t\tfor (i = 0; i < childMarkers.length; i++) {\n\t\t\tnewPos = map.layerPointToLatLng(positions[i]);\n\t\t\tm = childMarkers[i];\n\n\t\t\t// Add the leg before the marker, so that in case the latter is a circleMarker, the leg is behind it.\n\t\t\tleg = new L.Polyline([this._latlng, newPos], legOptions);\n\t\t\tmap.addLayer(leg);\n\t\t\tm._spiderLeg = leg;\n\n\t\t\t// Now add the marker.\n\t\t\tm._preSpiderfyLatlng = m._latlng;\n\t\t\tm.setLatLng(newPos);\n\t\t\tif (m.setZIndexOffset) {\n\t\t\t\tm.setZIndexOffset(1000000); //Make these appear on top of EVERYTHING\n\t\t\t}\n\n\t\t\tfg.addLayer(m);\n\t\t}\n\t\tthis.setOpacity(0.3);\n\n\t\tgroup._ignoreMove = false;\n\t\tgroup.fire('spiderfied', {\n\t\t\tcluster: this,\n\t\t\tmarkers: childMarkers\n\t\t});\n\t},\n\n\t_animationUnspiderfy: function () {\n\t\tthis._noanimationUnspiderfy();\n\t}\n});\n\n//Animated versions here\nL.MarkerCluster.include({\n\n\t_animationSpiderfy: function (childMarkers, positions) {\n\t\tvar me = this,\n\t\t\tgroup = this._group,\n\t\t\tmap = group._map,\n\t\t\tfg = group._featureGroup,\n\t\t\tthisLayerLatLng = this._latlng,\n\t\t\tthisLayerPos = map.latLngToLayerPoint(thisLayerLatLng),\n\t\t\tsvg = L.Path.SVG,\n\t\t\tlegOptions = L.extend({}, this._group.options.spiderLegPolylineOptions), // Copy the options so that we can modify them for animation.\n\t\t\tfinalLegOpacity = legOptions.opacity,\n\t\t\ti, m, leg, legPath, legLength, newPos;\n\n\t\tif (finalLegOpacity === undefined) {\n\t\t\tfinalLegOpacity = L.MarkerClusterGroup.prototype.options.spiderLegPolylineOptions.opacity;\n\t\t}\n\n\t\tif (svg) {\n\t\t\t// If the initial opacity of the spider leg is not 0 then it appears before the animation starts.\n\t\t\tlegOptions.opacity = 0;\n\n\t\t\t// Add the class for CSS transitions.\n\t\t\tlegOptions.className = (legOptions.className || '') + ' leaflet-cluster-spider-leg';\n\t\t} else {\n\t\t\t// Make sure we have a defined opacity.\n\t\t\tlegOptions.opacity = finalLegOpacity;\n\t\t}\n\n\t\tgroup._ignoreMove = true;\n\n\t\t// Add markers and spider legs to map, hidden at our center point.\n\t\t// Traverse in ascending order to make sure that inner circleMarkers are on top of further legs. Normal markers are re-ordered by newPosition.\n\t\t// The reverse order trick no longer improves performance on modern browsers.\n\t\tfor (i = 0; i < childMarkers.length; i++) {\n\t\t\tm = childMarkers[i];\n\n\t\t\tnewPos = map.layerPointToLatLng(positions[i]);\n\n\t\t\t// Add the leg before the marker, so that in case the latter is a circleMarker, the leg is behind it.\n\t\t\tleg = new L.Polyline([thisLayerLatLng, newPos], legOptions);\n\t\t\tmap.addLayer(leg);\n\t\t\tm._spiderLeg = leg;\n\n\t\t\t// Explanations: https://jakearchibald.com/2013/animated-line-drawing-svg/\n\t\t\t// In our case the transition property is declared in the CSS file.\n\t\t\tif (svg) {\n\t\t\t\tlegPath = leg._path;\n\t\t\t\tlegLength = legPath.getTotalLength() + 0.1; // Need a small extra length to avoid remaining dot in Firefox.\n\t\t\t\tlegPath.style.strokeDasharray = legLength; // Just 1 length is enough, it will be duplicated.\n\t\t\t\tlegPath.style.strokeDashoffset = legLength;\n\t\t\t}\n\n\t\t\t// If it is a marker, add it now and we'll animate it out\n\t\t\tif (m.setZIndexOffset) {\n\t\t\t\tm.setZIndexOffset(1000000); // Make normal markers appear on top of EVERYTHING\n\t\t\t}\n\t\t\tif (m.clusterHide) {\n\t\t\t\tm.clusterHide();\n\t\t\t}\n\t\t\t\n\t\t\t// Vectors just get immediately added\n\t\t\tfg.addLayer(m);\n\n\t\t\tif (m._setPos) {\n\t\t\t\tm._setPos(thisLayerPos);\n\t\t\t}\n\t\t}\n\n\t\tgroup._forceLayout();\n\t\tgroup._animationStart();\n\n\t\t// Reveal markers and spider legs.\n\t\tfor (i = childMarkers.length - 1; i >= 0; i--) {\n\t\t\tnewPos = map.layerPointToLatLng(positions[i]);\n\t\t\tm = childMarkers[i];\n\n\t\t\t//Move marker to new position\n\t\t\tm._preSpiderfyLatlng = m._latlng;\n\t\t\tm.setLatLng(newPos);\n\t\t\t\n\t\t\tif (m.clusterShow) {\n\t\t\t\tm.clusterShow();\n\t\t\t}\n\n\t\t\t// Animate leg (animation is actually delegated to CSS transition).\n\t\t\tif (svg) {\n\t\t\t\tleg = m._spiderLeg;\n\t\t\t\tlegPath = leg._path;\n\t\t\t\tlegPath.style.strokeDashoffset = 0;\n\t\t\t\t//legPath.style.strokeOpacity = finalLegOpacity;\n\t\t\t\tleg.setStyle({opacity: finalLegOpacity});\n\t\t\t}\n\t\t}\n\t\tthis.setOpacity(0.3);\n\n\t\tgroup._ignoreMove = false;\n\n\t\tsetTimeout(function () {\n\t\t\tgroup._animationEnd();\n\t\t\tgroup.fire('spiderfied', {\n\t\t\t\tcluster: me,\n\t\t\t\tmarkers: childMarkers\n\t\t\t});\n\t\t}, 200);\n\t},\n\n\t_animationUnspiderfy: function (zoomDetails) {\n\t\tvar me = this,\n\t\t\tgroup = this._group,\n\t\t\tmap = group._map,\n\t\t\tfg = group._featureGroup,\n\t\t\tthisLayerPos = zoomDetails ? map._latLngToNewLayerPoint(this._latlng, zoomDetails.zoom, zoomDetails.center) : map.latLngToLayerPoint(this._latlng),\n\t\t\tchildMarkers = this.getAllChildMarkers(null, true),\n\t\t\tsvg = L.Path.SVG,\n\t\t\tm, i, leg, legPath, legLength, nonAnimatable;\n\n\t\tgroup._ignoreMove = true;\n\t\tgroup._animationStart();\n\n\t\t//Make us visible and bring the child markers back in\n\t\tthis.setOpacity(1);\n\t\tfor (i = childMarkers.length - 1; i >= 0; i--) {\n\t\t\tm = childMarkers[i];\n\n\t\t\t//Marker was added to us after we were spiderfied\n\t\t\tif (!m._preSpiderfyLatlng) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t//Close any popup on the marker first, otherwise setting the location of the marker will make the map scroll\n\t\t\tm.closePopup();\n\n\t\t\t//Fix up the location to the real one\n\t\t\tm.setLatLng(m._preSpiderfyLatlng);\n\t\t\tdelete m._preSpiderfyLatlng;\n\n\t\t\t//Hack override the location to be our center\n\t\t\tnonAnimatable = true;\n\t\t\tif (m._setPos) {\n\t\t\t\tm._setPos(thisLayerPos);\n\t\t\t\tnonAnimatable = false;\n\t\t\t}\n\t\t\tif (m.clusterHide) {\n\t\t\t\tm.clusterHide();\n\t\t\t\tnonAnimatable = false;\n\t\t\t}\n\t\t\tif (nonAnimatable) {\n\t\t\t\tfg.removeLayer(m);\n\t\t\t}\n\n\t\t\t// Animate the spider leg back in (animation is actually delegated to CSS transition).\n\t\t\tif (svg) {\n\t\t\t\tleg = m._spiderLeg;\n\t\t\t\tlegPath = leg._path;\n\t\t\t\tlegLength = legPath.getTotalLength() + 0.1;\n\t\t\t\tlegPath.style.strokeDashoffset = legLength;\n\t\t\t\tleg.setStyle({opacity: 0});\n\t\t\t}\n\t\t}\n\n\t\tgroup._ignoreMove = false;\n\n\t\tsetTimeout(function () {\n\t\t\t//If we have only <= one child left then that marker will be shown on the map so don't remove it!\n\t\t\tvar stillThereChildCount = 0;\n\t\t\tfor (i = childMarkers.length - 1; i >= 0; i--) {\n\t\t\t\tm = childMarkers[i];\n\t\t\t\tif (m._spiderLeg) {\n\t\t\t\t\tstillThereChildCount++;\n\t\t\t\t}\n\t\t\t}\n\n\n\t\t\tfor (i = childMarkers.length - 1; i >= 0; i--) {\n\t\t\t\tm = childMarkers[i];\n\n\t\t\t\tif (!m._spiderLeg) { //Has already been unspiderfied\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (m.clusterShow) {\n\t\t\t\t\tm.clusterShow();\n\t\t\t\t}\n\t\t\t\tif (m.setZIndexOffset) {\n\t\t\t\t\tm.setZIndexOffset(0);\n\t\t\t\t}\n\n\t\t\t\tif (stillThereChildCount > 1) {\n\t\t\t\t\tfg.removeLayer(m);\n\t\t\t\t}\n\n\t\t\t\tmap.removeLayer(m._spiderLeg);\n\t\t\t\tdelete m._spiderLeg;\n\t\t\t}\n\t\t\tgroup._animationEnd();\n\t\t\tgroup.fire('unspiderfied', {\n\t\t\t\tcluster: me,\n\t\t\t\tmarkers: childMarkers\n\t\t\t});\n\t\t}, 200);\n\t}\n});\n\n\nL.MarkerClusterGroup.include({\n\t//The MarkerCluster currently spiderfied (if any)\n\t_spiderfied: null,\n\n\tunspiderfy: function () {\n\t\tthis._unspiderfy.apply(this, arguments);\n\t},\n\n\t_spiderfierOnAdd: function () {\n\t\tthis._map.on('click', this._unspiderfyWrapper, this);\n\n\t\tif (this._map.options.zoomAnimation) {\n\t\t\tthis._map.on('zoomstart', this._unspiderfyZoomStart, this);\n\t\t}\n\t\t//Browsers without zoomAnimation or a big zoom don't fire zoomstart\n\t\tthis._map.on('zoomend', this._noanimationUnspiderfy, this);\n\n\t\tif (!L.Browser.touch) {\n\t\t\tthis._map.getRenderer(this);\n\t\t\t//Needs to happen in the pageload, not after, or animations don't work in webkit\n\t\t\t// http://stackoverflow.com/questions/8455200/svg-animate-with-dynamically-added-elements\n\t\t\t//Disable on touch browsers as the animation messes up on a touch zoom and isn't very noticable\n\t\t}\n\t},\n\n\t_spiderfierOnRemove: function () {\n\t\tthis._map.off('click', this._unspiderfyWrapper, this);\n\t\tthis._map.off('zoomstart', this._unspiderfyZoomStart, this);\n\t\tthis._map.off('zoomanim', this._unspiderfyZoomAnim, this);\n\t\tthis._map.off('zoomend', this._noanimationUnspiderfy, this);\n\n\t\t//Ensure that markers are back where they should be\n\t\t// Use no animation to avoid a sticky leaflet-cluster-anim class on mapPane\n\t\tthis._noanimationUnspiderfy();\n\t},\n\n\t//On zoom start we add a zoomanim handler so that we are guaranteed to be last (after markers are animated)\n\t//This means we can define the animation they do rather than Markers doing an animation to their actual location\n\t_unspiderfyZoomStart: function () {\n\t\tif (!this._map) { //May have been removed from the map by a zoomEnd handler\n\t\t\treturn;\n\t\t}\n\n\t\tthis._map.on('zoomanim', this._unspiderfyZoomAnim, this);\n\t},\n\n\t_unspiderfyZoomAnim: function (zoomDetails) {\n\t\t//Wait until the first zoomanim after the user has finished touch-zooming before running the animation\n\t\tif (L.DomUtil.hasClass(this._map._mapPane, 'leaflet-touching')) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._map.off('zoomanim', this._unspiderfyZoomAnim, this);\n\t\tthis._unspiderfy(zoomDetails);\n\t},\n\n\t_unspiderfyWrapper: function () {\n\t\t/// _unspiderfy but passes no arguments\n\t\tthis._unspiderfy();\n\t},\n\n\t_unspiderfy: function (zoomDetails) {\n\t\tif (this._spiderfied) {\n\t\t\tthis._spiderfied.unspiderfy(zoomDetails);\n\t\t}\n\t},\n\n\t_noanimationUnspiderfy: function () {\n\t\tif (this._spiderfied) {\n\t\t\tthis._spiderfied._noanimationUnspiderfy();\n\t\t}\n\t},\n\n\t//If the given layer is currently being spiderfied then we unspiderfy it so it isn't on the map anymore etc\n\t_unspiderfyLayer: function (layer) {\n\t\tif (layer._spiderLeg) {\n\t\t\tthis._featureGroup.removeLayer(layer);\n\n\t\t\tif (layer.clusterShow) {\n\t\t\t\tlayer.clusterShow();\n\t\t\t}\n\t\t\t\t//Position will be fixed up immediately in _animationUnspiderfy\n\t\t\tif (layer.setZIndexOffset) {\n\t\t\t\tlayer.setZIndexOffset(0);\n\t\t\t}\n\n\t\t\tthis._map.removeLayer(layer._spiderLeg);\n\t\t\tdelete layer._spiderLeg;\n\t\t}\n\t}\n});\n", "/**\n * Adds 1 public method to MCG and 1 to L.Marker to facilitate changing\n * markers' icon options and refreshing their icon and their parent clusters\n * accordingly (case where their iconCreateFunction uses data of childMarkers\n * to make up the cluster icon).\n */\n\n\nL.MarkerClusterGroup.include({\n\t/**\n\t * Updates the icon of all clusters which are parents of the given marker(s).\n\t * In singleMarkerMode, also updates the given marker(s) icon.\n\t * @param layers L.MarkerClusterGroup|L.LayerGroup|Array(L.Marker)|Map(L.Marker)|\n\t * L.MarkerCluster|L.Marker (optional) list of markers (or single marker) whose parent\n\t * clusters need to be updated. If not provided, retrieves all child markers of this.\n\t * @returns {L.MarkerClusterGroup}\n\t */\n\trefreshClusters: function (layers) {\n\t\tif (!layers) {\n\t\t\tlayers = this._topClusterLevel.getAllChildMarkers();\n\t\t} else if (layers instanceof L.MarkerClusterGroup) {\n\t\t\tlayers = layers._topClusterLevel.getAllChildMarkers();\n\t\t} else if (layers instanceof L.LayerGroup) {\n\t\t\tlayers = layers._layers;\n\t\t} else if (layers instanceof L.MarkerCluster) {\n\t\t\tlayers = layers.getAllChildMarkers();\n\t\t} else if (layers instanceof L.Marker) {\n\t\t\tlayers = [layers];\n\t\t} // else: must be an Array(L.Marker)|Map(L.Marker)\n\t\tthis._flagParentsIconsNeedUpdate(layers);\n\t\tthis._refreshClustersIcons();\n\n\t\t// In case of singleMarkerMode, also re-draw the markers.\n\t\tif (this.options.singleMarkerMode) {\n\t\t\tthis._refreshSingleMarkerModeMarkers(layers);\n\t\t}\n\n\t\treturn this;\n\t},\n\n\t/**\n\t * Simply flags all parent clusters of the given markers as having a \"dirty\" icon.\n\t * @param layers Array(L.Marker)|Map(L.Marker) list of markers.\n\t * @private\n\t */\n\t_flagParentsIconsNeedUpdate: function (layers) {\n\t\tvar id, parent;\n\n\t\t// Assumes layers is an Array or an Object whose prototype is non-enumerable.\n\t\tfor (id in layers) {\n\t\t\t// Flag parent clusters' icon as \"dirty\", all the way up.\n\t\t\t// Dumb process that flags multiple times upper parents, but still\n\t\t\t// much more efficient than trying to be smart and make short lists,\n\t\t\t// at least in the case of a hierarchy following a power law:\n\t\t\t// http://jsperf.com/flag-nodes-in-power-hierarchy/2\n\t\t\tparent = layers[id].__parent;\n\t\t\twhile (parent) {\n\t\t\t\tparent._iconNeedsUpdate = true;\n\t\t\t\tparent = parent.__parent;\n\t\t\t}\n\t\t}\n\t},\n\n\t/**\n\t * Re-draws the icon of the supplied markers.\n\t * To be used in singleMarkerMode only.\n\t * @param layers Array(L.Marker)|Map(L.Marker) list of markers.\n\t * @private\n\t */\n\t_refreshSingleMarkerModeMarkers: function (layers) {\n\t\tvar id, layer;\n\n\t\tfor (id in layers) {\n\t\t\tlayer = layers[id];\n\n\t\t\t// Make sure we do not override markers that do not belong to THIS group.\n\t\t\tif (this.hasLayer(layer)) {\n\t\t\t\t// Need to re-create the icon first, then re-draw the marker.\n\t\t\t\tlayer.setIcon(this._overrideMarkerIcon(layer));\n\t\t\t}\n\t\t}\n\t}\n});\n\nL.Marker.include({\n\t/**\n\t * Updates the given options in the marker's icon and refreshes the marker.\n\t * @param options map object of icon options.\n\t * @param directlyRefreshClusters boolean (optional) true to trigger\n\t * MCG.refreshClustersOf() right away with this single marker.\n\t * @returns {L.Marker}\n\t */\n\trefreshIconOptions: function (options, directlyRefreshClusters) {\n\t\tvar icon = this.options.icon;\n\n\t\tL.setOptions(icon, options);\n\n\t\tthis.setIcon(icon);\n\n\t\t// Shortcut to refresh the associated MCG clusters right away.\n\t\t// To be used when refreshing a single marker.\n\t\t// Otherwise, better use MCG.refreshClusters() once at the end with\n\t\t// the list of modified markers.\n\t\tif (directlyRefreshClusters && this.__parent) {\n\t\t\tthis.__parent._group.refreshClusters(this);\n\t\t}\n\n\t\treturn this;\n\t}\n});\n"], + "mappings": "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", + "names": ["MarkerClusterGroup", "options", "animate", "layer", "visibleLayer", "currentZoom", "layersArray", "skipLayerAddEvent", "fg", "npg", "chunked", "chunkInterval", "chunkProgress", "l", "offset", "originalArray", "m", "started", "process", "start", "elapsed", "markers", "otherMarker", "needsClustering", "i", "layersArray2", "l2", "marker", "bounds", "method", "context", "needsRemoving", "thisNeedsRemoving", "j", "layers", "id", "result", "anArray", "callback", "map", "showMarker", "vMarker", "obj", "z", "gridUnclustered", "minZoom", "e", "isPopupOpen", "from", "to", "dragStart", "removeFromDistanceGrid", "dontUpdateMap", "gridClusters", "cluster", "el", "oel", "type", "data", "propagate", "childCount", "c", "spiderfyOnMaxZoom", "showCoverageOnHover", "zoomToBoundsOnClick", "spiderfyOnEveryZoom", "bottomCluster", "newBounds", "maxZoom", "radius", "radiusFn", "zoom", "markerPoint", "closest", "parent", "newCluster", "lastParent", "fn", "mapZoom", "maxLat", "group", "output", "icon", "previousZoomLevel", "newZoomLevel", "startPos", "n", "me", "MarkerCluster", "a", "b", "storageArray", "ignoreDraggedMarker", "fitBoundsOptions", "childClusters", "boundsZoom", "newClusters", "new1", "isNotificationFromChild", "child", "latSum", "lngSum", "totalCount", "childLatLng", "center", "cm", "mapMinZoom", "zoomLevel", "nm", "k", "previousBounds", "exceptBounds", "boundsToApplyTo", "zoomLevelToStart", "zoomLevelToStop", "runAtEveryLevel", "runAtBottomLevel", "backup", "cellSize", "point", "x", "y", "grid", "row", "cell", "stamp", "len", "removed", "dist", "objectPoint", "closestDistSq", "coord", "p", "p2", "dx", "dy", "cpt", "bl", "vY", "vX", "baseLine", "latLngs", "maxD", "maxPt", "newPoints", "pt", "d", "convexHullBaseLines", "t", "minLat", "maxLng", "minLng", "maxLatPt", "minLatPt", "maxLngPt", "minLngPt", "minPt", "ch", "childMarkers", "points", "positions", "zoomDetails", "count", "centerPt", "circumference", "legLength", "angleStep", "res", "angle", "spiderfyDistanceMultiplier", "separation", "lengthFactor", "legOptions", "leg", "newPos", "thisLayerLatLng", "thisLayerPos", "svg", "finalLegOpacity", "legPath", "nonAnimatable", "stillThereChildCount", "directlyRefreshClusters"] +} diff --git a/Resources/Public/JavaScript/markerclusterer.LICENSE.txt b/Resources/Public/JavaScript/markerclusterer.LICENSE.txt new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/Resources/Public/JavaScript/markerclusterer.LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Resources/Public/JavaScript/markerclusterer.min.js b/Resources/Public/JavaScript/markerclusterer.min.js new file mode 100644 index 000000000..0daff431d --- /dev/null +++ b/Resources/Public/JavaScript/markerclusterer.min.js @@ -0,0 +1,2 @@ +var markerClusterer=function(t){"use strict";var r,e,n="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},o={};function i(){if(e)return r;e=1;var t=function(t){return t&&t.Math===Math&&t};return r=t("object"==typeof globalThis&&globalThis)||t("object"==typeof window&&window)||t("object"==typeof self&&self)||t("object"==typeof n&&n)||t("object"==typeof r&&r)||function(){return this}()||Function("return this")()}var s,a,u,c,f,l,h,p,m={};function d(){return a?s:(a=1,s=function(t){try{return!!t()}catch(t){return!0}})}function g(){if(c)return u;c=1;var t=d();return u=!t(function(){return 7!==Object.defineProperty({},1,{get:function(){return 7}})[1]})}function v(){if(l)return f;l=1;var t=d();return f=!t(function(){var t=function(){}.bind();return"function"!=typeof t||t.hasOwnProperty("prototype")})}function y(){if(p)return h;p=1;var t=v(),r=Function.prototype.call;return h=t?r.bind(r):function(){return r.apply(r,arguments)},h}var w,b,E,k,x,M,O,P,C,S,j,A,I,_,T,L,q,R,Z,z,D,F,N,U,B,W,$,V,G,H,K,Y,X,J,Q,tt,rt,et,nt,ot,it,st={};function at(){return E?b:(E=1,b=function(t,r){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:r}})}function ut(){if(x)return k;x=1;var t=v(),r=Function.prototype,e=r.call,n=t&&r.bind.bind(e,e);return k=t?n:function(t){return function(){return e.apply(t,arguments)}},k}function ct(){if(O)return M;O=1;var t=ut(),r=t({}.toString),e=t("".slice);return M=function(t){return e(r(t),8,-1)}}function ft(){return j?S:(j=1,S=function(t){return null==t})}function lt(){if(I)return A;I=1;var t=ft(),r=TypeError;return A=function(e){if(t(e))throw new r("Can't call method on "+e);return e}}function ht(){if(T)return _;T=1;var t=function(){if(C)return P;C=1;var t=ut(),r=d(),e=ct(),n=Object,o=t("".split);return P=r(function(){return!n("z").propertyIsEnumerable(0)})?function(t){return"String"===e(t)?o(t,""):n(t)}:n}(),r=lt();return _=function(e){return t(r(e))}}function pt(){if(q)return L;q=1;var t="object"==typeof document&&document.all;return L=void 0===t&&void 0!==t?function(r){return"function"==typeof r||r===t}:function(t){return"function"==typeof t}}function mt(){if(Z)return R;Z=1;var t=pt();return R=function(r){return"object"==typeof r?null!==r:t(r)}}function dt(){if(D)return z;D=1;var t=i(),r=pt();return z=function(e,n){return arguments.length<2?(o=t[e],r(o)?o:void 0):t[e]&&t[e][n];var o},z}function gt(){if(N)return F;N=1;var t=ut();return F=t({}.isPrototypeOf)}function vt(){if($)return W;$=1;var t,r,e=i(),n=function(){if(B)return U;B=1;var t=i().navigator,r=t&&t.userAgent;return U=r?String(r):""}(),o=e.process,s=e.Deno,a=o&&o.versions||s&&s.version,u=a&&a.v8;return u&&(r=(t=u.split("."))[0]>0&&t[0]<4?1:+(t[0]+t[1])),!r&&n&&(!(t=n.match(/Edge\/(\d+)/))||t[1]>=74)&&(t=n.match(/Chrome\/(\d+)/))&&(r=+t[1]),W=r}function yt(){if(G)return V;G=1;var t=vt(),r=d(),e=i().String;return V=!!Object.getOwnPropertySymbols&&!r(function(){var r=Symbol("symbol detection");return!e(r)||!(Object(r)instanceof Symbol)||!Symbol.sham&&t&&t<41})}function wt(){if(K)return H;K=1;var t=yt();return H=t&&!Symbol.sham&&"symbol"==typeof Symbol.iterator}function bt(){if(X)return Y;X=1;var t=dt(),r=pt(),e=gt(),n=wt(),o=Object;return Y=n?function(t){return"symbol"==typeof t}:function(n){var i=t("Symbol");return r(i)&&e(i.prototype,o(n))}}function Et(){if(Q)return J;Q=1;var t=String;return J=function(r){try{return t(r)}catch(t){return"Object"}}}function kt(){if(rt)return tt;rt=1;var t=pt(),r=Et(),e=TypeError;return tt=function(n){if(t(n))return n;throw new e(r(n)+" is not a function")}}function xt(){if(nt)return et;nt=1;var t=kt(),r=ft();return et=function(e,n){var o=e[n];return r(o)?void 0:t(o)}}function Mt(){if(it)return ot;it=1;var t=y(),r=pt(),e=mt(),n=TypeError;return ot=function(o,i){var s,a;if("string"===i&&r(s=o.toString)&&!e(a=t(s,o)))return a;if(r(s=o.valueOf)&&!e(a=t(s,o)))return a;if("string"!==i&&r(s=o.toString)&&!e(a=t(s,o)))return a;throw new n("Can't convert object to primitive value")}}var Ot,Pt,Ct,St,jt,At,It,_t,Tt,Lt,qt,Rt,Zt,zt,Dt,Ft,Nt,Ut,Bt,Wt,$t,Vt,Gt,Ht,Kt={exports:{}};function Yt(){return Pt?Ot:(Pt=1,Ot=!1)}function Xt(){if(St)return Ct;St=1;var t=i(),r=Object.defineProperty;return Ct=function(e,n){try{r(t,e,{value:n,configurable:!0,writable:!0})}catch(r){t[e]=n}return n}}function Jt(){if(jt)return Kt.exports;jt=1;var t=Yt(),r=i(),e=Xt(),n="__core-js_shared__",o=Kt.exports=r[n]||e(n,{});return(o.versions||(o.versions=[])).push({version:"3.44.0",mode:t?"pure":"global",copyright:"© 2014-2025 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.44.0/LICENSE",source:"https://github.com/zloirock/core-js"}),Kt.exports}function Qt(){if(It)return At;It=1;var t=Jt();return At=function(r,e){return t[r]||(t[r]=e||{})}}function tr(){if(Tt)return _t;Tt=1;var t=lt(),r=Object;return _t=function(e){return r(t(e))}}function rr(){if(qt)return Lt;qt=1;var t=ut(),r=tr(),e=t({}.hasOwnProperty);return Lt=Object.hasOwn||function(t,n){return e(r(t),n)}}function er(){if(Zt)return Rt;Zt=1;var t=ut(),r=0,e=Math.random(),n=t(1.1.toString);return Rt=function(t){return"Symbol("+(void 0===t?"":t)+")_"+n(++r+e,36)}}function nr(){if(Dt)return zt;Dt=1;var t=i(),r=Qt(),e=rr(),n=er(),o=yt(),s=wt(),a=t.Symbol,u=r("wks"),c=s?a.for||a:a&&a.withoutSetter||n;return zt=function(t){return e(u,t)||(u[t]=o&&e(a,t)?a[t]:c("Symbol."+t)),u[t]}}function or(){if(Nt)return Ft;Nt=1;var t=y(),r=mt(),e=bt(),n=xt(),o=Mt(),i=nr(),s=TypeError,a=i("toPrimitive");return Ft=function(i,u){if(!r(i)||e(i))return i;var c,f=n(i,a);if(f){if(void 0===u&&(u="default"),c=t(f,i,u),!r(c)||e(c))return c;throw new s("Can't convert object to primitive value")}return void 0===u&&(u="number"),o(i,u)}}function ir(){if(Bt)return Ut;Bt=1;var t=or(),r=bt();return Ut=function(e){var n=t(e,"string");return r(n)?n:n+""}}function sr(){if($t)return Wt;$t=1;var t=i(),r=mt(),e=t.document,n=r(e)&&r(e.createElement);return Wt=function(t){return n?e.createElement(t):{}}}function ar(){if(Gt)return Vt;Gt=1;var t=g(),r=d(),e=sr();return Vt=!t&&!r(function(){return 7!==Object.defineProperty(e("div"),"a",{get:function(){return 7}}).a})}function ur(){if(Ht)return m;Ht=1;var t=g(),r=y(),e=function(){if(w)return st;w=1;var t={}.propertyIsEnumerable,r=Object.getOwnPropertyDescriptor,e=r&&!t.call({1:2},1);return st.f=e?function(t){var e=r(this,t);return!!e&&e.enumerable}:t,st}(),n=at(),o=ht(),i=ir(),s=rr(),a=ar(),u=Object.getOwnPropertyDescriptor;return m.f=t?u:function(t,c){if(t=o(t),c=i(c),a)try{return u(t,c)}catch(t){}if(s(t,c))return n(!r(e.f,t,c),t[c])},m}var cr,fr,lr,hr,pr,mr,dr,gr={};function vr(){if(fr)return cr;fr=1;var t=g(),r=d();return cr=t&&r(function(){return 42!==Object.defineProperty(function(){},"prototype",{value:42,writable:!1}).prototype})}function yr(){if(hr)return lr;hr=1;var t=mt(),r=String,e=TypeError;return lr=function(n){if(t(n))return n;throw new e(r(n)+" is not an object")}}function wr(){if(pr)return gr;pr=1;var t=g(),r=ar(),e=vr(),n=yr(),o=ir(),i=TypeError,s=Object.defineProperty,a=Object.getOwnPropertyDescriptor,u="enumerable",c="configurable",f="writable";return gr.f=t?e?function(t,r,e){if(n(t),r=o(r),n(e),"function"==typeof t&&"prototype"===r&&"value"in e&&f in e&&!e[f]){var i=a(t,r);i&&i[f]&&(t[r]=e.value,e={configurable:c in e?e[c]:i[c],enumerable:u in e?e[u]:i[u],writable:!1})}return s(t,r,e)}:s:function(t,e,a){if(n(t),e=o(e),n(a),r)try{return s(t,e,a)}catch(t){}if("get"in a||"set"in a)throw new i("Accessors not supported");return"value"in a&&(t[e]=a.value),t},gr}function br(){if(dr)return mr;dr=1;var t=g(),r=wr(),e=at();return mr=t?function(t,n,o){return r.f(t,n,e(1,o))}:function(t,r,e){return t[r]=e,t}}var Er,kr,xr,Mr,Or,Pr,Cr,Sr,jr,Ar,Ir,_r,Tr,Lr,qr,Rr={exports:{}};function Zr(){if(Mr)return xr;Mr=1;var t=ut(),r=pt(),e=Jt(),n=t(Function.toString);return r(e.inspectSource)||(e.inspectSource=function(t){return n(t)}),xr=e.inspectSource}function zr(){if(Sr)return Cr;Sr=1;var t=Qt(),r=er(),e=t("keys");return Cr=function(t){return e[t]||(e[t]=r(t))}}function Dr(){return Ar?jr:(Ar=1,jr={})}function Fr(){if(_r)return Ir;_r=1;var t,r,e,n=function(){if(Pr)return Or;Pr=1;var t=i(),r=pt(),e=t.WeakMap;return Or=r(e)&&/native code/.test(String(e))}(),o=i(),s=mt(),a=br(),u=rr(),c=Jt(),f=zr(),l=Dr(),h="Object already initialized",p=o.TypeError,m=o.WeakMap;if(n||c.state){var d=c.state||(c.state=new m);d.get=d.get,d.has=d.has,d.set=d.set,t=function(t,r){if(d.has(t))throw new p(h);return r.facade=t,d.set(t,r),r},r=function(t){return d.get(t)||{}},e=function(t){return d.has(t)}}else{var g=f("state");l[g]=!0,t=function(t,r){if(u(t,g))throw new p(h);return r.facade=t,a(t,g,r),r},r=function(t){return u(t,g)?t[g]:{}},e=function(t){return u(t,g)}}return Ir={set:t,get:r,has:e,enforce:function(n){return e(n)?r(n):t(n,{})},getterFor:function(t){return function(e){var n;if(!s(e)||(n=r(e)).type!==t)throw new p("Incompatible receiver, "+t+" required");return n}}}}function Nr(){if(Tr)return Rr.exports;Tr=1;var t=ut(),r=d(),e=pt(),n=rr(),o=g(),i=function(){if(kr)return Er;kr=1;var t=g(),r=rr(),e=Function.prototype,n=t&&Object.getOwnPropertyDescriptor,o=r(e,"name"),i=o&&"something"===function(){}.name,s=o&&(!t||t&&n(e,"name").configurable);return Er={EXISTS:o,PROPER:i,CONFIGURABLE:s}}().CONFIGURABLE,s=Zr(),a=Fr(),u=a.enforce,c=a.get,f=String,l=Object.defineProperty,h=t("".slice),p=t("".replace),m=t([].join),v=o&&!r(function(){return 8!==l(function(){},"length",{value:8}).length}),y=String(String).split("String"),w=Rr.exports=function(t,r,e){"Symbol("===h(f(r),0,7)&&(r="["+p(f(r),/^Symbol\(([^)]*)\).*$/,"$1")+"]"),e&&e.getter&&(r="get "+r),e&&e.setter&&(r="set "+r),(!n(t,"name")||i&&t.name!==r)&&(o?l(t,"name",{value:r,configurable:!0}):t.name=r),v&&e&&n(e,"arity")&&t.length!==e.arity&&l(t,"length",{value:e.arity});try{e&&n(e,"constructor")&&e.constructor?o&&l(t,"prototype",{writable:!1}):t.prototype&&(t.prototype=void 0)}catch(t){}var s=u(t);return n(s,"source")||(s.source=m(y,"string"==typeof r?r:"")),t};return Function.prototype.toString=w(function(){return e(this)&&c(this).source||s(this)},"toString"),Rr.exports}function Ur(){if(qr)return Lr;qr=1;var t=pt(),r=wr(),e=Nr(),n=Xt();return Lr=function(o,i,s,a){a||(a={});var u=a.enumerable,c=void 0!==a.name?a.name:i;if(t(s)&&e(s,c,a),a.global)u?o[i]=s:n(i,s);else{try{a.unsafe?o[i]&&(u=!0):delete o[i]}catch(t){}u?o[i]=s:r.f(o,i,{value:s,enumerable:!1,configurable:!a.nonConfigurable,writable:!a.nonWritable})}return o}}var Br,Wr,$r,Vr,Gr,Hr,Kr,Yr,Xr,Jr,Qr,te,re,ee,ne,oe,ie,se={};function ae(){if(Vr)return $r;Vr=1;var t=function(){if(Wr)return Br;Wr=1;var t=Math.ceil,r=Math.floor;return Br=Math.trunc||function(e){var n=+e;return(n>0?r:t)(n)}}();return $r=function(r){var e=+r;return e!=e||0===e?0:t(e)}}function ue(){if(Hr)return Gr;Hr=1;var t=ae(),r=Math.max,e=Math.min;return Gr=function(n,o){var i=t(n);return i<0?r(i+o,0):e(i,o)}}function ce(){if(Yr)return Kr;Yr=1;var t=ae(),r=Math.min;return Kr=function(e){var n=t(e);return n>0?r(n,9007199254740991):0}}function fe(){if(Jr)return Xr;Jr=1;var t=ce();return Xr=function(r){return t(r.length)}}function le(){if(ee)return re;ee=1;var t=ut(),r=rr(),e=ht(),n=function(){if(te)return Qr;te=1;var t=ht(),r=ue(),e=fe(),n=function(n){return function(o,i,s){var a=t(o),u=e(a);if(0===u)return!n&&-1;var c,f=r(s,u);if(n&&i!=i){for(;u>f;)if((c=a[f++])!=c)return!0}else for(;u>f;f++)if((n||f in a)&&a[f]===i)return n||f||0;return!n&&-1}};return Qr={includes:n(!0),indexOf:n(!1)}}().indexOf,o=Dr(),i=t([].push);return re=function(t,s){var a,u=e(t),c=0,f=[];for(a in u)!r(o,a)&&r(u,a)&&i(f,a);for(;s.length>c;)r(u,a=s[c++])&&(~n(f,a)||i(f,a));return f}}function he(){return oe?ne:(oe=1,ne=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"])}var pe,me,de,ge,ve,ye,we,be,Ee,ke,xe,Me,Oe,Pe,Ce,Se,je,Ae,Ie,_e={};function Te(){if(de)return me;de=1;var t=dt(),r=ut(),e=function(){if(ie)return se;ie=1;var t=le(),r=he().concat("length","prototype");return se.f=Object.getOwnPropertyNames||function(e){return t(e,r)},se}(),n=(pe||(pe=1,_e.f=Object.getOwnPropertySymbols),_e),o=yr(),i=r([].concat);return me=t("Reflect","ownKeys")||function(t){var r=e.f(o(t)),s=n.f;return s?i(r,s(t)):r},me}function Le(){if(ve)return ge;ve=1;var t=rr(),r=Te(),e=ur(),n=wr();return ge=function(o,i,s){for(var a=r(i),u=n.f,c=e.f,f=0;ff;)e.f(t,s=u[f++],a[s]);return t},Xe}(),n=he(),o=Dr(),i=Qe(),s=sr(),a=zr(),u="prototype",c="script",f=a("IE_PROTO"),l=function(){},h=function(t){return"<"+c+">"+t+""},p=function(t){t.write(h("")),t.close();var r=t.parentWindow.Object;return t=null,r},m=function(){try{t=new ActiveXObject("htmlfile")}catch(t){}var r,e,o;m="undefined"!=typeof document?document.domain&&t?p(t):(e=s("iframe"),o="java"+c+":",e.style.display="none",i.appendChild(e),e.src=String(o),(r=e.contentWindow.document).open(),r.write(h("document.F=Object")),r.close(),r.F):p(t);for(var a=n.length;a--;)delete m[u][n[a]];return m()};return o[f]=!0,$e=Object.create||function(t,n){var o;return null!==t?(l[u]=r(t),o=new l,l[u]=null,o[f]=t):o=m(),void 0===n?o:e.f(o,n)}}function rn(){if(He)return Ge;He=1;var t,r,e,n=d(),o=pt(),i=mt(),s=tn(),a=Ze(),u=Ur(),c=nr(),f=Yt(),l=c("iterator"),h=!1;return[].keys&&("next"in(e=[].keys())?(r=a(a(e)))!==Object.prototype&&(t=r):h=!0),!i(t)||n(function(){var r={};return t[l].call(r)!==r})?t={}:f&&(t=s(t)),o(t[l])||u(t,l,function(){return this}),Ge={IteratorPrototype:t,BUGGY_SAFARI_ITERATORS:h}}Ye||(Ye=1,function(){if(Ke)return o;Ke=1;var t=qe(),r=i(),e=Re(),n=yr(),s=pt(),a=Ze(),u=ze(),c=De(),f=d(),l=rr(),h=nr(),p=rn().IteratorPrototype,m=g(),v=Yt(),y="constructor",w="Iterator",b=h("toStringTag"),E=TypeError,k=r[w],x=v||!s(k)||k.prototype!==p||!f(function(){k({})}),M=function(){if(e(this,p),a(this)===p)throw new E("Abstract class Iterator not directly constructable")},O=function(t,r){m?u(p,t,{configurable:!0,get:function(){return r},set:function(r){if(n(this),this===p)throw new E("You can't redefine this property");l(this,t)?this[t]=r:c(this,t,r)}}):p[t]=r};l(p,b)||O(b,w),!x&&l(p,y)&&p[y]!==Object||O(y,M),M.prototype=p,t({global:!0,constructor:!0,forced:x},{Iterator:M})}());var en,nn,on,sn,an,un,cn,fn,ln,hn,pn,mn,dn,gn,vn,yn,wn,bn,En,kn,xn={};function Mn(){return nn?en:(nn=1,en=function(t){return{iterator:t,next:t.next,done:!1}})}function On(){if(sn)return on;sn=1;var t=Ur();return on=function(r,e,n){for(var o in e)t(r,o,e[o],n);return r}}function Pn(){return un?an:(un=1,an=function(t,r){return{value:t,done:r}})}function Cn(){if(fn)return cn;fn=1;var t=y(),r=yr(),e=xt();return cn=function(n,o,i){var s,a;r(n);try{if(!(s=e(n,"return"))){if("throw"===o)throw i;return i}s=t(s,n)}catch(t){a=!0,s=t}if("throw"===o)throw i;if(a)throw s;return r(s),i}}function Sn(){if(hn)return ln;hn=1;var t=Cn();return ln=function(r,e,n){for(var o=r.length-1;o>=0;o--)if(void 0!==r[o])try{n=t(r[o].iterator,e,n)}catch(t){e="throw",n=t}if("throw"===e)throw n;return n}}function jn(){if(mn)return pn;mn=1;var t=y(),r=tn(),e=br(),n=On(),o=nr(),i=Fr(),s=xt(),a=rn().IteratorPrototype,u=Pn(),c=Cn(),f=Sn(),l=o("toStringTag"),h="IteratorHelper",p="WrapForValidIterator",m="normal",d="throw",g=i.set,v=function(e){var o=i.getterFor(e?p:h);return n(r(a),{next:function(){var t=o(this);if(e)return t.nextHandler();if(t.done)return u(void 0,!0);try{var r=t.nextHandler();return t.returnHandlerResult?r:u(r,t.done)}catch(r){throw t.done=!0,r}},return:function(){var r=o(this),n=r.iterator;if(r.done=!0,e){var i=s(n,"return");return i?t(i,n):u(void 0,!0)}if(r.inner)try{c(r.inner.iterator,m)}catch(t){return c(n,d,t)}if(r.openIters)try{f(r.openIters,m)}catch(t){return c(n,d,t)}return n&&c(n,m),u(void 0,!0)}})},w=v(!0),b=v(!1);return e(b,l,"Iterator Helper"),pn=function(t,r,e){var n=function(n,o){o?(o.iterator=n.iterator,o.next=n.next):o=n,o.type=r?p:h,o.returnHandlerResult=!!e,o.nextHandler=t,o.counter=0,o.done=!1,g(this,o)};return n.prototype=r?w:b,n}}function An(){if(gn)return dn;gn=1;var t=yr(),r=Cn();return dn=function(e,n,o,i){try{return i?n(t(o)[0],o[1]):n(o)}catch(t){r(e,"throw",t)}}}function In(){return yn?vn:(yn=1,vn=function(t,r){var e="function"==typeof Iterator&&Iterator.prototype[t];if(e)try{e.call({next:null},r).next()}catch(t){return!0}})}function _n(){if(bn)return wn;bn=1;var t=i();return wn=function(r,e){var n=t.Iterator,o=n&&n.prototype,i=o&&o[r],s=!1;if(i)try{i.call({next:function(){return{done:!0}},return:function(){s=!0}},-1)}catch(t){t instanceof e||(s=!1)}if(!s)return i}}function Tn(t,r){var e={};for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&r.indexOf(n)<0&&(e[n]=t[n]);if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(n=Object.getOwnPropertySymbols(t);oZn.getVisible(t)).length}push(t){this.markers.push(t)}delete(){this.marker&&(Zn.setMap(this.marker,null),this.marker=void 0),this.markers.length=0}}function Dn(t){if(null==t)throw Error(arguments.length>1&&void 0!==arguments[1]?arguments[1]:"assertion failed")}const Fn=(t,r,e,n)=>{const o=t.getBounds();Dn(o);const i=Nn(o,r,n);return e.filter(t=>i.contains(Zn.getPosition(t)))},Nn=(t,r,e)=>{const{northEast:n,southWest:o}=Wn(t,r),i=$n({northEast:n,southWest:o},e);return Vn(i,r)},Un=(t,r,e)=>{const n=Nn(t,r,e),o=n.getNorthEast(),i=n.getSouthWest();return[i.lng(),i.lat(),o.lng(),o.lat()]},Bn=(t,r)=>{const e=(r.lat-t.lat)*Math.PI/180,n=(r.lng-t.lng)*Math.PI/180,o=Math.sin(e/2),i=Math.sin(n/2),s=o*o+Math.cos(t.lat*Math.PI/180)*Math.cos(r.lat*Math.PI/180)*i*i;return 6371*(2*Math.atan2(Math.sqrt(s),Math.sqrt(1-s)))},Wn=(t,r)=>{const e=r.fromLatLngToDivPixel(t.getNorthEast()),n=r.fromLatLngToDivPixel(t.getSouthWest());return Dn(e),Dn(n),{northEast:e,southWest:n}},$n=(t,r)=>{let{northEast:e,southWest:n}=t;return e.x+=r,e.y-=r,n.x-=r,n.y+=r,{northEast:e,southWest:n}},Vn=(t,r)=>{let{northEast:e,southWest:n}=t;const o=r.fromDivPixelToLatLng(n),i=r.fromDivPixelToLatLng(e);return new google.maps.LatLngBounds(o,i)};class Gn{constructor(t){let{maxZoom:r=16}=t;this.maxZoom=r}noop(t){let{markers:r}=t;return Kn(r)}}class Hn extends Gn{constructor(t){var{viewportPadding:r=60}=t;super(Tn(t,["viewportPadding"])),this.viewportPadding=60,this.viewportPadding=r}calculate(t){let{markers:r,map:e,mapCanvasProjection:n}=t;const o=e.getZoom();return Dn(o),o>=this.maxZoom?{clusters:this.noop({markers:r}),changed:!1}:{clusters:this.cluster({markers:Fn(e,n,r,this.viewportPadding),map:e,mapCanvasProjection:n})}}}const Kn=t=>t.map(t=>new zn({position:Zn.getPosition(t),markers:[t]}));var Yn,Xn,Jn,Qn,to,ro,eo,no,oo,io,so,ao,uo,co,fo,lo,ho,po,mo,go,vo={};function yo(){if(Qn)return Jn;Qn=1;var t=function(){if(Xn)return Yn;Xn=1;var t=ct(),r=ut();return Yn=function(e){if("Function"===t(e))return r(e)}}(),r=kt(),e=v(),n=t(t.bind);return Jn=function(t,o){return r(t),void 0===o?t:e?n(t,o):function(){return t.apply(o,arguments)}},Jn}function wo(){return ro?to:(ro=1,to={})}function bo(){if(no)return eo;no=1;var t=nr(),r=wo(),e=t("iterator"),n=Array.prototype;return eo=function(t){return void 0!==t&&(r.Array===t||n[e]===t)}}function Eo(){if(ao)return so;ao=1;var t=function(){if(io)return oo;io=1;var t={};return t[nr()("toStringTag")]="z",oo="[object z]"===String(t)}(),r=pt(),e=ct(),n=nr()("toStringTag"),o=Object,i="Arguments"===e(function(){return arguments}());return so=t?e:function(t){var s,a,u;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(a=function(t,r){try{return t[r]}catch(t){}}(s=o(t),n))?a:i?e(s):"Object"===(u=e(s))&&r(s.callee)?"Arguments":u}}function ko(){if(co)return uo;co=1;var t=Eo(),r=xt(),e=ft(),n=wo(),o=nr()("iterator");return uo=function(i){if(!e(i))return r(i,o)||r(i,"@@iterator")||n[t(i)]}}function xo(){if(lo)return fo;lo=1;var t=y(),r=kt(),e=yr(),n=Et(),o=ko(),i=TypeError;return fo=function(s,a){var u=arguments.length<2?o(s):a;if(r(u))return e(t(u,s));throw new i(n(s)+" is not iterable")},fo}function Mo(){if(po)return ho;po=1;var t=yo(),r=y(),e=yr(),n=Et(),o=bo(),i=fe(),s=gt(),a=xo(),u=ko(),c=Cn(),f=TypeError,l=function(t,r){this.stopped=t,this.result=r},h=l.prototype;return ho=function(p,m,d){var g,v,y,w,b,E,k,x=d&&d.that,M=!(!d||!d.AS_ENTRIES),O=!(!d||!d.IS_RECORD),P=!(!d||!d.IS_ITERATOR),C=!(!d||!d.INTERRUPTED),S=t(m,x),j=function(t){return g&&c(g,"normal"),new l(!0,t)},A=function(t){return M?(e(t),C?S(t[0],t[1],j):S(t[0],t[1])):C?S(t,j):S(t)};if(O)g=p.iterator;else if(P)g=p;else{if(!(v=u(p)))throw new f(n(p)+" is not iterable");if(o(v)){for(y=0,w=i(p);w>y;y++)if((b=A(p[y]))&&s(h,b))return b;return new l(!1)}g=a(p,v)}for(E=O?p.next:g.next;!(k=r(E,g)).done;){try{b=A(k.value)}catch(t){c(g,"throw",t)}if("object"==typeof b&&b&&s(h,b))return b}return new l(!1)}}go||(go=1,function(){if(mo)return vo;mo=1;var t=qe(),r=y(),e=Mo(),n=kt(),o=yr(),i=Mn(),s=Cn(),a=_n()("forEach",TypeError);t({target:"Iterator",proto:!0,real:!0,forced:a},{forEach:function(t){o(this);try{n(t)}catch(t){s(this,"throw",t)}if(a)return r(a,this,t);var u=i(this),c=0;e(u,function(r){t(r,c++)},{IS_RECORD:!0})}})}());var Oo=Object.getOwnPropertyNames,Po=Object.getOwnPropertySymbols,Co=Object.prototype.hasOwnProperty;function So(t,r){return function(e,n,o){return t(e,n,o)&&r(e,n,o)}}function jo(t){return function(r,e,n){if(!r||!e||"object"!=typeof r||"object"!=typeof e)return t(r,e,n);var o=n.cache,i=o.get(r),s=o.get(e);if(i&&s)return i===e&&s===r;o.set(r,e),o.set(e,r);var a=t(r,e,n);return o.delete(r),o.delete(e),a}}function Ao(t){return Oo(t).concat(Po(t))}var Io=Object.hasOwn||function(t,r){return Co.call(t,r)};function _o(t,r){return t===r||!t&&!r&&t!=t&&r!=r}var To=Object.getOwnPropertyDescriptor,Lo=Object.keys;function qo(t,r,e){var n=t.length;if(r.length!==n)return!1;for(;n-- >0;)if(!e.equals(t[n],r[n],n,n,t,r,e))return!1;return!0}function Ro(t,r){return _o(t.getTime(),r.getTime())}function Zo(t,r){return t.name===r.name&&t.message===r.message&&t.cause===r.cause&&t.stack===r.stack}function zo(t,r){return t===r}function Do(t,r,e){var n=t.size;if(n!==r.size)return!1;if(!n)return!0;for(var o,i,s=new Array(n),a=t.entries(),u=0;(o=a.next())&&!o.done;){for(var c=r.entries(),f=!1,l=0;(i=c.next())&&!i.done;)if(s[l])l++;else{var h=o.value,p=i.value;if(e.equals(h[0],p[0],u,l,t,r,e)&&e.equals(h[1],p[1],h[0],p[0],t,r,e)){f=s[l]=!0;break}l++}if(!f)return!1;u++}return!0}var Fo=_o;function No(t,r,e){var n=Lo(t),o=n.length;if(Lo(r).length!==o)return!1;for(;o-- >0;)if(!Ho(t,r,e,n[o]))return!1;return!0}function Uo(t,r,e){var n,o,i,s=Ao(t),a=s.length;if(Ao(r).length!==a)return!1;for(;a-- >0;){if(!Ho(t,r,e,n=s[a]))return!1;if(o=To(t,n),i=To(r,n),(o||i)&&(!o||!i||o.configurable!==i.configurable||o.enumerable!==i.enumerable||o.writable!==i.writable))return!1}return!0}function Bo(t,r){return _o(t.valueOf(),r.valueOf())}function Wo(t,r){return t.source===r.source&&t.flags===r.flags}function $o(t,r,e){var n=t.size;if(n!==r.size)return!1;if(!n)return!0;for(var o,i,s=new Array(n),a=t.values();(o=a.next())&&!o.done;){for(var u=r.values(),c=!1,f=0;(i=u.next())&&!i.done;){if(!s[f]&&e.equals(o.value,i.value,o.value,i.value,t,r,e)){c=s[f]=!0;break}f++}if(!c)return!1}return!0}function Vo(t,r){var e=t.length;if(r.length!==e)return!1;for(;e-- >0;)if(t[e]!==r[e])return!1;return!0}function Go(t,r){return t.hostname===r.hostname&&t.pathname===r.pathname&&t.protocol===r.protocol&&t.port===r.port&&t.hash===r.hash&&t.username===r.username&&t.password===r.password}function Ho(t,r,e,n){return!("_owner"!==n&&"__o"!==n&&"__v"!==n||!t.$$typeof&&!r.$$typeof)||Io(r,n)&&e.equals(t[n],r[n],n,n,t,r,e)}var Ko=Array.isArray,Yo="function"==typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView:null,Xo=Object.assign,Jo=Object.prototype.toString.call.bind(Object.prototype.toString);var Qo=ti();function ti(t){void 0===t&&(t={});var r,e=t.circular,n=void 0!==e&&e,o=t.createInternalComparator,i=t.createState,s=t.strict,a=void 0!==s&&s,u=function(t){var r=t.circular,e=t.createCustomConfig,n=t.strict,o={areArraysEqual:n?Uo:qo,areDatesEqual:Ro,areErrorsEqual:Zo,areFunctionsEqual:zo,areMapsEqual:n?So(Do,Uo):Do,areNumbersEqual:Fo,areObjectsEqual:n?Uo:No,arePrimitiveWrappersEqual:Bo,areRegExpsEqual:Wo,areSetsEqual:n?So($o,Uo):$o,areTypedArraysEqual:n?Uo:Vo,areUrlsEqual:Go};if(e&&(o=Xo({},o,e(o))),r){var i=jo(o.areArraysEqual),s=jo(o.areMapsEqual),a=jo(o.areObjectsEqual),u=jo(o.areSetsEqual);o=Xo({},o,{areArraysEqual:i,areMapsEqual:s,areObjectsEqual:a,areSetsEqual:u})}return o}(t),c=function(t){var r=t.areArraysEqual,e=t.areDatesEqual,n=t.areErrorsEqual,o=t.areFunctionsEqual,i=t.areMapsEqual,s=t.areNumbersEqual,a=t.areObjectsEqual,u=t.arePrimitiveWrappersEqual,c=t.areRegExpsEqual,f=t.areSetsEqual,l=t.areTypedArraysEqual,h=t.areUrlsEqual;return function(t,p,m){if(t===p)return!0;if(null==t||null==p)return!1;var d=typeof t;if(d!==typeof p)return!1;if("object"!==d)return"number"===d?s(t,p,m):"function"===d&&o(t,p,m);var g=t.constructor;if(g!==p.constructor)return!1;if(g===Object)return a(t,p,m);if(Ko(t))return r(t,p,m);if(null!=Yo&&Yo(t))return l(t,p,m);if(g===Date)return e(t,p,m);if(g===RegExp)return c(t,p,m);if(g===Map)return i(t,p,m);if(g===Set)return f(t,p,m);var v=Jo(t);return"[object Date]"===v?e(t,p,m):"[object RegExp]"===v?c(t,p,m):"[object Map]"===v?i(t,p,m):"[object Set]"===v?f(t,p,m):"[object Object]"===v?"function"!=typeof t.then&&"function"!=typeof p.then&&a(t,p,m):"[object URL]"===v?h(t,p,m):"[object Error]"===v?n(t,p,m):"[object Arguments]"===v?a(t,p,m):("[object Boolean]"===v||"[object Number]"===v||"[object String]"===v)&&u(t,p,m)}}(u);return function(t){var r=t.circular,e=t.comparator,n=t.createState,o=t.equals,i=t.strict;if(n)return function(t,s){var a=n(),u=a.cache,c=void 0===u?r?new WeakMap:void 0:u,f=a.meta;return e(t,s,{cache:c,equals:o,meta:f,strict:i})};if(r)return function(t,r){return e(t,r,{cache:new WeakMap,equals:o,meta:void 0,strict:i})};var s={cache:void 0,equals:o,meta:void 0,strict:i};return function(t,r){return e(t,r,s)}}({circular:n,comparator:c,createState:i,equals:o?o(c):(r=c,function(t,e,n,o,i,s,a){return r(t,e,a)}),strict:a})}ti({strict:!0}),ti({circular:!0}),ti({circular:!0,strict:!0}),ti({createInternalComparator:function(){return _o}}),ti({strict:!0,createInternalComparator:function(){return _o}}),ti({circular:!0,createInternalComparator:function(){return _o}}),ti({circular:!0,createInternalComparator:function(){return _o},strict:!0});const ri=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];class ei{static from(t){if(!(t instanceof ArrayBuffer))throw new Error("Data must be an instance of ArrayBuffer.");const[r,e]=new Uint8Array(t,0,2);if(219!==r)throw new Error("Data does not appear to be in a KDBush format.");const n=e>>4;if(1!==n)throw new Error(`Got v${n} data when expected v1.`);const o=ri[15&e];if(!o)throw new Error("Unrecognized array type.");const[i]=new Uint16Array(t,2,1),[s]=new Uint32Array(t,4,1);return new ei(s,i,o,t)}constructor(t,r=64,e=Float64Array,n){if(isNaN(t)||t<0)throw new Error(`Unpexpected numItems value: ${t}.`);this.numItems=+t,this.nodeSize=Math.min(Math.max(+r,2),65535),this.ArrayType=e,this.IndexArrayType=t<65536?Uint16Array:Uint32Array;const o=ri.indexOf(this.ArrayType),i=2*t*this.ArrayType.BYTES_PER_ELEMENT,s=t*this.IndexArrayType.BYTES_PER_ELEMENT,a=(8-s%8)%8;if(o<0)throw new Error(`Unexpected typed array class: ${e}.`);n&&n instanceof ArrayBuffer?(this.data=n,this.ids=new this.IndexArrayType(this.data,8,t),this.coords=new this.ArrayType(this.data,8+s+a,2*t),this._pos=2*t,this._finished=!0):(this.data=new ArrayBuffer(8+i+s+a),this.ids=new this.IndexArrayType(this.data,8,t),this.coords=new this.ArrayType(this.data,8+s+a,2*t),this._pos=0,this._finished=!1,new Uint8Array(this.data,0,2).set([219,16+o]),new Uint16Array(this.data,2,1)[0]=r,new Uint32Array(this.data,4,1)[0]=t)}add(t,r){const e=this._pos>>1;return this.ids[e]=e,this.coords[this._pos++]=t,this.coords[this._pos++]=r,e}finish(){const t=this._pos>>1;if(t!==this.numItems)throw new Error(`Added ${t} items when expected ${this.numItems}.`);return ni(this.ids,this.coords,this.nodeSize,0,this.numItems-1,0),this._finished=!0,this}range(t,r,e,n){if(!this._finished)throw new Error("Data not yet indexed - call index.finish().");const{ids:o,coords:i,nodeSize:s}=this,a=[0,o.length-1,0],u=[];for(;a.length;){const c=a.pop()||0,f=a.pop()||0,l=a.pop()||0;if(f-l<=s){for(let s=l;s<=f;s++){const a=i[2*s],c=i[2*s+1];a>=t&&a<=e&&c>=r&&c<=n&&u.push(o[s])}continue}const h=l+f>>1,p=i[2*h],m=i[2*h+1];p>=t&&p<=e&&m>=r&&m<=n&&u.push(o[h]),(0===c?t<=p:r<=m)&&(a.push(l),a.push(h-1),a.push(1-c)),(0===c?e>=p:n>=m)&&(a.push(h+1),a.push(f),a.push(1-c))}return u}within(t,r,e){if(!this._finished)throw new Error("Data not yet indexed - call index.finish().");const{ids:n,coords:o,nodeSize:i}=this,s=[0,n.length-1,0],a=[],u=e*e;for(;s.length;){const c=s.pop()||0,f=s.pop()||0,l=s.pop()||0;if(f-l<=i){for(let e=l;e<=f;e++)ai(o[2*e],o[2*e+1],t,r)<=u&&a.push(n[e]);continue}const h=l+f>>1,p=o[2*h],m=o[2*h+1];ai(p,m,t,r)<=u&&a.push(n[h]),(0===c?t-e<=p:r-e<=m)&&(s.push(l),s.push(h-1),s.push(1-c)),(0===c?t+e>=p:r+e>=m)&&(s.push(h+1),s.push(f),s.push(1-c))}return a}}function ni(t,r,e,n,o,i){if(o-n<=e)return;const s=n+o>>1;oi(t,r,s,n,o,i),ni(t,r,e,n,s-1,1-i),ni(t,r,e,s+1,o,1-i)}function oi(t,r,e,n,o,i){for(;o>n;){if(o-n>600){const s=o-n+1,a=e-n+1,u=Math.log(s),c=.5*Math.exp(2*u/3),f=.5*Math.sqrt(u*c*(s-c)/s)*(a-s/2<0?-1:1);oi(t,r,e,Math.max(n,Math.floor(e-a*c/s+f)),Math.min(o,Math.floor(e+(s-a)*c/s+f)),i)}const s=r[2*e+i];let a=n,u=o;for(ii(t,r,n,e),r[2*o+i]>s&&ii(t,r,n,o);as;)u--}r[2*n+i]===s?ii(t,r,n,u):(u++,ii(t,r,u,o)),u<=e&&(n=u+1),e<=u&&(o=u-1)}}function ii(t,r,e,n){si(t,e,n),si(r,2*e,2*n),si(r,2*e+1,2*n+1)}function si(t,r,e){const n=t[r];t[r]=t[e],t[e]=n}function ai(t,r,e,n){const o=t-e,i=r-n;return o*o+i*i}const ui={minZoom:0,maxZoom:16,minPoints:2,radius:40,extent:512,nodeSize:64,log:!1,generateId:!1,reduce:null,map:t=>t},ci=Math.fround||(fi=new Float32Array(1),t=>(fi[0]=+t,fi[0]));var fi;class li{constructor(t){this.options=Object.assign(Object.create(ui),t),this.trees=new Array(this.options.maxZoom+1),this.stride=this.options.reduce?7:6,this.clusterProps=[]}load(t){const{log:r,minZoom:e,maxZoom:n}=this.options;r&&console.time("total time");const o=`prepare ${t.length} points`;r&&console.time(o),this.points=t;const i=[];for(let r=0;r=e;t--){const e=+Date.now();s=this.trees[t]=this._createTree(this._cluster(s,t)),r&&console.log("z%d: %d clusters in %dms",t,s.numItems,+Date.now()-e)}return r&&console.timeEnd("total time"),this}getClusters(t,r){let e=((t[0]+180)%360+360)%360-180;const n=Math.max(-90,Math.min(90,t[1]));let o=180===t[2]?180:((t[2]+180)%360+360)%360-180;const i=Math.max(-90,Math.min(90,t[3]));if(t[2]-t[0]>=360)e=-180,o=180;else if(e>o){const t=this.getClusters([e,n,180,i],r),s=this.getClusters([-180,n,o,i],r);return t.concat(s)}const s=this.trees[this._limitZoom(r)],a=s.range(mi(e),di(i),mi(o),di(n)),u=s.data,c=[];for(const t of a){const r=this.stride*t;c.push(u[r+5]>1?hi(u,r,this.clusterProps):this.points[u[r+3]])}return c}getChildren(t){const r=this._getOriginId(t),e=this._getOriginZoom(t),n="No cluster with the specified id.",o=this.trees[e];if(!o)throw new Error(n);const i=o.data;if(r*this.stride>=i.length)throw new Error(n);const s=this.options.radius/(this.options.extent*Math.pow(2,e-1)),a=i[r*this.stride],u=i[r*this.stride+1],c=o.within(a,u,s),f=[];for(const r of c){const e=r*this.stride;i[e+4]===t&&f.push(i[e+5]>1?hi(i,e,this.clusterProps):this.points[i[e+3]])}if(0===f.length)throw new Error(n);return f}getLeaves(t,r,e){r=r||10,e=e||0;const n=[];return this._appendLeaves(n,t,r,e,0),n}getTile(t,r,e){const n=this.trees[this._limitZoom(t)],o=Math.pow(2,t),{extent:i,radius:s}=this.options,a=s/i,u=(e-a)/o,c=(e+1+a)/o,f={features:[]};return this._addTileFeatures(n.range((r-a)/o,u,(r+1+a)/o,c),n.data,r,e,o,f),0===r&&this._addTileFeatures(n.range(1-a/o,u,1,c),n.data,o,e,o,f),r===o-1&&this._addTileFeatures(n.range(0,u,a/o,c),n.data,-1,e,o,f),f.features.length?f:null}getClusterExpansionZoom(t){let r=this._getOriginZoom(t)-1;for(;r<=this.options.maxZoom;){const e=this.getChildren(t);if(r++,1!==e.length)break;t=e[0].properties.cluster_id}return r}_appendLeaves(t,r,e,n,o){const i=this.getChildren(r);for(const r of i){const i=r.properties;if(i&&i.cluster?o+i.point_count<=n?o+=i.point_count:o=this._appendLeaves(t,i.cluster_id,e,n,o):o1;let u,c,f;if(a)u=pi(r,t,this.clusterProps),c=r[t],f=r[t+1];else{const e=this.points[r[t+3]];u=e.properties;const[n,o]=e.geometry.coordinates;c=mi(n),f=di(o)}const l={type:1,geometry:[[Math.round(this.options.extent*(c*o-e)),Math.round(this.options.extent*(f*o-n))]],tags:u};let h;h=a||this.options.generateId?r[t+3]:this.points[r[t+3]].id,void 0!==h&&(l.id=h),i.features.push(l)}}_limitZoom(t){return Math.max(this.options.minZoom,Math.min(Math.floor(+t),this.options.maxZoom+1))}_cluster(t,r){const{radius:e,extent:n,reduce:o,minPoints:i}=this.options,s=e/(n*Math.pow(2,r)),a=t.data,u=[],c=this.stride;for(let e=0;er&&(p+=a[e+5])}if(p>h&&p>=i){let t,i=n*h,s=f*h,m=-1;const d=(e/c<<5)+(r+1)+this.points.length;for(const n of l){const u=n*c;if(a[u+2]<=r)continue;a[u+2]=r;const f=a[u+5];i+=a[u]*f,s+=a[u+1]*f,a[u+4]=d,o&&(t||(t=this._map(a,e,!0),m=this.clusterProps.length,this.clusterProps.push(t)),o(t,this._map(a,u)))}a[e+4]=d,u.push(i/p,s/p,1/0,d,-1,p),o&&u.push(m)}else{for(let t=0;t1)for(const t of l){const e=t*c;if(!(a[e+2]<=r)){a[e+2]=r;for(let t=0;t>5}_getOriginZoom(t){return(t-this.points.length)%32}_map(t,r,e){if(t[r+5]>1){const n=this.clusterProps[t[r+6]];return e?Object.assign({},n):n}const n=this.points[t[r+3]].properties,o=this.options.map(n);return e&&o===n?Object.assign({},o):o}}function hi(t,r,e){return{type:"Feature",id:t[r+3],properties:pi(t,r,e),geometry:{type:"Point",coordinates:[(n=t[r],360*(n-.5)),gi(t[r+1])]}};var n}function pi(t,r,e){const n=t[r+5],o=n>=1e4?`${Math.round(n/1e3)}k`:n>=1e3?Math.round(n/100)/10+"k":n,i=t[r+6],s=-1===i?{}:Object.assign({},e[i]);return Object.assign(s,{cluster:!0,cluster_id:t[r+3],point_count:n,point_count_abbreviated:o})}function mi(t){return t/360+.5}function di(t){const r=Math.sin(t*Math.PI/180),e=.5-.25*Math.log((1+r)/(1-r))/Math.PI;return e<0?0:e>1?1:e}function gi(t){const r=(180-360*t)*Math.PI/180;return 360*Math.atan(Math.exp(r))/Math.PI-90}class vi extends Gn{constructor(t){var{maxZoom:r,radius:e=60}=t,n=Tn(t,["maxZoom","radius"]);super({maxZoom:r}),this.markers=[],this.clusters=[],this.state={zoom:-1},this.superCluster=new li(Object.assign({maxZoom:this.maxZoom,radius:e},n))}calculate(t){let r=!1,e=t.map.getZoom();Dn(e),e=Math.round(e);const n={zoom:e};if(!Qo(t.markers,this.markers)){r=!0,this.markers=[...t.markers];const e=this.markers.map(t=>{const r=Zn.getPosition(t);return{type:"Feature",geometry:{type:"Point",coordinates:[r.lng(),r.lat()]},properties:{marker:t}}});this.superCluster.load(e)}return r||(this.state.zoom<=this.maxZoom||n.zoom<=this.maxZoom)&&(r=!Qo(this.state,n)),this.state=n,0===t.markers.length?(this.clusters=[],{clusters:this.clusters,changed:r}):(r&&(this.clusters=this.cluster(t)),{clusters:this.clusters,changed:r})}cluster(t){let{map:r}=t;const e=r.getZoom();return Dn(e),this.superCluster.getClusters([-180,-90,180,90],Math.round(e)).map(t=>this.transformCluster(t))}transformCluster(t){let{geometry:{coordinates:[r,e]},properties:n}=t;if(n.cluster)return new zn({markers:this.superCluster.getLeaves(n.cluster_id,1/0).map(t=>t.properties.marker),position:{lat:e,lng:r}});const o=n.marker;return new zn({markers:[o],position:Zn.getPosition(o)})}}var yi,wi,bi,Ei,ki,xi={};function Mi(){if(bi)return xi;bi=1;var t=qe(),r=Mo(),e=kt(),n=yr(),o=Mn(),i=Cn(),s=_n(),a=function(){if(wi)return yi;wi=1;var t=v(),r=Function.prototype,e=r.apply,n=r.call;return yi="object"==typeof Reflect&&Reflect.apply||(t?n.bind(e):function(){return n.apply(e,arguments)}),yi}(),u=d(),c=TypeError,f=u(function(){[].keys().reduce(function(){},void 0)}),l=!f&&s("reduce",c);return t({target:"Iterator",proto:!0,real:!0,forced:f||l},{reduce:function(t){n(this);try{e(t)}catch(t){i(this,"throw",t)}var s=arguments.length<2,u=s?void 0:arguments[1];if(l)return a(l,this,s?[t]:[t,u]);var f=o(this),h=0;if(r(f,function(r){s?(s=!1,u=r):u=t(u,r,h),h++},{IS_RECORD:!0}),s)throw new c("Reduce of empty iterator with no initial value");return u}}),xi}Ei||(Ei=1,Mi());class Oi{constructor(t,r){this.markers={sum:t.length};const e=r.map(t=>t.count),n=e.reduce((t,r)=>t+r,0);this.clusters={count:r.length,markers:{mean:n/r.length,sum:n,min:Math.min(...e),max:Math.max(...e)}}}}class Pi{render(t,r,e){let{count:n,position:o}=t;const i=`\n\n\n\n${n}\n`,s=`Cluster of ${n} markers`,a=Number(google.maps.Marker.MAX_ZINDEX)+n;if(Zn.isAdvancedMarkerAvailable(e)){const t=(new DOMParser).parseFromString(i,"image/svg+xml").documentElement;t.setAttribute("transform","translate(0 25)");const r={map:e,position:o,zIndex:a,title:s,content:t};return new google.maps.marker.AdvancedMarkerElement(r)}const u={position:o,zIndex:a,title:s,icon:{url:`data:image/svg+xml;base64,${btoa(i)}`,anchor:new google.maps.Point(25,25)}};return new google.maps.Marker(u)}}class Ci{constructor(){!function(t,r){for(let e in r.prototype)t.prototype[e]=r.prototype[e]}(Ci,google.maps.OverlayView)}}t.MarkerClustererEvents=void 0,(ki=t.MarkerClustererEvents||(t.MarkerClustererEvents={})).CLUSTERING_BEGIN="clusteringbegin",ki.CLUSTERING_END="clusteringend",ki.CLUSTER_CLICK="click",ki.GMP_CLICK="gmp-click";const Si=(t,r,e)=>{r.bounds&&e.fitBounds(r.bounds)};return t.AbstractAlgorithm=Gn,t.AbstractViewportAlgorithm=Hn,t.Cluster=zn,t.ClusterStats=Oi,t.DefaultRenderer=Pi,t.GridAlgorithm=class extends Hn{constructor(t){var{maxDistance:r=4e4,gridSize:e=40}=t;super(Tn(t,["maxDistance","gridSize"])),this.clusters=[],this.state={zoom:-1},this.maxDistance=r,this.gridSize=e}calculate(t){let{markers:r,map:e,mapCanvasProjection:n}=t;const o=e.getZoom();Dn(o);const i={zoom:o};let s=!1;return this.state.zoom>=this.maxZoom&&i.zoom>=this.maxZoom||(s=!Qo(this.state,i)),this.state=i,o>=this.maxZoom?{clusters:this.noop({markers:r}),changed:s}:{clusters:this.cluster({markers:Fn(e,n,r,this.viewportPadding),map:e,mapCanvasProjection:n})}}cluster(t){let{markers:r,map:e,mapCanvasProjection:n}=t;return this.clusters=[],r.forEach(t=>{this.addToClosestCluster(t,e,n)}),this.clusters}addToClosestCluster(t,r,e){let n=this.maxDistance,o=null;for(let r=0;r{this.addMarker(t,!0)}),r||this.render()}removeMarker(t,r){const e=this.markers.indexOf(t);return-1!==e&&(Zn.setMap(t,null),this.markers.splice(e,1),r||this.render(),!0)}removeMarkers(t,r){let e=!1;return t.forEach(t=>{e=this.removeMarker(t,!0)||e}),e&&!r&&this.render(),e}clearMarkers(t){this.markers.length=0,t||this.render()}render(){const r=this.getMap();if(r instanceof google.maps.Map&&r.getProjection()){google.maps.event.trigger(this,t.MarkerClustererEvents.CLUSTERING_BEGIN,this);const{clusters:e,changed:n}=this.algorithm.calculate({markers:this.markers,map:r,mapCanvasProjection:this.getProjection()});if(n||null==n){const t=new Set;for(const r of e)1==r.markers.length&&t.add(r.markers[0]);const r=[];for(const e of this.clusters)null!=e.marker&&(1==e.markers.length?t.has(e.marker)||Zn.setMap(e.marker,null):r.push(e.marker));this.clusters=e,this.renderClusters(),requestAnimationFrame(()=>r.forEach(t=>Zn.setMap(t,null)))}google.maps.event.trigger(this,t.MarkerClustererEvents.CLUSTERING_END,this)}}onAdd(){const t=this.getMap();Dn(t),this.idleListener=t.addListener("idle",this.render.bind(this)),this.render()}onRemove(){this.idleListener&&google.maps.event.removeListener(this.idleListener),this.reset()}reset(){this.markers.forEach(t=>Zn.setMap(t,null)),this.clusters.forEach(t=>t.delete()),this.clusters=[]}renderClusters(){const r=new Oi(this.markers,this.clusters),e=this.getMap();this.clusters.forEach(n=>{if(1===n.markers.length)n.marker=n.markers[0];else if(n.marker=this.renderer.render(n,r,e),n.markers.forEach(t=>Zn.setMap(t,null)),this.onClusterClick){const r=Zn.isAdvancedMarker(n.marker)?t.MarkerClustererEvents.GMP_CLICK:t.MarkerClustererEvents.CLUSTER_CLICK;n.marker.addListener(r,r=>{google.maps.event.trigger(this,t.MarkerClustererEvents.CLUSTER_CLICK,n),this.onClusterClick(r,n,e)})}Zn.setMap(n.marker,e)})}},t.MarkerUtils=Zn,t.NoopAlgorithm=class extends Gn{constructor(t){super(Tn(t,[]))}calculate(t){let{markers:r,map:e,mapCanvasProjection:n}=t;return{clusters:this.cluster({markers:r,map:e,mapCanvasProjection:n}),changed:!1}}cluster(t){return this.noop(t)}},t.SuperClusterAlgorithm=vi,t.SuperClusterViewportAlgorithm=class extends Hn{constructor(t){var{maxZoom:r,radius:e=60,viewportPadding:n=60}=t,o=Tn(t,["maxZoom","radius","viewportPadding"]);super({maxZoom:r,viewportPadding:n}),this.markers=[],this.clusters=[],this.superCluster=new li(Object.assign({maxZoom:this.maxZoom,radius:e},o)),this.state={zoom:-1,view:[0,0,0,0]}}calculate(t){const r=this.getViewportState(t);let e=!Qo(this.state,r);if(!Qo(t.markers,this.markers)){e=!0,this.markers=[...t.markers];const r=this.markers.map(t=>{const r=Zn.getPosition(t);return{type:"Feature",geometry:{type:"Point",coordinates:[r.lng(),r.lat()]},properties:{marker:t}}});this.superCluster.load(r)}return e&&(this.clusters=this.cluster(t),this.state=r),{clusters:this.clusters,changed:e}}cluster(t){const r=this.getViewportState(t);return this.superCluster.getClusters(r.view,r.zoom).map(t=>this.transformCluster(t))}transformCluster(t){let{geometry:{coordinates:[r,e]},properties:n}=t;if(n.cluster)return new zn({markers:this.superCluster.getLeaves(n.cluster_id,1/0).map(t=>t.properties.marker),position:{lat:e,lng:r}});const o=n.marker;return new zn({markers:[o],position:Zn.getPosition(o)})}getViewportState(t){const r=t.map.getZoom(),e=t.map.getBounds();return Dn(r),Dn(e),{zoom:Math.round(r),view:Un(e,t.mapCanvasProjection,this.viewportPadding)}}},t.defaultOnClusterClickHandler=Si,t.distanceBetweenPoints=Bn,t.extendBoundsToPaddedViewport=Nn,t.extendPixelBounds=$n,t.filterMarkersToPaddedViewport=Fn,t.getPaddedViewport=Un,t.noop=Kn,t.pixelBoundsToLatLngBounds=Vn,t}({}); +//# sourceMappingURL=index.min.js.map