1(function( $ ) { 2 3 // 1) Define available map style arrays 4 var mapStyles = { 5 default: null, 6 7 silver: [ 8 { elementType: 'geometry', stylers: [{ color: '#f5f5f5' }] }, 9 { elementType: 'labels.icon', stylers: [{ visibility: 'off' }] }, 10 { elementType: 'labels.text.fill', stylers: [{ color: '#616161' }] }, 11 { elementType: 'labels.text.stroke', stylers: [{ color: '#f5f5f5' }] }, 12 { 13 featureType: 'administrative.land_parcel', 14 elementType: 'labels.text.fill', 15 stylers: [{ color: '#bdbdbd' }] 16 }, 17 { 18 featureType: 'poi', 19 elementType: 'geometry', 20 stylers: [{ color: '#eeeeee' }] 21 }, 22 { 23 featureType: 'poi', 24 elementType: 'labels.text.fill', 25 stylers: [{ color: '#757575' }] 26 }, 27 { 28 featureType: 'road', 29 elementType: 'geometry', 30 stylers: [{ color: '#ffffff' }] 31 }, 32 { 33 featureType: 'road.arterial', 34 elementType: 'labels.text.fill', 35 stylers: [{ color: '#757575' }] 36 }, 37 { 38 featureType: 'road.highway', 39 elementType: 'geometry', 40 stylers: [{ color: '#dadada' }] 41 }, 42 { 43 featureType: 'road.highway', 44 elementType: 'labels.text.fill', 45 stylers: [{ color: '#616161' }] 46 }, 47 { 48 featureType: 'road.local', 49 elementType: 'labels.text.fill', 50 stylers: [{ color: '#9e9e9e' }] 51 }, 52 { 53 featureType: 'transit.line', 54 elementType: 'geometry', 55 stylers: [{ color: '#e5e5e5' }] 56 }, 57 { 58 featureType: 'transit.station', 59 elementType: 'geometry', 60 stylers: [{ color: '#eeeeee' }] 61 }, 62 { 63 featureType: 'water', 64 elementType: 'geometry', 65 stylers: [{ color: '#c9c9c9' }] 66 }, 67 { 68 featureType: 'water', 69 elementType: 'labels.text.fill', 70 stylers: [{ color: '#9e9e9e' }] 71 } 72 ], 73 74 darkContrast: [ 75 { elementType: 'geometry', stylers: [{ color: '#212121' }] }, 76 { elementType: 'labels.icon', stylers: [{ visibility: 'off' }] }, 77 { elementType: 'labels.text.fill', stylers: [{ color: '#e0e0e0' }] }, 78 { elementType: 'labels.text.stroke', stylers: [{ color: '#212121' }] }, 79 { 80 featureType: 'landscape', 81 elementType: 'geometry', 82 stylers: [{ color: '#2e2e2e' }] 83 }, 84 { 85 featureType: 'poi', 86 elementType: 'geometry', 87 stylers: [{ color: '#2e2e2e' }] 88 }, 89 { 90 featureType: 'road', 91 elementType: 'geometry', 92 stylers: [{ color: '#383838' }] 93 }, 94 { 95 featureType: 'road', 96 elementType: 'labels.text.fill', 97 stylers: [{ color: '#ffffff' }] 98 }, 99 { 100 featureType: 'water', 101 elementType: 'geometry', 102 stylers: [{ color: '#000000' }] 103 } 104 ], 105 106 wilderness: [ 107 { 108 featureType: 'landscape', 109 elementType: 'geometry.fill', 110 stylers: [{ color: '#f4f1e9' }] 111 }, 112 { 113 featureType: 'water', 114 elementType: 'geometry.fill', 115 stylers: [{ color: '#a8d8e3' }] 116 }, 117 { 118 featureType: 'road', 119 elementType: 'geometry', 120 stylers: [{ color: '#e3e3e3' }] 121 }, 122 { 123 featureType: 'road.arterial', 124 elementType: 'geometry', 125 stylers: [{ color: '#d7d7d7' }] 126 }, 127 { 128 featureType: 'road.highway', 129 elementType: 'geometry', 130 stylers: [{ color: '#cfcfcf' }] 131 }, 132 { 133 featureType: 'poi.park', 134 elementType: 'geometry.fill', 135 stylers: [{ color: '#c7d7c1' }] 136 }, 137 { 138 elementType: 'labels.text.fill', 139 stylers: [{ color: '#4a4a4a' }] 140 }, 141 { 142 elementType: 'labels.icon', 143 stylers: [{ visibility: 'off' }] 144 }, 145 { 146 featureType: 'poi', 147 elementType: 'labels.text.fill', 148 stylers: [{ color: '#6b6b6b' }] 149 }, 150 { 151 featureType: 'transit.line', 152 elementType: 'geometry', 153 stylers: [{ color: '#e5e5e5' }] 154 } 155 ] 156 }; 157 158 // 2) UK & Ireland bounds 159 var ukIrelandBounds = new google.maps.LatLngBounds( 160 { lat: 49.9, lng: -10.5 }, 161 { lat: 61.5, lng: 2.1 } 162 ); 163 164 // 3) Main initMap 165 function initMap($el) { 166 var styleKey = $el.data('map-style') || 'default'; 167 var appliedStyles = mapStyles[styleKey] || null; 168 169 var map = new google.maps.Map($el[0], { 170 zoom: $el.data('zoom') || 8, 171 scrollwheel: false, 172 mapTypeId: google.maps.MapTypeId.ROADMAP, 173 styles: appliedStyles 174 });
175 176 // collect all infoWindows so we can close them together 177 var infoWindows = []; 178 google.maps.event.addListener(map, 'click', function(){ 179 infoWindows.forEach(iw => iw.close()); 180 }); 181 182 // 4) Legacy markers (unchanged) 183 map.markers = []; 184 $el.find('.marker').each(function(){ 185 initLegacyMarker($(this), map, infoWindows); 186 }); 187 188 // 5) Parse JSON attrs 189 var repJSON = [], regJSON = []; 190 try { repJSON = JSON.parse($el.attr('data-repeater-markers') || '[]'); } 191 catch(e){ console.error('Invalid repeater JSON', e); } 192 try { regJSON = JSON.parse($el.attr('data-regions') || '[]'); } 193 catch(e){ console.error('Invalid regions JSON', e); } 194 195 // 6) ACF repeater markers 196 var repIW = new google.maps.InfoWindow({ maxWidth:400 }), 197 repHoverIW = new google.maps.InfoWindow({ disableAutoPan:true }); 198 infoWindows.push(repIW, repHoverIW); 199 200 repJSON.forEach(function(m){ 201 var normalIcon = m.icon 202 ? { url: m.icon, scaledSize: new google.maps.Size(50,50) } 203 : null; 204 var hoverIcon = m.icon 205 ? { url: m.icon, scaledSize: new google.maps.Size(55,55) } 206 : null; 207 208 var mk = new google.maps.Marker({ 209 position: { lat: m.lat, lng: m.lng }, 210 map: map, 211 title: m.title, 212 icon: normalIcon 213 }); 214 215 // â **PUSH the repeater marker** so `map.markers` isnât empty 216 map.markers.push(mk); 217 218 // --- click â full popup with carousel --- 219 mk.addListener('click', function(){ 220 infoWindows.forEach(iw => iw.close()); 221 222 // build carousel from m.gallery 223 var carouselHTML = ''; 224 if (Array.isArray(m.gallery) && m.gallery.length) { 225 carouselHTML = '<div class="map-carousel">'; 226 m.gallery.forEach(function(url, i){ 227 carouselHTML += 228 '<img src="' + url + '" class="map-carousel-img" ' + 229 'style="display:' + (i ? 'none' : 'block') + ';width:100%;">'; 230 }); 231 if (m.gallery.length > 1) { 232 carouselHTML += 233 '<button class="map-carousel-prev">❮</button>' + 234 '<button class="map-carousel-next">❯</button>'; 235 } 236 carouselHTML += '</div>'; 237 } 238 239 var html = 240 '<div class="custom-iw">' + 241 carouselHTML + 242 '<button class="iw-close">×</button>' + 243 '<h3>' + m.title + '</h3>' + 244 '<div class="iw-desc">' + m.desc + '</div>' + 245 '</div>'; 246 247 repIW.setContent(html); 248 repIW.open(map, mk); 249 250 google.maps.event.addListenerOnce(repIW, 'domready', function(){ 251 var w = document.querySelector('.gm-style-iw-d'); 252 if (w) { 253 w.style.padding = '0'; 254 w.style.marginLeft = '-12px'; 255 w.style.overflow = 'auto'; 256 } 257 var btn = document.querySelector('.custom-iw .iw-close'); 258 if (btn) btn.addEventListener('click', () => repIW.close()); 259 initCarousel(); 260 }); 261 }); 262 263 // --- hover â enlarge + title tooltip --- 264 mk.addListener('mouseover', function(){ 265 infoWindows.forEach(iw => iw.close()); 266 if (hoverIcon) mk.setIcon(hoverIcon); 267 repHoverIW.setContent( 268 '<div class="hover-title" style="padding:8px 12px;">' 269 + m.title + '</div>' 270 ); 271 repHoverIW.open(map, mk); 272 }); 273 mk.addListener('mouseout', function(){ 274 if (normalIcon) mk.setIcon(normalIcon); 275 repHoverIW.close(); 276 }); 277 }); 278 279 // 7) GeoJSON region overlays (carousel-enabled) 280 if (regJSON.length && google.maps.Data) { 281 var regionHoverIW = new google.maps.InfoWindow({ disableAutoPan:true }), 282 regionClickIW = new google.maps.InfoWindow({ maxWidth:400 });
283 infoWindows.push(regionHoverIW, regionClickIW); 284 285 var baseColors = ['#3d5a40','#4a7d8c','#a86e3d','#8c7b6c','#5f5f64','#6b4c6c']; 286 var regionColors = regJSON.map(function(_, i){ 287 return i < baseColors.length 288 ? baseColors[i] 289 : 'hsl(' + Math.round(360 * i / regJSON.length) + ',40%,60%)'; 290 }); 291 292 map.data.setStyle(function(feature){ 293 var c = feature.getProperty('_color') || baseColors[0]; 294 return { strokeColor: c, strokeWeight: 2, fillColor: c, fillOpacity: 0.3 }; 295 }); 296 297 regJSON.forEach(function(fc, idx){ 298 var feats = map.data.addGeoJson(fc); 299 feats.forEach(function(f){ 300 f.setProperty('_color', regionColors[idx]); 301 }); 302 }); 303 304 // hover tooltip 305 map.data.addListener('mouseover', function(e){ 306 map.data.overrideStyle(e.feature, { fillOpacity: 0.6 }); 307 var bounds = new google.maps.LatLngBounds(); 308 e.feature.getGeometry().forEachLatLng(function(latlng){ 309 bounds.extend(latlng); 310 }); 311 regionHoverIW.setContent( 312 '<div class="hover-title" style="padding:8px 12px;">' 313 + e.feature.getProperty('name') + 314 '</div>' 315 ); 316 regionHoverIW.setPosition(bounds.getCenter()); 317 regionHoverIW.open(map); 318 }); 319 map.data.addListener('mouseout', function(e){ 320 map.data.revertStyle(e.feature); 321 regionHoverIW.close(); 322 }); 323 324 // click â open carousel popup 325 map.data.addListener('click', function(e){ 326 infoWindows.forEach(iw => iw.close()); 327 var p = e.feature.getProperty.bind(e.feature), 328 gallery = p('gallery') || [], 329 carouselHTML = ''; 330 331 if (gallery.length) { 332 carouselHTML = '<div class="map-carousel">'; 333 gallery.forEach(function(url, i){ 334 carouselHTML += 335 '<img src="' + url + '" class="map-carousel-img" ' + 336 'style="display:' + (i ? 'none' : 'block') + ';width:100%;">'; 337 }); 338 if (gallery.length > 1) { 339 carouselHTML += 340 '<button class="map-carousel-prev">❮</button>' + 341 '<button class="map-carousel-next">❯</button>'; 342 } 343 carouselHTML += '</div>'; 344 } 345 346 var bounds = new google.maps.LatLngBounds(); 347 e.feature.getGeometry().forEachLatLng(function(latlng){ 348 bounds.extend(latlng); 349 }); 350 351 var html = 352 '<div class="custom-iw">' + 353 carouselHTML + 354 '<h3>' + p('name') + '</h3>' + 355 '<div class="iw-desc">' + p('desc') + '</div>' + 356 '<button class="iw-close">×</button>' + 357 '</div>'; 358 359 regionClickIW.setContent(html); 360 regionClickIW.setPosition(bounds.getCenter()); 361 regionClickIW.open(map); 362 363 google.maps.event.addListenerOnce(regionClickIW, 'domready', function(){ 364 var w = document.querySelector('.gm-style-iw-d'); 365 if (w) { 366 w.style.padding = '0'; 367 w.style.marginLeft = '-12px'; 368 w.style.overflow = 'auto'; 369 } 370 var btn = document.querySelector('.custom-iw .iw-close'); 371 if (btn) btn.addEventListener('click', () => regionClickIW.close()); 372 initCarousel(); 373 }); 374 }); 375 } 376 377 // 8) Initial centering 378 if (regJSON.length) { 379 map.fitBounds(ukIrelandBounds); 380 google.maps.event.addListenerOnce(map, 'bounds_changed', function(){ 381 map.setZoom(map.getZoom() + 1); 382 }); 383 } else { 384 var allMk = map.markers; 385 if (allMk.length === 1) { 386 map.setCenter(allMk[0].getPosition()); 387 } else if (allMk.length > 1) { 388 var bb = new google.maps.LatLngBounds(); 389 allMk.forEach(function(mk){ 390 bb.extend(mk.getPosition()); 391 }); 392 map.fitBounds(bb); 393 } 394 } 395 396 return map; 397 } 398 399 // 9) Legacy marker helper (unchanged) 400 function initLegacyMarker($m, map, infoWindows) { 401 var lat = parseFloat($m.data('lat')), 402 lng = parseFloat($m.data('lng')); 403 var mk = new google.maps.Marker({ 404 position: { lat: lat, lng: lng }, 405 map: map, 406 icon: "https://www.wildernessscotland.com/wp-content/themes/wilderness2018/images/new-marker.png"
407 }); 408 map.markers.push(mk); 409 410 if ($m.html()) { 411 var iw = new google.maps.InfoWindow({ content: $m.html(), maxWidth: 400 }); 412 infoWindows.push(iw); 413 mk.addListener('click', function(){ 414 infoWindows.forEach(function(w){ w.close(); }); 415 iw.open(map, mk); 416 google.maps.event.addListenerOnce(iw, 'domready', function(){ 417 var w = document.querySelector('.gm-style-iw-d'); 418 if (w) { 419 w.style.padding = '0'; 420 w.style.marginLeft = '-12px'; 421 w.style.overflow = 'auto'; 422 } 423 }); 424 }); 425 } 426 } 427 428 // 10) Carousel initializer (unchanged) 429 function initCarousel() { 430 var ct = document.querySelector('.gm-style-iw .map-carousel'); 431 if (!ct) return; 432 var imgs = ct.querySelectorAll('.map-carousel-img'), 433 idx = 0; 434 var next = ct.querySelector('.map-carousel-next'), 435 prev = ct.querySelector('.map-carousel-prev'); 436 437 if (next) { 438 next.onclick = function() { 439 imgs[idx].style.display = 'none'; 440 idx = (idx + 1) % imgs.length; 441 imgs[idx].style.display = 'block'; 442 }; 443 } 444 if (prev) { 445 prev.onclick = function() { 446 imgs[idx].style.display = 'none'; 447 idx = (idx - 1 + imgs.length) % imgs.length; 448 imgs[idx].style.display = 'block'; 449 }; 450 } 451 } 452 453 // 11) On DOM ready 454 $(function(){ 455 $('.custom-acf-map').each(function(){ 456 initMap($(this)); 457 }); 458 }); 459 460})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.