`:''}${img}`;
}
const img = new Image();
img.onload = () => {
const w = img.naturalWidth, h = img.naturalHeight;
const map = L.map('map', { crs:L.CRS.Simple, minZoom:-2, maxZoom:5, zoomControl:true });
const bounds = [[0,0],[h,w]];
L.imageOverlay(MAP_IMAGE_URL, bounds, { crossOrigin:'anonymous' }).addTo(map);
map.fitBounds(bounds);
const popupOpts = { className:'tv-popup', maxWidth:600, minWidth:220,
autoPan:true, keepInView:true, autoPanPaddingTopLeft:[0,80], autoPanPaddingBottomRight:[0,40] };
const selfies = L.layerGroup().addTo(map);
// Delete mode
let deleteMode=false;
const delBtn=document.getElementById('m-delmode');
delBtn.onclick=()=>{ deleteMode=!deleteMode; delBtn.textContent='Delete mode: '+(deleteMode?'ON':'OFF'); delBtn.classList.toggle('on', deleteMode); };
function addMarker(latlng, title, desc, imgUrl){
const m = L.marker(latlng,{icon:icon(), title:title||'Selfie', desc:desc||'', imgUrl:imgUrl||null}).addTo(selfies);
m.bindPopup(popupHtml(title,desc,imgUrl), popupOpts);
m.on('click', () => m.openPopup());
m.on('contextmenu', () => { if(deleteMode){ selfies.removeLayer(m); saveShared().catch(console.warn); } });
return m;
}
function collectMarkers(){
const all=[]; selfies.eachLayer(l=>{ const ll=l.getLatLng();
all.push({ type:'selfie', y:ll.lat, x:ll.lng, title:l.options.title||'Selfie', desc:l.options.desc||'', img:l.options.imgUrl||null });
}); return all;
}
async function saveShared(){
const payload = JSON.stringify(collectMarkers());
const res = await fetch(SAVE_URL,{ method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({ data: payload }) });
if(!res.ok) throw new Error(await res.text());
toast('Saved ✅');
}
function applyMarkers(arr){ arr.forEach(m => addMarker([m.y,m.x], m.title||'Selfie', m.desc||'', m.img||null)); }
const tI=document.getElementById('m-title'),
dI=document.getElementById('m-desc'),
pI=document.getElementById('m-photo'),
addBtn=document.getElementById('m-add');
function validateInputs(){
const name = tI.value.trim();
if(!name){ alert('Please enter a player username.'); tI.focus(); return false; }
const f = pI.files[0];
if(f){
const ok = ['image/jpeg','image/png','image/webp'];
if(!ok.includes(f.type)){ alert('Only JPG/JPEG, PNG, or WEBP allowed.'); pI.value=''; return false; }
if(f.size > 10*1024*1024){ alert('Image is over 10MB.'); pI.value=''; return false; }
}
return true;
}
async function uploadPhotoIfAny(){
const f = pI.files[0]; if(!f) return null;
const fd = new FormData(); fd.append('photo', f);
const res = await fetch(UPLOAD_URL, { method:'POST', body: fd });
if(!res.ok) throw new Error(await res.text());
const j = await res.json(); return j.url;
}
let placing=null;
addBtn.onclick = () => {
if(!validateInputs()) return;
placing = { title: tI.value, desc: dI.value };
addBtn.textContent='Click map…'; addBtn.disabled=true; map.getContainer().style.cursor='crosshair';
function cancel(){ placing=null; addBtn.textContent='Add to Map'; addBtn.disabled=false; map.getContainer().style.cursor=''; document.removeEventListener('keydown',esc); }
function esc(e){ if(e.key==='Escape') cancel(); } document.addEventListener('keydown',esc);
map.once('click', async e => {
try{
const imgUrl = await uploadPhotoIfAny();
addMarker([e.latlng.lat,e.latlng.lng], placing.title, placing.desc, imgUrl);
await saveShared();
}catch(err){ alert('Could not add selfie: ' + err.message); }
finally{ cancel(); tI.value=''; dI.value=''; pI.value=''; }
});
};
(async function(){
try{
const res = await fetch(DATA_URL,{cache:'no-store'}); if(!res.ok) throw new Error('HTTP '+res.status);
const arr = await res.json(); selfies.clearLayers(); applyMarkers(arr);
}catch(e){ console.warn('Could not load shared data:', e); }
})();
};
img.src = MAP_IMAGE_URL;