Pico y Placa Buenaventura

`; try { mount(root); } catch (err) { console.error(err); root.innerHTML = `
No se pudo cargar el módulo.
Detalle: ${String(err && err.message ? err.message : err)}
`; } }); }; if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', () => window.PZ_PYP_INIT_ALL()); else window.PZ_PYP_INIT_ALL(); window.addEventListener('elementor/frontend/init', () => setTimeout(() => window.PZ_PYP_INIT_ALL(), 50)); let tries = 0; const t = setInterval(() => { tries++; window.PZ_PYP_INIT_ALL(); if (tries >= 12) clearInterval(t); }, 300); function getTZ(root){ return (root.getAttribute('data-tz') || 'America/Bogota').trim() || 'America/Bogota'; } function nowPartsInTZ(tz){ const dtf = new Intl.DateTimeFormat('en-CA', { timeZone: tz, year:'numeric', month:'2-digit', day:'2-digit', hour:'2-digit', minute:'2-digit', second:'2-digit', hour12:false }); const parts = dtf.formatToParts(new Date()); const m = {}; for (const p of parts) if (p.type !== 'literal') m[p.type] = p.value; return { year:+m.year, month:+m.month, day:+m.day, hour:+m.hour, minute:+m.minute, second:+m.second }; } function ymdFromParts(p){ return `${p.year}-${pad2(p.month)}-${pad2(p.day)}`; } function minutesOfDayFromParts(p){ return p.hour*60 + p.minute; } function dateUTCNoonFromYMD(ymd){ const [y,m,d] = ymd.split('-').map(Number); return new Date(Date.UTC(y, m-1, d, 12, 0, 0)); } function addDaysYMD(ymd, delta){ const dt = dateUTCNoonFromYMD(ymd); dt.setUTCDate(dt.getUTCDate() + delta); return `${dt.getUTCFullYear()}-${pad2(dt.getUTCMonth()+1)}-${pad2(dt.getUTCDate())}`; } function prettyDateHeaderES(tz, ymd){ const dt = dateUTCNoonFromYMD(ymd); const s = new Intl.DateTimeFormat('es-CO', { timeZone: tz, weekday:'long', day:'numeric', month:'long' }).format(dt); return s.charAt(0).toUpperCase() + s.slice(1); } function dayChipES(tz, ymd, isToday){ const dt = dateUTCNoonFromYMD(ymd); const name = isToday ? 'HOY' : new Intl.DateTimeFormat('es-CO', { timeZone: tz, weekday:'short' }).format(dt).replace('.','').toUpperCase(); const num = new Intl.DateTimeFormat('es-CO', { timeZone: tz, day:'2-digit' }).format(dt); return { name, num }; } function isHHMM(s){ return /^([01]\d|2[0-3]):([0-5]\d)$/.test(String(s||'').trim()); } function toMinutes(hhmm){ if (!isHHMM(hhmm)) return null; const [h,m] = hhmm.split(':').map(Number); return h*60 + m; } function time24to12ES(hhmm){ if (!isHHMM(hhmm)) return String(hhmm||''); const [h,m] = hhmm.split(':').map(Number); const h12 = ((h + 11) % 12) + 1; const suf = h >= 12 ? 'p. m.' : 'a. m.'; return `${h12}:${pad2(m)} ${suf}`; } function scheduleLabel(schedule){ const slots = Array.isArray(schedule) ? schedule : []; if (!slots.length) return 'Sin restricción'; return slots.map(s => `${time24to12ES(s.start)} a ${time24to12ES(s.end)}`).join(' · '); } function endTimingOnly(schedule, nowMin){ const slots = (Array.isArray(schedule) ? schedule : []) .map(s => ({ s: toMinutes(String(s.start||'')), e: toMinutes(String(s.end||'')) })) .filter(x => x.s!==null && x.e!==null) .sort((a,b)=>a.s-b.s); for (const slot of slots){ if (nowMin >= slot.s && nowMin < slot.e) return { kind:'end', at: slot.e }; } return { kind:'none' }; } function hmFromDelta(mins){ const m = Math.max(0, mins); return { h: Math.floor(m/60), m: m%60 }; } function safeUrl(u){ const s = String(u ?? '').trim(); return /^https?:\/\//i.test(s) ? s : ''; } function iconSvg(type){ const common = `width="24" height="24" viewBox="0 0 24 24" fill="none" aria-hidden="true"`; const car = ``; const bus = ``; const taxi = ``; const k = String(type||'').toLowerCase(); if (k.includes('bus')) return bus; if (k.includes('taxi')) return taxi; return car; } function pinSvg(){ return ``; } function chevDownSvg(){ return ``; } function resolveRestriction(cat, ymd){ const rule = cat.rule || {}; if (rule.type === "date_map"){ const v = (rule.map || {})[ymd]; if (!v) return { kind:"unknown", value:"SIN INFORMACIÓN" }; if (String(v).toUpperCase() === "NO_APLICA") return { kind:"na", value:"NO APLICA" }; return { kind:"digits", value:String(v) }; } return { kind:"unknown", value:"SIN INFORMACIÓN" }; } function mount(root){ const tz = getTZ(root); const key = String(root.getAttribute("data-key") || "").trim(); const cfg = window.PZ_PYP_DATA && window.PZ_PYP_DATA[key] ? window.PZ_PYP_DATA[key] : null; if (!cfg) throw new Error(`No existe window.PZ_PYP_DATA["${key}"]. Revisa data-key.`); const city = cfg.city; const catsAll = (Array.isArray(city.categories) ? city.categories : []) .filter(c => c && c.enabled !== false) .slice() .sort((a,b)=>Number(a.priority||99)-Number(b.priority||99)); root.innerHTML = `
PICO Y PLACA ${String(city.name||'').toUpperCase()}
Desliza para ver más
⚠️ Si vas a viajar, revisa el pico y placa para la fecha de tu viaje.
`; const $ = (s) => root.querySelector(s); const elStrip = $('.pz-strip'); const elDateDisplay = $('.pz-date-display'); const elPages = $('.pz-pages'); const elDots = $('.pz-dots'); const elPrev = $('.pz-nav--prev'); const elNext = $('.pz-nav--next'); const elSwipe = $('.pz-swipehint'); const elCredits = $('.pz-credits'); const elCitySel = $('.pz-cityselect'); const opts = city.switch?.options || []; elCitySel.innerHTML = opts.map(o => ``).join(''); elCitySel.addEventListener('change', (e) => { const u = safeUrl(e.target.value); if (u) window.location.href = u; }); const srcName = String(city.source?.name || 'Fuente oficial').trim(); const srcUrl = safeUrl(city.source?.url || ''); elCredits.innerHTML = srcUrl ? `Fuente: ${srcName}` : `Fuente: ${srcName}`; let todayYMD = ymdFromParts(nowPartsInTZ(tz)); let selectedYMD = todayYMD; function renderStrip(){ const days = []; for (let i=0;i<9;i++) days.push(addDaysYMD(todayYMD, i)); elStrip.innerHTML = days.map(ymd => { const isToday = ymd === todayYMD; const isSel = ymd === selectedYMD; const chip = dayChipES(tz, ymd, isToday); return ` `; }).join(''); elStrip.querySelectorAll('.pz-day').forEach(btn=>{ btn.addEventListener('click', ()=>{ selectedYMD = btn.getAttribute('data-ymd'); renderStrip(); renderAll(); }); }); } let perView = 4; let pageIndex = 0; let pages = []; function computePerView(){ const w = root.getBoundingClientRect().width || window.innerWidth; if (w < 600) return 1; if (w < 980) return 2; return 4; } function chunk(arr, size){ const out = []; for (let i=0;i
${iconSvg(cat.icon || cat.id)}
${String(cat.name||cat.id).toUpperCase()}
${String(cat.plate_label || 'Placas terminadas en:')}
--
Horario
--
`; } function renderPages(){ perView = computePerView(); pageIndex = 0; const single = catsAll.length === 1; if (single) perView = 1; if (single) pages = [catsAll]; else if (perView === 4) pages = [catsAll.slice(0,4)]; else pages = chunk(catsAll, perView); elPages.innerHTML = pages.map((cats, idx) => { const klass = `pz-page ${idx===0?'is-active':''} pz-per-${perView} ${single?'pz-single':''}`; return `
${cats.map(cat => cardHtml(cat)).join('')}
`; }).join(''); if (perView === 4 || single){ elDots.innerHTML = ''; } else { elDots.innerHTML = pages.map((_,i)=> ``).join(''); elDots.querySelectorAll('.pz-dot').forEach((d,i)=> d.addEventListener('click', ()=>goTo(i))); } const showNav = (!single) && (perView !== 4) && pages.length > 1; elPrev.style.display = showNav ? 'flex' : 'none'; elNext.style.display = showNav ? 'flex' : 'none'; elSwipe.style.display = showNav ? 'block' : 'none'; elDots.style.display = showNav ? 'flex' : 'none'; updateNavState(); updateCardsDynamic(); } function goTo(i){ pageIndex = Math.max(0, Math.min(i, pages.length-1)); elPages.querySelectorAll('.pz-page').forEach(p=>p.classList.remove('is-active')); const active = elPages.querySelector(`.pz-page[data-page="${pageIndex}"]`); if (active) active.classList.add('is-active'); elDots.querySelectorAll('.pz-dot').forEach((d,idx)=>d.classList.toggle('is-active', idx===pageIndex)); updateNavState(); updateCardsDynamic(); } function updateNavState(){ const single = catsAll.length === 1; if (single || perView === 4){ elPrev.disabled = true; elNext.disabled = true; elPrev.style.opacity = 0; elNext.style.opacity = 0; return; } elPrev.disabled = pageIndex<=0; elNext.disabled = pageIndex>=pages.length-1; elPrev.style.opacity = elPrev.disabled ? .35 : 1; elNext.style.opacity = elNext.disabled ? .35 : 1; } function renderAll(){ elDateDisplay.textContent = prettyDateHeaderES(tz, selectedYMD); renderPages(); } function updateCardsDynamic(){ const nowP = nowPartsInTZ(tz); todayYMD = ymdFromParts(nowP); const nowMin = minutesOfDayFromParts(nowP); const isToday = selectedYMD === todayYMD; renderStrip(); elDateDisplay.textContent = prettyDateHeaderES(tz, selectedYMD); root.querySelectorAll('.pz-card').forEach(card=>{ const id = card.getAttribute('data-cat'); const cat = catsAll.find(c=>c.id===id); if (!cat) return; const r = resolveRestriction(cat, selectedYMD); const elValue = card.querySelector('.pz-value'); const elHours = card.querySelector('.pz-bandhours'); const elTimer = card.querySelector('.pz-timer'); elTimer.style.display = 'none'; elTimer.textContent = ''; const sched = Array.isArray(cat.schedule) ? cat.schedule : []; if (r.kind === 'na'){ elValue.textContent = 'NO APLICA'; elHours.textContent = 'No aplica'; return; } if (r.kind === 'unknown'){ elValue.textContent = 'SIN INFORMACIÓN'; elHours.textContent = scheduleLabel(sched); return; } elValue.textContent = r.value; elHours.textContent = scheduleLabel(sched); if (!isToday || !sched.length) return; const t2 = endTimingOnly(sched, nowMin); if (t2.kind === 'end'){ const hm = hmFromDelta(t2.at - nowMin); elTimer.style.display = 'block'; elTimer.textContent = `Termina en ${hm.h}h ${pad2(hm.m)}m`; } }); } elPrev.addEventListener('click', ()=>goTo(pageIndex-1)); elNext.addEventListener('click', ()=>goTo(pageIndex+1)); let startX = null; elPages.addEventListener('touchstart', (e)=>{ if (catsAll.length === 1) return; if (perView === 4) return; startX = e.touches && e.touches[0] ? e.touches[0].clientX : null; }, {passive:true}); elPages.addEventListener('touchend', (e)=>{ if (catsAll.length === 1) return; if (perView === 4 || startX === null) return; const endX = e.changedTouches && e.changedTouches[0] ? e.changedTouches[0].clientX : null; if (endX === null) return; const dx = endX - startX; if (Math.abs(dx) > 40){ if (dx < 0) goTo(pageIndex+1); else goTo(pageIndex-1); } startX = null; }, {passive:true}); renderStrip(); renderAll(); updateCardsDynamic(); root._pzTimer && clearInterval(root._pzTimer); root._pzTimer = setInterval(() => updateCardsDynamic(), 30*1000); window.addEventListener('resize', ()=>{ const newPV = computePerView(); if (newPV !== perView) renderAll(); }); } })();
Redacción Seguros Bolívar

