diff --git a/frontend/textbooks/physics_10_ch1.html b/frontend/textbooks/physics_10_ch1.html
index ca7e5e8..1c25f5f 100644
--- a/frontend/textbooks/physics_10_ch1.html
+++ b/frontend/textbooks/physics_10_ch1.html
@@ -670,34 +670,620 @@ function wireReadBtn(paraId){
function build_p1(){
const box = document.getElementById('p1-body');
let html = '';
+
+ /* THEORY 1 — положения МКТ */
html += makeCard('theory', "Основные положения МКТ", "§1", `
-
Основные положения МКТ — этот параграф в разработке (Phase 1+).
- Здесь появятся: теория, формулы, разобранные примеры и 3–4 интерактива в стиле «алгебры 11» — таблицы, симуляции, ползунки, drag-and-drop и автопроверяемые тренажёры.
-
- Phase 0: создан скелет учебника. Phase 1+: наполнение этого § содержанием по учебнику «Физика 10» (Беларусь, 2019).
-
+ Молекулярно-кинетическая теория (МКТ) объясняет строение и свойства веществ на основе движения и взаимодействия частиц (атомов, молекул, ионов).
+ Три основных положения МКТ:
+
+ Вещество состоит из частиц. Молекулы и атомы имеют размер около $10^{-10}$ м.
+ Частицы движутся непрерывно и хаотически. Это движение называется тепловым .
+ Частицы взаимодействуют между собой : на малых расстояниях — отталкиваются, на больших — притягиваются.
+
+ Все макроскопические свойства (температура, давление, плотность, теплопроводность и т. д.) объясняются микроскопическими процессами.
`);
+
+ /* THEORY 2 — опытные подтверждения */
+ html += makeCard('rule', "Опытные подтверждения МКТ", "§1", `
+ Броуновское движение (Р. Броун, 1827): хаотическое движение мелких частиц (например, пыльцы в воде) под действием ударов молекул. Чем меньше частица и выше температура — тем интенсивнее движение.
+ Диффузия — самопроизвольное перемешивание веществ за счёт движения молекул. Скорость диффузии возрастает с температурой.
+ Сжимаемость газов и тепловое расширение тел — также прямое следствие движения и взаимодействия молекул.
+ `);
+
+ /* THEORY 3 — размеры и числа */
+ html += makeCard('example', "Размеры и количество молекул", "§1", `
+
+ Размер молекулы: $\\sim 10^{-10}$ м (нанометр или ангстрем).
+ Размер атома водорода: $\\sim 0{,}5 \\cdot 10^{-10}$ м.
+ В $1 \\text{ см}^3$ воды примерно $3{,}3 \\cdot 10^{22}$ молекул.
+ В $1$ моль вещества — $N_A = 6{,}022 \\cdot 10^{23}$ молекул (число Авогадро).
+
+ Пример: если выпить стакан воды (200 мл) и подождать долгое время, в любом другом стакане воды через некоторое время будут несколько молекул из выпитого — настолько их много в любом веществе.
+ `);
+
+ /* INTERACTIVE 1 — Симуляция броуновского движения */
+ html += `
+
+
Оранжевая «броуновская» частица среди синих молекул газа. Меняй температуру — наблюдай хаотическое движение.
+
+ Температура: 300 К
+
+
+
+
+
+ Пауза
+ Сброс
+
+
+ Чем выше $T$, тем сильнее удары молекул, тем хаотичнее движется броуновская частица. Жёлтый след показывает её траекторию.
+
+
`;
+
+ /* INTERACTIVE 2 — DnD сортер: положение МКТ ↔ опыт */
+ html += `
+
+
Перетащи каждое явление в соответствующее положение МКТ.
+
+
+
+
+
+
3. Частицы взаимодействуют
+
+
Проверить Сначала
+
+
`;
+
+ /* INTERACTIVE 3 — Квикфайр: Верно/Неверно */
+ html += `
+
+
8 утверждений. Выбери «Верно» или «Неверно». Допуск ошибок — 1.
+
Задача 1 / 8 Очки: 0 / 8
+
+
+
+
Начать заново
+
`;
+
+ /* INTERACTIVE 4 — тренажёр чисел */
+ html += `
+
+
5 задач на число Авогадро, размеры молекул, моли. Допуск $\\pm 5\\%$. Используй $N_A = 6 \\cdot 10^{23}$.
+
Задача 1 / 5 Очки: 0 / 5
+
+
+ ответ =
+
+ Проверить
+ Заново
+
+
+
`;
+
html += secNav(null, 'p2');
html += readButton('p1');
+
box.innerHTML = html;
renderMath(box);
+
+ /* IV1 — Броуновское движение */
+ (function(){
+ const svg = document.getElementById('p1-iv1-svg');
+ const tInp = document.getElementById('p1-iv1-T');
+ const tLab = document.getElementById('p1-iv1-tL');
+ const btnPause = document.getElementById('p1-iv1-pause');
+ const btnReset = document.getElementById('p1-iv1-reset');
+ const W = 420, H = 320;
+ const baseSpeed = 80;
+ const tempChanges = new Set();
+ let _xpDone = false;
+ let raf = null, lastT = 0, paused = false;
+ let sim = null;
+ let brown = null;
+ let trail = [];
+
+ function makeSim(){
+ sim = PHYS.createGasSim({W, H, N: 50, speed: baseSpeed, r: 3});
+ brown = { x: W/2, y: H/2, vx: 0, vy: 0, r: 12 };
+ trail = [];
+ // initial temp
+ applyTemp(+tInp.value);
+ }
+ function applyTemp(T){
+ // baseSpeed соответствует T0=300 К; scale = sqrt(T/T0)
+ const targetScale = Math.sqrt(T/300);
+ // компенсируем текущую среднюю скорость
+ let curAvg = 0;
+ for(const p of sim.particles){ curAvg += Math.hypot(p.vx, p.vy); }
+ curAvg /= sim.particles.length;
+ const targetAvg = baseSpeed * targetScale;
+ if(curAvg > 0.01) sim.setSpeed(targetAvg / curAvg);
+ }
+ function frame(t){
+ raf = requestAnimationFrame(frame);
+ if(!lastT){ lastT = t; return; }
+ let dt = (t - lastT) / 1000;
+ lastT = t;
+ if(paused){ render(); return; }
+ if(dt > 0.06) dt = 0.06;
+ sim.step(dt);
+
+ // обновляем броуновскую частицу: суммируем импульс от ближних молекул
+ let fx = 0, fy = 0;
+ const R = brown.r + 4;
+ for(const p of sim.particles){
+ const dx = brown.x - p.x, dy = brown.y - p.y;
+ const d2 = dx*dx + dy*dy;
+ if(d2 < R*R && d2 > 1){
+ const d = Math.sqrt(d2);
+ const f = (R - d) / R;
+ fx += dx/d * f * 60;
+ fy += dy/d * f * 60;
+ }
+ }
+ // демпфирование + импульс
+ brown.vx = brown.vx * 0.88 + fx * dt;
+ brown.vy = brown.vy * 0.88 + fy * dt;
+ brown.x += brown.vx * dt;
+ brown.y += brown.vy * dt;
+ // отражение от стенок
+ if(brown.x < brown.r){ brown.x = brown.r; brown.vx = -brown.vx*0.6; }
+ if(brown.x > W - brown.r){ brown.x = W - brown.r; brown.vx = -brown.vx*0.6; }
+ if(brown.y < brown.r){ brown.y = brown.r; brown.vy = -brown.vy*0.6; }
+ if(brown.y > H - brown.r){ brown.y = H - brown.r; brown.vy = -brown.vy*0.6; }
+
+ trail.push({x: brown.x, y: brown.y});
+ if(trail.length > 60) trail.shift();
+ render();
+ }
+ function render(){
+ let g = '';
+ // фон тёмный (уже в SVG), молекулы синие
+ g += sim.render('#60a5fa');
+ // след броуновской — polyline с убывающей opacity
+ if(trail.length > 1){
+ for(let i = 1; i < trail.length; i++){
+ const op = i / trail.length;
+ g += ` `;
+ }
+ }
+ // броуновская частица — оранжевая
+ g += ` `;
+ svg.innerHTML = g;
+ }
+
+ makeSim();
+ raf = requestAnimationFrame(frame);
+
+ tInp.addEventListener('input', () => {
+ const T = +tInp.value;
+ tLab.textContent = T;
+ applyTemp(T);
+ tempChanges.add(T);
+ if(!_xpDone && tempChanges.size >= 4){
+ _xpDone = true;
+ addXp(10, 'p1-iv1');
+ bumpProgress('p1', 15);
+ }
+ });
+ btnPause.addEventListener('click', () => {
+ paused = !paused;
+ btnPause.textContent = paused ? 'Продолжить' : 'Пауза';
+ });
+ btnReset.addEventListener('click', () => {
+ makeSim();
+ trail = [];
+ });
+ // cleanup при потере фокуса (минимизируем нагрузку)
+ document.addEventListener('visibilitychange', () => {
+ if(document.hidden && raf){ cancelAnimationFrame(raf); raf = null; lastT = 0; }
+ else if(!document.hidden && !raf){ raf = requestAnimationFrame(frame); }
+ });
+ })();
+
+ /* IV2 — DnD: положение ↔ опыт */
+ (function(){
+ const items = [
+ { id:'q1', cat:'c2', html:'Запах духов распространяется в комнате' },
+ { id:'q2', cat:'c2', html:'Пыльца хаотично движется в воде' },
+ { id:'q3', cat:'c1', html:'Воздух сжимается в насосе' },
+ { id:'q4', cat:'c3', html:'Капля воды растекается по стеклу' },
+ { id:'q5', cat:'c1', html:'Стальной шарик падает в воде медленнее, чем в воздухе' },
+ { id:'q6', cat:'c2', html:'Газ заполняет весь сосуд' },
+ ];
+ const sorter = setupSorter({
+ poolId:'p1-iv2-pool',
+ scopeSelector:'#p1-iv2',
+ items: items,
+ cats:['c1','c2','c3'],
+ columnLayout:false,
+ });
+ document.getElementById('p1-iv2-check').addEventListener('click', ()=>{
+ const fb = document.getElementById('p1-iv2-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,'p1-iv2'); bumpProgress('p1', 15); }
+ else feedback(fb, false, '✗ Правильно ' + correct + ' из 6. Попробуй ещё.');
+ });
+ document.getElementById('p1-iv2-reset').addEventListener('click', ()=>{ sorter.reset(); document.getElementById('p1-iv2-fb').style.display = 'none'; });
+ })();
+
+ /* IV3 — квикфайр Верно/Неверно */
+ (function(){
+ const Q = [
+ { q:'Молекулы вещества движутся хаотически.', ans:true, why:'Тепловое движение — это хаотическое движение молекул.' },
+ { q:'При нагревании молекулы движутся медленнее.', ans:false, why:'Наоборот — при нагревании движение усиливается.' },
+ { q:'Атомы можно увидеть в обычный световой микроскоп.', ans:false, why:'Размер атома $\\sim 10^{-10}$ м — нужен электронный микроскоп.' },
+ { q:'Между молекулами действуют только силы притяжения.', ans:false, why:'На малых расстояниях — отталкивание, на больших — притяжение.' },
+ { q:'Размер молекулы порядка $10^{-10}$ м.', ans:true, why:'Это типичный размер молекулы (≈ 1 ангстрем).' },
+ { q:'Броуновское движение объясняется ударами молекул жидкости.', ans:true, why:'Хаотические удары молекул заставляют двигаться броуновские частицы.' },
+ { q:'Диффузия в газах происходит быстрее, чем в жидкостях.', ans:true, why:'В газах молекулы движутся свободнее и быстрее.' },
+ { q:'В 1 моль любого вещества одинаковое число молекул — $N_A$.', ans:true, why:'$N_A = 6{,}022 \\cdot 10^{23}$ — число Авогадро.' },
+ ];
+ let i = 0, score = 0;
+ const qEl = document.getElementById('p1-iv3-q');
+ const oEl = document.getElementById('p1-iv3-opts');
+ const fb = document.getElementById('p1-iv3-fb');
+ const iEl = document.getElementById('p1-iv3-i');
+ const sEl = document.getElementById('p1-iv3-s');
+
+ function show(){
+ if(i >= Q.length){
+ qEl.innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length;
+ oEl.innerHTML = '';
+ if(score === Q.length){ addXp(15, 'p1-iv3'); bumpProgress('p1', 25); }
+ else if(score >= 5){ addXp(8, 'p1-iv3'); bumpProgress('p1', 15); }
+ return;
+ }
+ iEl.textContent = (i+1);
+ sEl.textContent = score;
+ const item = Q[i];
+ qEl.innerHTML = item.q;
+ oEl.innerHTML = 'Верно Неверно ';
+ fb.style.display = 'none';
+ renderMath(qEl);
+ oEl.querySelectorAll('button').forEach(b => {
+ b.addEventListener('click', () => {
+ const v = b.dataset.v === '1';
+ if(v === item.ans){ score++; feedback(fb, true, '✓ Верно! ' + item.why + ' Дальше ▶'); }
+ else feedback(fb, false, '✗ Неверно. ' + item.why + ' Дальше ▶');
+ sEl.textContent = score;
+ oEl.querySelectorAll('button').forEach(x => x.disabled = true);
+ i++;
+ setTimeout(show, 1400);
+ });
+ });
+ }
+ document.getElementById('p1-iv3-restart').addEventListener('click', () => { i = 0; score = 0; show(); });
+ show();
+ })();
+
+ /* IV4 — тренажёр чисел */
+ (function(){
+ const Q = [
+ { q:'В стакане воды $2{,}4 \\cdot 10^{24}$ молекул. Сколько это молей? ($N_A = 6 \\cdot 10^{23}$)', ans:4, hint:'$\\nu = N/N_A = 2{,}4 \\cdot 10^{24} / 6 \\cdot 10^{23} = 4$' },
+ { q:'В 18 г воды ($M = 18$ г/моль) сколько моль?', ans:1, hint:'$\\nu = m/M = 18/18 = 1$ моль' },
+ { q:'В 1 кг водорода ($M = 2$ г/моль) сколько моль?', ans:500, hint:'$\\nu = 1000/2 = 500$ моль' },
+ { q:'В 3 моль газа сколько молекул? Введи число $X$ для ответа $X \\cdot 10^{23}$', ans:18, hint:'$N = 3 \\cdot 6 \\cdot 10^{23} = 18 \\cdot 10^{23}$' },
+ { q:'Размер молекулы $\\sim 10^{-10}$ м. Сколько молекул в ряд поместится на $1$ мм? Введи порядок: $10^X$, $X = ?$', ans:7, hint:'$10^{-3}/10^{-10} = 10^{7}$' },
+ ];
+ let i = 0, score = 0;
+ function show(){
+ if(i >= Q.length){
+ document.getElementById('p1-iv4-q').innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length;
+ if(score === Q.length){ addXp(15, 'p1-iv4'); bumpProgress('p1', 25); }
+ else if(score >= 3){ addXp(8, 'p1-iv4'); bumpProgress('p1', 15); }
+ return;
+ }
+ document.getElementById('p1-iv4-i').textContent = (i+1);
+ document.getElementById('p1-iv4-s').textContent = score;
+ document.getElementById('p1-iv4-q').innerHTML = Q[i].q;
+ document.getElementById('p1-iv4-ans').value = '';
+ renderMath(document.getElementById('p1-iv4-q'));
+ document.getElementById('p1-iv4-fb').style.display = 'none';
+ }
+ function go(){
+ if(i >= Q.length) return;
+ const fb = document.getElementById('p1-iv4-fb');
+ const raw = document.getElementById('p1-iv4-ans').value.replace(',', '.');
+ const ans = parseFloat(raw);
+ if(isNaN(ans)){ feedback(fb, false, '✗ Введи число.'); return; }
+ const tol = Math.max(0.05 * Math.abs(Q[i].ans), 0.05);
+ if(Math.abs(ans - Q[i].ans) < tol){ score++; feedback(fb, true, '✓ Верно! '+Q[i].hint+'. Дальше ▶'); }
+ else feedback(fb, false, '✗ Неверно. Ответ: $'+Q[i].ans+'$. '+Q[i].hint+'. Дальше ▶');
+ document.getElementById('p1-iv4-s').textContent = score;
+ i++;
+ setTimeout(show, 1500);
+ }
+ document.getElementById('p1-iv4-go').addEventListener('click', go);
+ document.getElementById('p1-iv4-ans').addEventListener('keydown', e => { if(e.key === 'Enter') go(); });
+ document.getElementById('p1-iv4-start').addEventListener('click', () => { i = 0; score = 0; show(); });
+ show();
+ })();
+
wireReadBtn('p1');
}
function build_p2(){
const box = document.getElementById('p2-body');
let html = '';
- html += makeCard('theory', "Масса и размеры молекул. Количество вещества", "§2", `
- Масса и размеры молекул. Количество вещества — этот параграф в разработке (Phase 1+).
- Здесь появятся: теория, формулы, разобранные примеры и 3–4 интерактива в стиле «алгебры 11» — таблицы, симуляции, ползунки, drag-and-drop и автопроверяемые тренажёры.
-
- Phase 0: создан скелет учебника. Phase 1+: наполнение этого § содержанием по учебнику «Физика 10» (Беларусь, 2019).
-
+
+ /* THEORY 1 — количество вещества */
+ html += makeCard('theory', "Количество вещества и моль", "§2", `
+ Количество вещества $\\nu$ (греч. «ню») — физическая величина, равная числу частиц вещества, делённому на число Авогадро:
+ $$\\nu = \\dfrac{N}{N_A}$$
+ Единица: моль . Один моль — количество вещества, содержащее столько же частиц, сколько атомов в $12$ г углерода-12.
+ Число Авогадро: $N_A = 6{,}022 \\cdot 10^{23}$ моль$^{-1}$.
`);
+
+ /* THEORY 2 — молярная масса */
+ html += makeCard('rule', "Молярная масса. Связь с массой", "§2", `
+ Молярная масса $M$ — масса одного моля вещества:
+ $$M = m_0 \\cdot N_A$$
+ где $m_0$ — масса одной молекулы. Единица СИ — кг/моль , привычная — г/моль .
+ Связь количества вещества с массой:
+ $$\\nu = \\dfrac{m}{M} = \\dfrac{N}{N_A}$$
+ Относительная молекулярная масса $M_r$ — безразмерна: $M_r = M$ (в г/моль). Например, $M_r(\\text{H}_2\\text{O}) = 18$, $M(\\text{H}_2\\text{O}) = 18$ г/моль $= 0{,}018$ кг/моль.
+ `);
+
+ /* THEORY 3 — масса молекулы */
+ html += makeCard('example', "Масса одной молекулы и концентрация", "§2", `
+ Зная молярную массу и число Авогадро, найдём массу одной молекулы:
+ $$m_0 = \\dfrac{M}{N_A}$$
+ Примеры:
+
+ Молекула воды ($M = 18$ г/моль): $m_0 = \\dfrac{18 \\cdot 10^{-3}}{6{,}022 \\cdot 10^{23}} \\approx 3 \\cdot 10^{-26}$ кг.
+ Атом водорода ($M = 1$ г/моль): $m_0 \\approx 1{,}66 \\cdot 10^{-27}$ кг (= 1 а.е.м.).
+ Атом углерода ($M = 12$ г/моль): $m_0 \\approx 2 \\cdot 10^{-26}$ кг.
+
+ Концентрация молекул $n$ — число молекул в единице объёма:
+ $$n = \\dfrac{N}{V}$$
+ Единица: $\\text{м}^{-3}$.
+ `);
+
+ /* INTERACTIVE 1 — калькулятор Авогадро */
+ html += `
+
+
Введи массу $m$ (г) и молярную массу $M$ (г/моль) — получи количество вещества $\\nu$, число молекул $N$ и массу одной молекулы $m_0$.
+
+ Масса $m$, г
+ Молярная масса $M$, г/моль
+
+
+ Эталон:
+
+ — выбери вещество —
+ Вода H₂O (M = 18)
+ Углекислый газ CO₂ (M = 44)
+ Кислород O₂ (M = 32)
+ Азот N₂ (M = 28)
+ Водород H₂ (M = 2)
+ Железо Fe (M = 56)
+ Углерод C (M = 12)
+
+
+
+ Вычислить
+
+
+
+
`;
+
+ /* INTERACTIVE 2 — DnD сортер: вещество ↔ молярная масса */
+ html += `
+
+
Перетащи каждое вещество в ящик с его молярной массой.
+
+
+
+
Проверить Сначала
+
+
`;
+
+ /* INTERACTIVE 3 — квикфайр «Что больше?» */
+ html += `
+
+
6 вопросов «что больше» — выбери первое или второе.
+
Задача 1 / 6 Очки: 0 / 6
+
+
+
+
Начать заново
+
`;
+
+ /* INTERACTIVE 4 — тренажёр количества вещества */
+ html += `
+
+
6 задач на $\\nu = m/M$ и $N = \\nu N_A$. Допуск $\\pm 5\\%$. Используй $N_A = 6 \\cdot 10^{23}$.
+
Задача 1 / 6 Очки: 0 / 6
+
+
+ ответ =
+
+ Проверить
+ Заново
+
+
+
`;
+
html += secNav('p1', 'p3');
html += readButton('p2');
+
box.innerHTML = html;
renderMath(box);
+
+ /* IV1 — калькулятор Авогадро */
+ (function(){
+ const mI = document.getElementById('p2-iv1-m');
+ const MI = document.getElementById('p2-iv1-M');
+ const sel = document.getElementById('p2-iv1-preset');
+ const out = document.getElementById('p2-iv1-out');
+ const fb = document.getElementById('p2-iv1-fb');
+ const go = document.getElementById('p2-iv1-go');
+ const used = new Set();
+ let _done = false;
+ const NA = 6e23;
+
+ function calc(){
+ const m = parseFloat(mI.value);
+ const M = parseFloat(MI.value);
+ if(!isFinite(m) || m <= 0){ feedback(fb, false, '✗ Введи положительную массу.'); return; }
+ if(!isFinite(M) || M <= 0){ feedback(fb, false, '✗ Введи положительную молярную массу.'); return; }
+ const nu = m / M;
+ const N = nu * NA;
+ // m0 в кг: m0 = M(кг/моль) / N_A = M*1e-3 / N_A
+ const m0 = (M * 1e-3) / NA;
+ const NstrExp = Math.floor(Math.log10(N));
+ const NstrCoef = N / Math.pow(10, NstrExp);
+ const m0Exp = Math.floor(Math.log10(m0));
+ const m0Coef = m0 / Math.pow(10, m0Exp);
+
+ out.innerHTML =
+ 'Количество вещества: $\\nu = \\dfrac{m}{M} = \\dfrac{'+(+m.toFixed(3))+'}{'+(+M.toFixed(3))+'} \\approx '+(+nu.toFixed(4))+'$ моль
'
+ + 'Число молекул: $N = \\nu \\cdot N_A = '+(+nu.toFixed(4))+' \\cdot 6 \\cdot 10^{23} \\approx '+(+NstrCoef.toFixed(3))+' \\cdot 10^{'+NstrExp+'}$
'
+ + 'Масса одной молекулы: $m_0 = \\dfrac{M}{N_A} \\approx '+(+m0Coef.toFixed(3))+' \\cdot 10^{'+m0Exp+'}$ кг
';
+ renderMath(out);
+ feedback(fb, true, '✓ Вычислено.');
+ used.add((+M.toFixed(2))+':'+(+m.toFixed(2)));
+ if(!_done && used.size >= 4){ _done = true; addXp(10, 'p2-iv1'); bumpProgress('p2', 15); }
+ }
+ sel.addEventListener('change', () => {
+ if(sel.value){ MI.value = sel.value; }
+ });
+ go.addEventListener('click', calc);
+ mI.addEventListener('keydown', e => { if(e.key === 'Enter') calc(); });
+ MI.addEventListener('keydown', e => { if(e.key === 'Enter') calc(); });
+ })();
+
+ /* IV2 — DnD: вещество ↔ молярная масса */
+ (function(){
+ const items = [
+ { id:'w1', cat:'m18', html:'Вода H$_2$O' },
+ { id:'w2', cat:'m44', html:'Углекислый газ CO$_2$' },
+ { id:'w3', cat:'m32', html:'Кислород O$_2$' },
+ { id:'w4', cat:'m28', html:'Азот N$_2$' },
+ { id:'w5', cat:'m2', html:'Водород H$_2$' },
+ { id:'w6', cat:'m16', html:'Метан CH$_4$' },
+ ];
+ const sorter = setupSorter({
+ poolId:'p2-iv2-pool',
+ scopeSelector:'#p2-iv2',
+ items: items,
+ cats:['m2','m16','m18','m28','m32','m44'],
+ columnLayout:false,
+ });
+ document.getElementById('p2-iv2-check').addEventListener('click', ()=>{
+ const fb = document.getElementById('p2-iv2-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,'p2-iv2'); bumpProgress('p2', 15); }
+ else feedback(fb, false, '✗ Правильно ' + correct + ' из 6. Попробуй ещё.');
+ });
+ document.getElementById('p2-iv2-reset').addEventListener('click', ()=>{ sorter.reset(); document.getElementById('p2-iv2-fb').style.display = 'none'; });
+ })();
+
+ /* IV3 — квикфайр «Что больше?» */
+ (function(){
+ const Q = [
+ { q:'Что весит больше: $1$ моль воды (M=18) или $1$ моль водорода (M=2)?', a:'1 моль воды (18 г)', b:'1 моль водорода (2 г)', ans:0, why:'Молярная масса воды 18 г/моль > 2 г/моль.' },
+ { q:'Что больше по массе: $36$ г воды или $1$ моль воды (M=18)?', a:'36 г воды', b:'1 моль воды (18 г)', ans:0, why:'36 г = 2 моль воды > 1 моль (18 г).' },
+ { q:'Что весит больше: $N_A$ молекул кислорода (M=32) или $2 N_A$ молекул водорода (M=2)?', a:'$N_A$ молекул O$_2$ (32 г)', b:'$2 N_A$ молекул H$_2$ (4 г)', ans:0, why:'32 г > 4 г.' },
+ { q:'Что больше по массе: $1$ моль CO$_2$ (M=44) или $1$ кг воды?', a:'1 моль CO$_2$ (44 г)', b:'1 кг воды (1000 г)', ans:1, why:'1000 г > 44 г.' },
+ { q:'Что больше по числу частиц: $10^{23}$ молекул железа или $10^{22}$ молекул свинца?', a:'$10^{23}$ молекул Fe', b:'$10^{22}$ молекул Pb', ans:0, why:'$10^{23} > 10^{22}$ в 10 раз.' },
+ { q:'Что больше по массе: $5$ моль H$_2$ (M=2) или $1$ моль O$_2$ (M=32)?', a:'5 моль H$_2$ (10 г)', b:'1 моль O$_2$ (32 г)', ans:1, why:'$5 \\cdot 2 = 10$ г против $32$ г.' },
+ ];
+ let i = 0, score = 0;
+ const qEl = document.getElementById('p2-iv3-q');
+ const oEl = document.getElementById('p2-iv3-opts');
+ const fb = document.getElementById('p2-iv3-fb');
+ const iEl = document.getElementById('p2-iv3-i');
+ const sEl = document.getElementById('p2-iv3-s');
+
+ function show(){
+ if(i >= Q.length){
+ qEl.innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length;
+ oEl.innerHTML = '';
+ if(score === Q.length){ addXp(15, 'p2-iv3'); bumpProgress('p2', 25); }
+ else if(score >= 4){ addXp(8, 'p2-iv3'); bumpProgress('p2', 15); }
+ return;
+ }
+ iEl.textContent = (i+1);
+ sEl.textContent = score;
+ const item = Q[i];
+ qEl.innerHTML = item.q;
+ oEl.innerHTML = 'Первое: '+item.a+' Второе: '+item.b+' ';
+ fb.style.display = 'none';
+ renderMath(qEl); renderMath(oEl);
+ oEl.querySelectorAll('button').forEach(b => {
+ b.addEventListener('click', () => {
+ const v = +b.dataset.v;
+ if(v === item.ans){ score++; feedback(fb, true, '✓ Верно! ' + item.why + ' Дальше ▶'); }
+ else feedback(fb, false, '✗ Неверно. ' + item.why + ' Дальше ▶');
+ sEl.textContent = score;
+ oEl.querySelectorAll('button').forEach(x => x.disabled = true);
+ i++;
+ setTimeout(show, 1500);
+ });
+ });
+ }
+ document.getElementById('p2-iv3-restart').addEventListener('click', () => { i = 0; score = 0; show(); });
+ show();
+ })();
+
+ /* IV4 — тренажёр количества вещества */
+ (function(){
+ const Q = [
+ { q:'В 36 г воды (M=18 г/моль) сколько моль?', ans:2, hint:'$\\nu = m/M = 36/18 = 2$ моль' },
+ { q:'В 88 г углекислого газа (M=44 г/моль) сколько моль?', ans:2, hint:'$\\nu = 88/44 = 2$ моль' },
+ { q:'Сколько молекул в 1 моль вещества? Введи показатель $X$ для $6 \\cdot 10^X$', ans:23, hint:'$N_A = 6 \\cdot 10^{23}$' },
+ { q:'M = 64 г/моль. Сколько моль в 32 г этого вещества?', ans:0.5, hint:'$\\nu = 32/64 = 0{,}5$ моль' },
+ { q:'Сколько грамм в 3 моль воды (M=18 г/моль)?', ans:54, hint:'$m = \\nu M = 3 \\cdot 18 = 54$ г' },
+ { q:'В 36 г воды сколько молекул? Введи $X$ для ответа $X \\cdot 10^{23}$', ans:12, hint:'$\\nu = 2$ моль, $N = 2 \\cdot 6 \\cdot 10^{23} = 12 \\cdot 10^{23}$' },
+ ];
+ let i = 0, score = 0;
+ function show(){
+ if(i >= Q.length){
+ document.getElementById('p2-iv4-q').innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length;
+ if(score === Q.length){ addXp(15, 'p2-iv4'); bumpProgress('p2', 25); }
+ else if(score >= 4){ addXp(8, 'p2-iv4'); bumpProgress('p2', 15); }
+ return;
+ }
+ document.getElementById('p2-iv4-i').textContent = (i+1);
+ document.getElementById('p2-iv4-s').textContent = score;
+ document.getElementById('p2-iv4-q').innerHTML = Q[i].q;
+ document.getElementById('p2-iv4-ans').value = '';
+ renderMath(document.getElementById('p2-iv4-q'));
+ document.getElementById('p2-iv4-fb').style.display = 'none';
+ }
+ function go(){
+ if(i >= Q.length) return;
+ const fb = document.getElementById('p2-iv4-fb');
+ const raw = document.getElementById('p2-iv4-ans').value.replace(',', '.');
+ const ans = parseFloat(raw);
+ if(isNaN(ans)){ feedback(fb, false, '✗ Введи число.'); return; }
+ const tol = Math.max(0.05 * Math.abs(Q[i].ans), 0.05);
+ if(Math.abs(ans - Q[i].ans) < tol){ score++; feedback(fb, true, '✓ Верно! '+Q[i].hint+'. Дальше ▶'); }
+ else feedback(fb, false, '✗ Неверно. Ответ: $'+Q[i].ans+'$. '+Q[i].hint+'. Дальше ▶');
+ document.getElementById('p2-iv4-s').textContent = score;
+ i++;
+ setTimeout(show, 1500);
+ }
+ document.getElementById('p2-iv4-go').addEventListener('click', go);
+ document.getElementById('p2-iv4-ans').addEventListener('keydown', e => { if(e.key === 'Enter') go(); });
+ document.getElementById('p2-iv4-start').addEventListener('click', () => { i = 0; score = 0; show(); });
+ show();
+ })();
+
wireReadBtn('p2');
}