'use strict'; /* ────────────────────────────────────────────────────────────────── Exam 9 — Math 2025 renderer Variants loaded into window.VARIANTS by /js/exam9/variants/vNN.js ────────────────────────────────────────────────────────────────── */ const STORAGE_KEY = 'exam9_progress_v1'; let currentVariant = null; let katexLoaded = false; /* ── KaTeX bootstrap ────────────────────────────────────────────── */ function onKatexLoad() { katexLoaded = true; if (currentVariant !== null) runKatex(document.getElementById('ex-main')); } function runKatex(el) { if (!katexLoaded || !el) return; try { renderMathInElement(el, { delimiters: [ { left: '$$', right: '$$', display: true }, { left: '$', right: '$', display: false }, ], throwOnError: false, }); } catch {} } /* ── Progress in localStorage ───────────────────────────────────── */ function loadProgress() { try { return JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}'); } catch { return {}; } } function saveProgress(p) { try { localStorage.setItem(STORAGE_KEY, JSON.stringify(p)); } catch {} } function markSolutionViewed(variantNum, taskIdx) { const p = loadProgress(); p[variantNum] = p[variantNum] || []; if (!p[variantNum].includes(taskIdx)) { p[variantNum].push(taskIdx); saveProgress(p); } } /* ── Variant picker ─────────────────────────────────────────────── */ function buildGrid() { const grid = document.getElementById('variant-grid'); const progress = loadProgress(); grid.innerHTML = ''; Object.keys(VARIANTS).sort((a, b) => Number(a) - Number(b)).forEach(n => { const v = VARIANTS[n]; const total = (v.tasks || []).length; const viewed = (progress[n] || []).length; let cls = ''; if (viewed === total && total > 0) cls = ' done'; else if (viewed > 0) cls = ' partial'; const isActive = Number(n) === currentVariant ? ' active' : ''; const btn = document.createElement('button'); btn.className = 'vg-btn' + cls + isActive; btn.textContent = n; btn.title = `${v.label}${viewed === total ? ' ✓' : viewed > 0 ? ` (${viewed}/${total})` : ''}`; btn.onclick = () => { selectVariant(Number(n)); closePicker(); }; grid.appendChild(btn); }); } function togglePicker() { const overlay = document.getElementById('picker-overlay'); const btn = document.getElementById('picker-btn'); if (overlay.classList.contains('visible')) closePicker(); else { buildGrid(); overlay.classList.add('visible'); btn.classList.add('open'); document.addEventListener('keydown', onEsc); } } function closePicker() { document.getElementById('picker-overlay').classList.remove('visible'); document.getElementById('picker-btn').classList.remove('open'); document.removeEventListener('keydown', onEsc); } function onOverlayClick(e) { if (e.target === document.getElementById('picker-overlay')) closePicker(); } function onEsc(e) { if (e.key === 'Escape') closePicker(); } /* ── Task rendering ─────────────────────────────────────────────── */ function buildOpts(opts) { const isLong = opts.some(([, t]) => t.length > 40 && !t.startsWith('$')); const cls = isLong ? 'opts-vertical' : 'opts'; return `
` + opts.map(([l, t]) => `${l})${t}` ).join('') + `
`; } const SOL_ICON_CLOSED = ``; function renderVariant(num) { const main = document.getElementById('ex-main'); const v = VARIANTS[num]; if (!v) { main.innerHTML = '
Вариант не найден
'; return; } main.innerHTML = `
${v.label}${v.tasks.length} заданий
` + v.tasks.map((t, i) => `
${i + 1}
Задание ${i + 1}
${t.text}
${t.figure ? `
${t.figure}
` : ''} ${t.opts ? buildOpts(t.opts) : ''}
${t.sol ? `
${t.sol}
` : ''}
` ).join(''); runKatex(main); } function toggleSol(btn, variantNum, taskIdx) { const panel = btn.nextElementSibling; const open = panel.classList.contains('visible'); panel.classList.toggle('visible', !open); btn.classList.toggle('open', !open); btn.querySelector('span').textContent = open ? 'Показать решение' : 'Скрыть решение'; if (!open) { if (!panel.dataset.k) { runKatex(panel); panel.dataset.k = '1'; } markSolutionViewed(variantNum, taskIdx); } } function selectVariant(num) { currentVariant = num; document.getElementById('picker-label').textContent = VARIANTS[num].label; document.querySelectorAll('.vg-btn').forEach(b => { b.classList.toggle('active', Number(b.textContent) === num); }); renderVariant(num); // Persist last opened variant try { localStorage.setItem('exam9_last_variant', String(num)); } catch {} window.scrollTo({ top: 0, behavior: 'smooth' }); } /* ── Boot ───────────────────────────────────────────────────────── */ (function boot() { const keys = Object.keys(VARIANTS); if (!keys.length) { document.getElementById('ex-main').innerHTML = '
Варианты не загружены
'; return; } // Resume last opened variant or open first one let initial = Number(keys[0]); try { const last = Number(localStorage.getItem('exam9_last_variant')); if (last && VARIANTS[last]) initial = last; } catch {} selectVariant(initial); })();