(function(){ var M=["JANVIER","FÉVRIER","MARS","AVRIL","MAI","JUIN","JUILLET","AOÛT","SEPTEMBRE","OCTOBRE","NOVEMBRE","DÉCEMBRE"]; var Mlong=["Janvier","Février","Mars","Avril","Mai","Juin","Juillet","Août","Septembre","Octobre","Novembre","Décembre"]; function strip(h){var d=document.createElement("div");d.innerHTML=h||"";return(d.textContent||d.innerText||"").trim();} function trunc(s,n){var w=s.split(/\s+/);return w.length>n?w.slice(0,n).join(" ")+"…":s;} function pad(n){return n<10?"0"+n:""+n;} function pickVenue(ev){ var v=ev.venue; if(Array.isArray(v))v=v[0]||{}; if(!v||typeof v!=="object")return{}; return v; } function pickOrg(ev){ var o=ev.organizer; if(Array.isArray(o))o=o[0]||{}; if(!o||typeof o!=="object")return{}; return o; } function venueLabel(v){ if(!v)return""; var hasVenue=!!v.venue,hasCity=!!v.city,hasAddr=!!v.address; if(!hasVenue&&!hasCity&&!hasAddr)return""; var parts=[]; if(v.venue)parts.push(v.venue); if(v.address&&parts.indexOf(v.address)<0)parts.push(v.address); if(v.city&&parts.indexOf(v.city)<0)parts.push(v.city); return parts.join(", "); } function shortLoc(v){ if(!v)return""; var hasV=!!v.venue,hasC=!!v.city; if(hasC&&hasV&&v.city!==v.venue)return v.venue+", "+v.city; return v.venue||v.city||""; } function getTitle(ev){ if(typeof ev.title==="string")return ev.title; if(ev.title&&ev.title.rendered)return strip(ev.title.rendered); return ""; } function getExcerpt(ev){ var ex=""; if(typeof ev.excerpt==="string")ex=ev.excerpt; else if(ev.excerpt&&ev.excerpt.rendered)ex=ev.excerpt.rendered; if(ex){var t=strip(ex);if(t)return t;} var de=""; if(typeof ev.description==="string")de=ev.description; else if(ev.description&&ev.description.rendered)de=ev.description.rendered; return de?strip(de):""; } function getDescHtml(ev){ var de=""; if(typeof ev.description==="string")de=ev.description; else if(ev.description&&ev.description.rendered)de=ev.description.rendered; if(de)return de; var ex=""; if(typeof ev.excerpt==="string")ex=ev.excerpt; else if(ev.excerpt&&ev.excerpt.rendered)ex=ev.excerpt.rendered; return ex||""; } function getCategory(ev){ if(ev.categories&&ev.categories.length){ var c=ev.categories[0]; if(c&&c.name)return c.name; } return "Événement"; } function fmtDate(d){return d.getDate()+" "+Mlong[d.getMonth()]+" "+d.getFullYear();} function fmtDateRange(s,e){ if(!s)return"—"; if(!e||s.toDateString()===e.toDateString())return fmtDate(s); return fmtDate(s)+" → "+fmtDate(e); } function fmtIcs(d){return d.getUTCFullYear()+pad(d.getUTCMonth()+1)+pad(d.getUTCDate())+"T"+pad(d.getUTCHours())+pad(d.getUTCMinutes())+"00Z";} function buildIcs(ev,s,e,vlabel){ var lines=["BEGIN:VCALENDAR","VERSION:2.0","PRODID:-//Dahira Touba Grenoble//FR","BEGIN:VEVENT", "UID:dahira-"+(ev.id||Date.now())+"@peachpuff-starling-297435.hostingersite.com", "DTSTAMP:"+fmtIcs(new Date()), "DTSTART:"+fmtIcs(s), "DTEND:"+fmtIcs(e||s), "SUMMARY:"+getTitle(ev).replace(/[,;\\]/g,"\\$&"), "LOCATION:"+(vlabel||"Grenoble").replace(/[,;\\]/g,"\\$&"), "DESCRIPTION:"+strip(getDescHtml(ev)).replace(/[,;\\]/g,"\\$&").replace(/\n/g," "), "END:VEVENT","END:VCALENDAR"]; return "data:text/calendar;charset=utf-8,"+encodeURIComponent(lines.join("\r\n")); } function card(ev){ var s=ev.start_date?new Date(ev.start_date.replace(" ","T")):null; var day=s?s.getDate():"",mon=s?M[s.getMonth()]:""; var title=getTitle(ev); var desc=trunc(getExcerpt(ev),22); var v=pickVenue(ev); var loc=shortLoc(v); var a=document.createElement("a"); a.href="#"; a.className="dtg-ev-card"; a.setAttribute("data-ev-id", ev.id||""); var h='
'+day+''+mon+'

'+title+'

'; if(desc)h+='

'+desc+'

'; if(loc)h+='

'+loc+'

'; h+='
'; a.innerHTML=h; a.addEventListener("click",function(e){e.preventDefault();openModal(ev);}); return a; } function render(evs,g){ g.innerHTML=""; if(!evs||!evs.length){var p=document.createElement("p");p.className="dtg-ev-empty";p.textContent="Aucun événement à venir.";g.appendChild(p);return;} evs.forEach(function(e){g.appendChild(card(e));}); } function openModal(ev){ var modal=document.getElementById("dtgModal");if(!modal)return; var s=ev.start_date?new Date(ev.start_date.replace(" ","T")):null; var e=ev.end_date?new Date(ev.end_date.replace(" ","T")):null; var v=pickVenue(ev); var o=pickOrg(ev); var vlabel=venueLabel(v)||"Grenoble"; document.getElementById("dtgModalCat").textContent=getCategory(ev); document.getElementById("dtgModalTitle").textContent=getTitle(ev); document.getElementById("dtgModalDate").textContent=fmtDateRange(s,e); var hours="—"; if(s&&e){ var sameDay=s.toDateString()===e.toDateString(); var sH=s.getHours(),sM=s.getMinutes(),eH=e.getHours(),eM=e.getMinutes(); if(sH===0&&sM===0&&eH===0&&eM===0){hours="Toute la journée";} else{ hours=pad(sH)+"h"+pad(sM)+" → "+pad(eH)+"h"+pad(eM); if(!sameDay){hours+=" (J+"+Math.ceil((e-s)/86400000)+")";} } } document.getElementById("dtgModalHours").textContent=hours; document.getElementById("dtgModalVenue").textContent=vlabel; document.getElementById("dtgModalOrg").textContent=o.organizer||"Dahira Touba Grenoble"; document.getElementById("dtgModalDesc").innerHTML=getDescHtml(ev)||"

Plus d'informations à venir.

"; var icsBtn=document.getElementById("dtgModalIcs"); if(s){ icsBtn.href=buildIcs(ev,s,e||s,vlabel); icsBtn.setAttribute("download",getTitle(ev).replace(/\s+/g,"-").toLowerCase()+".ics"); icsBtn.style.display=""; }else{icsBtn.style.display="none";} modal.removeAttribute("hidden"); modal.classList.add("is-open"); document.body.classList.add("dtg-modal-open"); } function closeModal(){ var modal=document.getElementById("dtgModal");if(!modal)return; modal.classList.remove("is-open"); modal.setAttribute("hidden",""); document.body.classList.remove("dtg-modal-open"); } function bindModal(){ var modal=document.getElementById("dtgModal");if(!modal)return; var els=modal.querySelectorAll("[data-dtg-close]"); for(var i=0;i