¡Hola! Somos el equipo de redacción. A través de nuestros artículos también queremos brindar tranquilidad y enriquecer la vida con integridad. Por eso, aquí ofrecemos contenidos educativos, recomendaciones, noticias y mucho más. Bienvenidos todos los lectores y las empresas que desean aprender y actualizarse con información de calidad.

Recent Posts

Temporada de lluvias: consejos de prevención y seguridad

Ante la ola invernal que actualmente vivimos en el país, es importante implementar medidas de prevención y seguridad. ¡Tome nota!

29 January, 2026

¿Cómo prevenir el cáncer con hábitos diarios?

Según la OPS, el cáncer que causa más muertes entre los hombres es el de pulmón (18%) y en las…

29 January, 2026

8 pistas para ahorrar energía en casa y cuidar el medio ambiente

Ahorre energía en casa con estos 8 consejos prácticos. Reduzca su consumo, cuide el medio ambiente y mejore el bienestar…

28 January, 2026

PROFE ARL 2026: formación, tecnología y prevención para transformar la seguridad laboral en Colombia

Conozca PROFE ARL 2026, el programa de Seguros Bolívar ARL que transforma la seguridad y salud en el trabajo con…

27 January, 2026

Impacto geopolítico en la cadena de suministro: claves para líderes logísticos en América Latina

La geopolítica está redefiniendo la logística global. Descubra cómo anticipar riesgos y fortalecer su cadena de suministro en América Latina.

23 January, 2026

Día Sin Carro y Sin Moto 2026: Lo que debe saber

Conozca detalles de la jornada que tiene como objetivo promover el uso de otras alternativas de transporte y reducir la…

23 January, 2026