{"id":16075,"date":"2025-10-30T18:12:13","date_gmt":"2025-10-30T18:12:13","guid":{"rendered":"https:\/\/scoprigaeta.it\/interactive-gaeta-luminaries-map\/"},"modified":"2025-12-16T23:27:18","modified_gmt":"2025-12-16T23:27:18","slug":"interactive-gaeta-luminaries-map","status":"publish","type":"page","link":"https:\/\/scoprigaeta.it\/en\/interactive-gaeta-luminaries-map\/","title":{"rendered":"Interactive Gaeta Luminaries Map"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"16075\" class=\"elementor elementor-16075 elementor-13120\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-d645ea5 e-flex e-con-boxed e-con e-parent\" data-id=\"d645ea5\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-89bda72 elementor-widget elementor-widget-shortcode\" data-id=\"89bda72\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">    \n    <div id=\"fdl-nav-app\">\n        <header class=\"fdl-nav-header\">\n            <div class=\"fdl-brand-group\">\n                <div class=\"fdl-brand-main\">SCOPRI GAETA<\/div>\n                <div class=\"fdl-brand-sub\">FAVOLE DI LUCE 2025<\/div>\n            <\/div>\n            <div class=\"fdl-score-badge\"><span class=\"dashicons dashicons-awards\"><\/span> <span id=\"score-counter\">0\/27<\/span><\/div>\n        <\/header>\n\n        <div id=\"fdl-map-stage\"><\/div>\n\n        <div class=\"fdl-floating-controls\">\n            <button id=\"btn-locate-me\" class=\"fdl-float-btn\"><span class=\"dashicons dashicons-location\"><\/span><\/button>\n            <button id=\"btn-close-map\" class=\"fdl-close-map-btn\">\n                <span class=\"dashicons dashicons-arrow-down-alt2\"><\/span> \n                CLOSE MAP            <\/button>\n        <\/div>\n        \n        <div class=\"fdl-bottom-sheet\" id=\"bottom-sheet\">\n            <div class=\"fdl-sheet-deco\"><\/div>\n            <div class=\"fdl-card-info\">\n                <div class=\"fdl-info-row\">\n                    <div class=\"fdl-thumb-preview\"><img decoding=\"async\" id=\"curr-img\" src=\"\" onclick=\"expandImage()\"><\/div>\n                    <div class=\"fdl-text-content\">\n                        <span class=\"fdl-id-tag\" id=\"curr-id\">TAPPA 1<\/span>\n                        <h2 id=\"curr-name\">Loading...<\/h2>\n                        <div class=\"fdl-distance-row\"><span class=\"dashicons dashicons-location\"><\/span> <span id=\"curr-dist\">Waiting for GPS...<\/span><\/div>\n                    <\/div>\n                <\/div>\n                <div class=\"fdl-action-bar\">\n                    <button id=\"btn-camera\" class=\"fdl-btn-primary\">\n                        <span class=\"dashicons dashicons-camera\"><\/span> \n                        TAKE PHOTO                    <\/button>\n                    <button id=\"btn-nav-full\" class=\"fdl-btn-secondary\">\n                        <span class=\"dashicons dashicons-randomize\"><\/span> \n                        START TOUR                    <\/button>\n                <\/div>\n            <\/div>\n            <div class=\"fdl-big-slider\"><div class=\"fdl-track\" id=\"fdl-track\"><\/div><\/div>\n        <\/div>\n\n        <input type=\"file\" id=\"inp-camera\" accept=\"image\/*\" capture=\"environment\" style=\"display:none;\">\n        \n        <div id=\"modal-win\" class=\"fdl-modal\">\n            <div class=\"fdl-modal-box\">\n                <h1>\ud83c\udf84 CONGRATULATIONS! \ud83c\udf84<\/h1>\n                <p>Tour Completed!<\/p>\n                <div class=\"win-code\" id=\"win-code\">CODE<\/div>\n                <a href=\"#\" id=\"wa-link\" class=\"fdl-wa-btn\">Claim Prize<\/a>\n                <button onclick=\"document.getElementById('modal-win').classList.remove('open')\">Close<\/button>\n            <\/div>\n        <\/div>\n        \n        <div id=\"modal-img\" class=\"fdl-modal\" onclick=\"this.classList.remove('open')\">\n            <img decoding=\"async\" id=\"full-img-src\" src=\"\" style=\"max-width:90%;max-height:80vh;border-radius:8px;border:2px solid #fff;\">\n        <\/div>\n    <\/div>\n\n    <style>\n        :root { --gaeta-red: #b71c1c; --gaeta-gold: #FFD700; --bg-white: #f5f5f5; --navbar-height: 80px; }\n        body.elementor-page { margin: 0; padding: 0; overflow: hidden; }\n        #fdl-nav-app { position: fixed; top: 0; left: 0; right: 0; bottom: var(--navbar-height); background: var(--bg-white); font-family: 'Helvetica Neue', Arial, sans-serif; display: flex; flex-direction: column; z-index: 900; }\n        #fdl-map-stage { position: absolute; inset: 0; z-index: 0; background: #e0e0e0; }\n        .fdl-nav-header { position: absolute; top: 0; left: 0; right: 0; height: 70px; background: linear-gradient(180deg, rgba(255,255,255,0.95) 0%, rgba(255,255,255,0) 100%); z-index: 1000; display: flex; justify-content: space-between; align-items: center; padding: 0 20px; pointer-events: none; }\n        .fdl-brand-group { pointer-events: auto; }\n        .fdl-brand-main { font-weight: 900; color: var(--gaeta-red); font-size: 16px; letter-spacing: -0.5px; }\n        .fdl-brand-sub { font-size: 10px; font-weight: bold; color: #555; letter-spacing: 2px; text-transform: uppercase; }\n        .fdl-score-badge { pointer-events: auto; background: var(--gaeta-red); color: white; padding: 5px 12px; border-radius: 20px; font-weight: bold; font-size: 13px; box-shadow: 0 4px 10px rgba(183,28,28,0.3); display: flex; align-items: center; gap: 5px; }\n        .fdl-floating-controls { position: absolute; right: 15px; top: 80px; z-index: 900; display: flex; flex-direction: column; gap: 10px; align-items: flex-end; }\n        .fdl-float-btn { width: 45px; height: 45px; background: white; border: none; border-radius: 50%; box-shadow: 0 4px 10px rgba(0,0,0,0.2); color: #333; font-size: 20px; display: flex; align-items: center; justify-content: center; cursor: pointer; }\n        .fdl-close-map-btn { background: var(--gaeta-red); color: white; border: none; padding: 10px 20px; border-radius: 30px; font-weight: bold; font-size: 12px; box-shadow: 0 5px 15px rgba(0,0,0,0.3); cursor: pointer; display: flex; align-items: center; gap: 8px; opacity: 0; pointer-events: none; transform: translateY(20px); transition: 0.3s; position: fixed; bottom: calc(var(--navbar-height) + 20px); left: 50%; transform: translateX(-50%) translateY(50px); }\n        .fdl-close-map-btn.active { opacity: 1; pointer-events: auto; transform: translateX(-50%) translateY(0); }\n        .fdl-bottom-sheet { position: absolute; bottom: 0; left: 0; right: 0; background: #fff; border-radius: 25px 25px 0 0; box-shadow: 0 -5px 20px rgba(0,0,0,0.15); z-index: 10; display: flex; flex-direction: column; justify-content: flex-end; padding-bottom: 10px; transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1); }\n        .fdl-bottom-sheet.hidden { transform: translateY(110%); }\n        .fdl-sheet-deco { height: 4px; background: repeating-linear-gradient(45deg, var(--gaeta-red), var(--gaeta-red) 10px, #fff 10px, #fff 20px); position: absolute; top: 0; left: 20px; right: 20px; border-radius: 0 0 5px 5px; }\n        .fdl-card-info { padding: 25px 20px 10px 20px; }\n        .fdl-info-row { display: flex; gap: 15px; align-items: center; margin-bottom: 15px; }\n        .fdl-thumb-preview { width: 70px; height: 70px; border-radius: 8px; overflow: hidden; border: 2px solid var(--gaeta-gold); flex-shrink: 0; box-shadow: 0 5px 10px rgba(0,0,0,0.1); }\n        #curr-img { width: 100%; height: 100%; object-fit: cover; border-radius: 8px; }\n        .fdl-text-content { flex: 1; }\n        .fdl-id-tag { font-size: 10px; font-weight: bold; background: #eee; padding: 2px 6px; border-radius: 4px; color: #555; }\n        #curr-name { margin: 3px 0; font-size: 18px; line-height: 1.1; color: #222; font-weight: 800; }\n        .fdl-distance-row { display: flex; align-items: center; gap: 5px; color: var(--gaeta-red); font-weight: bold; font-size: 12px; margin-top: 2px; }\n        .fdl-action-bar { display: flex; gap: 10px; }\n        .fdl-btn-primary { flex: 2; background: var(--gaeta-red); color: white; border: none; padding: 12px; border-radius: 10px; font-weight: bold; font-size: 13px; cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 8px; box-shadow: 0 4px 10px rgba(183,28,28,0.25); }\n        .fdl-btn-secondary { flex: 1.5; background: #fff; color: #333; border: 1px solid #ddd; padding: 12px; border-radius: 10px; font-weight: bold; font-size: 11px; cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 5px; text-decoration: none; text-align: center; }\n        .fdl-btn-primary.done { background: #2e7d32; pointer-events: none; }\n        .fdl-big-slider { margin-top: 10px; height: 110px; padding-left: 20px; overflow: hidden; }\n        .fdl-track { display: flex; gap: 15px; overflow-x: auto; height: 100%; padding-right: 20px; align-items: center; scrollbar-width: none; }\n        .fdl-thumb { flex: 0 0 90px; height: 90px; border-radius: 15px; overflow: hidden; position: relative; transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); border: 3px solid transparent; box-shadow: 0 4px 8px rgba(0,0,0,0.1); background: #000; padding:0; }\n        .fdl-thumb img { width: 100% !important; height: 100% !important; object-fit: cover !important; object-position: center !important; display: block; margin: 0; padding: 0; opacity: 0.8; }\n        .fdl-thumb.active { transform: scale(1.05) translateY(-5px); border-color: var(--gaeta-red); z-index: 2; box-shadow: 0 10px 20px rgba(183,28,28,0.2); }\n        .fdl-thumb.active img { opacity: 1; }\n        .fdl-thumb.visited { border-color: #2e7d32; }\n        .fdl-thumb-num { position: absolute; bottom: 0; left: 0; right: 0; background: linear-gradient(to top, rgba(0,0,0,0.8), transparent); color: white; font-size: 14px; font-weight: bold; padding: 5px; text-align: center; }\n        .pin-wrapper { transition: transform 0.3s; }\n        .pin-inner { width: 30px; height: 30px; background: var(--gaeta-red); border: 2px solid white; border-radius: 50%; color: white; font-weight: bold; display: flex; align-items: center; justify-content: center; font-size: 12px; box-shadow: 0 3px 10px rgba(0,0,0,0.3); }\n        .pin-wrapper.active { transform: scale(1.3); z-index: 500 !important; }\n        .pin-wrapper.active .pin-inner { background: var(--gaeta-gold); color: #000; border-color: #000; }\n        .pin-wrapper.visited .pin-inner { background: #2e7d32; }\n        .user-dot { width: 16px; height: 16px; background: #2196F3; border: 3px solid white; border-radius: 50%; box-shadow: 0 0 10px rgba(0,0,0,0.5); position: relative; }\n        .user-dot::after { content:''; position: absolute; top:-10px; left:-10px; width: 36px; height: 36px; border-radius: 50%; background: rgba(33, 150, 243, 0.3); animation: pulse 2s infinite; }\n        @keyframes pulse { 0% { transform: scale(0.5); opacity: 1; } 100% { transform: scale(1.5); opacity: 0; } }\n        .fdl-modal { position: fixed; inset: 0; z-index: 2000; background: rgba(0,0,0,0.8); display: flex; align-items: center; justify-content: center; opacity: 0; pointer-events: none; transition: 0.3s; backdrop-filter: blur(5px); }\n        .fdl-modal.open { opacity: 1; pointer-events: auto; }\n        .fdl-modal-box { background: white; padding: 30px; border-radius: 20px; text-align: center; max-width: 300px; width: 90%; }\n        .win-code { font-family: monospace; font-size: 24px; color: var(--gaeta-red); margin: 15px 0; background: #eee; padding: 10px; border-radius: 8px; }\n        .fdl-wa-btn { display: block; background: #25D366; color: white; padding: 12px; border-radius: 8px; font-weight: bold; text-decoration: none; margin-bottom: 10px; }\n    <\/style>\n\n    <script>\n    document.addEventListener(\"DOMContentLoaded\", function(){\n        const points = [{\"id\":1,\"name\":\"Acquario delle Meraviglie\",\"place\":\"Posizione 1\",\"lat\":41.22519077336052,\"lng\":13.56730067526396,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251208_175018-scaled.webp\"},{\"id\":2,\"name\":\"Balena Scintillante\",\"place\":\"Posizione 2\",\"lat\":41.22096629117086,\"lng\":13.570025070042057,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251208_175641-scaled.webp\"},{\"id\":3,\"name\":\"La Madonna Nostra\",\"place\":\"Posizione 3\",\"lat\":41.2192110535702,\"lng\":13.568978928148343,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251208_180227-scaled.webp\"},{\"id\":4,\"name\":\"Fabbrica dei Desideri\",\"place\":\"Posizione 4\",\"lat\":41.21791577906555,\"lng\":13.570389811821155,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251208_180520-scaled.webp\"},{\"id\":5,\"name\":\"Scrigno delle Fiabe\",\"place\":\"Posizione 5\",\"lat\":41.21691908620515,\"lng\":13.57052946514642,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251208_181233-scaled.webp\"},{\"id\":6,\"name\":\"Vulcano Splendente\",\"place\":\"Posizione 6\",\"lat\":41.21669714848053,\"lng\":13.569837067931974,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251208_180839-scaled.webp\"},{\"id\":7,\"name\":\"Via dei Pianeti\",\"place\":\"Posizione 7\",\"lat\":41.21636020522276,\"lng\":13.570223445839686,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251208_180941-scaled.webp\"},{\"id\":8,\"name\":\"Dodo Brillante\",\"place\":\"Posizione 8\",\"lat\":41.21587395470725,\"lng\":13.570258320984896,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251208_181056-scaled.webp\"},{\"id\":9,\"name\":\"Magia del Natale\",\"place\":\"Posizione 9\",\"lat\":41.21591834287104,\"lng\":13.571103265034782,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251208_181233-scaled.webp\"},{\"id\":10,\"name\":\"Sinfonia Luminosa\",\"place\":\"Posizione 10\",\"lat\":41.21469967507208,\"lng\":13.569542497400288,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251205_010201.webp\"},{\"id\":11,\"name\":\"Musica di Babbo Natale\",\"place\":\"Posizione 11\",\"lat\":41.213198503396676,\"lng\":13.5673591165889,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251208_192522-scaled.webp\"},{\"id\":12,\"name\":\"Giardino dei Panda\",\"place\":\"Posizione 12\",\"lat\":41.21283934700196,\"lng\":13.566753233040766,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251208_192404-scaled.webp\"},{\"id\":13,\"name\":\"Misteri Antico Egitto (In Allestimento)\",\"place\":\"Posizione 13\",\"lat\":41.21255282756523,\"lng\":13.566527225221588,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/11\/DJI_20251204142358_0060_D.webp\"},{\"id\":14,\"name\":\"Sentiero Giurassico\",\"place\":\"Posizione 14\",\"lat\":41.21488328375934,\"lng\":13.571022746536634,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251208_181542-scaled.webp\"},{\"id\":15,\"name\":\"Sogno di Natale\",\"place\":\"Posizione 15\",\"lat\":41.21518391665099,\"lng\":13.571147125299001,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251208_181430-scaled.webp\"},{\"id\":16,\"name\":\"Albero di Natale\",\"place\":\"Posizione 16\",\"lat\":41.21360204755517,\"lng\":13.572041943376599,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251208_181836-scaled.webp\"},{\"id\":17,\"name\":\"Tic Toc Campanile\",\"place\":\"Posizione 17\",\"lat\":41.21366257896424,\"lng\":13.571473425948943,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251208_181744-scaled.webp\"},{\"id\":18,\"name\":\"Casa di Babbo Natale\",\"place\":\"Posizione 18\",\"lat\":41.21428403152459,\"lng\":13.571548445844,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251205_005953.webp\"},{\"id\":19,\"name\":\"Drago Zu\",\"place\":\"Posizione 19\",\"lat\":41.21336395680275,\"lng\":13.580421905169239,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251208_182830-scaled.webp\"},{\"id\":20,\"name\":\"Reame Preistorico\",\"place\":\"Posizione 20\",\"lat\":41.212326839518674,\"lng\":13.58161776863821,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251205_002648.webp\"},{\"id\":21,\"name\":\"L'Annunziata\",\"place\":\"Posizione 21\",\"lat\":41.21172958163768,\"lng\":13.581477996473167,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/11\/dji_fly_20251119_183236_0053_1763573708588_photo.webp\"},{\"id\":22,\"name\":\"Vascello dei Sogni\",\"place\":\"Posizione 22\",\"lat\":41.2109224677302,\"lng\":13.582717189894124,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251205_003030.webp\"},{\"id\":23,\"name\":\"Aiutanti Babbo Natale\",\"place\":\"Posizione 23\",\"lat\":41.21031309013318,\"lng\":13.58324856778933,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251205_003142-1.webp\"},{\"id\":24,\"name\":\"Jurassic Villa\",\"place\":\"Posizione 24\",\"lat\":41.209792491531395,\"lng\":13.583887656687892,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251208_184343-scaled.webp\"},{\"id\":25,\"name\":\"Tempio di Luce\",\"place\":\"Posizione 25\",\"lat\":41.210559263223246,\"lng\":13.581113220868167,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251208_183412-scaled.webp\"},{\"id\":26,\"name\":\"Casa Pan di Zenzero\",\"place\":\"Posizione 26\",\"lat\":41.20961895774359,\"lng\":13.586871882644479,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251205_003557.webp\"},{\"id\":27,\"name\":\"Abbraccio Materno\",\"place\":\"Posizione 27\",\"lat\":41.209118532150164,\"lng\":13.58827184629864,\"img\":\"https:\/\/scoprigaeta.it\/wp-content\/uploads\/2025\/12\/20251208_183919-scaled.webp\"}];\n        \/\/ RECUPERA TRADUZIONI PHP\n        const lang = {\"loading\":\"Loading...\",\"wait_gps\":\"Waiting for GPS...\",\"tappa\":\"STAGE\",\"distance\":\"Distance\",\"visitata\":\"VISITED\",\"scatta\":\"TAKE PHOTO\",\"gps_search\":\"Searching for GPS...\",\"confirm_shot\":\"Confirm shot?\",\"mem_full\":\"Memory full. Photo not saved.\",\"win_text\":\"I completed Favole di Luce! Code:\",\"gps_err\":\"Unable to detect GPS\"};\n        \n        const STORAGE_KEY = 'fdl_v18_data';\n        \n        let progress = { ids: [], images: {} };\n        try { if(localStorage.getItem(STORAGE_KEY)) progress = JSON.parse(localStorage.getItem(STORAGE_KEY)); } catch(e){}\n\n        let currentIdx = 0;\n        let map = null, userMarker = null, userPos = null;\n        let activeRouteLayer = null; \n\n        const ui = {\n            sheet: document.getElementById('bottom-sheet'),\n            btnCloseMap: document.getElementById('btn-close-map'),\n            btnNavFull: document.getElementById('btn-nav-full'),\n            mapStage: document.getElementById('fdl-map-stage')\n        };\n\n        function init() {\n            initMap();\n            renderSlider();\n            loadPoint(0);\n            updateScore();\n            startTracking();\n        }\n\n        function initMap() {\n            map = L.map('fdl-map-stage', {zoomControl: false}).setView([41.215, 13.575], 14);\n            L.tileLayer('https:\/\/{s}.basemaps.cartocdn.com\/rastertiles\/voyager\/{z}\/{x}\/{y}{r}.png', { maxZoom: 19 }).addTo(map);\n\n            points.forEach((p, i) => {\n                const isVisited = progress.ids.includes(p.id);\n                const className = `pin-wrapper ${isVisited ? 'visited' : ''}`;\n                const icon = L.divIcon({\n                    className: 'custom-div-icon',\n                    html: `<div class=\"${className}\" id=\"pin-${p.id}\"><div class=\"pin-inner\">${p.id}<\/div><\/div>`,\n                    iconSize: [30, 30], iconAnchor: [15, 15]\n                });\n                const m = L.marker([p.lat, p.lng], {icon: icon}).addTo(map);\n                m.on('click', () => { \n                    loadPoint(i);\n                    if(ui.sheet.classList.contains('hidden')) ui.btnCloseMap.click(); \n                });\n            });\n        }\n\n        ui.btnNavFull.onclick = function() {\n            ui.sheet.classList.add('hidden'); \n            ui.btnCloseMap.classList.add('active'); \n            drawTourRoute();\n            setTimeout(() => { map.invalidateSize(); }, 400);\n        };\n\n        ui.btnCloseMap.onclick = function() {\n            ui.sheet.classList.remove('hidden'); \n            ui.btnCloseMap.classList.remove('active'); \n            if(activeRouteLayer) { map.removeLayer(activeRouteLayer); activeRouteLayer = null; }\n            setTimeout(() => { \n                map.invalidateSize(); \n                const p = points[currentIdx];\n                map.flyTo([p.lat, p.lng], 16, {paddingBottomRight: [0, 200]}); \n            }, 400);\n        };\n\n        function drawTourRoute() {\n            if(activeRouteLayer) map.removeLayer(activeRouteLayer);\n            let routeCoords = [];\n            if(userPos) routeCoords.push(userPos);\n            for(let i = currentIdx; i < points.length; i++) {\n                routeCoords.push([points[i].lat, points[i].lng]);\n            }\n            if(routeCoords.length > 1) {\n                activeRouteLayer = L.polyline(routeCoords, {\n                    color: '#2196F3', weight: 5, opacity: 0.8, lineCap: 'round'\n                }).addTo(map);\n                map.fitBounds(activeRouteLayer.getBounds(), {padding: [50, 50]});\n            }\n        }\n        \n        document.getElementById('btn-locate-me').onclick = function() {\n            if(userPos) map.flyTo(userPos, 18); else alert(lang.gps_search);\n        };\n\n        function startTracking() {\n            if(\"geolocation\" in navigator) {\n                navigator.geolocation.watchPosition(\n                    pos => {\n                        userPos = [pos.coords.latitude, pos.coords.longitude];\n                        updateUserOnMap();\n                    },\n                    err => console.warn(\"GPS Err\"), {enableHighAccuracy: true}\n                );\n            }\n        }\n\n        function updateUserOnMap() {\n            if(!userPos || !map) return;\n            if(!userMarker) {\n                const userIcon = L.divIcon({ className: 'user-pin-wrap', html: '<div class=\"user-dot\"><\/div>', iconSize: [20, 20], iconAnchor: [10, 10] });\n                userMarker = L.marker(userPos, {icon: userIcon, zIndexOffset: 1000}).addTo(map);\n            } else {\n                userMarker.setLatLng(userPos);\n            }\n            const p = points[currentIdx];\n            const dist = map.distance(userPos, [p.lat, p.lng]);\n            let distText = dist < 1000 ? Math.round(dist) + \" mt\" : (dist\/1000).toFixed(1) + \" km\";\n            \/\/ USATO LANG.DISTANCE\n            document.getElementById('curr-dist').innerText = lang.distance + \": \" + distText;\n        }\n\n        function loadPoint(idx) {\n            currentIdx = idx;\n            const p = points[idx];\n            const isDone = progress.ids.includes(p.id);\n\n            document.querySelectorAll('.fdl-thumb').forEach(el => el.classList.remove('active'));\n            const thumb = document.getElementById('t-'+p.id);\n            if(thumb) { thumb.classList.add('active'); thumb.scrollIntoView({behavior:'smooth', inline:'center'}); }\n            \n            document.querySelectorAll('.pin-wrapper').forEach(el => el.classList.remove('active'));\n            const pin = document.getElementById('pin-'+p.id);\n            if(pin) pin.classList.add('active');\n\n            let imgShow = p.img;\n            if(isDone && progress.images && progress.images[p.id]) imgShow = progress.images[p.id];\n\n            document.getElementById('curr-img').src = imgShow;\n            document.getElementById('full-img-src').src = imgShow;\n            \/\/ USATO LANG.TAPPA\n            document.getElementById('curr-id').innerText = lang.tappa + \" \" + p.id;\n            document.getElementById('curr-name').innerText = p.name;\n\n            const btnCam = document.getElementById('btn-camera');\n            if(isDone) {\n                \/\/ USATO LANG.VISITATA\n                btnCam.innerHTML = '<span class=\"dashicons dashicons-yes\"><\/span> ' + lang.visitata;\n                btnCam.classList.add('done');\n            } else {\n                \/\/ USATO LANG.SCATTA\n                btnCam.innerHTML = '<span class=\"dashicons dashicons-camera\"><\/span> ' + lang.scatta;\n                btnCam.classList.remove('done');\n            }\n\n            if(!ui.sheet.classList.contains('hidden')) {\n                map.flyTo([p.lat, p.lng], 16, {paddingBottomRight: [0, 200]});\n            }\n        }\n\n        function renderSlider() {\n            const track = document.getElementById('fdl-track');\n            track.innerHTML = '';\n            points.forEach((p, i) => {\n                const isDone = progress.ids.includes(p.id);\n                const div = document.createElement('div');\n                div.className = `fdl-thumb ${isDone ? 'visited' : ''}`;\n                div.id = 't-'+p.id;\n                div.innerHTML = `<img decoding=\"async\" src=\"${p.img}\"><div class=\"fdl-thumb-num\">${p.id}<\/div>`;\n                div.onclick = () => {\n                    if(ui.sheet.classList.contains('hidden')) ui.btnCloseMap.click();\n                    loadPoint(i);\n                };\n                track.appendChild(div);\n            });\n        }\n\n        const inpCam = document.getElementById('inp-camera');\n        document.getElementById('btn-camera').onclick = () => { if(!document.getElementById('btn-camera').classList.contains('done')) inpCam.click(); };\n        window.expandImage = () => document.getElementById('modal-img').classList.add('open');\n\n        inpCam.onchange = (e) => {\n            const file = e.target.files[0];\n            if(!file) return;\n            const reader = new FileReader(); reader.readAsDataURL(file);\n            reader.onload = (event) => {\n                const img = new Image(); img.src = event.target.result;\n                img.onload = () => {\n                    const canvas = document.createElement('canvas');\n                    const MAX_WIDTH = 600; \n                    const scaleSize = MAX_WIDTH \/ img.width;\n                    canvas.width = MAX_WIDTH; canvas.height = img.height * scaleSize;\n                    const ctx = canvas.getContext('2d'); ctx.drawImage(img, 0, 0, canvas.width, canvas.height);\n                    const compressedDataUrl = canvas.toDataURL('image\/jpeg', 0.6);\n                    if(confirm(lang.confirm_shot)) saveProgress(points[currentIdx].id, compressedDataUrl);\n                }\n            }\n        };\n\n        function saveProgress(id, imgData) {\n            const p = points.find(x => x.id == id);\n            if(!progress.ids.includes(id)) progress.ids.push(id);\n            progress.images[id] = imgData;\n            try { localStorage.setItem(STORAGE_KEY, JSON.stringify(progress)); } catch (e) { delete progress.images[id]; localStorage.setItem(STORAGE_KEY, JSON.stringify(progress)); alert(lang.mem_full); }\n            document.getElementById('t-'+p.id).classList.add('visited');\n            document.getElementById('pin-'+p.id).parentElement.classList.add('visited');\n            loadPoint(currentIdx);\n            updateScore();\n        }\n\n        function updateScore() {\n            const score = progress.ids.length;\n            document.getElementById('score-counter').innerText = score + \"\/\" + points.length;\n            if(score >= points.length) {\n                document.getElementById('modal-win').classList.add('open');\n                document.getElementById('win-code').innerText = \"WIN-\" + Date.now().toString().slice(-5);\n                \/\/ USATO LANG.WIN_TEXT\n                document.getElementById('wa-link').href = \"https:\/\/wa.me\/390000000000?text=\" + encodeURIComponent(lang.win_text) + document.getElementById('win-code').innerText;\n            }\n        }\n\n        init();\n    });\n    <\/script>\n    <\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"_acf_changed":false,"footnotes":""},"zona":[111],"class_list":["post-16075","page","type-page","status-publish","hentry","zona-gaeta-city-center"],"acf":[],"_links":{"self":[{"href":"https:\/\/scoprigaeta.it\/en\/wp-json\/wp\/v2\/pages\/16075","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/scoprigaeta.it\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/scoprigaeta.it\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/scoprigaeta.it\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/scoprigaeta.it\/en\/wp-json\/wp\/v2\/comments?post=16075"}],"version-history":[{"count":2,"href":"https:\/\/scoprigaeta.it\/en\/wp-json\/wp\/v2\/pages\/16075\/revisions"}],"predecessor-version":[{"id":16079,"href":"https:\/\/scoprigaeta.it\/en\/wp-json\/wp\/v2\/pages\/16075\/revisions\/16079"}],"wp:attachment":[{"href":"https:\/\/scoprigaeta.it\/en\/wp-json\/wp\/v2\/media?parent=16075"}],"wp:term":[{"taxonomy":"zona","embeddable":true,"href":"https:\/\/scoprigaeta.it\/en\/wp-json\/wp\/v2\/zona?post=16075"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}