diff --git a/frontend/textbooks/physics_10_ch5.html b/frontend/textbooks/physics_10_ch5.html
index 6b9ce94..9c507b7 100644
--- a/frontend/textbooks/physics_10_ch5.html
+++ b/frontend/textbooks/physics_10_ch5.html
@@ -2874,35 +2874,629 @@ function build_p32(){
function build_p33(){
const box = document.getElementById('p33-body');
let html = '';
- html += makeCard('theory', "Самоиндукция", "§33", `
-
Самоиндукция — этот параграф в разработке (Phase 1+).
-
Здесь появятся: теория, формулы, разобранные примеры и 3–4 интерактива в стиле «алгебры 11» — таблицы, симуляции, ползунки, drag-and-drop и автопроверяемые тренажёры.
-
- Phase 0: создан скелет учебника. Phase 5+: наполнение этого § содержанием по учебнику «Физика 10» (Беларусь, 2019).
-
+
+ /* THEORY 1 — Самоиндукция и индуктивность */
+ html += makeCard('theory', "Самоиндукция и индуктивность", "§33", `
+
Самоиндукция — возникновение ЭДС индукции в катушке при изменении тока в этой же катушке.
+
Когда ток меняется, магнитный поток через катушку (созданный её собственным током) тоже меняется — это вызывает ЭДС индукции по закону Фарадея.
+
Индуктивность $L$ — характеристика катушки, показывающая, какой магнитный поток создаётся в ней при данном токе:
+
$$\\Phi = LI$$
+
где $\\Phi$ — магнитный поток через все витки катушки, $I$ — ток в ней.
+
Единица индуктивности: Генри (Гн) = Вб/А. 1 Гн — индуктивность катушки, в которой ток 1 А создаёт магнитный поток 1 Вб.
+
$L$ зависит от:
+
+
числа витков $N$ (квадратично — $L \\propto N^2$);
+
геометрии (длина $\\ell$, площадь сечения $S$);
+
магнитной проницаемости сердечника (с ферромагнитным сердечником $L$ в сотни раз больше).
+
+
Аналогия. Индуктивность $L$ для тока — как масса $m$ для скорости: чем больше $L$, тем «тяжелее» меняется ток. Это «электромагнитная инерция».
`);
+
+ /* THEORY 2 — ЭДС самоиндукции */
+ html += makeCard('rule', "ЭДС самоиндукции", "§33", `
+
Если ток в катушке меняется со скоростью $\\Delta I/\\Delta t$, в ней возникает ЭДС самоиндукции:
При замыкании цепи ток не достигает $I_{\\max} = \\mathcal{E}/R$ мгновенно — самоиндукция тормозит его рост: $I(t) = I_{\\max}(1 - e^{-t/\\tau})$, где $\\tau = L/R$.
+
+
+
+
+
+
+
+
+
+
+
`;
+
+ /* INTERACTIVE 2 — Калькулятор индуктивности и энергии */
+ html += `
`;
+
html += secNav('p32', 'final5');
html += readButton('p33');
+
box.innerHTML = html;
renderMath(box);
+
+ /* IV1 — LR-цепь */
+ (function(){
+ const svg = document.getElementById('p33-iv1-svg');
+ const out = document.getElementById('p33-iv1-out');
+ const EI = document.getElementById('p33-iv1-E'), EL = document.getElementById('p33-iv1-EL');
+ const RI = document.getElementById('p33-iv1-R'), RL = document.getElementById('p33-iv1-RL');
+ const LI = document.getElementById('p33-iv1-L'), LL = document.getElementById('p33-iv1-LL');
+ const bGo = document.getElementById('p33-iv1-go');
+ const bRs = document.getElementById('p33-iv1-reset');
+ let animT0 = null, running = false, rafId = null;
+ let configs = new Set();
+ let _done = false;
+
+ function draw(progress){
+ const W = 480, H = 260;
+ const E = +EI.value, R = +RI.value, L = (+LI.value) / 1000; // Гн
+ EL.textContent = E.toFixed(1);
+ RL.textContent = R.toString();
+ LL.textContent = (+LI.value).toString();
+ const Imax = E / R;
+ const tau = L / R;
+ // total animation time ~ 5*tau, мин 0.6 с, макс 3 с
+ const animDur = Math.max(0.6, Math.min(3, 5*tau));
+ const tReal = progress * animDur;
+ const I = Imax * (1 - Math.exp(-tReal / tau));
+
+ let g = '';
+ g += '';
+ g += 'RL-цепь: ток нарастает как $I(t) = I_{max}(1 - e^{-t/τ})$';
+
+ // Schema slot (left): battery + switch + R + L (квадрат)
+ // Координаты схемы
+ const sx = 30, sy = 60, sw = 200, sh = 160;
+ g += '';
+ // прямоугольный контур цепи
+ const cx1 = sx+30, cx2 = sx+sw-20;
+ const cy1 = sy+40, cy2 = sy+sh-30;
+ // верх
+ g += PHYS.wire(cx1, cy1, cx1+50, cy1); // от + батареи направо
+ g += PHYS.wire(cx1+50+10, cy1, cx2, cy1); // через ключ к правому верх. углу (промежуток для ключа)
+ // правый бок (L)
+ g += PHYS.wire(cx2, cy1, cx2, cy1+30);
+ // L symbol в правой стороне (горизонталь нарисуем посередине правой стороны)
+ g += PHYS.inductorSymbol((cx2), (cy1+cy2)/2, undefined, 'h');
+ // соединение L и правого бока
+ g += PHYS.wire(cx2, (cy1+cy2)/2 + 12, cx2, cy2);
+ // низ
+ g += PHYS.wire(cx2, cy2, cx1+90, cy2);
+ // R в нижней части
+ g += PHYS.resistor(cx1+70, cy2);
+ g += PHYS.wire(cx1+70-20, cy2, cx1, cy2);
+ // левый бок (батарея)
+ g += PHYS.wire(cx1, cy2, cx1, cy1+30);
+ g += PHYS.batteryEMF(cx1, (cy1+cy2)/2, undefined, 'v');
+ g += PHYS.wire(cx1, (cy1+cy2)/2 - 12, cx1, cy1);
+
+ // Ключ (наклонная линия): закрыт если running или progress>0
+ const swX1 = cx1+50, swX2 = cx1+50+10;
+ if(running || progress > 0){
+ g += '';
+ } else {
+ g += '';
+ }
+ g += '';
+ g += '';
+
+ // Подписи параметров
+ g += 'ε='+E.toFixed(1)+' В';
+ g += 'R='+R+' Ом';
+ g += 'L='+(+LI.value)+' мГн';
+
+ // График справа
+ const gx = 260, gy = 50, gw = 200, gh = 170;
+ g += '';
+ // оси
+ g += '';
+ g += '';
+ g += 't';
+ g += 'I';
+ // линия Imax (пунктир)
+ const imaxY = gy + 22;
+ g += '';
+ g += 'I_max';
+ // линия 0.63 Imax — для подписи τ
+ const tauY = gy + 22 + 0.37 * ((gy+gh-25) - imaxY);
+ g += '';
+ g += '0.63 I_max';
+ // кривая до текущего progress (или полная при progress=1)
+ const steps = 60;
+ let path = '';
+ const tFinal = progress * 5*tau / Math.max(1e-9, animDur); // нормированно к τ
+ const sMax = Math.min(5, 5 * progress * (animDur / (5*tau))); // безразмерное по τ
+ for(let k=0; k<=steps; k++){
+ const s = (k/steps) * sMax; // s = t/τ
+ const iv = 1 - Math.exp(-s);
+ const px = (gx+30) + (s/5) * ((gx+gw-10) - (gx+30));
+ const py = imaxY + (1 - iv) * ((gy+gh-25) - imaxY);
+ path += (k===0?'M ':'L ') + px.toFixed(1) + ' ' + py.toFixed(1) + ' ';
+ }
+ if(progress > 0) g += '';
+
+ // подпись τ — отметка x = τ на оси (s=1 в нормировке)
+ const tauX = (gx+30) + (1/5) * ((gx+gw-10) - (gx+30));
+ g += '';
+ g += 'τ';
+
+ svg.innerHTML = g;
+
+ const tauMs = tau * 1000;
+ out.innerHTML = '$I_{max} = \\mathcal{E}/R = '+Imax.toFixed(3)+'$ А $\\tau = L/R = '+tauMs.toFixed(2)+'$ мс Текущий ток: $I = '+I.toFixed(3)+'$ А';
+ renderMath(out);
+ }
+
+ function step(now){
+ if(!running){ return; }
+ if(!animT0) animT0 = now;
+ const E = +EI.value, R = +RI.value, L = (+LI.value)/1000;
+ const tau = L/R;
+ const animDur = Math.max(0.6, Math.min(3, 5*tau));
+ const elapsed = (now - animT0) / 1000;
+ const p = Math.min(1, elapsed / animDur);
+ draw(p);
+ if(p < 1){ rafId = requestAnimationFrame(step); }
+ else {
+ running = false;
+ const key = (+EI.value).toFixed(1)+'|'+RI.value+'|'+LI.value;
+ configs.add(key);
+ if(!_done && configs.size >= 4){ _done = true; addXp(15, 'p33-iv1'); bumpProgress('p33', 20); }
+ }
+ }
+ function start(){
+ if(running) return;
+ animT0 = null; running = true;
+ rafId = requestAnimationFrame(step);
+ }
+ function reset(){
+ running = false; if(rafId) cancelAnimationFrame(rafId);
+ draw(0);
+ }
+ bGo.addEventListener('click', start);
+ bRs.addEventListener('click', reset);
+ [EI, RI, LI].forEach(el => el.addEventListener('input', ()=>{ reset(); }));
+ draw(0);
+ })();
+
+ /* IV2 — Калькулятор */
+ (function(){
+ const out = document.getElementById('p33-iv2-out');
+ const bGo = document.getElementById('p33-iv2-calc');
+ const iL = document.getElementById('p33-iv2-L');
+ const iI = document.getElementById('p33-iv2-I');
+ const iDI = document.getElementById('p33-iv2-dI');
+ const iDT = document.getElementById('p33-iv2-dt');
+ let count = 0, _done = false;
+
+ function calc(){
+ const L = +iL.value, I = +iI.value, dI = +iDI.value, dt = +iDT.value;
+ if(![L,I,dI,dt].every(isFinite) || L < 0 || dt <= 0){
+ out.innerHTML = 'Проверь ввод: $L \\ge 0$, $\\Delta t > 0$.';
+ renderMath(out);
+ return;
+ }
+ const phi = L * I;
+ const W = L * I * I / 2;
+ const Esi = L * Math.abs(dI) / dt;
+ let html = '';
+ html += '$\\Phi = LI = '+L+'\\cdot '+I+' = $ '+phi.toFixed(4)+' Вб ';
+ html += '$W = \\dfrac{LI^2}{2} = \\dfrac{'+L+'\\cdot '+(I*I)+'}{2} = $ '+W.toFixed(4)+' Дж ';
+ html += '$|\\mathcal{E}_{si}| = L\\,\\dfrac{|\\Delta I|}{\\Delta t} = '+L+'\\cdot \\dfrac{'+Math.abs(dI)+'}{'+dt+'} = $ '+Esi.toFixed(4)+' В';
+ out.innerHTML = html;
+ renderMath(out);
+ count++;
+ if(!_done && count >= 3){ _done = true; addXp(10, 'p33-iv2'); bumpProgress('p33', 15); }
+ }
+ bGo.addEventListener('click', calc);
+ [iL, iI, iDI, iDT].forEach(x => x.addEventListener('keydown', e => { if(e.key==='Enter') calc(); }));
+ })();
+
+ /* IV3 — Что произойдёт с током? */
+ (function(){
+ const OPTS = ['Растёт постепенно', 'Падает постепенно', 'Не меняется / нет ЭДС'];
+ const Q = [
+ { q:'Цепь с $L$ замыкают (был разомкнут). Что происходит с током?', ans:0, why:'Самоиндукция тормозит рост, но ток постепенно растёт от 0 до $I_{max} = \\mathcal{E}/R$.' },
+ { q:'Цепь с $L$ размыкают. Что происходит с током до размыкания (в катушке)?', ans:1, why:'Самоиндукция поддерживает ток, но он постепенно падает до 0 (может проскочить искра).' },
+ { q:'В катушке течёт постоянный ток $I = 5$ А ($\\Delta I = 0$). Чему равна $\\mathcal{E}_{si}$?', ans:2, why:'$\\mathcal{E}_{si} = -L\\,\\Delta I/\\Delta t = 0$ при $\\Delta I = 0$. ЭДС самоиндукции не возникает.' },
+ { q:'В цепи нет индуктивности ($L = 0$). Замкнули — что с током?', ans:2, why:'$\\tau = L/R = 0$. Ток мгновенно устанавливается на $I_{max} = \\mathcal{E}/R$. Постепенного изменения нет.' },
+ { q:'$L$ увеличили в 2 раза (при тех же $\\mathcal{E}$ и $R$). После замыкания цепи — как ведёт себя ток?', ans:0, why:'$\\tau = L/R$ удвоится → ток растёт медленнее, но всё равно растёт до того же $I_{max}$.' },
+ { q:'Катушку с током отключили от источника, но замкнули на резистор. Что с током в катушке сразу после?', ans:1, why:'Энергия $LI^2/2$ постепенно рассеивается в $R$ → ток экспоненциально падает: $I(t) = I_0 e^{-t/\\tau}$.' }
+ ];
+ let i = 0, score = 0;
+ const qEl = document.getElementById('p33-iv3-q');
+ const oEl = document.getElementById('p33-iv3-opts');
+ const fb = document.getElementById('p33-iv3-fb');
+ const iEl = document.getElementById('p33-iv3-i');
+ const sEl = document.getElementById('p33-iv3-s');
+
+ function show(){
+ if(i >= Q.length){
+ qEl.innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length;
+ oEl.innerHTML = '';
+ if(score === Q.length){ addXp(15, 'p33-iv3'); bumpProgress('p33', 25); }
+ else if(score >= 4){ addXp(8, 'p33-iv3'); bumpProgress('p33', 15); }
+ return;
+ }
+ iEl.textContent = (i+1);
+ sEl.textContent = score;
+ qEl.innerHTML = Q[i].q;
+ oEl.innerHTML = OPTS.map((t, k) => '').join('');
+ fb.style.display = 'none';
+ renderMath(qEl);
+ oEl.querySelectorAll('button').forEach(b => {
+ b.addEventListener('click', () => {
+ const v = +b.dataset.v;
+ if(v === Q[i].ans){ score++; feedback(fb, true, '✓ Верно! ' + Q[i].why + ' Дальше ▶'); }
+ else feedback(fb, false, '✗ Верно: ' + OPTS[Q[i].ans] + '. ' + Q[i].why + ' Дальше ▶');
+ sEl.textContent = score;
+ oEl.querySelectorAll('button').forEach(x => x.disabled = true);
+ i++;
+ setTimeout(show, 1900);
+ });
+ });
+ }
+ document.getElementById('p33-iv3-restart').addEventListener('click', () => { i = 0; score = 0; show(); });
+ show();
+ })();
+
+ /* IV4 — Тренажёр индуктивности */
+ (function(){
+ const Q = [
+ { q:'$L = 0{,}5$ Гн, $I = 4$ А. Найди энергию магнитного поля $W$ (в Дж).', ans:4, tol:0.25, why:'$W = LI^2/2 = 0{,}5\\cdot 16/2 = 4$ Дж.' },
+ { q:'$L = 100$ мГн, $I = 2$ А. Найди магнитный поток $\\Phi$ (в мВб).', ans:200, tol:10, why:'$\\Phi = LI = 0{,}1\\cdot 2 = 0{,}2$ Вб $= 200$ мВб.' },
+ { q:'$L = 1$ Гн, $\\Delta I = 5$ А за $\\Delta t = 0{,}1$ с. Найди $|\\mathcal{E}_{si}|$ (в В).', ans:50, tol:2.5, why:'$|\\mathcal{E}_{si}| = L\\,|\\Delta I|/\\Delta t = 1\\cdot 5/0{,}1 = 50$ В.' },
+ { q:'Постоянная времени RL-цепи: $L = 0{,}5$ Гн, $R = 10$ Ом. Найди $\\tau$ (в мс).', ans:50, tol:2.5, why:'$\\tau = L/R = 0{,}5/10 = 0{,}05$ с $= 50$ мс.' },
+ { q:'Во сколько раз изменится энергия магнитного поля $W = LI^2/2$, если ток $I$ удвоить (при том же $L$)?', ans:4, tol:0.2, why:'$W \\propto I^2$ → удвоение $I$ даёт рост $W$ в $2^2 = 4$ раза.' }
+ ];
+ let i = 0, score = 0;
+ const qEl = document.getElementById('p33-iv4-q');
+ const fb = document.getElementById('p33-iv4-fb');
+ const iEl = document.getElementById('p33-iv4-i');
+ const sEl = document.getElementById('p33-iv4-s');
+ const inp = document.getElementById('p33-iv4-inp');
+ const bGo = document.getElementById('p33-iv4-go');
+
+ function show(){
+ if(i >= Q.length){
+ qEl.innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length;
+ inp.disabled = true; bGo.disabled = true;
+ if(score === Q.length){ addXp(15, 'p33-iv4'); bumpProgress('p33', 25); }
+ else if(score >= 3){ addXp(8, 'p33-iv4'); bumpProgress('p33', 15); }
+ return;
+ }
+ iEl.textContent = (i+1);
+ sEl.textContent = score;
+ qEl.innerHTML = Q[i].q;
+ fb.style.display = 'none';
+ inp.value = ''; inp.disabled = false; bGo.disabled = false; inp.focus();
+ renderMath(qEl);
+ }
+ function check(){
+ if(inp.disabled) return;
+ const v = parseFloat(inp.value.replace(',','.'));
+ if(!isFinite(v)){ feedback(fb, false, 'Введи число.'); return; }
+ const tol = Math.max(Q[i].tol, Math.abs(Q[i].ans)*0.05);
+ const ok = Math.abs(v - Q[i].ans) <= tol;
+ if(ok){ score++; feedback(fb, true, '✓ Верно! ' + Q[i].why + ' Дальше ▶'); }
+ else feedback(fb, false, '✗ Верно: ' + Q[i].ans + '. ' + Q[i].why + ' Дальше ▶');
+ sEl.textContent = score;
+ inp.disabled = true; bGo.disabled = true;
+ i++;
+ setTimeout(show, 1900);
+ }
+ bGo.addEventListener('click', check);
+ inp.addEventListener('keydown', e => { if(e.key==='Enter') check(); });
+ document.getElementById('p33-iv4-restart').addEventListener('click', () => { i = 0; score = 0; inp.disabled=false; bGo.disabled=false; show(); });
+ show();
+ })();
+
wireReadBtn('p33');
}
function build_final5(){
const box = document.getElementById('final5-body');
let html = '';
- html += makeCard('theory', "Финал главы 5", "★", `
-
Финал главы 5 — этот параграф в разработке (Phase 1+).
-
Здесь появятся: теория, формулы, разобранные примеры и 3–4 интерактива в стиле «алгебры 11» — таблицы, симуляции, ползунки, drag-and-drop и автопроверяемые тренажёры.
-
- Phase 0: создан скелет учебника. Phase 5+: наполнение этого § содержанием по учебнику «Физика 10» (Беларусь, 2019).
-
- `);
+
+ /* Часть А — Шпаргалка главы (7 mini-карточек) */
+ const SHEET = [
+ { t:'§ 27 · Поле тока', icon:'', body:'Создаётся движущимися зарядами. Опыт Эрстеда: стрелка возле проводника отклоняется.' },
+ { t:'§ 28 · Индукция $\\vec{B}$', icon:'', body:'$\\vec{B}$ — векторная характеристика поля (Тл). Правило буравчика. Линии замкнуты.' },
+ { t:'§ 29 · Сила Ампера', icon:'', body:'$F_A = BIL\\sin\\alpha$. Правило левой руки: 4 пальца — ток, ладонь — $\\vec{B}$, большой — $\\vec{F}$.' },
+ { t:'§ 30 · Лоренц', icon:'', body:'$F_L = qvB\\sin\\alpha$. Окружность: $R = mv/(qB)$. Работа $\\vec{F}_L$ = 0.' },
+ { t:'§ 31 · Поток $\\Phi$', icon:'', body:'$\\Phi = BS\\cos\\alpha$ [Вб]. ЭМИ — ток в контуре возникает при изменении $\\Phi$.' },
+ { t:'§ 32 · Фарадей + Ленц', icon:'', body:'$\\mathcal{E}_i = -N\\,\\Delta\\Phi/\\Delta t$. Ток индукции противодействует изменению потока.' },
+ { t:'§ 33 · Самоиндукция', icon:'', body:'$\\Phi = LI$, $L$ в Гн. $W = LI^2/2$. $\\mathcal{E}_{si} = -L\\,\\Delta I/\\Delta t$. $\\tau = L/R$.' },
+ ];
+
+ html += `
+
+ ${ICONS.theory}
+ Шпаргалка главы 5 — Магнитное поле и ЭМИ
+ Итог
+
+
+
Ключевые формулы и идеи всех 7 параграфов главы — повтори перед битвой с боссами.
+
+ ${SHEET.map(s => `
+
+ ${s.icon}
+
${s.t}
+
+
${s.body}
+
`).join('')}
+
+
+
`;
+
+ /* Часть Б — 7 боссов intro */
+ html += `
+
+ ${ICONS.rule}
+ Боссы главы 5
+ 7
+
+
+
7 интегрированных задач по §§27–33. За каждого побеждённого босса: +10 XP, +14% к прогрессу. Победишь всех — ачивка «Мастер магнетизма» и +50 XP бонус.