feat(math5): Глава 2 «Выражения. Уравнения» — §1–9 + финал (Sonnet по эталону)

Числовые выражения и порядок действий, выражения с переменными, уравнение
(SVG-весы + решение/проверка корня), формулы (P,S,путь), решение задач
уравнением, угол (SVG-рисунок + классификация острый/прямой/тупой/развёрнутый),
прикладные/занимательные/исторические § + финал-боссы. Реализовано Sonnet-агентом
по образцу math_5_ch1, проверено: грузится без ошибок, §1–9 без заглушек. Тесты: 11/11.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Maxim Dolgolyov
2026-06-03 10:18:29 +03:00
parent 12a08e7d42
commit 06e9846cc3
2 changed files with 961 additions and 5 deletions
+27 -4
View File
@@ -75,10 +75,33 @@ for (const ch of CHAPTERS) {
});
}
test('ch2/ch3: §§ без билдеров — заглушка движка (каркас ждёт наполнения)', async () => {
for (const f of ['math_5_ch2.html', 'math_5_ch3.html']) {
const { doc } = await loadDom(f);
assert.ok(doc.querySelector('#p1-body .m6-placeholder'), f + ': заглушка § 1');
test('ch3: §§ без билдеров — заглушка движка (каркас ждёт наполнения)', async () => {
const { doc } = await loadDom('math_5_ch3.html');
assert.ok(doc.querySelector('#p1-body .m6-placeholder'), 'ch3: заглушка § 1');
});
test('ch2: выражения/уравнения/углы + финал', async () => {
const { doc, errors } = await loadDom('math_5_ch2.html');
const win = doc.defaultView;
assert.ok(!doc.querySelector('#p1-body .m6-placeholder'), '§1 наполнен');
assert.ok(doc.querySelector('#p1-iv1 #p1-a'), '§1: тренажёр выражений');
win.goTo('p3'); await wait(80);
assert.ok(doc.querySelector('#p3-iv1 #p3-a'), '§3: решение уравнения');
win.goTo('p6'); await wait(80);
assert.ok(doc.querySelector('#p6-fig svg'), '§6: SVG угла');
win.goTo('final'); await wait(80);
assert.ok(doc.querySelector('#fin-go'), 'финал: арена боссов');
win.bumpProgress('final', 100); await wait(20);
assert.ok(win.M6STATE.achievements.has('ch2_done'), 'достижение «Глава 2 пройдена»');
assert.deepEqual(errors, [], 'нет ошибок: ' + errors.join(' | '));
});
test('ch2: все § §1–§9 наполнены (нет заглушек)', async () => {
const { doc } = await loadDom('math_5_ch2.html');
const win = doc.defaultView;
for (let n = 1; n <= 9; n++) {
win.goTo('p' + n); await wait(20);
assert.ok(!doc.querySelector('#p' + n + '-body .m6-placeholder'), '§' + n + ' наполнен');
}
});
+934 -1
View File
@@ -87,11 +87,944 @@ window.M6 = {
{ id:'p9', num:'§ 9', name:'Исторические сведения', sub:'Как появились уравнения', applied:true },
{ id:'final', num:'★', name:'Финал главы', sub:'Тест · боссы главы 2', final:true }
],
achLabels: { final_done:'Глава 2 пройдена!' },
achLabels: {
p1_done:'Порядок действий освоен!', p2_done:'Переменные покорены!',
p3_done:'Уравнения решаю!', p4_done:'Формулы работают!',
p5_done:'Задачи через уравнения!', p6_done:'Углы измерены!',
p7_done:'Математика вокруг нас!', p8_done:'Головоломки решены!',
p9_done:'История алгебры изучена!', ch2_done:'Глава 2 пройдена!'
},
finalAch: ['ch2_done', 'Глава 2 «Выражения. Уравнения» пройдена!'],
sidebars: {}, tips: [], glossary: [], searchRows: [], builders: {},
footer: 'Интерактивный учебник «Математика 5» · Глава 2 · Выражения. Уравнения · LearnSpace'
};
/* ===================== ВСПОМОГАТЕЛЬНОЕ ===================== */
function _ri(a,b){ return a + Math.floor(Math.random()*(b-a+1)); }
function _pick(a){ return a[_ri(0,a.length-1)]; }
function _kf(x){ return String(x).replace('.','{,}'); }
/* ===================== § 1. ЧИСЛОВЫЕ ВЫРАЖЕНИЯ ===================== */
function buildP1(){
var box=document.getElementById('p1-body'); var h='';
h+=makeCard('oral','Где это в жизни','1.0',
'<p>Купили $3$ тетради по $5$ р. и $2$ ручки по $8$ р. Сколько заплатили? Запись $3\\cdot5+2\\cdot8$ — это <b>числовое выражение</b>. Чтобы найти его значение, нужно знать, в каком порядке выполнять действия.</p>');
h+=makeCard('rule','Порядок действий','1.1',
'<p>1) Если есть <b>скобки</b> — вычисляем то, что в скобках, первым.</p>'
+'<p>2) Затем — <b>умножение и деление</b> (слева направо).</p>'
+'<p>3) Затем — <b>сложение и вычитание</b> (слева направо).</p>'
+'<p>Пример: $3+2\\cdot4=3+8=11$. Скобки меняют порядок: $(3+2)\\cdot4=5\\cdot4=20$.</p>');
h+=makeCard('example','Разбор по шагам','1.2',
'<p>Вычислим $24:(8-2)\\cdot3-5$.</p>'
+'<ol style="padding-left:22px;line-height:2">'
+'<li>Скобки: $8-2=6$. Выражение: $24:6\\cdot3-5$.</li>'
+'<li>Деление: $24:6=4$. Выражение: $4\\cdot3-5$.</li>'
+'<li>Умножение: $4\\cdot3=12$. Выражение: $12-5$.</li>'
+'<li>Вычитание: $12-5=7$. Ответ: $7$.</li>'
+'</ol>');
h+=makeCard('theory','А знаешь ли ты?','1.3',
'<p>Правила порядка действий появились не сразу. Ещё в XVII–XVIII веке математики записывали выражения по-разному. Сегодня во всём мире принят единый стандарт: <b>PEMDAS</b> (Parentheses, Exponents, Multiplication, Division, Addition, Subtraction) или по-русски: скобки, степени, ×÷, +.</p>');
h+='<div class="wg" id="p1-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Вычисли выражение</div></div>'
+'<div class="wg-help">Вычисли значение числового выражения, соблюдая порядок действий. Ответ — целое число.</div>'
+'<div class="score-display"><span>Пример <b id="p1-i">1</b> / 6</span><span>Очки: <b id="p1-s">0</b> / 6</span></div>'
+'<div id="p1-q" class="qbox" style="font-size:1.15rem"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="text" id="p1-a" class="tinp" style="width:110px;text-align:center" placeholder="ответ"><button class="btn primary" id="p1-go">Проверить</button></div>'
+'<div class="feedback" id="p1-fb"></div></div>';
h+='<div class="wg" id="p1-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Что вычислим первым?</div></div>'
+'<div class="wg-help">Выбери, какое действие в выражении нужно выполнить <b>первым</b>.</div>'
+'<div class="score-display"><span>Вопрос <b id="p1-oi">1</b> / 5</span><span>Очки: <b id="p1-os">0</b> / 5</span></div>'
+'<div id="p1-oq" class="qbox"></div>'
+'<div id="p1-oopt" style="display:flex;gap:8px;justify-content:center;flex-wrap:wrap"></div>'
+'<div class="feedback" id="p1-ofb"></div></div>';
h+=secNav(null,'p2')+readBtn('p1');
box.innerHTML=h; renderMath(box);
(function(){
var EXPR=[
{q:'$2+3\\cdot4$',a:14},
{q:'$(2+3)\\cdot4$',a:20},
{q:'$18:3+7$',a:13},
{q:'$18:(3+6)\\cdot2$',a:4},
{q:'$5\\cdot6-4\\cdot3$',a:18},
{q:'$40-3\\cdot(4+2)$',a:22},
{q:'$(15-5):(2+3)$',a:2},
{q:'$3+4\\cdot5-6$',a:17}
];
var order=[],i=0,score=0,cur=null;
function reorder(){ order=EXPR.map(function(_,k){return k;}); for(var j=order.length-1;j>0;j--){ var k=_ri(0,j),t=order[j];order[j]=order[k];order[k]=t; } }
reorder();
function show(){ if(i>=6){ document.getElementById('p1-q').innerHTML='<b>Готово!</b> Результат: '+score+' / 6'; if(score>=5){addXp(15,'p1-iv1');bumpProgress('p1',30);}else if(score>=3){addXp(8,'p1-iv1');bumpProgress('p1',16);} return; }
cur=EXPR[order[i]]; document.getElementById('p1-i').textContent=i+1;
document.getElementById('p1-q').innerHTML=cur.q; renderMath(document.getElementById('p1-q'));
document.getElementById('p1-a').value=''; document.getElementById('p1-fb').style.display='none'; }
function go(){ if(i>=6)return; var fb=document.getElementById('p1-fb'), v=parseInt(document.getElementById('p1-a').value.replace(',','.').trim(),10);
if(isNaN(v)){ feedback(fb,false,'Введи целое число.'); return; }
if(v===cur.a){ score++; feedback(fb,true,'✓ Верно! Ответ '+cur.a+'.'); } else feedback(fb,false,'✗ Нет. Правильный ответ: '+cur.a+'.');
document.getElementById('p1-s').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p1-go').addEventListener('click',go);
document.getElementById('p1-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
(function(){
var QZ=[
{q:'В выражении $5+2\\cdot3$ что считаем первым?', o:['$2\\cdot3$','$5+2$','$5+6$'], a:0},
{q:'В выражении $(10-4)\\cdot2$ что считаем первым?', o:['$10-4$','$4\\cdot2$','$10\\cdot2$'], a:0},
{q:'В выражении $20:4+6$ что считаем первым?', o:['$20:4$','$4+6$','$20:10$'], a:0},
{q:'В выражении $3\\cdot(2+8)-1$ что считаем первым?', o:['$2+8$','$3\\cdot2$','$8-1$'], a:0},
{q:'В выражении $15-3\\cdot4+2$ что считаем первым?', o:['$3\\cdot4$','$15-3$','$4+2$'], a:0},
{q:'В выражении $6:(3-1)\\cdot2$ что считаем первым?', o:['$3-1$','$6:3$','$1\\cdot2$'], a:0}
];
var order=[],i=0,score=0,cur=null;
function reorder(){ order=QZ.map(function(_,k){return k;}); for(var j=order.length-1;j>0;j--){ var k=_ri(0,j),t=order[j];order[j]=order[k];order[k]=t; } }
reorder();
function show(){ if(i>=5){ document.getElementById('p1-oq').innerHTML='<b>Готово!</b> Результат: '+score+' / 5'; document.getElementById('p1-oopt').innerHTML=''; if(score>=4){addXp(15,'p1-iv2');bumpProgress('p1',30);}else if(score>=2){addXp(8,'p1-iv2');bumpProgress('p1',16);} return; }
cur=QZ[order[i]]; document.getElementById('p1-oi').textContent=i+1;
document.getElementById('p1-oq').innerHTML=cur.q; renderMath(document.getElementById('p1-oq'));
var idx=[0,1,2]; for(var j=idx.length-1;j>0;j--){var k=_ri(0,j),t=idx[j];idx[j]=idx[k];idx[k]=t;}
var html=''; idx.forEach(function(oi){ html+='<button class="btn primary" data-oi="'+oi+'">'+cur.o[oi]+'</button>'; });
document.getElementById('p1-oopt').innerHTML=html;
document.querySelectorAll('#p1-oopt [data-oi]').forEach(function(b){ b.addEventListener('click',function(){ ans(+b.getAttribute('data-oi')); }); });
renderMath(document.getElementById('p1-oopt'));
document.getElementById('p1-ofb').style.display='none'; }
function ans(oi){ if(i>=5)return; var fb=document.getElementById('p1-ofb');
if(oi===cur.a){ score++; feedback(fb,true,'✓ Верно!'); } else feedback(fb,false,'✗ Нет. Верный ответ: '+cur.o[cur.a]+'.');
document.getElementById('p1-os').textContent=score; i++; setTimeout(show,1300); }
show();
})();
}
/* ===================== § 2. ВЫРАЖЕНИЯ С ПЕРЕМЕННЫМИ ===================== */
function buildP2(){
var box=document.getElementById('p2-body'); var h='';
h+=makeCard('oral','Где это в жизни','2.0',
'<p>Цена одного билета — $50$ р. Сколько стоят $n$ билетов? Ответ: $50\\cdot n$ — это <b>выражение с переменной</b>. Переменная (буква) обозначает число, которое может меняться. Именно так появляется общая формула, работающая для любого числа.</p>');
h+=makeCard('theory','Что такое переменная','2.1',
'<p><b>Выражение с переменной</b> — это выражение, которое содержит букву. Буква называется <b>переменной</b>.</p>'
+'<p>Примеры: $a+5$, $3\\cdot x$, $b-7$, $2\\cdot a+b$.</p>'
+'<p><b>Значение выражения</b> — конкретное число, которое получается после подстановки числа вместо переменной.</p>');
h+=makeCard('rule','Как найти значение выражения','2.2',
'<p>Шаг 1. Запишем выражение с буквой.</p>'
+'<p>Шаг 2. Заменим букву данным числом (подставим).</p>'
+'<p>Шаг 3. Вычислим результат по правилу порядка действий.</p>'
+'<p>Пример: $3\\cdot a+1$ при $a=4$: $3\\cdot4+1=12+1=13$.</p>');
h+=makeCard('example','Разбор по шагам','2.3',
'<p>Найдём значение выражения $2\\cdot(a+3)-b$ при $a=5,\\;b=4$.</p>'
+'<ol style="padding-left:22px;line-height:2">'
+'<li>Подставляем: $2\\cdot(5+3)-4$.</li>'
+'<li>Скобки: $5+3=8$.</li>'
+'<li>Умножение: $2\\cdot8=16$.</li>'
+'<li>Вычитание: $16-4=12$. Ответ: $12$.</li>'
+'</ol>');
h+=makeCard('theory','А знаешь ли ты?','2.4',
'<p>Использовать буквы для обозначения чисел первым предложил французский математик <b>Франсуа Виет</b> в $1591$ году. До него уравнения записывали словами — представь, как это неудобно! Именно Виет сделал алгебру «буквенной».</p>');
h+='<div class="wg" id="p2-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Подставь значение</div></div>'
+'<div class="wg-help">Вычисли значение выражения при данном значении переменной.</div>'
+'<div class="score-display"><span>Пример <b id="p2-i">1</b> / 6</span><span>Очки: <b id="p2-s">0</b> / 6</span></div>'
+'<div id="p2-q" class="qbox" style="font-size:1.05rem"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="text" id="p2-a" class="tinp" style="width:110px;text-align:center" placeholder="ответ"><button class="btn primary" id="p2-go">Проверить</button></div>'
+'<div class="feedback" id="p2-fb"></div></div>';
h+='<div class="wg" id="p2-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Верно ли прочитано?</div></div>'
+'<div class="wg-help">Выбери верное словесное описание выражения.</div>'
+'<div class="score-display"><span>Вопрос <b id="p2-ri">1</b> / 5</span><span>Очки: <b id="p2-rs">0</b> / 5</span></div>'
+'<div id="p2-rq" class="qbox"></div>'
+'<div id="p2-ropt" style="display:flex;gap:8px;justify-content:center;flex-wrap:wrap"></div>'
+'<div class="feedback" id="p2-rfb"></div></div>';
h+=secNav('p1','p3')+readBtn('p2');
box.innerHTML=h; renderMath(box);
(function(){
var i=0,score=0,cur=null;
function gen(){
var t=_ri(0,3), a=_ri(2,9), b=_ri(2,7), c=_ri(1,6);
if(t===0){ cur={q:'$a+'+b+'$ при $a='+a+'$',ans:a+b}; }
else if(t===1){ cur={q:'$'+c+'\\cdot a$ при $a='+a+'$',ans:c*a}; }
else if(t===2){ cur={q:'$a\\cdot'+b+'-'+c+'$ при $a='+a+'$',ans:a*b-c}; }
else { cur={q:'$2\\cdot(a+'+b+')$ при $a='+a+'$',ans:2*(a+b)}; }
}
function show(){ if(i>=6){ document.getElementById('p2-q').innerHTML='<b>Готово!</b> Результат: '+score+' / 6'; if(score>=5){addXp(15,'p2-iv1');bumpProgress('p2',30);}else if(score>=3){addXp(8,'p2-iv1');bumpProgress('p2',16);} return; }
gen(); document.getElementById('p2-i').textContent=i+1;
document.getElementById('p2-q').innerHTML=cur.q; renderMath(document.getElementById('p2-q'));
document.getElementById('p2-a').value=''; document.getElementById('p2-fb').style.display='none'; }
function go(){ if(i>=6)return; var fb=document.getElementById('p2-fb'), v=parseInt(document.getElementById('p2-a').value.replace(',','.').trim(),10);
if(isNaN(v)){ feedback(fb,false,'Введи целое число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! Ответ '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Правильный ответ: '+cur.ans+'.');
document.getElementById('p2-s').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p2-go').addEventListener('click',go);
document.getElementById('p2-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
(function(){
var QZ=[
{q:'Как читается $a+5$?',o:['$a$ плюс пять','пять плюс $a$ минус один','$a$ умножить на пять'],a:0},
{q:'Как читается $3\\cdot b$?',o:['три умножить на $b$','$b$ плюс три','$b$ в степени три'],a:0},
{q:'Что значит «значение выражения»?',o:['конкретное число после подстановки','название буквы','знак действия'],a:0},
{q:'$x-7$ при $x=12$ равно:',o:['$5$','$7$','$19$'],a:0},
{q:'$4\\cdot a$ при $a=3$ равно:',o:['$12$','$7$','$43$'],a:0},
{q:'$b+b$ равносильно:',o:['$2\\cdot b$','$b^2$','$b+2$'],a:0}
];
var order=[],i=0,score=0,cur=null;
function reorder(){ order=QZ.map(function(_,k){return k;}); for(var j=order.length-1;j>0;j--){ var k=_ri(0,j),t=order[j];order[j]=order[k];order[k]=t; } }
reorder();
function show(){ if(i>=5){ document.getElementById('p2-rq').innerHTML='<b>Готово!</b> Результат: '+score+' / 5'; document.getElementById('p2-ropt').innerHTML=''; if(score>=4){addXp(15,'p2-iv2');bumpProgress('p2',30);}else if(score>=2){addXp(8,'p2-iv2');bumpProgress('p2',16);} return; }
cur=QZ[order[i]]; document.getElementById('p2-ri').textContent=i+1;
document.getElementById('p2-rq').innerHTML=cur.q; renderMath(document.getElementById('p2-rq'));
var idx=[0,1,2]; for(var j=idx.length-1;j>0;j--){var k=_ri(0,j),t=idx[j];idx[j]=idx[k];idx[k]=t;}
var html=''; idx.forEach(function(oi){ html+='<button class="btn primary" data-oi="'+oi+'">'+cur.o[oi]+'</button>'; });
document.getElementById('p2-ropt').innerHTML=html;
document.querySelectorAll('#p2-ropt [data-oi]').forEach(function(b){ b.addEventListener('click',function(){ ans(+b.getAttribute('data-oi')); }); });
renderMath(document.getElementById('p2-ropt'));
document.getElementById('p2-rfb').style.display='none'; }
function ans(oi){ if(i>=5)return; var fb=document.getElementById('p2-rfb');
if(oi===cur.a){ score++; feedback(fb,true,'✓ Верно!'); } else feedback(fb,false,'✗ Нет. Верный ответ: '+cur.o[cur.a]+'.');
document.getElementById('p2-rs').textContent=score; i++; setTimeout(show,1300); }
show();
})();
}
/* ===================== § 3. УРАВНЕНИЕ ===================== */
function buildP3(){
var box=document.getElementById('p3-body'); var h='';
h+=makeCard('oral','Где это в жизни','3.0',
'<p>«В кошельке было несколько рублей, ты потратил $15$ р. и осталось $28$ р. Сколько было?» — это задача на уравнение. Уравнения позволяют найти <b>неизвестное</b>, обозначив его буквой и составив равенство.</p>');
h+=makeCard('theory','Уравнение и его корень','3.1',
'<p><b>Уравнение</b> — это равенство, содержащее переменную. Например: $x+5=12$.</p>'
+'<p><b>Корень уравнения</b> — это такое значение переменной, при котором уравнение обращается в верное равенство.</p>'
+'<p>В уравнении $x+5=12$ корень $x=7$ (проверка: $7+5=12$ — верно!).</p>');
h+=makeCard('rule','Как решать простые уравнения','3.2',
'<p>Используем связь между компонентами действий:</p>'
+'<ul style="padding-left:22px;line-height:2">'
+'<li>$x+a=b \\Rightarrow x=b-a$</li>'
+'<li>$x-a=b \\Rightarrow x=b+a$</li>'
+'<li>$a-x=b \\Rightarrow x=a-b$</li>'
+'<li>$x\\cdot a=b \\Rightarrow x=b:a$</li>'
+'<li>$x:a=b \\Rightarrow x=b\\cdot a$</li>'
+'</ul>');
h+=makeCard('example','Разбор по шагам','3.3',
'<p>Решим уравнение $3\\cdot x-4=11$.</p>'
+'<ol style="padding-left:22px;line-height:2">'
+'<li>Перенесём $-4$: $3\\cdot x=11+4=15$.</li>'
+'<li>Делим обе стороны на $3$: $x=15:3=5$.</li>'
+'<li>Проверка: $3\\cdot5-4=15-4=11$. Верно!</li>'
+'</ol>');
h+=makeCard('theory','А знаешь ли ты?','3.4',
'<p>Слово «алгебра» пришло из арабского трактата «Аль-Китаб аль-мухтасар фи хисаб <b>аль-джабр</b> валь-мукабала» (около $820$ года н. э.), написанного математиком <b>аль-Хорезми</b>. «Аль-джабр» означает «восстановление» (переноса слагаемого). Его имя дало слово «алгоритм»!</p>');
/* Визуал «весы» для уравнения x + a = b */
h+='<div id="p3-scale" style="text-align:center;margin:12px 0">'
+'<svg id="p3-scale-svg" viewBox="0 0 320 140" width="320" style="max-width:100%">'
/* стойка */
+'<rect x="157" y="30" width="6" height="80" rx="2" fill="#6b7280"/>'
+'<rect x="120" y="27" width="80" height="6" rx="3" fill="#374151"/>'
/* левая тарелка */
+'<line x1="160" y1="30" x2="80" y2="75" stroke="#6b7280" stroke-width="1.5"/>'
+'<rect x="40" y="75" width="80" height="22" rx="8" fill="#0d9488" opacity=".85"/>'
+'<text x="80" y="91" font-size="13" font-weight="800" fill="white" text-anchor="middle">x</text>'
/* правая тарелка */
+'<line x1="160" y1="30" x2="240" y2="75" stroke="#6b7280" stroke-width="1.5"/>'
+'<rect x="200" y="75" width="80" height="22" rx="8" fill="#0d9488" opacity=".85"/>'
+'<text id="p3-scale-rhs" x="240" y="91" font-size="13" font-weight="800" fill="white" text-anchor="middle">?</text>'
+'</svg>'
+'<div style="font-size:.85rem;color:var(--muted)">Весы: левая чаша = правая чаша</div>'
+'</div>';
h+='<div class="wg" id="p3-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Реши уравнение</div></div>'
+'<div class="wg-help">Найди корень уравнения и введи ответ числом.</div>'
+'<div class="score-display"><span>Уравнение <b id="p3-i">1</b> / 6</span><span>Очки: <b id="p3-s">0</b> / 6</span></div>'
+'<div id="p3-q" class="qbox" style="font-size:1.1rem"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="text" id="p3-a" class="tinp" style="width:110px;text-align:center" placeholder="x = ?"><button class="btn primary" id="p3-go">Проверить</button></div>'
+'<div class="feedback" id="p3-fb"></div></div>';
h+='<div class="wg" id="p3-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Является ли число корнем?</div></div>'
+'<div class="wg-help">Проверь подстановкой: является ли данное число корнем уравнения?</div>'
+'<div class="score-display"><span>Вопрос <b id="p3-yi">1</b> / 5</span><span>Очки: <b id="p3-ys">0</b> / 5</span></div>'
+'<div id="p3-yq" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;flex-wrap:wrap"><button class="btn primary" data-yn="yes">Да, является</button><button class="btn primary" data-yn="no">Нет, не является</button></div>'
+'<div class="feedback" id="p3-yfb"></div></div>';
h+=secNav('p2','p4')+readBtn('p3');
box.innerHTML=h; renderMath(box);
(function(){
var i=0,score=0,cur=null;
function gen(){
var t=_ri(0,4), x=_ri(2,12), a=_ri(2,15), b;
if(t===0){ b=x+a; cur={q:'$x+'+a+'='+b+'$',ans:x}; }
else if(t===1){ b=x-a; if(b<0){b=x+a;t=0;cur={q:'$x+'+a+'='+b+'$',ans:x};}else{cur={q:'$x-'+a+'='+b+'$',ans:x};} }
else if(t===2){ b=a-x; if(b<0){x=_ri(1,a-1);b=a-x;} cur={q:'$'+a+'-x='+b+'$',ans:x}; }
else if(t===3){ var mult=_ri(2,9); b=x*mult; cur={q:'$x\\cdot'+mult+'='+b+'$',ans:x}; }
else { var div=_ri(2,9); b=x*div; cur={q:'$x:'+div+'='+x+'$',ans:x}; }
}
function updateScale(eq){ var el=document.getElementById('p3-scale-rhs'); if(el)el.textContent=eq||'?'; }
function show(){ if(i>=6){ document.getElementById('p3-q').innerHTML='<b>Готово!</b> Результат: '+score+' / 6'; if(score>=5){addXp(15,'p3-iv1');bumpProgress('p3',30);}else if(score>=3){addXp(8,'p3-iv1');bumpProgress('p3',16);} return; }
gen(); document.getElementById('p3-i').textContent=i+1;
document.getElementById('p3-q').innerHTML=cur.q; renderMath(document.getElementById('p3-q'));
document.getElementById('p3-a').value=''; document.getElementById('p3-fb').style.display='none'; }
function go(){ if(i>=6)return; var fb=document.getElementById('p3-fb'), v=parseInt(document.getElementById('p3-a').value.replace(',','.').trim(),10);
if(isNaN(v)){ feedback(fb,false,'Введи целое число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! x = '+cur.ans+'.'); updateScale(cur.ans); } else feedback(fb,false,'✗ Нет. Правильный ответ: x = '+cur.ans+'.');
document.getElementById('p3-s').textContent=score; i++; setTimeout(show,1300); }
document.getElementById('p3-go').addEventListener('click',go);
document.getElementById('p3-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
(function(){
var i=0,score=0,cur=null;
function gen(){
var x=_ri(2,10), a=_ri(2,8), b=x+a;
var isRoot=_ri(0,1)===0;
var tested=isRoot?x:x+_ri(1,4);
cur={q:'Уравнение $x+'+a+'='+b+'$. Число $'+tested+'$ — корень?', correct:isRoot, root:x, tested:tested};
}
function show(){ if(i>=5){ document.getElementById('p3-yq').innerHTML='<b>Готово!</b> Результат: '+score+' / 5'; if(score>=4){addXp(15,'p3-iv2');bumpProgress('p3',30);}else if(score>=2){addXp(8,'p3-iv2');bumpProgress('p3',16);} return; }
gen(); document.getElementById('p3-yi').textContent=i+1;
document.getElementById('p3-yq').innerHTML=cur.q; renderMath(document.getElementById('p3-yq'));
document.getElementById('p3-yfb').style.display='none'; }
function ans(yn){ if(i>=5)return; var fb=document.getElementById('p3-yfb'), ok=(yn==='yes')===cur.correct;
if(ok){ score++; feedback(fb,true,'✓ Верно! Корень: x = '+cur.root+'.'); } else feedback(fb,false,'✗ Нет. Корень: x = '+cur.root+' (проверь подстановку).');
document.getElementById('p3-ys').textContent=score; i++; setTimeout(show,1300); }
document.querySelectorAll('#p3-iv2 [data-yn]').forEach(function(b){ b.addEventListener('click',function(){ ans(b.getAttribute('data-yn')); }); });
show();
})();
}
/* ===================== § 4. ФОРМУЛЫ ===================== */
function buildP4(){
var box=document.getElementById('p4-body'); var h='';
h+=makeCard('oral','Где это в жизни','4.0',
'<p>Прораб знает: площадь комнаты $S=a\\cdot b$, а периметр плинтуса $P=2(a+b)$. Водитель использует $s=v\\cdot t$, чтобы рассчитать время в пути. <b>Формулы</b> — это уравнения в общем виде, работающие для любых конкретных чисел.</p>');
h+=makeCard('theory','Основные формулы','4.1',
'<p><b>Периметр прямоугольника:</b> $P=2\\cdot(a+b)$, где $a,b$ — стороны.</p>'
+'<p><b>Площадь прямоугольника:</b> $S=a\\cdot b$.</p>'
+'<p><b>Периметр квадрата:</b> $P=4\\cdot a$, где $a$ — сторона.</p>'
+'<p><b>Путь:</b> $s=v\\cdot t$, где $v$ — скорость, $t$ — время.</p>');
h+=makeCard('rule','Как применять формулу','4.2',
'<p>1) Определи, какая формула нужна.</p>'
+'<p>2) Подставь данные числа вместо букв.</p>'
+'<p>3) Выполни вычисления.</p>'
+'<p>Пример: прямоугольник $6\\times4$. Площадь: $S=6\\cdot4=24$ (кв. ед.). Периметр: $P=2\\cdot(6+4)=20$ (ед.).</p>');
h+=makeCard('example','Разбор по шагам','4.3',
'<p>Автомобиль едет $60$ км/ч. Сколько км проедет за $3$ ч?</p>'
+'<ol style="padding-left:22px;line-height:2">'
+'<li>Формула пути: $s=v\\cdot t$.</li>'
+'<li>Подставляем: $s=60\\cdot3$.</li>'
+'<li>Вычисляем: $s=180$ км.</li>'
+'<li>Проверка: $180:60=3$ ч — верно!</li>'
+'</ol>');
h+=makeCard('theory','А знаешь ли ты?','4.4',
'<p>Формула $s=v\\cdot t$ была известна ещё в Средневековье. Но систематически буквенные формулы в физике и математике стали писать только после работ <b>Галилея</b> и <b>Ньютона</b> (XVII век). До них описание законов природы занимало несколько страниц текста вместо одной строки!</p>');
h+='<div class="wg" id="p4-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Подставь в формулу</div></div>'
+'<div class="wg-help">Вычисли требуемую величину по формуле. Ответ — целое число.</div>'
+'<div class="score-display"><span>Задача <b id="p4-i">1</b> / 6</span><span>Очки: <b id="p4-s">0</b> / 6</span></div>'
+'<div id="p4-q" class="qbox" style="font-size:1rem;text-align:left"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="text" id="p4-a" class="tinp" style="width:110px;text-align:center" placeholder="ответ"><button class="btn primary" id="p4-go">Проверить</button></div>'
+'<div class="feedback" id="p4-fb"></div></div>';
h+='<div class="wg" id="p4-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Какая формула?</div></div>'
+'<div class="wg-help">Выбери нужную формулу для данной задачи.</div>'
+'<div class="score-display"><span>Вопрос <b id="p4-fi">1</b> / 5</span><span>Очки: <b id="p4-fs">0</b> / 5</span></div>'
+'<div id="p4-fq" class="qbox"></div>'
+'<div id="p4-fopt" style="display:flex;gap:8px;justify-content:center;flex-wrap:wrap"></div>'
+'<div class="feedback" id="p4-ffb"></div></div>';
h+=secNav('p3','p5')+readBtn('p4');
box.innerHTML=h; renderMath(box);
(function(){
var i=0,score=0,cur=null;
function gen(){
var t=_ri(0,3);
if(t===0){ var a=_ri(3,12),b=_ri(3,12); cur={q:'Площадь прямоугольника со сторонами $'+a+'$ и $'+b+'$. Формула: $S=a\\cdot b$. Ответ:',ans:a*b}; }
else if(t===1){ var a=_ri(3,15),b=_ri(3,10); cur={q:'Периметр прямоугольника со сторонами $'+a+'$ и $'+b+'$. Формула: $P=2(a+b)$. Ответ:',ans:2*(a+b)}; }
else if(t===2){ var a=_ri(4,15); cur={q:'Периметр квадрата со стороной $'+a+'$. Формула: $P=4a$. Ответ:',ans:4*a}; }
else { var v=_ri(40,100), tm=_ri(2,6); cur={q:'Скорость $'+v+'$ км/ч, время $'+tm+'$ ч. Путь: $s=v\\cdot t$. Ответ (км):',ans:v*tm}; }
}
function show(){ if(i>=6){ document.getElementById('p4-q').innerHTML='<b>Готово!</b> Результат: '+score+' / 6'; if(score>=5){addXp(15,'p4-iv1');bumpProgress('p4',30);}else if(score>=3){addXp(8,'p4-iv1');bumpProgress('p4',16);} return; }
gen(); document.getElementById('p4-i').textContent=i+1;
document.getElementById('p4-q').innerHTML=cur.q; renderMath(document.getElementById('p4-q'));
document.getElementById('p4-a').value=''; document.getElementById('p4-fb').style.display='none'; }
function go(){ if(i>=6)return; var fb=document.getElementById('p4-fb'), v=parseInt(document.getElementById('p4-a').value.replace(',','.').trim(),10);
if(isNaN(v)){ feedback(fb,false,'Введи целое число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! Ответ '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Правильно: '+cur.ans+'.');
document.getElementById('p4-s').textContent=score; i++; setTimeout(show,1300); }
document.getElementById('p4-go').addEventListener('click',go);
document.getElementById('p4-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
(function(){
var QZ=[
{q:'Нужно найти площадь прямоугольника:',o:['$S=a\\cdot b$','$P=2(a+b)$','$s=v\\cdot t$'],a:0},
{q:'Нужно найти периметр квадрата:',o:['$P=4a$','$S=a^2$','$s=v\\cdot t$'],a:0},
{q:'Нужно найти путь при данной скорости и времени:',o:['$s=v\\cdot t$','$S=a\\cdot b$','$P=2(a+b)$'],a:0},
{q:'Нужно найти периметр прямоугольника:',o:['$P=2(a+b)$','$S=a\\cdot b$','$P=4a$'],a:0},
{q:'Нужно найти скорость, зная путь и время:',o:['$v=s:t$','$t=s:v$','$s=v+t$'],a:0}
];
var order=[],i=0,score=0,cur=null;
function reorder(){ order=QZ.map(function(_,k){return k;}); for(var j=order.length-1;j>0;j--){ var k=_ri(0,j),t=order[j];order[j]=order[k];order[k]=t; } }
reorder();
function show(){ if(i>=5){ document.getElementById('p4-fq').innerHTML='<b>Готово!</b> Результат: '+score+' / 5'; document.getElementById('p4-fopt').innerHTML=''; if(score>=4){addXp(15,'p4-iv2');bumpProgress('p4',30);}else if(score>=2){addXp(8,'p4-iv2');bumpProgress('p4',16);} return; }
cur=QZ[order[i]]; document.getElementById('p4-fi').textContent=i+1;
document.getElementById('p4-fq').innerHTML=cur.q; renderMath(document.getElementById('p4-fq'));
var idx=[0,1,2]; for(var j=idx.length-1;j>0;j--){var k=_ri(0,j),t=idx[j];idx[j]=idx[k];idx[k]=t;}
var html=''; idx.forEach(function(oi){ html+='<button class="btn primary" data-oi="'+oi+'">'+cur.o[oi]+'</button>'; });
document.getElementById('p4-fopt').innerHTML=html;
document.querySelectorAll('#p4-fopt [data-oi]').forEach(function(b){ b.addEventListener('click',function(){ ans(+b.getAttribute('data-oi')); }); });
renderMath(document.getElementById('p4-fopt'));
document.getElementById('p4-ffb').style.display='none'; }
function ans(oi){ if(i>=5)return; var fb=document.getElementById('p4-ffb');
if(oi===cur.a){ score++; feedback(fb,true,'✓ Верно!'); } else feedback(fb,false,'✗ Нет. Верно: '+cur.o[cur.a]+'.');
document.getElementById('p4-fs').textContent=score; i++; setTimeout(show,1300); }
show();
})();
}
/* ===================== § 5. РЕШЕНИЕ ЗАДАЧ С ПОМОЩЬЮ УРАВНЕНИЙ ===================== */
function buildP5(){
var box=document.getElementById('p5-body'); var h='';
h+=makeCard('oral','Где это в жизни','5.0',
'<p>«В двух коробках $60$ карандашей. В первой на $12$ больше, чем во второй. Сколько карандашей в каждой?» — такую задачу проще решить <b>через уравнение</b>: обозначить неизвестное буквой, записать условие как равенство, решить уравнение.</p>');
h+=makeCard('rule','Алгоритм составления уравнения','5.1',
'<p>1) Выбери, что обозначить через $x$ (обычно то, что ищут).</p>'
+'<p>2) Выражи остальные величины через $x$.</p>'
+'<p>3) Составь уравнение по условию задачи.</p>'
+'<p>4) Реши уравнение и дай ответ в контексте задачи.</p>'
+'<p>5) Выполни проверку.</p>');
h+=makeCard('example','Разбор по шагам','5.2',
'<p>В двух коробках $60$ карандашей. В первой на $12$ больше, чем во второй. Сколько в каждой?</p>'
+'<ol style="padding-left:22px;line-height:2">'
+'<li>Пусть во второй $x$ карандашей.</li>'
+'<li>Тогда в первой $x+12$.</li>'
+'<li>Уравнение: $x+(x+12)=60 \\Rightarrow 2x+12=60 \\Rightarrow 2x=48 \\Rightarrow x=24$.</li>'
+'<li>Во второй $24$, в первой $24+12=36$.</li>'
+'<li>Проверка: $24+36=60$ и $36-24=12$. Верно!</li>'
+'</ol>');
h+=makeCard('theory','А знаешь ли ты?','5.3',
'<p>Задачи, решаемые через уравнения, встречаются в египетских папирусах возрастом более $3500$ лет. Там неизвестное называли «аха» (куча). Так что «найди x» — традиция тысячелетней давности!</p>');
h+='<div class="wg" id="p5-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Сюжетная задача — через уравнение</div></div>'
+'<div class="wg-help">Составь уравнение и найди ответ. Введи числовой ответ на вопрос задачи.</div>'
+'<div class="score-display"><span>Задача <b id="p5-i">1</b> / 6</span><span>Очки: <b id="p5-s">0</b> / 6</span></div>'
+'<div id="p5-q" class="qbox" style="font-size:.98rem;text-align:left"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="text" id="p5-a" class="tinp" style="width:110px;text-align:center" placeholder="ответ"><button class="btn primary" id="p5-go">Проверить</button></div>'
+'<div class="feedback" id="p5-fb"></div></div>';
h+='<div class="wg" id="p5-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Какое уравнение?</div></div>'
+'<div class="wg-help">Выбери уравнение, соответствующее условию задачи.</div>'
+'<div class="score-display"><span>Вопрос <b id="p5-ei">1</b> / 5</span><span>Очки: <b id="p5-es">0</b> / 5</span></div>'
+'<div id="p5-eq" class="qbox"></div>'
+'<div id="p5-eopt" style="display:flex;gap:8px;justify-content:center;flex-wrap:wrap"></div>'
+'<div class="feedback" id="p5-efb"></div></div>';
h+=secNav('p4','p6')+readBtn('p5');
box.innerHTML=h; renderMath(box);
(function(){
var PROB=[
{q:'Число $x$ увеличили на $14$ и получили $30$. Найди $x$.',a:16},
{q:'Купили несколько тетрадей по $8$ р. Заплатили $48$ р. Сколько тетрадей?',a:6},
{q:'В двух пакетах $50$ кг муки. В первом $x$ кг, во втором на $6$ кг меньше. Найди $x$.',a:28},
{q:'Длина забора $P=54$ м. Забор состоит из трёх равных секций. Длина одной секции?',a:18},
{q:'Поезд ехал $4$ ч со скоростью $v$ км/ч и проехал $280$ км. Найди $v$.',a:70},
{q:'Саше $x$ лет, Маше на $5$ лет больше, вместе им $27$ лет. Сколько лет Саше?',a:11},
{q:'В трёх ящиках поровну яблок, всего $96$. Сколько яблок в каждом?',a:32},
{q:'Число уменьшили на $23$ и получили $45$. Найди исходное число.',a:68}
];
var order=[],i=0,score=0,cur=null;
function reorder(){ order=PROB.map(function(_,k){return k;}); for(var j=order.length-1;j>0;j--){ var k=_ri(0,j),t=order[j];order[j]=order[k];order[k]=t; } }
reorder();
function show(){ if(i>=6){ document.getElementById('p5-q').innerHTML='<b>Готово!</b> Результат: '+score+' / 6'; if(score>=5){addXp(15,'p5-iv1');bumpProgress('p5',30);}else if(score>=3){addXp(8,'p5-iv1');bumpProgress('p5',16);} return; }
cur=PROB[order[i]]; document.getElementById('p5-i').textContent=i+1;
document.getElementById('p5-q').innerHTML=cur.q; renderMath(document.getElementById('p5-q'));
document.getElementById('p5-a').value=''; document.getElementById('p5-fb').style.display='none'; }
function go(){ if(i>=6)return; var fb=document.getElementById('p5-fb'), v=parseInt(document.getElementById('p5-a').value.replace(',','.').trim(),10);
if(isNaN(v)){ feedback(fb,false,'Введи целое число.'); return; }
if(v===cur.a){ score++; feedback(fb,true,'✓ Верно! Ответ '+cur.a+'.'); } else feedback(fb,false,'✗ Нет. Правильно: '+cur.a+'.');
document.getElementById('p5-s').textContent=score; i++; setTimeout(show,1400); }
document.getElementById('p5-go').addEventListener('click',go);
document.getElementById('p5-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
(function(){
var QZ=[
{q:'«Число увеличили на $7$ и получили $20$.» Какое уравнение?',o:['$x+7=20$','$x-7=20$','$7x=20$'],a:0},
{q:'«Число умножили на $4$ и получили $36$.» Какое уравнение?',o:['$4x=36$','$x+4=36$','$x:4=36$'],a:0},
{q:'«Из числа вычли $8$ и получили $15$.» Какое уравнение?',o:['$x-8=15$','$x+8=15$','$8-x=15$'],a:0},
{q:'«Число разделили на $5$ и получили $7$.» Какое уравнение?',o:['$x:5=7$','$5x=7$','$x-5=7$'],a:0},
{q:'«Сумма двух чисел равна $40$, одно из них $17$.» Какое уравнение?',o:['$x+17=40$','$x-17=40$','$17x=40$'],a:0}
];
var order=[],i=0,score=0,cur=null;
function reorder(){ order=QZ.map(function(_,k){return k;}); for(var j=order.length-1;j>0;j--){ var k=_ri(0,j),t=order[j];order[j]=order[k];order[k]=t; } }
reorder();
function show(){ if(i>=5){ document.getElementById('p5-eq').innerHTML='<b>Готово!</b> Результат: '+score+' / 5'; document.getElementById('p5-eopt').innerHTML=''; if(score>=4){addXp(15,'p5-iv2');bumpProgress('p5',30);}else if(score>=2){addXp(8,'p5-iv2');bumpProgress('p5',16);} return; }
cur=QZ[order[i]]; document.getElementById('p5-ei').textContent=i+1;
document.getElementById('p5-eq').innerHTML=cur.q; renderMath(document.getElementById('p5-eq'));
var idx=[0,1,2]; for(var j=idx.length-1;j>0;j--){var k=_ri(0,j),t=idx[j];idx[j]=idx[k];idx[k]=t;}
var html=''; idx.forEach(function(oi){ html+='<button class="btn primary" data-oi="'+oi+'">'+cur.o[oi]+'</button>'; });
document.getElementById('p5-eopt').innerHTML=html;
document.querySelectorAll('#p5-eopt [data-oi]').forEach(function(b){ b.addEventListener('click',function(){ ans(+b.getAttribute('data-oi')); }); });
renderMath(document.getElementById('p5-eopt'));
document.getElementById('p5-efb').style.display='none'; }
function ans(oi){ if(i>=5)return; var fb=document.getElementById('p5-efb');
if(oi===cur.a){ score++; feedback(fb,true,'✓ Верно!'); } else feedback(fb,false,'✗ Нет. Верно: '+cur.o[cur.a]+'.');
document.getElementById('p5-es').textContent=score; i++; setTimeout(show,1300); }
show();
})();
}
/* ===================== § 6. УГОЛ. ИЗМЕРЕНИЕ И ПОСТРОЕНИЕ УГЛОВ ===================== */
function buildP6(){
var box=document.getElementById('p6-body'); var h='';
h+=makeCard('oral','Где это в жизни','6.0',
'<p>Поворот кресла, наклон солнечных лучей, угол в архитектуре — везде мы встречаем <b>углы</b>. Строитель с транспортиром, навигатор с компасом, конструктор в CAD-программе — все измеряют и задают углы.</p>');
h+=makeCard('theory','Что такое угол','6.1',
'<p><b>Угол</b> — геометрическая фигура, образованная двумя лучами (<b>сторонами</b>), исходящими из одной точки (<b>вершины</b>).</p>'
+'<p>Угол измеряют в <b>градусах</b> ($1^\\circ$ — $1/360$ полного оборота). Прибор для измерения — <b>транспортир</b>.</p>');
h+=makeCard('rule','Виды углов','6.2',
'<p><b>Острый:</b> $0^\\circ < \\alpha < 90^\\circ$</p>'
+'<p><b>Прямой:</b> $\\alpha = 90^\\circ$ (обозначают квадратиком у вершины)</p>'
+'<p><b>Тупой:</b> $90^\\circ < \\alpha < 180^\\circ$</p>'
+'<p><b>Развёрнутый:</b> $\\alpha = 180^\\circ$ (стороны образуют прямую)</p>');
/* SVG-визуал угла — статический пример */
h+='<div id="p6-angle-demo" style="text-align:center;margin:10px 0">'
+'<svg viewBox="0 0 300 160" width="300" style="max-width:100%;display:inline-block">'
/* Острый */
+'<g transform="translate(30,130)">'
+'<line x1="0" y1="0" x2="60" y2="0" stroke="#0d9488" stroke-width="2"/>'
+'<line x1="0" y1="0" x2="40" y2="-55" stroke="#0d9488" stroke-width="2"/>'
+'<path d="M18,0 A18,18,0,0,0,10.6,-15" fill="none" stroke="#0d9488" stroke-width="1.5"/>'
+'<text x="8" y="-18" font-size="11" fill="#0d9488" font-weight="700">~45°</text>'
+'<text x="22" y="14" font-size="10" fill="#0d9488">острый</text>'
+'</g>'
/* Прямой */
+'<g transform="translate(120,130)">'
+'<line x1="0" y1="0" x2="60" y2="0" stroke="#4f46e5" stroke-width="2"/>'
+'<line x1="0" y1="0" x2="0" y2="-60" stroke="#4f46e5" stroke-width="2"/>'
+'<rect x="0" y="-14" width="14" height="14" fill="none" stroke="#4f46e5" stroke-width="1.5"/>'
+'<text x="8" y="-20" font-size="11" fill="#4f46e5" font-weight="700">90°</text>'
+'<text x="-4" y="14" font-size="10" fill="#4f46e5">прямой</text>'
+'</g>'
/* Тупой */
+'<g transform="translate(215,130)">'
+'<line x1="0" y1="0" x2="65" y2="0" stroke="#e11d48" stroke-width="2"/>'
+'<line x1="0" y1="0" x2="-30" y2="-52" stroke="#e11d48" stroke-width="2"/>'
+'<path d="M22,0 A22,22,0,0,0,-10,-19" fill="none" stroke="#e11d48" stroke-width="1.5"/>'
+'<text x="-4" y="-22" font-size="11" fill="#e11d48" font-weight="700">~120°</text>'
+'<text x="10" y="14" font-size="10" fill="#e11d48">тупой</text>'
+'</g>'
+'</svg>'
+'</div>';
h+=makeCard('example','Разбор по шагам','6.3',
'<p>Определим вид угла в $125^\\circ$.</p>'
+'<ol style="padding-left:22px;line-height:2">'
+'<li>Проверим: $125^\\circ > 90^\\circ$ — не прямой и не острый.</li>'
+'<li>Проверим: $125^\\circ < 180^\\circ$ — не развёрнутый.</li>'
+'<li>Значит, $90^\\circ < 125^\\circ < 180^\\circ$ — угол <b>тупой</b>.</li>'
+'</ol>');
h+=makeCard('theory','А знаешь ли ты?','6.4',
'<p>Разбивка окружности на $360^\\circ$ — наследие <b>вавилонян</b>. Они считали в шестидесятеричной системе и знали, что год содержит около $360$ дней. Сегодня в навигации и астрономии $360^\\circ$ — незыблемый стандарт.</p>');
h+='<div class="wg" id="p6-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Классифицируй угол</div></div>'
+'<div class="wg-help">По рисунку угла нажми его вид.</div>'
+'<div class="score-display"><span>Вопрос <b id="p6-i">1</b> / 6</span><span>Очки: <b id="p6-s">0</b> / 6</span></div>'
+'<div id="p6-fig" style="text-align:center;margin:8px 0"></div>'
+'<div style="display:flex;gap:8px;justify-content:center;flex-wrap:wrap"><button class="btn primary" data-kind="острый">острый</button><button class="btn primary" data-kind="прямой">прямой</button><button class="btn primary" data-kind="тупой">тупой</button><button class="btn primary" data-kind="развёрнутый">развёрнутый</button></div>'
+'<div class="feedback" id="p6-fb"></div></div>';
h+='<div class="wg" id="p6-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Сколько градусов?</div></div>'
+'<div class="wg-help">По виду угла введи его точную меру (для прямого) или оцени: выбери вариант.</div>'
+'<div class="score-display"><span>Вопрос <b id="p6-di">1</b> / 5</span><span>Очки: <b id="p6-ds">0</b> / 5</span></div>'
+'<div id="p6-dq" class="qbox"></div>'
+'<div id="p6-dopt" style="display:flex;gap:8px;justify-content:center;flex-wrap:wrap"></div>'
+'<div class="feedback" id="p6-dfb"></div></div>';
h+=secNav('p5','p7')+readBtn('p6');
box.innerHTML=h; renderMath(box);
function angleSVG(deg){
var W=220,H=160,cx=40,cy=130;
var rad=deg*Math.PI/180;
var L=140;
var x2=cx+L, y2=cy;
var x3=Math.round(cx+L*Math.cos(Math.PI-rad)), y3=Math.round(cy-L*Math.sin(Math.PI-rad));
var col=deg===90?'#4f46e5':(deg===180?'#374151':(deg<90?'#0d9488':'#e11d48'));
var s='<svg viewBox="0 0 '+W+' '+H+'" width="220" style="max-width:100%">';
s+='<line x1="'+cx+'" y1="'+cy+'" x2="'+x2+'" y2="'+y2+'" stroke="'+col+'" stroke-width="2.5"/>';
if(deg===180){
s+='<line x1="'+cx+'" y1="'+cy+'" x2="'+(cx-L)+'" y2="'+y2+'" stroke="'+col+'" stroke-width="2.5"/>';
} else {
s+='<line x1="'+cx+'" y1="'+cy+'" x2="'+x3+'" y2="'+y3+'" stroke="'+col+'" stroke-width="2.5"/>';
}
s+='<circle cx="'+cx+'" cy="'+cy+'" r="4" fill="'+col+'"/>';
if(deg===90){
s+='<rect x="'+cx+'" y="'+(cy-16)+'" width="16" height="16" fill="none" stroke="'+col+'" stroke-width="1.5"/>';
} else if(deg!==180){
var arcR=30;
var ax=Math.round(cx+arcR), ay=cy;
var bx=Math.round(cx+arcR*Math.cos(Math.PI-rad)), by=Math.round(cy-arcR*Math.sin(Math.PI-rad));
var laf=deg>180?1:0;
s+='<path d="M'+ax+','+ay+' A'+arcR+','+arcR+',0,'+laf+',0,'+bx+','+by+'" fill="none" stroke="'+col+'" stroke-width="1.5"/>';
}
s+='<text x="'+(cx+14)+'" y="'+(cy-18)+'" font-size="13" font-weight="700" fill="'+col+'">'+deg+'°</text>';
return s+'</svg>';
}
(function(){
var KINDS=[
{deg:35,kind:'острый'},{deg:55,kind:'острый'},{deg:70,kind:'острый'},
{deg:90,kind:'прямой'},
{deg:110,kind:'тупой'},{deg:130,kind:'тупой'},{deg:150,kind:'тупой'},
{deg:180,kind:'развёрнутый'}
];
var order=[],i=0,score=0,cur=null;
function reorder(){ order=KINDS.map(function(_,k){return k;}); for(var j=order.length-1;j>0;j--){ var k=_ri(0,j),t=order[j];order[j]=order[k];order[k]=t; } }
reorder();
function show(){ if(i>=6){ document.getElementById('p6-fig').innerHTML='<b>Готово! '+score+' / 6</b>'; if(score>=5){addXp(15,'p6-iv1');bumpProgress('p6',30);}else if(score>=3){addXp(8,'p6-iv1');bumpProgress('p6',16);} return; }
cur=KINDS[order[i]]; document.getElementById('p6-i').textContent=i+1;
document.getElementById('p6-fig').innerHTML=angleSVG(cur.deg);
document.getElementById('p6-fb').style.display='none'; }
function ans(kind){ if(i>=6)return; var fb=document.getElementById('p6-fb');
if(kind===cur.kind){ score++; feedback(fb,true,'✓ Верно — '+cur.deg+'° — '+cur.kind+'.'); } else feedback(fb,false,'✗ Нет. Это '+cur.kind+' угол ('+cur.deg+'°).');
document.getElementById('p6-s').textContent=score; i++; setTimeout(show,1200); }
document.querySelectorAll('#p6-iv1 [data-kind]').forEach(function(b){ b.addEventListener('click',function(){ ans(b.getAttribute('data-kind')); }); });
show();
})();
(function(){
var QZ=[
{q:'Прямой угол равен …',o:['90°','180°','45°'],a:0},
{q:'Развёрнутый угол равен …',o:['180°','90°','360°'],a:0},
{q:'Угол $35°$ — какой вид?',o:['острый','тупой','прямой'],a:0},
{q:'Угол $140°$ — какой вид?',o:['тупой','острый','развёрнутый'],a:0},
{q:'Какой угол НЕ острый из следующих: $60°$, $95°$, $30°$?',o:['95°','60°','30°'],a:0},
{q:'Сумма двух прямых углов равна …',o:['180°','90°','360°'],a:0}
];
var order=[],i=0,score=0,cur=null;
function reorder(){ order=QZ.map(function(_,k){return k;}); for(var j=order.length-1;j>0;j--){ var k=_ri(0,j),t=order[j];order[j]=order[k];order[k]=t; } }
reorder();
function show(){ if(i>=5){ document.getElementById('p6-dq').innerHTML='<b>Готово!</b> Результат: '+score+' / 5'; document.getElementById('p6-dopt').innerHTML=''; if(score>=4){addXp(15,'p6-iv2');bumpProgress('p6',30);}else if(score>=2){addXp(8,'p6-iv2');bumpProgress('p6',16);} return; }
cur=QZ[order[i]]; document.getElementById('p6-di').textContent=i+1;
document.getElementById('p6-dq').innerHTML=cur.q;
var idx=[0,1,2]; for(var j=idx.length-1;j>0;j--){var k=_ri(0,j),t=idx[j];idx[j]=idx[k];idx[k]=t;}
var html=''; idx.forEach(function(oi){ html+='<button class="btn primary" data-oi="'+oi+'">'+cur.o[oi]+'</button>'; });
document.getElementById('p6-dopt').innerHTML=html;
document.querySelectorAll('#p6-dopt [data-oi]').forEach(function(b){ b.addEventListener('click',function(){ ans(+b.getAttribute('data-oi')); }); });
document.getElementById('p6-dfb').style.display='none'; }
function ans(oi){ if(i>=5)return; var fb=document.getElementById('p6-dfb');
if(oi===cur.a){ score++; feedback(fb,true,'✓ Верно!'); } else feedback(fb,false,'✗ Нет. Верно: '+cur.o[cur.a]+'.');
document.getElementById('p6-ds').textContent=score; i++; setTimeout(show,1300); }
show();
})();
}
/* ===================== § 7. МАТЕМАТИКА ВОКРУГ НАС (applied) ===================== */
function buildP7(){
var box=document.getElementById('p7-body'); var h='';
h+=makeCard('oral','Где это в жизни','7.0',
'<p>Формулы и уравнения встречаются повсюду — в магазине, на кухне, при ремонте, в расписании поездов. Научившись составлять выражения и решать уравнения, ты можешь решать реальные жизненные задачи.</p>');
h+=makeCard('theory','Примеры применения','7.1',
'<p><b>Скидка:</b> цена $p$, скидка $d\\%$. Новая цена $= p\\cdot(100-d):100$.</p>'
+'<p><b>Расход ткани:</b> нужно $n$ платьев, на каждое $a$ м ткани — $x=a\\cdot n$.</p>'
+'<p><b>Грузовик:</b> грузит $m$ кг за рейс, нужно перевезти $M$ кг — $x=M:m$ рейсов.</p>'
+'<p><b>Обои:</b> ширина рулона $w$, длина $L$, периметр комнаты $P$ — рулонов $P:w$.</p>');
h+='<div class="wg" id="p7-iv1"><div class="wg-header"><span class="wg-badge">Интерактив</span><div class="wg-title">Жизненные задачи</div></div>'
+'<div class="wg-help">Реши прикладную задачу, используя выражение или уравнение.</div>'
+'<div class="score-display"><span>Задача <b id="p7-i">1</b> / 6</span><span>Очки: <b id="p7-s">0</b> / 6</span></div>'
+'<div id="p7-q" class="qbox" style="font-size:.97rem;text-align:left"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="text" id="p7-a" class="tinp" style="width:110px;text-align:center" placeholder="ответ"><button class="btn primary" id="p7-go">Проверить</button></div>'
+'<div class="feedback" id="p7-fb"></div></div>';
h+=secNav('p6','p8')+readBtn('p7');
box.innerHTML=h; renderMath(box);
(function(){
var PROB=[
{q:'Тетрадь стоит $12$ р., ручка — $8$ р. Купили $3$ тетради и $2$ ручки. Сколько заплатили (р.)?',a:52},
{q:'Поезд едет $4$ ч со скоростью $80$ км/ч. Расстояние (км)?',a:320},
{q:'Комната $5\\times4$ м. Периметр (м)?',a:18},
{q:'Площадь огорода $48$ кв.м, ширина $6$ м. Длина (м)?',a:8},
{q:'В коробке $120$ конфет. Дети разобрали по $8$. Сколько детей?',a:15},
{q:'Одна рубашка стоит $x$ р. Три рубашки стоят $180$ р. Найди $x$.',a:60},
{q:'Чайник ёмкостью $2$ л нужно наполнить из крана. Кран даёт $400$ мл/мин. Сколько минут?',a:5},
{q:'Велосипедист проехал $x$ км за $2$ ч со скоростью $18$ км/ч. Найди $x$.',a:36}
];
var order=[],i=0,score=0,cur=null;
function reorder(){ order=PROB.map(function(_,k){return k;}); for(var j=order.length-1;j>0;j--){ var k=_ri(0,j),t=order[j];order[j]=order[k];order[k]=t; } }
reorder();
function show(){ if(i>=6){ document.getElementById('p7-q').innerHTML='<b>Готово!</b> Результат: '+score+' / 6'; if(score>=5){addXp(15,'p7-iv1');bumpProgress('p7',30);}else if(score>=3){addXp(8,'p7-iv1');bumpProgress('p7',16);} return; }
cur=PROB[order[i]]; document.getElementById('p7-i').textContent=i+1;
document.getElementById('p7-q').innerHTML=cur.q; renderMath(document.getElementById('p7-q'));
document.getElementById('p7-a').value=''; document.getElementById('p7-fb').style.display='none'; }
function go(){ if(i>=6)return; var fb=document.getElementById('p7-fb'), v=parseInt(document.getElementById('p7-a').value.replace(',','.').trim(),10);
if(isNaN(v)){ feedback(fb,false,'Введи целое число.'); return; }
if(v===cur.a){ score++; feedback(fb,true,'✓ Верно! Ответ '+cur.a+'.'); } else feedback(fb,false,'✗ Нет. Правильно: '+cur.a+'.');
document.getElementById('p7-s').textContent=score; i++; setTimeout(show,1400); }
document.getElementById('p7-go').addEventListener('click',go);
document.getElementById('p7-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
}
/* ===================== § 8. ЗАНИМАТЕЛЬНЫЕ ЗАДАЧИ (applied) ===================== */
function buildP8(){
var box=document.getElementById('p8-body'); var h='';
h+=makeCard('oral','Занимательные задачи','8.0',
'<p>Математика — это не только формулы, но и <b>логические головоломки</b>. Они развивают нестандартное мышление, учат искать <b>скрытые закономерности</b> и рассуждать нестандартно. Некоторые из этих задач требуют составить уравнение, другие — смекалку.</p>');
h+=makeCard('theory','Совет','8.1',
'<p>Не бойся пробовать! Для каждой задачи: <b>1)</b> Запиши, что известно. <b>2)</b> Попробуй обозначить неизвестное через $x$. <b>3)</b> Если не выходит — замени $x$ на конкретные числа и ищи закономерность.</p>');
h+='<div class="wg" id="p8-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Числовые головоломки</div></div>'
+'<div class="wg-help">Найди ответ на головоломку. Введи число.</div>'
+'<div class="score-display"><span>Задача <b id="p8-i">1</b> / 5</span><span>Очки: <b id="p8-s">0</b> / 5</span></div>'
+'<div id="p8-q" class="qbox" style="font-size:.97rem;text-align:left"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="text" id="p8-a" class="tinp" style="width:110px;text-align:center" placeholder="ответ"><button class="btn primary" id="p8-go">Проверить</button></div>'
+'<div class="feedback" id="p8-fb"></div></div>';
h+='<div class="wg" id="p8-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Продолжи последовательность</div></div>'
+'<div class="wg-help">Найди правило и введи следующий член числовой последовательности.</div>'
+'<div class="score-display"><span>Задача <b id="p8-li">1</b> / 5</span><span>Очки: <b id="p8-ls">0</b> / 5</span></div>'
+'<div id="p8-lq" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="text" id="p8-la" class="tinp" style="width:110px;text-align:center" placeholder="ответ"><button class="btn primary" id="p8-lgo">Проверить</button></div>'
+'<div class="feedback" id="p8-lfb"></div></div>';
h+=secNav('p7','p9')+readBtn('p8');
box.innerHTML=h; renderMath(box);
(function(){
var PROB=[
{q:'Думаю о числе. Удвою его и прибавлю $6$ — получу $20$. Какое это число?',a:7},
{q:'Три числа подряд. Их сумма равна $36$. Наименьшее из них?',a:11},
{q:'Из двухзначного числа вычти число, образованное перестановкой его цифр, и получится $18$. Наименьшее такое число?',a:31},
{q:'Сумма цифр числа равна $9$. Само число вдвое больше, чем $27$. Что это за число?',a:54},
{q:'Ленту длиной $24$ м разрезали на куски по $3$ м. Сколько разрезов сделали?',a:7}
];
var order=[],i=0,score=0,cur=null;
function reorder(){ order=PROB.map(function(_,k){return k;}); for(var j=order.length-1;j>0;j--){ var k=_ri(0,j),t=order[j];order[j]=order[k];order[k]=t; } }
reorder();
function show(){ if(i>=5){ document.getElementById('p8-q').innerHTML='<b>Готово!</b> Результат: '+score+' / 5'; if(score>=4){addXp(15,'p8-iv1');bumpProgress('p8',30);}else if(score>=2){addXp(8,'p8-iv1');bumpProgress('p8',16);} return; }
cur=PROB[order[i]]; document.getElementById('p8-i').textContent=i+1;
document.getElementById('p8-q').innerHTML=cur.q;
document.getElementById('p8-a').value=''; document.getElementById('p8-fb').style.display='none'; }
function go(){ if(i>=5)return; var fb=document.getElementById('p8-fb'), v=parseInt(document.getElementById('p8-a').value.replace(',','.').trim(),10);
if(isNaN(v)){ feedback(fb,false,'Введи целое число.'); return; }
if(v===cur.a){ score++; feedback(fb,true,'✓ Верно! Ответ '+cur.a+'.'); } else feedback(fb,false,'✗ Нет. Правильно: '+cur.a+'.');
document.getElementById('p8-s').textContent=score; i++; setTimeout(show,1400); }
document.getElementById('p8-go').addEventListener('click',go);
document.getElementById('p8-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
(function(){
var SEQS=[
{q:'$2,\\; 4,\\; 6,\\; 8,\\; ?$',a:10,hint:'+2'},
{q:'$1,\\; 3,\\; 9,\\; 27,\\; ?$',a:81,hint:'×3'},
{q:'$5,\\; 10,\\; 15,\\; 20,\\; ?$',a:25,hint:'+5'},
{q:'$100,\\; 90,\\; 80,\\; 70,\\; ?$',a:60,hint:'10'},
{q:'$2,\\; 6,\\; 18,\\; 54,\\; ?$',a:162,hint:'×3'},
{q:'$1,\\; 4,\\; 9,\\; 16,\\; ?$',a:25,hint:'квадраты'}
];
var order=[],i=0,score=0,cur=null;
function reorder(){ order=SEQS.map(function(_,k){return k;}); for(var j=order.length-1;j>0;j--){ var k=_ri(0,j),t=order[j];order[j]=order[k];order[k]=t; } }
reorder();
function show(){ if(i>=5){ document.getElementById('p8-lq').innerHTML='<b>Готово!</b> Результат: '+score+' / 5'; if(score>=4){addXp(15,'p8-iv2');bumpProgress('p8',30);}else if(score>=2){addXp(8,'p8-iv2');bumpProgress('p8',16);} return; }
cur=SEQS[order[i]]; document.getElementById('p8-li').textContent=i+1;
document.getElementById('p8-lq').innerHTML=cur.q; renderMath(document.getElementById('p8-lq'));
document.getElementById('p8-la').value=''; document.getElementById('p8-lfb').style.display='none'; }
function go(){ if(i>=5)return; var fb=document.getElementById('p8-lfb'), v=parseInt(document.getElementById('p8-la').value.replace(',','.').trim(),10);
if(isNaN(v)){ feedback(fb,false,'Введи целое число.'); return; }
if(v===cur.a){ score++; feedback(fb,true,'✓ Верно! Правило: '+cur.hint+'. Ответ '+cur.a+'.'); } else feedback(fb,false,'✗ Нет. Правило: '+cur.hint+'. Ответ '+cur.a+'.');
document.getElementById('p8-ls').textContent=score; i++; setTimeout(show,1400); }
document.getElementById('p8-lgo').addEventListener('click',go);
document.getElementById('p8-la').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
}
/* ===================== § 9. ИСТОРИЧЕСКИЕ СВЕДЕНИЯ (applied) ===================== */
function buildP9(){
var box=document.getElementById('p9-body'); var h='';
h+=makeCard('oral','История уравнений','9.0',
'<p>Уравнения решали задолго до того, как появились символы $x$ и $=$. На протяжении тысячелетий люди искали неизвестное — и эта история полна открытий, путешествий и даже споров о первенстве.</p>');
h+=makeCard('theory','Как это началось','9.1',
'<p><b>Древний Египет (~1650 до н. э.):</b> папирус Ринда содержит задачи, где неизвестное называют «аха» («куча»). Это простейшие линейные уравнения.</p>'
+'<p><b>Вавилон (~2000 до н. э.):</b> математики умели решать квадратные уравнения, записывая условие на глиняных табличках.</p>'
+'<p><b>Аль-Хорезми (IX в. н. э.):</b> его книга ввела термин «алгебра» и дала систематический метод решения уравнений. Слово «алгоритм» — латинизация его имени.</p>'
+'<p><b>Франсуа Виет (1591):</b> первым стал обозначать неизвестное и данные <b>буквами</b>. Современная алгебра начинается с него.</p>');
h+=makeCard('rule','Появление символов','9.2',
'<p>Знак $=$ придумал Роберт Рекорд в $1557$ году. Знаки $+$ и $-$ стали общеупотребительными к $1500$ году. Букву $x$ для неизвестного закрепил Декарт в $1637$ году. До этого — только слова и сокращения!</p>');
h+=makeCard('theory','А знаешь ли ты?','9.3',
'<p>Слово <b>«алгебра»</b> происходит от арабского «аль-джабр» — «восстановление (сломанных костей)». Так аль-Хорезми называл операцию переноса отрицательного члена в другую часть уравнения. Математика и медицина соединились в одном слове!</p>');
h+='<div class="wg" id="p9-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">История алгебры — квиз</div></div>'
+'<div class="wg-help">Выбери верный ответ.</div>'
+'<div class="score-display"><span>Вопрос <b id="p9-i">1</b> / 6</span><span>Очки: <b id="p9-s">0</b> / 6</span></div>'
+'<div id="p9-q" class="qbox"></div>'
+'<div id="p9-opt" style="display:flex;gap:8px;justify-content:center;flex-wrap:wrap"></div>'
+'<div class="feedback" id="p9-fb"></div></div>';
h+=secNav('p8','final')+readBtn('p9');
box.innerHTML=h; renderMath(box);
(function(){
var QZ=[
{q:'Как называли неизвестное в Египте?',o:['аха (куча)','икс','арабской буквой'],a:0},
{q:'Кто написал первый алгебраический трактат, давший слово «алгебра»?',o:['аль-Хорезми','Виет','Декарт'],a:0},
{q:'Кто первым стал обозначать неизвестное буквой $x$?',o:['Декарт','аль-Хорезми','Рекорд'],a:0},
{q:'Кто придумал знак равенства $=$?',o:['Роберт Рекорд','Евклид','Виет'],a:0},
{q:'Что означает слово «алгоритм»?',o:['латинизация имени аль-Хорезми','правило вычисления','алгебраическая запись'],a:0},
{q:'В каком году Декарт закрепил букву $x$ для неизвестного?',o:['1637','1591','1557'],a:0},
{q:'Кто первым использовал буквы для известных и неизвестных величин?',o:['Виет','аль-Хорезми','Рекорд'],a:0}
];
var order=[],i=0,score=0,cur=null;
function reorder(){ order=QZ.map(function(_,k){return k;}); for(var j=order.length-1;j>0;j--){ var k=_ri(0,j),t=order[j];order[j]=order[k];order[k]=t; } }
reorder();
function show(){ if(i>=6){ document.getElementById('p9-q').innerHTML='<b>Готово!</b> Результат: '+score+' / 6'; document.getElementById('p9-opt').innerHTML=''; if(score>=5){addXp(15,'p9-iv1');bumpProgress('p9',30);}else if(score>=3){addXp(8,'p9-iv1');bumpProgress('p9',16);} return; }
cur=QZ[order[i]]; document.getElementById('p9-i').textContent=i+1;
document.getElementById('p9-q').innerHTML=cur.q; renderMath(document.getElementById('p9-q'));
var idx=[0,1,2]; for(var j=idx.length-1;j>0;j--){var k=_ri(0,j),t=idx[j];idx[j]=idx[k];idx[k]=t;}
var html=''; idx.forEach(function(oi){ html+='<button class="btn primary" data-oi="'+oi+'">'+cur.o[oi]+'</button>'; });
document.getElementById('p9-opt').innerHTML=html;
document.querySelectorAll('#p9-opt [data-oi]').forEach(function(b){ b.addEventListener('click',function(){ ans(+b.getAttribute('data-oi')); }); });
document.getElementById('p9-fb').style.display='none'; }
function ans(oi){ if(i>=6)return; var fb=document.getElementById('p9-fb');
if(oi===cur.a){ score++; feedback(fb,true,'✓ Верно!'); } else feedback(fb,false,'✗ Нет. Верно: '+cur.o[cur.a]+'.');
document.getElementById('p9-s').textContent=score; i++; setTimeout(show,1300); }
show();
})();
}
/* ===================== ФИНАЛ ГЛАВЫ ===================== */
function buildFinal(){
var box=document.getElementById('final-body'); var h='';
h+=makeCard('theory','Финал главы 2','★',
'<p>Пять боссов проверят владение выражениями и уравнениями: порядок действий, переменные, корень уравнения, формулы, углы. Побей не меньше четырёх — и глава покорена!</p>');
h+='<div class="wg" id="fin"><div class="wg-header"><span class="wg-badge">Боссы</span><div class="wg-title">Сразись с главой 2</div></div>'
+'<div class="hp-boss"><div class="hp-boss-fill" id="fin-hp" style="width:100%"></div></div>'
+'<div class="score-display"><span>Босс <b id="fin-i">1</b> / 5</span><span>Побеждено: <b id="fin-s">0</b> / 5</span></div>'
+'<div id="fin-name" style="font-weight:800;color:#b91c1c;text-align:center;margin-bottom:6px"></div>'
+'<div id="fin-q" class="boss-q"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="text" id="fin-a" class="tinp" style="width:160px;text-align:center" placeholder="ответ"><button class="btn primary" id="fin-go">Удар!</button></div>'
+'<div class="feedback" id="fin-fb"></div></div>';
h+=secNav('p9',null)+readBtn('final','Завершить главу 2 (+10 XP)');
box.innerHTML=h; renderMath(box);
(function(){
var bosses=[
function(){
var pairs=[[2,3,4,14],[5,3,6,21],[3,4,2,14],[4,2,5,13],[6,2,3,15]];
var p=_pick(pairs);
return {name:'Страж Порядка', q:'Вычисли $'+p[0]+'+'+p[1]+'\\cdot'+p[2]+'$.',ans:p[3]};
},
function(){
var a=_ri(2,8), c=_ri(3,7), b=_ri(2,9);
var ans=c*a+b;
return {name:'Повелитель Переменных', q:'Найди значение $'+c+'\\cdot a+'+b+'$ при $a='+a+'$.',ans:ans};
},
function(){
var x=_ri(3,12), a=_ri(2,8), b=x+a;
return {name:'Хранитель Уравнений', q:'Реши уравнение $x+'+a+'='+b+'$.', ans:x};
},
function(){
var a=_ri(3,12), b=_ri(3,10);
return {name:'Мастер Формул', q:'Площадь прямоугольника $'+a+'\\times '+b+'$ (формула $S=a\\cdot b$).',ans:a*b};
},
function(){
var kinds=[{deg:45,name:'острый'},{deg:90,name:'прямой'},{deg:120,name:'тупой'},{deg:180,name:'развёрнутый'}];
var k=_pick(kinds);
return {name:'Страж Углов', q:'Угол $'+k.deg+'^\\circ$ — сколько в нём градусов?', ans:k.deg};
}
];
var i=0,score=0,cur=null,done=false;
function show(){
if(i>=5){ done=true; document.getElementById('fin-name').textContent=''; document.getElementById('fin-q').innerHTML=(score>=4?'<b>Победа!</b> Глава 2 пройдена! ':'<b>Бой окончен.</b> ')+'Побеждено боссов: '+score+' / 5.';
document.getElementById('fin-hp').style.width=(score>=4?0:40)+'%';
if(score>=4){ addXp(40,'final'); bumpProgress('final',100); if(window.confetti)try{confetti();}catch(e){} } else { bumpProgress('final',60); }
return; }
cur=bosses[i](); document.getElementById('fin-i').textContent=i+1; document.getElementById('fin-s').textContent=score;
document.getElementById('fin-name').textContent='Босс '+(i+1)+': '+cur.name;
document.getElementById('fin-hp').style.width=(100-i*20)+'%';
document.getElementById('fin-q').innerHTML=cur.q; renderMath(document.getElementById('fin-q'));
document.getElementById('fin-a').value=''; document.getElementById('fin-fb').style.display='none';
}
function go(){ if(done||i>=5)return; var fb=document.getElementById('fin-fb'), v=parseFloat(document.getElementById('fin-a').value.replace(',','.').trim());
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(Math.abs(v-cur.ans)<1e-9){ score++; feedback(fb,true,'✓ Босс повержен! Ответ '+cur.ans+'.'); } else feedback(fb,false,'✗ Босс устоял. Верный ответ: '+cur.ans+'.');
document.getElementById('fin-s').textContent=score; i++; setTimeout(show,1400); }
document.getElementById('fin-go').addEventListener('click',go);
document.getElementById('fin-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
}
/* ===================== ДАННЫЕ САЙДБАРА / ГЛОССАРИЯ ===================== */
var SIDEBARS = {
p1:{ title:'Шпаргалка § 1', rows:[
['Скобки','вычисляются первыми'],
['× и ÷','перед + и '],
['Слева направо','при одинаковом приоритете'],
['Пример','$3+2\\cdot4=11$; $(3+2)\\cdot4=20$'] ]},
p2:{ title:'Шпаргалка § 2', rows:[
['Переменная','буква вместо числа'],
['Значение','число после подстановки'],
['$a+5$ при $a=3$','$=3+5=8$'],
['Виет','ввёл буквы в 1591'] ]},
p3:{ title:'Шпаргалка § 3', rows:[
['Уравнение','равенство с переменной'],
['Корень','значение, делающее равенство верным'],
['$x+a=b$','$x=b-a$'],
['$x\\cdot a=b$','$x=b:a$'],
['$x:a=b$','$x=b\\cdot a$'] ]},
p4:{ title:'Шпаргалка § 4', rows:[
['$P_{\\text{прям}}$','$=2(a+b)$'],
['$S_{\\text{прям}}$','$=a\\cdot b$'],
['$P_{\\text{кв}}$','$=4a$'],
['$s$ путь','$=v\\cdot t$'] ]},
p5:{ title:'Шпаргалка § 5', rows:[
['1) Обозначь','неизвестное буквой $x$'],
['2) Выразь','остальное через $x$'],
['3) Составь','уравнение по условию'],
['4) Реши','и проверь в задаче'] ]},
p6:{ title:'Шпаргалка § 6', rows:[
['Острый','$0°<\\alpha<90°$'],
['Прямой','$\\alpha=90°$'],
['Тупой','$90°<\\alpha<180°$'],
['Развёрнутый','$\\alpha=180°$'],
['Транспортир','прибор для измерения'] ]},
p7:{ title:'Шпаргалка § 7', rows:[
['Сумма','$a+b$'],
['Произведение','$a\\cdot b$'],
['Путь','$s=v\\cdot t$'],
['Периметр','$P=2(a+b)$'] ]},
p8:{ title:'Шпаргалка § 8', rows:[
['Обозначь','неизвестное через $x$'],
['Ищи','закономерность'],
['Проверь','подстановкой'] ]},
p9:{ title:'Шпаргалка § 9', rows:[
['аль-Хорезми','IX в., «алгебра»'],
['Виет','1591, буквы в алгебре'],
['Декарт','1637, буква $x$'],
['Рекорд','1557, знак $=$'] ]},
final:{ title:'Финал главы 2', rows:[
['5 боссов','выражения, переменные, уравнения, формулы, углы'],
['Победа','4 из 5 и больше'],
['Награда','+40 XP и достижение «Глава 2 пройдена»'] ]}
};
var TIPS = [
{ sec:'p1', html:'Всегда ищи сначала скобки. Нет скобок? Тогда сначала $\\times$ и $\\div$, и лишь потом $+$ и $-$.' },
{ sec:'p2', html:'Подставляй и считай шаг за шагом — не торопись выполнять несколько действий сразу.' },
{ sec:'p3', html:'Нашёл корень — обязательно подставь обратно в уравнение и проверь, что получится верное равенство.' },
{ sec:'p4', html:'Выпиши формулу, потом подставь числа — так реже ошибаются, чем пытаясь считать «в голове».' },
{ sec:'p5', html:'Самое главное — правильно выбрать, что обозначить через $x$. Обычно это то, что спрашивают.' },
{ sec:'p6', html:'Запомни граничные значения: прямой $=90°$, развёрнутый $=180°$. Всё меньше $90°$ — острый, больше $90°$ — тупой.' },
{ sec:'final', html:'Перед ударом прочитай вопрос ещё раз. Убедись, что отвечаешь именно на то, что спрашивают.' }
];
var GLOSSARY = [
{ term:'числовое выражение', def:'Запись из чисел и знаков действий, имеющая определённое значение.', sec:'p1', aliases:['числовое выражение','числовых выражений','числовых выражениях'] },
{ term:'порядок действий', def:'Правило: сначала скобки, затем × и ÷, затем + и −.', sec:'p1', aliases:['порядок действий','порядок вычислений'] },
{ term:'переменная', def:'Буква, обозначающая неизвестное или произвольное число.', sec:'p2', aliases:['переменная','переменную','переменной'] },
{ term:'уравнение', def:'Равенство, содержащее переменную.', sec:'p3', aliases:['уравнение','уравнения','уравнений','уравнению'] },
{ term:'корень уравнения', def:'Значение переменной, при котором уравнение становится верным равенством.', sec:'p3', aliases:['корень','корнем','корня','корней'] },
{ term:'формула', def:'Краткая запись зависимости между величинами с помощью букв и знаков.', sec:'p4', aliases:['формула','формулу','формулы','формул'] },
{ term:'периметр', def:'Сумма длин всех сторон фигуры.', sec:'p4', aliases:['периметр','периметра','периметре'] },
{ term:'площадь', def:'Мера части плоскости, занятой фигурой.', sec:'p4', aliases:['площадь','площади'] },
{ term:'угол', def:'Геометрическая фигура из двух лучей с общим началом (вершиной).', sec:'p6', aliases:['угол','угла','углу','углы','углов'] },
{ term:'острый угол', def:'Угол от 0° до 90° (не включая 90°).', sec:'p6', aliases:['острый угол','острый'] },
{ term:'прямой угол', def:'Угол ровно 90°.', sec:'p6', aliases:['прямой угол','прямой'] },
{ term:'тупой угол', def:'Угол от 90° до 180° (не включая границы).', sec:'p6', aliases:['тупой угол','тупой'] },
{ term:'развёрнутый угол', def:'Угол ровно 180°. Его стороны образуют прямую.', sec:'p6', aliases:['развёрнутый угол','развёрнутый'] }
];
var BUILDERS = { p1:buildP1, p2:buildP2, p3:buildP3, p4:buildP4, p5:buildP5, p6:buildP6, p7:buildP7, p8:buildP8, p9:buildP9, final:buildFinal };
Object.assign(window.M6, { sidebars:SIDEBARS, tips:TIPS, glossary:GLOSSARY, builders:BUILDERS });
</script>
</body>