import './bootstrap'; import 'bootstrap'; import './api-keys'; import '../css/api-keys.css'; import '../css/api-key-status.css'; const icons = { light: '☀', dark: '☾', system: '◐' }; function updateThemeControls(event) { const state = event?.detail ?? { preference: window.ThemeManager.getPreference(), resolved: window.ThemeManager.getResolvedTheme(), }; document.querySelectorAll('[data-theme-value]').forEach((button) => { const active = button.dataset.themeValue === state.preference; button.classList.toggle('active', active); button.setAttribute('aria-pressed', String(active)); button.setAttribute('aria-current', active ? 'true' : 'false'); const check = button.querySelector('[data-theme-check]'); if (check) check.hidden = !active; }); document.querySelectorAll('[data-theme-current-label]').forEach((node) => { node.textContent = document.querySelector(`[data-theme-value="${state.preference}"]`)?.dataset.themeLabel ?? state.preference; }); document.querySelectorAll('[data-theme-current-icon]').forEach((node) => { node.textContent = icons[state.preference]; }); document.querySelectorAll('[data-theme-preference]').forEach((node) => { node.textContent = document.querySelector(`[data-theme-value="${state.preference}"]`)?.dataset.themeLabel ?? state.preference; }); document.querySelectorAll('[data-theme-resolved]').forEach((node) => { node.textContent = document.querySelector(`[data-theme-value="${state.resolved}"]`)?.dataset.themeLabel ?? state.resolved; }); } document.addEventListener('click', (event) => { const button = event.target.closest('[data-theme-value]'); if (button) { window.ThemeManager.setPreference(button.dataset.themeValue); } }); document.querySelector('[data-settings-theme]')?.addEventListener('change', event => window.ThemeManager.setPreference(event.target.value)); if (document.querySelector('input[name="reduced_motion"]:checked')) document.documentElement.dataset.reducedMotion = 'true'; window.addEventListener('trafficpumper:theme-change', updateThemeControls); updateThemeControls(); function renderRankingCharts() { document.querySelectorAll('[data-ranking-chart]').forEach((container) => { const series = JSON.parse(container.dataset.rankingChart || '[]'); const colors = ['#6d5dfc', '#16a085', '#e45175', '#e6a23c', '#2d8cf0', '#8e44ad']; const width = 900, height = 320, pad = 38; const points = series.flatMap((item) => item.points); if (!points.length) return; const dates = points.map((point) => new Date(point.date).getTime()); const minDate = Math.min(...dates), maxDate = Math.max(...dates); const x = (date) => pad + ((new Date(date).getTime() - minDate) / Math.max(1, maxDate - minDate)) * (width - pad * 2); const y = (rank) => pad + ((rank - 1) / 99) * (height - pad * 2); const grid = [1, 10, 20, 50, 100].map((rank) => `${rank}`).join(''); const paths = series.map((item, index) => { const coordinates = item.points.map((point) => `${x(point.date)},${y(point.rank)}`).join(' '); const dots = item.points.map((point) => `${item.keyword} · ${item.project} · #${point.rank} · ${new Date(point.date).toLocaleString()}`).join(''); return `${dots}`; }).join(''); const legend = series.map((item,index)=>`${item.keyword}`).join(''); container.innerHTML = `
${legend}
`; }); } renderRankingCharts(); window.addEventListener('trafficpumper:theme-change', renderRankingCharts); function renderVisibilityCharts(){document.querySelectorAll('[data-visibility-chart]').forEach(container=>{const data=JSON.parse(container.dataset.visibilityChart||'{}');const all=[...(data.current||[]),...(data.previous||[])];if(!all.length)return;const w=900,h=300,p=35;const dates=all.map(x=>new Date(x.date).getTime()),min=Math.min(...dates),max=Math.max(...dates);const x=d=>p+(new Date(d).getTime()-min)/Math.max(1,max-min)*(w-p*2),y=v=>h-p-(v/100)*(h-p*2);const series=(points,color,dash='')=>``+points.map(q=>`${q.date} · ${q.score}% · ${q.measured}`).join('');container.innerHTML=`${[0,25,50,75,100].map(v=>`${v}%`).join('')}${series(data.current||[],'#6d5dfc')}${series(data.previous||[],'#16a085','7 5')}`;});}renderVisibilityCharts();window.addEventListener('trafficpumper:theme-change',renderVisibilityCharts);