diff --git a/frontend/textbooks/physics_10_ch2.html b/frontend/textbooks/physics_10_ch2.html
index f51782e..9588403 100644
--- a/frontend/textbooks/physics_10_ch2.html
+++ b/frontend/textbooks/physics_10_ch2.html
@@ -640,34 +640,694 @@ function wireReadBtn(paraId){
function build_p11(){
const box = document.getElementById('p11-body');
let html = '';
- html += makeCard('theory', "Внутренняя энергия", "§11", `
-
Внутренняя энергия — этот параграф в разработке (Phase 1+).
-
Здесь появятся: теория, формулы, разобранные примеры и 3–4 интерактива в стиле «алгебры 11» — таблицы, симуляции, ползунки, drag-and-drop и автопроверяемые тренажёры.
-
- Phase 0: создан скелет учебника. Phase 2+: наполнение этого § содержанием по учебнику «Физика 10» (Беларусь, 2019).
-
+
+ /* THEORY 1 — Термодинамическая система и внутренняя энергия */
+ html += makeCard('theory', "Термодинамическая система и внутренняя энергия", "§11", `
+
Термодинамическая система — совокупность тел, способных взаимодействовать друг с другом и с окружающими телами путём обмена энергией. Система может быть изолированной (нет обмена с окружением) или открытой.
+
Внутренняя энергия $U$ — энергия движения и взаимодействия частиц системы:
+
+
кинетическая энергия теплового движения молекул и атомов;
+
потенциальная энергия взаимодействия молекул.
+
+
Внутренняя энергия не включает:
+
+
кинетическую энергию системы как целого (например, движение сосуда);
+
потенциальную энергию системы во внешнем поле.
+
+
$U$ — функция состояния: зависит только от макропараметров системы ($T$, $V$, $\\nu$).
`);
+
+ /* THEORY 2 — Внутренняя энергия идеального газа */
+ html += makeCard('rule', "Внутренняя энергия идеального газа", "§11", `
+
Для идеального одноатомного газа (He, Ne, Ar) взаимодействие молекул отсутствует, поэтому $U$ — это только кинетическая энергия молекул:
+
$$U = \\dfrac{3}{2}\\,\\nu R T = \\dfrac{3}{2}\\,N k_B T$$
+
через массу:
+
$$U = \\dfrac{3}{2}\\,\\dfrac{m}{M}\\,R T$$
+
Главное: внутренняя энергия идеального газа зависит только от температуры! Не зависит от объёма или давления.
+
Изменение внутренней энергии:
+
$$\\Delta U = \\dfrac{3}{2}\\,\\nu R\\,\\Delta T$$
+
Для двухатомных газов ($\\text{H}_2$, $\\text{N}_2$, $\\text{O}_2$) добавляются 2 вращательные степени свободы (всего $i=5$):
+
$$U = \\dfrac{5}{2}\\,\\nu R T$$
+ `);
+
+ /* THEORY 3 — Способы изменения внутренней энергии */
+ html += makeCard('example', "Способы изменения внутренней энергии", "§11", `
+
Внутреннюю энергию системы можно изменить двумя способами:
+
1) Совершение работы $A$:
+
+
сжатие газа поршнем (работа внешних сил над газом, $A_{внеш} > 0$) — $U$ растёт;
+
расширение газа (газ совершает работу, $A_{газ} > 0$) — $U$ уменьшается;
`;
+
html += secNav(null, 'p12');
html += readButton('p11');
+
box.innerHTML = html;
renderMath(box);
+
+ /* IV1 — Калькулятор U */
+ (function(){
+ const R = 8.314;
+ const nu = document.getElementById('p11-iv1-nu');
+ const t = document.getElementById('p11-iv1-t');
+ const nuL = document.getElementById('p11-iv1-nuL');
+ const tL = document.getElementById('p11-iv1-tL');
+ const out = document.getElementById('p11-iv1-out');
+ const fb = document.getElementById('p11-iv1-fb');
+ let count = 0; let _done = false;
+
+ function getI(){ const r = document.querySelector('input[name="p11-iv1-gas"]:checked'); return r && r.value === 'di' ? 5 : 3; }
+ function fmtNum(v){ return v.toLocaleString('ru-RU', {maximumFractionDigits: 0}); }
+
+ function sync(){
+ nuL.textContent = (+nu.value).toFixed(1);
+ const tv = +t.value;
+ // snap к 273, 300, 373
+ const snaps = [273, 300, 373];
+ let ts = tv;
+ for(const s of snaps){ if(Math.abs(tv - s) <= 4){ ts = s; break; } }
+ tL.textContent = ts;
+ t.dataset.snap = ts;
+ }
+ nu.addEventListener('input', sync); t.addEventListener('input', sync); sync();
+
+ document.getElementById('p11-iv1-go').addEventListener('click', () => {
+ const nv = +nu.value, tv = +(t.dataset.snap || t.value), i = getI();
+ const U = i/2 * nv * R * tv;
+ const U2 = i/2 * nv * R * (tv + 100);
+ const dU = U2 - U;
+ const frac = i === 3 ? '\\tfrac{3}{2}' : '\\tfrac{5}{2}';
+ out.innerHTML = '
Подстановка:
'
+ + '
$U = '+frac+'\\,\\nu R T = '+frac+' \\cdot '+nv.toFixed(1)+' \\cdot 8{,}314 \\cdot '+tv+' \\approx '+fmtNum(U)+'$ Дж
'
+ + '
При нагреве до $T+100 = '+(tv+100)+'$ К:
'
+ + '
$\\Delta U = '+frac+'\\,\\nu R \\cdot 100 \\approx '+fmtNum(dU)+'$ Дж
';
+ renderMath(out);
+ feedback(fb, true, '✓ Вычислено.');
+ count++;
+ if(!_done && count >= 4){ _done = true; addXp(10,'p11-iv1'); bumpProgress('p11', 15); }
+ });
+ })();
+
+ /* IV2 — График U(T) */
+ (function(){
+ const R = 8.314;
+ const svg = document.getElementById('p11-iv2-svg');
+ const nu = document.getElementById('p11-iv2-nu');
+ const nuL = document.getElementById('p11-iv2-nuL');
+ const info = document.getElementById('p11-iv2-info');
+ const seen = new Set(); let _done = false;
+
+ function render(){
+ const nv = +nu.value;
+ nuL.textContent = nv.toFixed(1);
+ const W=380, H=260, pad=42;
+ // x: T 200..600 К; y: U 0..15 кДж
+ const a = axes2D(W, H, pad, 200, 600, 0, 15);
+ let g = a.content;
+ g += 'T, К';
+ g += 'U, кДж';
+ // мономерная U(T) в кДж: U_kJ = 1.5 * nv * R * T / 1000
+ const fMono = T => 1.5 * nv * R * T / 1000;
+ const fDi = T => 2.5 * nv * R * T / 1000;
+ g += plotFunc(fMono, 200, 600, a.toX, a.toY, '#2563eb');
+ g += plotFunc(fDi, 200, 600, a.toX, a.toY, '#ea580c');
+ // подписи в конце линий
+ g += '';
+ g += '';
+ svg.innerHTML = g;
+
+ const Umono300 = (1.5 * nv * R * 300).toFixed(0);
+ const Udi300 = (2.5 * nv * R * 300).toFixed(0);
+ info.innerHTML = '$\\nu = '+nv.toFixed(1)+'$ моль. При $T = 300$ К: '
+ + '$U_{одно} \\approx '+Umono300+'$ Дж, '
+ + '$U_{двух} \\approx '+Udi300+'$ Дж. '
+ + 'Линейная зависимость $U \\propto T$; двухатомный газ имеет больше степеней свободы — наклон круче.';
+ renderMath(info);
+
+ seen.add(Math.round(nv*10));
+ if(!_done && seen.size >= 4){ _done = true; addXp(10,'p11-iv2'); bumpProgress('p11', 15); }
+ }
+ nu.addEventListener('input', render);
+ render();
+ })();
+
+ /* IV3 — DnD сортер */
+ (function(){
+ const items = [
+ { id:'a1', cat:'work', html:'Сжатие газа в насосе' },
+ { id:'a2', cat:'heat', html:'Нагревание чайника на плите' },
+ { id:'a3', cat:'work', html:'Накачивание шины' },
+ { id:'a4', cat:'heat', html:'Кубик льда тает в воде' },
+ { id:'a5', cat:'work', html:'Газ расширяется в цилиндре, толкая поршень' },
+ { id:'a6', cat:'heat', html:'Кофе остывает в чашке' },
+ ];
+ const sorter = setupSorter({
+ poolId:'p11-iv3-pool',
+ scopeSelector:'#p11-iv3',
+ items: items,
+ cats:['work','heat'],
+ columnLayout:false,
+ });
+ document.getElementById('p11-iv3-check').addEventListener('click', () => {
+ const fb = document.getElementById('p11-iv3-fb');
+ const placedCount = items.filter(it => sorter.placed[it.id]).length;
+ const correct = items.filter(it => sorter.placed[it.id] === it.cat).length;
+ if(placedCount < items.length){ feedback(fb, false, '✗ Размести все 6 ситуаций.'); return; }
+ if(correct === items.length){ feedback(fb, true, '✓ Все 6 верно! +10 XP'); addXp(10,'p11-iv3'); bumpProgress('p11', 15); }
+ else feedback(fb, false, '✗ Правильно ' + correct + ' из 6. Попробуй ещё.');
+ });
+ document.getElementById('p11-iv3-reset').addEventListener('click', () => { sorter.reset(); document.getElementById('p11-iv3-fb').style.display = 'none'; });
+ })();
+
+ /* IV4 — Тренажёр */
+ (function(){
+ const Q = [
+ { q:'1 моль одноатомного газа при $T = 300$ К. $U$ в Дж?', ans:3735, tol:50, hint:'$U = \\tfrac{3}{2}\\nu RT = 1{,}5 \\cdot 1 \\cdot 8{,}3 \\cdot 300 = 3735$' },
+ { q:'2 моль одноатомного газа при $T = 400$ К. $U$ в Дж?', ans:9960, tol:100, hint:'$U = 1{,}5 \\cdot 2 \\cdot 8{,}3 \\cdot 400 = 9960$' },
+ { q:'Одноатомный газ при $T = 300$ К имеет $U = 3735$ Дж. Каким станет $U$ при $T = 600$ К (в Дж)?', ans:7470, tol:100, hint:'$U \\propto T$: при удвоении $T$ — $U$ удваивается.' },
+ { q:'1 моль двухатомного газа при $T = 300$ К. $U$ в Дж?', ans:6225, tol:80, hint:'$U = \\tfrac{5}{2}\\nu RT = 2{,}5 \\cdot 1 \\cdot 8{,}3 \\cdot 300 = 6225$' },
+ { q:'2 моль одноатомного газа нагрели на $\\Delta T = 100$ К. $\\Delta U$ в Дж?', ans:2490, tol:50, hint:'$\\Delta U = \\tfrac{3}{2}\\nu R \\Delta T = 1{,}5 \\cdot 2 \\cdot 8{,}3 \\cdot 100 = 2490$' },
+ { q:'Зависит ли $U$ идеального газа от объёма? Введи 1 (да) или 2 (нет).', ans:2, tol:0.01, hint:'$U$ идеального газа зависит только от $T$.' },
+ ];
+ let i = 0, score = 0;
+ function show(){
+ if(i >= Q.length){
+ document.getElementById('p11-iv4-q').innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length;
+ if(score === Q.length){ addXp(15, 'p11-iv4'); bumpProgress('p11', 25); }
+ else if(score >= 4){ addXp(8, 'p11-iv4'); bumpProgress('p11', 15); }
+ return;
+ }
+ document.getElementById('p11-iv4-i').textContent = (i+1);
+ document.getElementById('p11-iv4-s').textContent = score;
+ document.getElementById('p11-iv4-q').innerHTML = Q[i].q;
+ document.getElementById('p11-iv4-ans').value = '';
+ renderMath(document.getElementById('p11-iv4-q'));
+ document.getElementById('p11-iv4-fb').style.display = 'none';
+ }
+ function go(){
+ if(i >= Q.length) return;
+ const fb = document.getElementById('p11-iv4-fb');
+ const raw = document.getElementById('p11-iv4-ans').value.replace(',', '.');
+ const ans = parseFloat(raw);
+ if(isNaN(ans)){ feedback(fb, false, '✗ Введи число.'); return; }
+ if(Math.abs(ans - Q[i].ans) <= Q[i].tol + 0.001){ score++; feedback(fb, true, '✓ Верно! '+Q[i].hint+'. Дальше ▶'); }
+ else feedback(fb, false, '✗ Неверно. Ответ: $'+Q[i].ans+'$. '+Q[i].hint+'. Дальше ▶');
+ document.getElementById('p11-iv4-s').textContent = score;
+ i++;
+ setTimeout(show, 1800);
+ }
+ document.getElementById('p11-iv4-go').addEventListener('click', go);
+ document.getElementById('p11-iv4-ans').addEventListener('keydown', e => { if(e.key === 'Enter') go(); });
+ document.getElementById('p11-iv4-start').addEventListener('click', () => { i = 0; score = 0; show(); });
+ show();
+ })();
+
wireReadBtn('p11');
}
function build_p12(){
const box = document.getElementById('p12-body');
let html = '';
- html += makeCard('theory', "Работа в термодинамике", "§12", `
-
Работа в термодинамике — этот параграф в разработке (Phase 1+).
-
Здесь появятся: теория, формулы, разобранные примеры и 3–4 интерактива в стиле «алгебры 11» — таблицы, симуляции, ползунки, drag-and-drop и автопроверяемые тренажёры.
-
- Phase 0: создан скелет учебника. Phase 2+: наполнение этого § содержанием по учебнику «Физика 10» (Беларусь, 2019).
-
+
+ /* THEORY 1 — Работа газа в изобарном процессе */
+ html += makeCard('theory', "Работа газа в изобарном процессе", "§12", `
+
Работа газа $A_{газ}$ — работа, совершаемая газом при изменении объёма.
+
Изобарный процесс ($p = \\text{const}$):
+
$$A_{газ} = p \\cdot \\Delta V = p\\,(V_2 - V_1)$$
+
+
Расширение ($V_2 > V_1$): $A_{газ} > 0$ — газ совершает положительную работу.
+
Сжатие ($V_2 < V_1$): $A_{газ} < 0$ — внешние силы совершают работу над газом.
+
Изохорный ($\\Delta V = 0$): $A_{газ} = 0$ — газ не совершает работу.
+
+
Связь с работой внешних сил:
+
$$A_{внеш} = -A_{газ}$$
`);
+
+ /* THEORY 2 — Графическое представление работы */
+ html += makeCard('rule', "Графическое представление работы", "§12", `
+
В координатах $p$–$V$ работа газа равна площади под кривой процесса:
+
$$A_{газ} = \\int_{V_1}^{V_2} p\\,dV$$
+
+
+
+
Процесс
+
Геометрия площади
+
Работа
+
+
+
+
Изобара ($p$=const)
прямоугольник
$A = p\\,\\Delta V$
+
Изохора ($V$=const)
нет ширины
$A = 0$
+
Изотерма ($T$=const)
под гиперболой
$A = \\nu RT\\ln\\dfrac{V_2}{V_1}$
+
Цикл
внутри замкнутой кривой
$A_{цикл}$ за оборот
+
+
+
Геометрический смысл важен для расчёта работы тепловых двигателей (§15).
+ `);
+
+ /* THEORY 3 — Работа в изотермическом процессе */
+ html += makeCard('example', "Работа в изотермическом процессе", "§12", `
+
Изотермический процесс ($T = \\text{const}$, $pV = \\text{const}$):
+
$$A_{газ} = \\nu R T \\ln\\dfrac{V_2}{V_1}$$
+
Это логарифмическая формула — применима при медленном (квазистатическом) изотермическом изменении объёма.
+
Для идеального газа при $T = \\text{const}$ внутренняя энергия не меняется ($\\Delta U = 0$), вся подведённая теплота превращается в работу: $Q = A_{газ}$.
+
Примеры:
+
+
Газ в цилиндре с поршнем в термостате расширили медленно от $V_1$ до $V_2$ — работа рассчитывается по формуле.
+
При сжатии нужно отводить тепло, чтобы $T$ оставалась постоянной.
+
При расширении подводим тепло — иначе газ охлаждался бы.
+
+ `);
+
+ /* INTERACTIVE 1 — Работа на PV-диаграмме (главный) */
+ html += `
+
ИНТЕРАКТИВ 1
Работа на $p$–$V$ диаграмме
+
Переключи процесс и сдвигай параметры — закрашенная площадь под кривой и есть работа $A_{газ}$.
+
+
+
+
+
+
+
+
+
+
+
`;
+
+ /* INTERACTIVE 2 — Калькулятор работы */
+ html += `
+
ИНТЕРАКТИВ 2
Калькулятор работы $A_{газ}$
+
Выбери тип процесса, введи параметры — получи работу с подстановкой формулы.
+
+
+
+
+
+
+
+
+
+
`;
+
+ /* INTERACTIVE 3 — Знак работы (квикфайр) */
+ html += `
+
ИНТЕРАКТИВ 3
Знак работы газа
+
6 ситуаций. Выбери знак работы газа: $A > 0$, $A < 0$ или $A = 0$.
+
Задание 1 / 6Очки: 0 / 6
+
+
+
+
+
+
+
+
`;
+
+ /* INTERACTIVE 4 — Тренажёр работы */
+ html += `
+
ИНТЕРАКТИВ 4
Тренажёр работы
+
5 задач. $R = 8{,}3$ Дж/(моль·К), 1 атм = $10^5$ Па, 1 л = $10^{-3}$ м³. Допуск $\\pm 5\\%$.
+
Задача 1 / 5Очки: 0 / 5
+
+
+ ответ =
+
+
+
+
+
+
`;
+
html += secNav('p11', 'p13');
html += readButton('p12');
+
box.innerHTML = html;
renderMath(box);
+
+ /* IV1 — PV-диаграмма с закрашиванием площади */
+ (function(){
+ const R = 8.314;
+ const slBox = document.getElementById('p12-iv1-sliders');
+ const svg = document.getElementById('p12-iv1-svg');
+ const info = document.getElementById('p12-iv1-info');
+ const COL = { bar:'#2563eb', hor:'#10b981', iso:'#ea580c' };
+ const seen = new Set(); let _done = false;
+
+ function getMode(){ const r = document.querySelector('input[name="p12-iv1-proc"]:checked'); return r ? r.value : 'bar'; }
+
+ function buildSliders(){
+ const m = getMode();
+ let h = '';
+ if(m === 'bar'){
+ h += '';
+ h += '';
+ h += '';
+ } else if(m === 'hor'){
+ h += '';
+ h += '';
+ h += '';
+ } else {
+ h += '';
+ h += '';
+ h += '';
+ }
+ slBox.innerHTML = h;
+ renderMath(slBox);
+ slBox.querySelectorAll('input[type=range]').forEach(i => i.addEventListener('input', render));
+ }
+
+ function render(){
+ const m = getMode();
+ const W=420, H=280, pad=44;
+ // оси: V 0..10 л × p 0..5 атм
+ const a = axes2D(W, H, pad, 0, 10, 0, 5);
+ let g = a.content;
+ g += 'V, л';
+ g += 'p, атм';
+
+ let A_J = 0, formula = '', label = '';
+ const color = COL[m];
+
+ if(m === 'bar'){
+ let v1 = +document.getElementById('p12-iv1-v1').value;
+ let v2 = +document.getElementById('p12-iv1-v2').value;
+ const p = +document.getElementById('p12-iv1-p').value;
+ document.getElementById('p12-iv1-v1L').textContent = v1.toFixed(1);
+ document.getElementById('p12-iv1-v2L').textContent = v2.toFixed(1);
+ document.getElementById('p12-iv1-pL').textContent = p.toFixed(1);
+ // площадь = прямоугольник между V1 и V2 на высоте p
+ const vL = Math.min(v1, v2), vR = Math.max(v1, v2);
+ const sign = v2 >= v1 ? '+' : '−';
+ g += '';
+ g += '';
+ // вертикали состояний
+ g += '';
+ g += '';
+ g += '1';
+ g += '2';
+ // стрелка направления
+ const xMid = (a.toX(v1)+a.toX(v2))/2;
+ g += '';
+
+ const dV = (v2 - v1) * 1e-3; // м³
+ A_J = p * 1e5 * dV;
+ formula = '$A_{газ} = p \\cdot \\Delta V = '+p.toFixed(1)+' \\cdot 10^5 \\cdot ('+v2.toFixed(1)+' - '+v1.toFixed(1)+') \\cdot 10^{-3} = '+A_J.toFixed(0)+'$ Дж';
+ label = (v2 > v1 ? 'расширение' : (v2 < v1 ? 'сжатие' : 'ΔV=0'));
+ } else if(m === 'hor'){
+ const v = +document.getElementById('p12-iv1-v1').value;
+ const p1 = +document.getElementById('p12-iv1-p').value;
+ const p2 = +document.getElementById('p12-iv1-p2').value;
+ document.getElementById('p12-iv1-v1L').textContent = v.toFixed(1);
+ document.getElementById('p12-iv1-pL').textContent = p1.toFixed(1);
+ document.getElementById('p12-iv1-p2L').textContent = p2.toFixed(1);
+ // вертикальная линия V = const
+ g += '';
+ g += '1';
+ g += '2';
+ A_J = 0;
+ formula = '$A_{газ} = 0$, т.к. $\\Delta V = 0$ (изохорный процесс).';
+ label = 'изохорно';
+ } else {
+ let v1 = +document.getElementById('p12-iv1-v1').value;
+ let v2 = +document.getElementById('p12-iv1-v2').value;
+ const T = +document.getElementById('p12-iv1-t').value;
+ document.getElementById('p12-iv1-v1L').textContent = v1.toFixed(1);
+ document.getElementById('p12-iv1-v2L').textContent = v2.toFixed(1);
+ document.getElementById('p12-iv1-tL').textContent = T;
+ // p(V) = nu*R*T / V; на 1 моль; p в атм при V в л
+ // p_атм = (1 * 8.314 * T) / (V_л * 1e-3) / 1e5 = 8.314*T / (V*100)
+ const NU = 1;
+ const fAtm = V => (NU * R * T) / (V * 1e-3) / 1e5;
+ // нарисовать кривую (всю гиперболу)
+ g += plotFunc(fAtm, 0.5, 10, a.toX, a.toY, color, 240);
+ // закрасить площадь между V1, V2
+ const vL = Math.min(v1, v2), vR = Math.max(v1, v2);
+ let d = 'M'+a.toX(vL)+','+a.toY(0);
+ const N = 80;
+ for(let i = 0; i <= N; i++){
+ const V = vL + (vR - vL) * i / N;
+ const pp = Math.min(fAtm(V), 5);
+ d += ' L'+a.toX(V).toFixed(2)+','+a.toY(pp).toFixed(2);
+ }
+ d += ' L'+a.toX(vR)+','+a.toY(0)+' Z';
+ g += '';
+ g += '1';
+ g += '2';
+
+ A_J = NU * R * T * Math.log(v2 / v1);
+ formula = '$A_{газ} = \\nu RT \\ln\\dfrac{V_2}{V_1} = 1 \\cdot 8{,}314 \\cdot '+T+' \\cdot \\ln\\dfrac{'+v2.toFixed(1)+'}{'+v1.toFixed(1)+'} \\approx '+A_J.toFixed(0)+'$ Дж';
+ label = (v2 > v1 ? 'изотермическое расширение' : (v2 < v1 ? 'изотермическое сжатие' : 'V₁ = V₂'));
+ }
+ svg.innerHTML = g;
+
+ const sgn = A_J > 0.5 ? 'положительная' : (A_J < -0.5 ? 'отрицательная' : 'нулевая');
+ info.innerHTML = '
'+label.charAt(0).toUpperCase()+label.slice(1)+' · работа '+sgn+'.
'
+ + '
'+formula+'
';
+ renderMath(info);
+
+ seen.add(m + ':' + Math.round(A_J/10));
+ if(!_done && seen.size >= 4){ _done = true; addXp(10,'p12-iv1'); bumpProgress('p12', 15); }
+ }
+ document.querySelectorAll('input[name="p12-iv1-proc"]').forEach(r => r.addEventListener('change', () => { buildSliders(); render(); }));
+ buildSliders();
+ render();
+ })();
+
+ /* IV2 — Калькулятор работы */
+ (function(){
+ const R = 8.314;
+ const tabs = document.getElementById('p12-iv2-tabs');
+ const inpsBox = document.getElementById('p12-iv2-inputs');
+ const out = document.getElementById('p12-iv2-out');
+ const fb = document.getElementById('p12-iv2-fb');
+ const used = new Set(); let _done = false;
+ let mode = 'bar';
+
+ function fieldHTML(id, label, val){
+ return '';
+ }
+ function build(){
+ let h = '';
+ if(mode === 'bar'){
+ h += fieldHTML('p12-iv2-p','$p$, атм','2');
+ h += fieldHTML('p12-iv2-v1','$V_1$, л','5');
+ h += fieldHTML('p12-iv2-v2','$V_2$, л','10');
+ } else if(mode === 'hor'){
+ h += '
В изохорном процессе $\\Delta V = 0$, поэтому $A_{газ} = 0$ при любых параметрах.
';
+ } else {
+ h += fieldHTML('p12-iv2-nu','$\\nu$, моль','1');
+ h += fieldHTML('p12-iv2-t','$T$, К','300');
+ h += fieldHTML('p12-iv2-v1','$V_1$, л','2');
+ h += fieldHTML('p12-iv2-v2','$V_2$, л','4');
+ }
+ inpsBox.innerHTML = h;
+ renderMath(inpsBox);
+ out.innerHTML = '';
+ fb.style.display = 'none';
+ }
+ function num(id){ const el = document.getElementById(id); return el ? parseFloat((el.value||'').replace(',','.')) : NaN; }
+ function calc(){
+ let A = 0, res = '';
+ if(mode === 'bar'){
+ const p = num('p12-iv2-p'), v1 = num('p12-iv2-v1'), v2 = num('p12-iv2-v2');
+ if(![p,v1,v2].every(x => isFinite(x)) || p <= 0 || v1 <= 0 || v2 <= 0){ feedback(fb,false,'✗ Все значения должны быть положительными.'); return; }
+ A = p * 1e5 * (v2 - v1) * 1e-3;
+ res = '$A_{газ} = p \\cdot \\Delta V = '+p+' \\cdot 10^5 \\cdot ('+v2+' - '+v1+') \\cdot 10^{-3} = '+A.toFixed(0)+'$ Дж';
+ } else if(mode === 'hor'){
+ A = 0;
+ res = '$A_{газ} = 0$, поскольку $\\Delta V = 0$.';
+ } else {
+ const nv = num('p12-iv2-nu'), T = num('p12-iv2-t'), v1 = num('p12-iv2-v1'), v2 = num('p12-iv2-v2');
+ if(![nv,T,v1,v2].every(x => isFinite(x) && x > 0)){ feedback(fb,false,'✗ Все значения должны быть положительными.'); return; }
+ A = nv * R * T * Math.log(v2 / v1);
+ res = '$A_{газ} = \\nu RT\\ln\\dfrac{V_2}{V_1} = '+nv+' \\cdot 8{,}314 \\cdot '+T+' \\cdot \\ln\\dfrac{'+v2+'}{'+v1+'} \\approx '+A.toFixed(0)+'$ Дж';
+ }
+ out.innerHTML = '
'+res+'
'
+ + '
Ответ:'+A.toFixed(0)+' Дж
';
+ renderMath(out);
+ feedback(fb, true, '✓ Вычислено.');
+ used.add(mode);
+ if(!_done && used.size === 3){ _done = true; addXp(10,'p12-iv2'); bumpProgress('p12', 15); }
+ }
+ tabs.querySelectorAll('button').forEach(b => {
+ b.addEventListener('click', () => {
+ mode = b.dataset.mode;
+ tabs.querySelectorAll('button').forEach(x => { x.className = 'btn'; x.style.background=''; x.style.borderColor=''; });
+ b.className = 'btn primary';
+ const colMap = { bar:'#2563eb', hor:'#10b981', iso:'#ea580c' };
+ b.style.background = colMap[mode]; b.style.borderColor = colMap[mode];
+ build();
+ });
+ });
+ document.getElementById('p12-iv2-go').addEventListener('click', calc);
+ build();
+ })();
+
+ /* IV3 — Знак работы (квикфайр) */
+ (function(){
+ const Q = [
+ { q:'Газ изобарно расширяется от $V_1 = 2$ л до $V_2 = 5$ л.', ans:'pos' },
+ { q:'Газ изобарно сжимается от $V_1 = 8$ л до $V_2 = 3$ л.', ans:'neg' },
+ { q:'Газ в герметичном сосуде нагревают (изохорно).', ans:'zero' },
+ { q:'Газ изотермически расширяется ($V_2 > V_1$).', ans:'pos' },
+ { q:'Газ толкает поршень наружу.', ans:'pos' },
+ { q:'Внешние силы сжимают газ. Знак $A_{газ}$?', ans:'neg' },
+ ];
+ let i = 0, score = 0; let _done = false;
+ const box = document.getElementById('p12-iv3');
+ function show(){
+ const qEl = document.getElementById('p12-iv3-q');
+ const fb = document.getElementById('p12-iv3-fb');
+ if(i >= Q.length){
+ qEl.innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length;
+ renderMath(qEl);
+ if(!_done){
+ _done = true;
+ if(score === Q.length){ addXp(15,'p12-iv3'); bumpProgress('p12', 25); }
+ else if(score >= 4){ addXp(8,'p12-iv3'); bumpProgress('p12', 15); }
+ }
+ return;
+ }
+ document.getElementById('p12-iv3-i').textContent = (i+1);
+ document.getElementById('p12-iv3-s').textContent = score;
+ qEl.innerHTML = Q[i].q;
+ renderMath(qEl);
+ fb.style.display = 'none';
+ }
+ box.querySelectorAll('button[data-sgn]').forEach(b => {
+ b.addEventListener('click', () => {
+ if(i >= Q.length) return;
+ const fb = document.getElementById('p12-iv3-fb');
+ const ans = b.dataset.sgn;
+ if(ans === Q[i].ans){ score++; feedback(fb, true, '✓ Верно! Дальше ▶'); }
+ else {
+ const labels = {pos:'$A>0$', neg:'$A<0$', zero:'$A=0$'};
+ feedback(fb, false, '✗ Неверно. Правильно: '+labels[Q[i].ans]+'. Дальше ▶');
+ }
+ document.getElementById('p12-iv3-s').textContent = score;
+ i++;
+ setTimeout(show, 1500);
+ });
+ });
+ show();
+ })();
+
+ /* IV4 — Тренажёр работы */
+ (function(){
+ const Q = [
+ { q:'Изобарно при $p = 2$ атм газ расширили от 5 л до 10 л. Работа газа в Дж?', ans:1000, tol:30, hint:'$A = p\\Delta V = 2 \\cdot 10^5 \\cdot 5 \\cdot 10^{-3} = 1000$ Дж' },
+ { q:'Изохорно газ нагрели от 300 К до 600 К. Работа газа в Дж?', ans:0, tol:1, hint:'$\\Delta V = 0 \\Rightarrow A = 0$' },
+ { q:'Изобарно при $p = 1$ атм газ сжали от 10 л до 4 л. Работа газа в Дж (со знаком)?', ans:-600, tol:20, hint:'$A = 10^5 \\cdot (-6 \\cdot 10^{-3}) = -600$ Дж' },
+ { q:'Изотермически 1 моль газа при $T = 300$ К расширили от 2 л до 4 л. Работа газа в Дж?', ans:1726, tol:50, hint:'$A = \\nu RT\\ln(V_2/V_1) = 8{,}3 \\cdot 300 \\cdot \\ln 2 \\approx 1726$ Дж' },
+ { q:'Газ при $p = 3$ атм совершил работу $A = 1500$ Дж. Найди $\\Delta V$ в литрах.', ans:5, tol:0.2, hint:'$\\Delta V = A/p = 1500/(3 \\cdot 10^5) = 5 \\cdot 10^{-3}$ м³ = 5 л' },
+ ];
+ let i = 0, score = 0;
+ function show(){
+ if(i >= Q.length){
+ document.getElementById('p12-iv4-q').innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length;
+ if(score === Q.length){ addXp(15, 'p12-iv4'); bumpProgress('p12', 25); }
+ else if(score >= 3){ addXp(8, 'p12-iv4'); bumpProgress('p12', 15); }
+ return;
+ }
+ document.getElementById('p12-iv4-i').textContent = (i+1);
+ document.getElementById('p12-iv4-s').textContent = score;
+ document.getElementById('p12-iv4-q').innerHTML = Q[i].q;
+ document.getElementById('p12-iv4-ans').value = '';
+ renderMath(document.getElementById('p12-iv4-q'));
+ document.getElementById('p12-iv4-fb').style.display = 'none';
+ }
+ function go(){
+ if(i >= Q.length) return;
+ const fb = document.getElementById('p12-iv4-fb');
+ const raw = document.getElementById('p12-iv4-ans').value.replace(',', '.');
+ const ans = parseFloat(raw);
+ if(isNaN(ans)){ feedback(fb, false, '✗ Введи число.'); return; }
+ if(Math.abs(ans - Q[i].ans) <= Q[i].tol + 0.001){ score++; feedback(fb, true, '✓ Верно! '+Q[i].hint+'. Дальше ▶'); }
+ else feedback(fb, false, '✗ Неверно. Ответ: $'+Q[i].ans+'$. '+Q[i].hint+'. Дальше ▶');
+ document.getElementById('p12-iv4-s').textContent = score;
+ i++;
+ setTimeout(show, 1800);
+ }
+ document.getElementById('p12-iv4-go').addEventListener('click', go);
+ document.getElementById('p12-iv4-ans').addEventListener('keydown', e => { if(e.key === 'Enter') go(); });
+ document.getElementById('p12-iv4-start').addEventListener('click', () => { i = 0; score = 0; show(); });
+ show();
+ })();
+
wireReadBtn('p12');
}