diff --git a/frontend/textbooks/geometry_8_ch1.html b/frontend/textbooks/geometry_8_ch1.html index 085ce5d..ddd52df 100644 --- a/frontend/textbooks/geometry_8_ch1.html +++ b/frontend/textbooks/geometry_8_ch1.html @@ -492,8 +492,8 @@ function buildParaSelector(){ const BUILT = new Set(); const BUILDERS = { p1:()=>buildP1(), p2:()=>buildP2(), p3:()=>buildP3(), p4:()=>buildP4(), - p5:()=>buildP5stub(), p6:()=>buildP6stub(), p7:()=>buildP7stub(), p8:()=>buildP8stub(), - p9:()=>buildP9stub(), p10:()=>buildP10stub(), p11:()=>buildP11stub(), p12:()=>buildP12stub(), + p5:()=>buildP5(), p6:()=>buildP6(), p7:()=>buildP7(), p8:()=>buildP8(), + p9:()=>buildP9(), p10:()=>buildP10(), p11:()=>buildP11stub(), p12:()=>buildP12stub(), p13:()=>buildP13stub(), p14:()=>buildP14stub(), p15:()=>buildP15stub(), p16:()=>buildP16stub(), final1:()=>buildFinal1stub(), }; @@ -1892,12 +1892,1475 @@ function buildP4(){ })(); renderMath(box); } -function buildP5stub(){ document.getElementById('p5-body').innerHTML = '

§5 — Волна 1: содержимое появится в следующем обновлении.

' + secNav('p4','p6'); } -function buildP6stub(){ document.getElementById('p6-body').innerHTML = '

§6 — Волна 1: содержимое появится в следующем обновлении.

' + secNav('p5','p7'); } -function buildP7stub(){ document.getElementById('p7-body').innerHTML = '

§7 — Волна 1: содержимое появится в следующем обновлении.

' + secNav('p6','p8'); } -function buildP8stub(){ document.getElementById('p8-body').innerHTML = '

§8 — Волна 1: содержимое появится в следующем обновлении.

' + secNav('p7','p9'); } -function buildP9stub(){ document.getElementById('p9-body').innerHTML = '

§9 — Волна 1: содержимое появится в следующем обновлении.

' + secNav('p8','p10'); } -function buildP10stub(){ document.getElementById('p10-body').innerHTML = '

§10 — Волна 1: содержимое появится в следующем обновлении.

' + secNav('p9','p11'); } +function buildP5(){ + const box = document.getElementById('p5-body'); + let html = ''; + + html += makeCard('theory','Свойства параллелограмма','5.1',` +

Теорема. В параллелограмме:

+ `); + + html += makeCard('rule','Доказательство свойств 1 и 2','5.2',` +

Проводим диагональ $AC$. Образуются $\\triangle ABC$ и $\\triangle CDA$.

+

$AB \\parallel CD$ $\\Rightarrow$ $\\angle BAC = \\angle DCA$ (накрест лежащие).

+

$BC \\parallel AD$ $\\Rightarrow$ $\\angle BCA = \\angle DAC$ (накрест лежащие).

+

$AC$ — общая сторона. По признаку «угол–сторона–угол»: $\\triangle ABC = \\triangle CDA$.

+

Из равенства треугольников: $AB=CD$, $BC=DA$, $\\angle B=\\angle D$. А $\\angle A=\\angle C$ — аналогично через диагональ $BD$.

`); + + html += makeCard('rule','Доказательство свойства 3','5.3',` +

Рассмотрим треугольники $\\triangle AOB$ и $\\triangle COD$, где $O$ — точка пересечения диагоналей.

+

$AB = CD$ (свойство 1), $\\angle OAB = \\angle OCD$, $\\angle OBA = \\angle ODC$ (накрест лежащие). По «угол–сторона–угол»: $\\triangle AOB = \\triangle COD$.

+

Следовательно: $AO = CO$ и $BO = DO$. Диагонали делятся пополам. $\\square$

`); + + /* --- INTERACTIVE 1: SVG-параллелограмм с живыми метриками --- */ + html += `
+
ИНТЕРАКТИВ 1
Живой параллелограмм — все свойства
+
Тащи вершины B и D. Все четыре свойства проверяются в реальном времени.
+
+
+
`; + + /* --- INTERACTIVE 2: Пошаговое доказательство свойства 1 --- */ + html += `
+
ИНТЕРАКТИВ 2
Доказательство: AB = CD (шаг за шагом)
+
Нажимай «Дальше» — смотри, как подсвечиваются треугольники.
+
+
+
+ + +
+
`; + + /* --- INTERACTIVE 3: Доказательство свойства 3 --- */ + html += `
+
ИНТЕРАКТИВ 3
Доказательство: AO = OC, BO = OD (шаг за шагом)
+
Диагонали делятся точкой пересечения пополам — доказательство через равные треугольники.
+
+
+
+ + +
+
`; + + /* --- INTERACTIVE 4: DnD — свойство → иллюстрация --- */ + html += `
+
ИНТЕРАКТИВ 4
Соотнеси свойство с описанием
+
Перетащи каждое свойство в правильную категорию.
+ ${DND_HINT_HTML} +
+
+
Стороны
+
Углы
+
Диагонали
+
+
+ +
`; + + /* --- INTERACTIVE 5: Тренажёр --- */ + html += `
+
ИНТЕРАКТИВ 5
Тренажёр задач на свойства параллелограмма
+
Задача 1 / 5Очки: 0
+
+
+ + + +
+ +
`; + + /* --- INTERACTIVE 6: Босс §5 --- */ + html += `
+
БОСС §5
Итоговые задачи
+
+5 XP за каждую верную задачу.
+
+
`; + + html += `
+ +
`; + + html += secNav('p4','p6'); + box.innerHTML = html; + + /* == SVG-параллелограмм == */ + (function(){ + const W=380, H=280; + let A={x:55,y:210}, B={x:195,y:210}, D={x:110,y:80}; + function getC(){ return {x:D.x+(B.x-A.x), y:D.y+(B.y-A.y)}; } + function dist(a,b){ return Math.hypot(b.x-a.x,b.y-a.y); } + function angDeg(O,P,Q){ const ax=P.x-O.x,ay=P.y-O.y,bx=Q.x-O.x,by=Q.y-O.y; return Math.acos(Math.max(-1,Math.min(1,(ax*bx+ay*by)/(Math.hypot(ax,ay)*Math.hypot(bx,by)))))*180/Math.PI; } + function intersect(A,C,B,D){ const r={x:C.x-A.x,y:C.y-A.y},s={x:D.x-B.x,y:D.y-B.y}; const den=r.x*s.y-r.y*s.x; if(Math.abs(den)<1e-9) return {x:(A.x+C.x)/2,y:(A.y+C.y)/2}; const t=((B.x-A.x)*s.y-(B.y-A.y)*s.x)/den; return {x:A.x+t*r.x,y:A.y+t*r.y}; } + function redraw(){ + const C=getC(); const pts=[A,B,C,D]; const labels=['A','B','C','D']; + const cx=(A.x+B.x+C.x+D.x)/4, cy=(A.y+B.y+C.y+D.y)/4; + const O=intersect(A,C,B,D); + let s=''; + s+=''; + s+=''; + s+=''; + s+=''; + s+='O'; + const movable=['B','D']; + pts.forEach((v,i)=>{ + const m=movable.includes(labels[i]); + s+=''; + s+=''; + const lx=v.x+(v.x-cx)*0.28, ly=v.y+(v.y-cy)*0.28; + s+=''+labels[i]+''; + }); + s+=''; + const wrap=document.getElementById('p5-svg-wrap'); + wrap.innerHTML=s; + const svgEl=wrap.querySelector('svg'); + svgEl.querySelectorAll('.p5-vh').forEach(el=>{ + el.style.cursor='grab'; + el.addEventListener('pointerdown',ev=>{ + if(ev.button!==undefined&&ev.button!==0) return; + const vname=el.dataset.v; + try{el.setPointerCapture(ev.pointerId);}catch(e){} + function onMove(e){ const rect=svgEl.getBoundingClientRect(); const sx=W/rect.width,sy=H/rect.height; const nx=Math.max(10,Math.min(W-10,(e.clientX-rect.left)*sx)); const ny=Math.max(10,Math.min(H-10,(e.clientY-rect.top)*sy)); if(vname==='B') B={x:nx,y:ny}; else if(vname==='D') D={x:nx,y:ny}; redraw(); } + function onUp(){ el.removeEventListener('pointermove',onMove);el.removeEventListener('pointerup',onUp);el.removeEventListener('pointercancel',onUp); } + el.addEventListener('pointermove',onMove); el.addEventListener('pointerup',onUp); el.addEventListener('pointercancel',onUp); + }); + }); + const C2=getC(); const O2=intersect(A,C2,B,D); + const ab=dist(A,B), bc=dist(B,C2), ao=dist(A,O2), bo=dist(B,O2); + const angA=angDeg(A,D,B), angB=angDeg(B,A,C2); + document.getElementById('p5-info').innerHTML=` +
AB = CD
${ab.toFixed(1)}
+
BC = AD
${bc.toFixed(1)}
+
AO = OC
${ao.toFixed(1)}
+
BO = OD
${bo.toFixed(1)}
+
∠A = ∠C
${angA.toFixed(1)}°
+
∠A + ∠B
${(angA+angB).toFixed(1)}°
`; + } + redraw(); + })(); + + /* == Доказательство свойства 1 == */ + (function(){ + const A={x:30,y:160},B={x:185,y:160},C={x:265,y:50},D={x:110,y:50}; + const cx=(A.x+B.x+C.x+D.x)/4,cy=(A.y+B.y+C.y+D.y)/4; + const steps=[ + {text:'Дано: $ABCD$ — параллелограмм. $AB\\parallel CD$, $BC\\parallel AD$. Проведём диагональ $AC$.', h:''}, + {text:'Шаг 1. $AB\\parallel CD$, $AC$ — секущая. $\\angle BAC = \\angle DCA$ — накрест лежащие углы.', h:'diag'}, + {text:'Шаг 2. $BC\\parallel AD$, $AC$ — секущая. $\\angle BCA = \\angle DAC$ — накрест лежащие углы.', h:'diag'}, + {text:'Шаг 3. $AC$ — общая сторона. По признаку «уголь–сторона–угол»: $\\triangle ABC = \\triangle CDA$.', h:'both'}, + {text:'Вывод. $AB = CD$ и $BC = DA$. Свойство 1 доказано. $\\square$', h:'both'}, + ]; + let step=0; + function draw(h){ + let s=''; + const t1=(h==='diag'||h==='both')?'rgba(225,29,72,.18)':'rgba(225,29,72,.06)'; + const t2=h==='both'?'rgba(16,185,129,.18)':'rgba(225,29,72,.06)'; + s+=''; + if(h){ s+=''; s+=''; s+=''; } + ['A','B','C','D'].forEach((lbl,i)=>{ const v=[A,B,C,D][i]; s+=''; const lx=v.x+(v.x-cx)*0.28,ly=v.y+(v.y-cy)*0.28; s+=''+lbl+''; }); + s+=''; + document.getElementById('p5-proof1-svg').innerHTML=s; + } + function show(){ const st=steps[step]; document.getElementById('p5-proof1-step').innerHTML=st.text; renderMath(document.getElementById('p5-proof1-step')); draw(st.h); document.getElementById('p5-proof1-next').textContent=step{ if(step{step=0;show();document.getElementById('p5-proof1-next').disabled=false;}); + show(); + })(); + + /* == Доказательство свойства 3 == */ + (function(){ + const A={x:30,y:160},B={x:185,y:160},C={x:265,y:50},D={x:110,y:50}; + const O={x:(A.x+C.x)/2,y:(A.y+C.y)/2}; + const cx=(A.x+B.x+C.x+D.x)/4,cy=(A.y+B.y+C.y+D.y)/4; + const steps=[ + {text:'Дано: $ABCD$ — параллелограмм, $O$ — точка пересечения диагоналей. Нужно доказать: $AO=OC$, $BO=OD$.', h:''}, + {text:'Шаг 1. $AB\\parallel CD$ и $AB=CD$ (свойство 1). Рассмотрим $\\triangle AOB$ и $\\triangle COD$.', h:'tri1'}, + {text:'Шаг 2. $\\angle OAB = \\angle OCD$ (накрест лежащие при $AB\\parallel CD$); $\\angle OBA=\\angle ODC$ (накрест лежащие).', h:'tri1'}, + {text:'Шаг 3. $AB=CD$, два угла равны. По «угол–сторона–угол»: $\\triangle AOB = \\triangle COD$.', h:'both3'}, + {text:'Вывод. $AO=CO$, $BO=DO$. Диагонали точкой пересечения делятся пополам. $\\square$', h:'both3'}, + ]; + let step=0; + function draw(h){ + let s=''; + s+=''; + s+=''; + s+=''; + if(h==='tri1'||h==='both3'){ s+=''; } + if(h==='both3'){ s+=''; } + s+=''; + s+='O'; + ['A','B','C','D'].forEach((lbl,i)=>{ const v=[A,B,C,D][i]; s+=''; const lx=v.x+(v.x-cx)*0.28,ly=v.y+(v.y-cy)*0.28; s+=''+lbl+''; }); + s+=''; + document.getElementById('p5-proof2-svg').innerHTML=s; + } + function show(){ const st=steps[step]; document.getElementById('p5-proof2-step').innerHTML=st.text; renderMath(document.getElementById('p5-proof2-step')); draw(st.h); document.getElementById('p5-proof2-next').textContent=step{ if(step{step=0;show();document.getElementById('p5-proof2-next').disabled=false;}); + show(); + })(); + + /* == DnD == */ + (function(){ + const items=[ + {id:'s1',html:'$AB = CD$', ans:'sides'}, + {id:'s2',html:'$BC = AD$', ans:'sides'}, + {id:'a1',html:'$\\angle A = \\angle C$', ans:'angles'}, + {id:'a2',html:'$\\angle B = \\angle D$', ans:'angles'}, + {id:'a3',html:'$\\angle A + \\angle B = 180°$', ans:'angles'}, + {id:'d1',html:'$AO = OC$', ans:'diag'}, + {id:'d2',html:'$BO = OD$', ans:'diag'}, + ]; + const sorter=setupSorter({poolId:'p5-dnd-pool',scopeSelector:'#p5-dnd-wrap',items,cats:['sides','angles','diag']}); + document.getElementById('p5-dnd-reset').addEventListener('click',()=>{sorter.reset();document.getElementById('p5-dnd-fb').style.display='none';}); + document.getElementById('p5-dnd-check').addEventListener('click',()=>{ + let ok=0; items.forEach(it=>{if(sorter.placed[it.id]===it.ans)ok++;}); + const fb=document.getElementById('p5-dnd-fb'); + if(ok===items.length){feedback(fb,true,'Все '+items.length+' верно! +5 XP');addXp(5,'p5-dnd');bumpProgress('p5',15);} + else feedback(fb,false,'Верно: '+ok+' из '+items.length+'.'); + }); + })(); + + /* == Тренажёр == */ + (function(){ + const tasks=[ + {q:'В параллелограмме $\\angle A = 65°$. Найди $\\angle B$.', ans:115, hint:'∠A+∠B=180°, ∠B=115°'}, + {q:'В параллелограмме $\\angle A = 65°$. Найди $\\angle C$.', ans:65, hint:'∠C=∠A=65°'}, + {q:'В параллелограмме $\\angle A = 65°$. Найди $\\angle D$.', ans:115, hint:'∠D=∠B=115°'}, + {q:'В параллелограмме $AB = 12$, периметр $P = 44$. Найди $BC$.', ans:10, hint:'P=2(12+BC), BC=(44/2-12)=10'}, + {q:'В параллелограмме $BD = 18$. Найди $BO$ (половину диагонали).', ans:9, hint:'BO=BD/2=9'}, + ]; + let idx=0,score=0; + function show(){ document.getElementById('p5-tr-i').textContent=idx+1; document.getElementById('p5-tr-task').innerHTML=tasks[idx].q; renderMath(document.getElementById('p5-tr-task')); document.getElementById('p5-tr-ans').value=''; document.getElementById('p5-tr-fb').style.display='none'; } + document.getElementById('p5-tr-start').addEventListener('click',()=>{idx=0;score=0;document.getElementById('p5-tr-score').textContent=0;show();}); + document.getElementById('p5-tr-go').addEventListener('click',()=>{ + const ans=+document.getElementById('p5-tr-ans').value; const fb=document.getElementById('p5-tr-fb'); + if(ans===tasks[idx].ans){ score++;document.getElementById('p5-tr-score').textContent=score;addXp(3,'p5-train');bumpProgress('p5',5); if(idxshow(),900);}else{feedback(fb,true,'Все задачи! +5 XP');addXp(5,'p5-train-all');} } + else feedback(fb,false,'Неверно. Подсказка: '+tasks[idx].hint); + }); + document.getElementById('p5-tr-ans').addEventListener('keydown',e=>{if(e.key==='Enter')document.getElementById('p5-tr-go').click();}); + show(); + })(); + + /* == Босс §5 == */ + (function(){ + const tasks=[ + {q:'В параллелограмме $\\angle A = 48°$. Найди $\\angle B$.', ans:132, hint:'∠A+∠B=180°'}, + {q:'В параллелограмме $AB=15$, $P=58$. Найди $BC$.', ans:14, hint:'P=2(AB+BC), BC=29-15=14'}, + {q:'Диагональ параллелограмма $AC=22$. Найди $AO$ ($O$ — точка пересечения диагоналей).', ans:11, hint:'AO=AC/2=11'}, + {q:'В параллелограмме $\\angle D=110°$. Найди $\\angle A$.', ans:70, hint:'∠A+∠D=180°, ∠A=70°'}, + ]; + const bossBox=document.getElementById('p5-boss-tasks'); + bossBox.innerHTML=tasks.map((t,i)=>` +
+
${t.q}
+
+ + +
+ +
`).join(''); + window.p5BossSolved=new Set(); + })(); + renderMath(box); +} +function buildP6(){ + const box = document.getElementById('p6-body'); + let html = ''; + + html += makeCard('theory','Признаки параллелограмма','6.1',` +

Четырёхугольник является параллелограммом, если выполнен хотя бы один из признаков:

+
    +
  • Признак 1. Две пары противоположных сторон равны: $AB=CD$ и $BC=AD$.
  • +
  • Признак 2. Одна пара противоположных сторон одновременно параллельна и равна: $AB\\parallel CD$ и $AB=CD$.
  • +
  • Признак 3. Диагонали точкой пересечения делятся пополам: $AO=OC$ и $BO=OD$.
  • +
`); + + html += makeCard('rule','Доказательство признака 1','6.2',` +

Дано: $AB=CD$, $BC=AD$. Проведём диагональ $AC$.

+

В $\\triangle ABC$ и $\\triangle CDA$: $AB=CD$, $BC=DA$, $AC=CA$ (общая). По признаку «три стороны»: $\\triangle ABC=\\triangle CDA$.

+

Из равенства треугольников: $\\angle BAC=\\angle DCA$ и $\\angle BCA=\\angle DAC$. Это накрест лежащие углы, значит $AB\\parallel CD$ и $BC\\parallel AD$. Следовательно, $ABCD$ — параллелограмм. $\\square$

`); + + html += makeCard('rule','Доказательство признака 3','6.3',` +

Дано: $AO=OC$, $BO=OD$. В $\\triangle AOB$ и $\\triangle COD$: $AO=CO$, $BO=DO$, $\\angle AOB=\\angle COD$ (вертикальные). По признаку «сторона–угол–сторона»: $\\triangle AOB=\\triangle COD$.

+

Отсюда $\\angle OAB=\\angle OCD$ — накрест лежащие, значит $AB\\parallel CD$. Аналогично $BC\\parallel AD$. Четырёхугольник — параллелограмм. $\\square$

`); + + /* --- INTERACTIVE 1: Три SVG-демонстрации признаков --- */ + html += `
+
ИНТЕРАКТИВ 1
Три признака параллелограмма
+
Нажми кнопку признака — смотри иллюстрацию и вывод.
+
+ + + +
+
+
+
`; + + /* --- INTERACTIVE 2: Тренажёр выбора признака --- */ + html += `
+
ИНТЕРАКТИВ 2
Выбери применимый признак
+
Прочитай условие и выбери, какой признак доказывает, что фигура — параллелограмм.
+
Вопрос 1 / 5Очки: 0
+
+
+ +
`; + + /* --- INTERACTIVE 3: DnD — условие → признак --- */ + html += `
+
ИНТЕРАКТИВ 3
Какой признак применить?
+
Перетащи условие к соответствующему признаку параллелограмма.
+ ${DND_HINT_HTML} +
+
+
Признак 1
+
Признак 2
+
Признак 3
+
+
+ +
`; + + /* --- INTERACTIVE 4: Мини-доказательство признака 1 --- */ + html += `
+
ИНТЕРАКТИВ 4
Доказательство признака 1 шаг за шагом
+
+
+
+ + +
+
`; + + /* --- INTERACTIVE 5: Босс §6 --- */ + html += `
+
БОСС §6
Итоговые задачи
+
+5 XP за каждую верную задачу.
+
+
`; + + html += `
+ +
`; + + html += secNav('p5','p7'); + box.innerHTML = html; + + /* == Три признака — SVG-демонстрации == */ + (function(){ + const A={x:40,y:155},B={x:175,y:155},C={x:245,y:55},D={x:110,y:55}; + const cx=(A.x+B.x+C.x+D.x)/4,cy=(A.y+B.y+C.y+D.y)/4; + function baseShape(){ return ''; } + function labels(){ let s=''; ['A','B','C','D'].forEach((lbl,i)=>{ const v=[A,B,C,D][i]; s+=''; const lx=v.x+(v.x-cx)*0.28,ly=v.y+(v.y-cy)*0.28; s+=''+lbl+''; }); return s; } + function midTick(p1,p2,col,n){ const mx=(p1.x+p2.x)/2,my=(p1.y+p2.y)/2,dx=p2.x-p1.x,dy=p2.y-p1.y,len=Math.hypot(dx,dy); const nx=-dy/len*6,ny=dx/len*6; let s=''; for(let k=0;k'; } return s; } + function showSign(n){ + let s=''; + s+=baseShape(); + if(n===1){ s+=midTick(A,B,'#10b981',1)+midTick(C,D,'#10b981',1)+midTick(B,C,'#f59e0b',2)+midTick(D,A,'#f59e0b',2); document.getElementById('p6-sign-text').innerHTML='Признак 1: $AB=CD$ (один штрих) и $BC=AD$ (два штриха). Следовательно, $ABCD$ — параллелограмм.'; } + else if(n===2){ s+=midTick(A,B,'#10b981',1)+midTick(C,D,'#10b981',1); s+='AB ∥ CD'; document.getElementById('p6-sign-text').innerHTML='Признак 2: $AB\\parallel CD$ и $AB=CD$. Следовательно, $ABCD$ — параллелограмм.'; } + else{ const O={x:(A.x+C.x)/2,y:(A.y+C.y)/2}; s+=''; s+=''; s+=''; s+=midTick(A,O,'#8b5cf6',1)+midTick(O,C,'#8b5cf6',1)+midTick(B,O,'#f97316',2)+midTick(O,D,'#f97316',2); document.getElementById('p6-sign-text').innerHTML='Признак 3: $AO=OC$ и $BO=OD$ — диагонали делятся пополам. Следовательно, $ABCD$ — параллелограмм.'; } + s+=labels()+''; + document.getElementById('p6-sign-svg').innerHTML=s; + renderMath(document.getElementById('p6-sign-text')); + [1,2,3].forEach(k=>{ const btn=document.getElementById('p6-sign-btn'+k); btn.className='btn'+(k===n?' primary':''); }); + } + document.getElementById('p6-sign-btn1').addEventListener('click',()=>showSign(1)); + document.getElementById('p6-sign-btn2').addEventListener('click',()=>showSign(2)); + document.getElementById('p6-sign-btn3').addEventListener('click',()=>showSign(3)); + showSign(1); + })(); + + /* == Тренажёр выбора признака == */ + (function(){ + const qs=[ + {q:'В четырёхугольнике $ABCD$: $AB=CD=7$ и $BC=AD=5$. Это параллелограмм?',opts:['Признак 1','Признак 2','Признак 3','Нет'],ans:0}, + {q:'В четырёхугольнике $AB\\parallel CD$ и $AB=CD$. Это параллелограмм?',opts:['Признак 1','Признак 2','Признак 3','Нет'],ans:1}, + {q:'Диагонали пересекаются в точке $O$: $AO=OC=6$, $BO=OD=8$. Это параллелограмм?',opts:['Признак 1','Признак 2','Признак 3','Нет'],ans:2}, + {q:'В четырёхугольнике все стороны разной длины и диагонали не делятся пополам.',opts:['Признак 1','Признак 2','Признак 3','Нет'],ans:3}, + {q:'В четырёхугольнике $BC\\parallel AD$ и $BC=AD$. Это параллелограмм?',opts:['Признак 1','Признак 2','Признак 3','Нет'],ans:1}, + ]; + let qi=0,qscore=0,answered=false; + function showQ(){ + answered=false; + const q=qs[qi]; + document.getElementById('p6-quiz-i').textContent=qi+1; + document.getElementById('p6-quiz-q').innerHTML=q.q; + renderMath(document.getElementById('p6-quiz-q')); + document.getElementById('p6-quiz-opts').innerHTML=q.opts.map((o,i)=>``).join(''); + document.getElementById('p6-quiz-fb').style.display='none'; + } + window.p6QuizAns=function(i){ + if(answered)return; answered=true; + const q=qs[qi]; const fb=document.getElementById('p6-quiz-fb'); + if(i===q.ans){qscore++;feedback(fb,true,'Верно! +3 XP');addXp(3,'p6-quiz');bumpProgress('p6',7);} + else feedback(fb,false,'Неверно. Правильно: '+q.opts[q.ans]); + document.querySelectorAll('[id^="p6-qopt-"]').forEach((b,bi)=>{b.disabled=true;if(bi===q.ans)b.style.background='var(--ok-bg)';else if(bi===i)b.style.background='var(--fail-bg)';}); + setTimeout(()=>{ qi++; if(qi'; },1300); + }; + showQ(); + })(); + + /* == DnD == */ + (function(){ + const items=[ + {id:'c1',html:'$AB=CD$ и $BC=AD$', ans:'r1'}, + {id:'c2',html:'Обе пары противоположных сторон равны', ans:'r1'}, + {id:'c3',html:'$AB\\parallel CD$ и $AB=CD$', ans:'r2'}, + {id:'c4',html:'Одна пара ∥ и =', ans:'r2'}, + {id:'c5',html:'$AO=OC$ и $BO=OD$', ans:'r3'}, + {id:'c6',html:'Диагонали делятся пополам', ans:'r3'}, + ]; + const sorter=setupSorter({poolId:'p6-dnd-pool',scopeSelector:'#p6-dnd-wrap',items,cats:['r1','r2','r3']}); + document.getElementById('p6-dnd-reset').addEventListener('click',()=>{sorter.reset();document.getElementById('p6-dnd-fb').style.display='none';}); + document.getElementById('p6-dnd-check').addEventListener('click',()=>{ + let ok=0; items.forEach(it=>{if(sorter.placed[it.id]===it.ans)ok++;}); + const fb=document.getElementById('p6-dnd-fb'); + if(ok===items.length){feedback(fb,true,'Все верно! +5 XP');addXp(5,'p6-dnd');bumpProgress('p6',15);} + else feedback(fb,false,'Верно: '+ok+' из '+items.length+'.'); + }); + })(); + + /* == Доказательство признака 1 == */ + (function(){ + const A={x:40,y:155},B={x:175,y:155},C={x:245,y:55},D={x:110,y:55}; + const cx=(A.x+B.x+C.x+D.x)/4,cy=(A.y+B.y+C.y+D.y)/4; + const steps=[ + {text:'Дано: $AB=CD$, $BC=AD$. Проведём диагональ $AC$.', h:''}, + {text:'Шаг 1. В $\\triangle ABC$ и $\\triangle CDA$: $AB=CD$, $BC=DA$, $AC=CA$ (общая сторона).', h:'diag'}, + {text:'Шаг 2. По признаку «три стороны»: $\\triangle ABC = \\triangle CDA$.', h:'both'}, + {text:'Шаг 3. Из равенства: $\\angle BAC=\\angle DCA$ и $\\angle BCA=\\angle DAC$ — накрест лежащие углы. Значит $AB\\parallel CD$ и $BC\\parallel AD$.', h:'both'}, + {text:'Вывод. Обе пары противоположных сторон параллельны $\\Rightarrow$ $ABCD$ — параллелограмм. $\\square$', h:'both'}, + ]; + let step=0; + function draw(h){ + let s=''; + const t1=(h==='diag'||h==='both')?'rgba(192,38,211,.18)':'rgba(192,38,211,.06)'; + const t2=h==='both'?'rgba(16,185,129,.18)':'rgba(192,38,211,.06)'; + s+=''; + if(h){ s+=''; s+=''; s+=''; } + ['A','B','C','D'].forEach((lbl,i)=>{ const v=[A,B,C,D][i]; s+=''; const lx=v.x+(v.x-cx)*0.28,ly=v.y+(v.y-cy)*0.28; s+=''+lbl+''; }); + s+=''; + document.getElementById('p6-proof-svg').innerHTML=s; + } + function show(){ const st=steps[step]; document.getElementById('p6-proof-step').innerHTML=st.text; renderMath(document.getElementById('p6-proof-step')); draw(st.h); document.getElementById('p6-proof-next').textContent=step{ if(step{step=0;show();document.getElementById('p6-proof-next').disabled=false;}); + show(); + })(); + + /* == Босс §6 == */ + (function(){ + const tasks=[ + {q:'В четырёхугольнике $AB=CD=9$, $BC=AD=6$. Это параллелограмм? Напиши номер признака (1, 2 или 3).', ans:1, hint:'Признак 1: две пары равных сторон'}, + {q:'В параллелограмме $\\angle A=75°$. Найди $\\angle C$.', ans:75, hint:'∠A=∠C в параллелограмме'}, + {q:'В четырёхугольнике $AO=OC=5$ и $BO=OD=7$. Это параллелограмм — какой признак? (1/2/3)', ans:3, hint:'Признак 3: диагонали делятся пополам'}, + {q:'В параллелограмме $AB=16$, $P=54$. Найди $BC$.', ans:11, hint:'P=2(16+BC), BC=27-16=11'}, + ]; + const bossBox=document.getElementById('p6-boss-tasks'); + bossBox.innerHTML=tasks.map((t,i)=>` +
+
${t.q}
+
+ + +
+ +
`).join(''); + window.p6BossSolved=new Set(); + })(); + renderMath(box); +} +function buildP7(){ + const box = document.getElementById('p7-body'); + let html = ''; + + html += makeCard('theory','Прямоугольник — определение','7.1',` +

Прямоугольник — параллелограмм, у которого один угол прямой.

+

Так как в параллелограмме сумма соседних углов равна $180°$, а один угол равен $90°$, то все углы прямоугольника прямые.

+

Обозначение: $\\square ABCD$, где $\\angle A=\\angle B=\\angle C=\\angle D=90°$.

`); + + html += makeCard('rule','Свойство диагоналей прямоугольника','7.2',` +

Теорема. Диагонали прямоугольника равны: $AC = BD$.

+

Доказательство. Рассмотрим $\\triangle ABC$ и $\\triangle BAD$: $AB=BA$ (общая), $\\angle ABC=\\angle BAD=90°$, $BC=AD$ (как в параллелограмме). По признаку «угол–сторона–угол»: $\\triangle ABC=\\triangle BAD$.

+

Следовательно: $AC=BD$. $\\square$

+

По теореме Пифагора: $d = \\sqrt{a^2 + b^2}$, где $a$, $b$ — стороны прямоугольника.

`); + + /* --- INTERACTIVE 1: SVG-прямоугольник с draggable B --- */ + html += `
+
ИНТЕРАКТИВ 1
Живой прямоугольник — равенство диагоналей
+
Тащи вершину B, чтобы изменить размеры прямоугольника. Диагонали всегда остаются равными.
+
+
+
`; + + /* --- INTERACTIVE 2: Пошаговое доказательство --- */ + html += `
+
ИНТЕРАКТИВ 2
Доказательство: диагонали прямоугольника равны
+
+
+
+ + +
+
`; + + /* --- INTERACTIVE 3: Калькулятор диагонали --- */ + html += `
+
ИНТЕРАКТИВ 3
Калькулятор диагонали прямоугольника
+
Введи стороны $a$ и $b$ — получи диагональ по теореме Пифагора.
+
+ + + +
+
+
`; + + /* --- INTERACTIVE 4: Тренажёр --- */ + html += `
+
ИНТЕРАКТИВ 4
Тренажёр задач на прямоугольник
+
Задача 1 / 5Очки: 0
+
+
+ + + +
+ +
`; + + /* --- INTERACTIVE 5: DnD прямоугольники --- */ + html += `
+
ИНТЕРАКТИВ 5
Это прямоугольник?
+
Разложи фигуры: является ли она прямоугольником?
+ ${DND_HINT_HTML} +
+
+
Прямоугольник
+
Не прямоугольник
+
+
+ +
`; + + /* --- INTERACTIVE 6: Босс §7 --- */ + html += `
+
БОСС §7
Итоговые задачи
+
+5 XP за каждую верную задачу.
+
+
`; + + html += `
+ +
`; + + html += secNav('p6','p8'); + box.innerHTML = html; + + /* == SVG-прямоугольник == */ + (function(){ + const W=380, H=270; + let B={x:240,y:200}; + const A={x:60,y:200}; + function getRect(){ return {A:{x:A.x,y:A.y}, B:{x:B.x,y:A.y}, C:{x:B.x,y:B.y}, D:{x:A.x,y:B.y}}; } + function dist(a,b){ return Math.hypot(b.x-a.x,b.y-a.y); } + function redraw(){ + const r=getRect(); const {A:Ra,B:Rb,C:Rc,D:Rd}=r; + const cx=(Ra.x+Rb.x+Rc.x+Rd.x)/4, cy=(Ra.y+Rb.y+Rc.y+Rd.y)/4; + let s=''; + s+=''; + s+=''; + s+=''; + // right-angle marks + const sq=8; + s+=''; + s+=''; + const labels=['A','B','C','D']; const pts=[Ra,Rb,Rc,Rd]; + pts.forEach((v,i)=>{ + const m=(i===2); + s+=''; + s+=''; + const lx=v.x+(v.x-cx)*0.28,ly=v.y+(v.y-cy)*0.28; + s+=''+labels[i]+''; + }); + s+=''; + const wrap=document.getElementById('p7-rect-svg'); + wrap.innerHTML=s; + const svgEl=wrap.querySelector('svg'); + svgEl.querySelectorAll('.p7-vh').forEach(el=>{ + el.style.cursor='grab'; + el.addEventListener('pointerdown',ev=>{ + if(ev.button!==undefined&&ev.button!==0)return; + try{el.setPointerCapture(ev.pointerId);}catch(e){} + function onMove(e){ const rect=svgEl.getBoundingClientRect(); const sx=W/rect.width,sy=H/rect.height; B={x:Math.max(A.x+30,Math.min(W-10,(e.clientX-rect.left)*sx)),y:Math.max(30,Math.min(H-10,(e.clientY-rect.top)*sy))}; redraw(); } + function onUp(){ el.removeEventListener('pointermove',onMove);el.removeEventListener('pointerup',onUp);el.removeEventListener('pointercancel',onUp); } + el.addEventListener('pointermove',onMove); el.addEventListener('pointerup',onUp); el.addEventListener('pointercancel',onUp); + }); + }); + const rr=getRect(); const ab=dist(rr.A,rr.B), bc=dist(rr.B,rr.C), ac=dist(rr.A,rr.C), bd=dist(rr.B,rr.D); + document.getElementById('p7-rect-info').innerHTML=` +
AB
${ab.toFixed(1)}
+
BC
${bc.toFixed(1)}
+
AC = BD
${ac.toFixed(1)}
+
Все углы
90°
`; + } + redraw(); + })(); + + /* == Доказательство == */ + (function(){ + const A={x:40,y:155},B={x:230,y:155},C={x:230,y:55},D={x:40,y:55}; + const cx=(A.x+B.x+C.x+D.x)/4,cy=(A.y+B.y+C.y+D.y)/4; + const steps=[ + {text:'Дано: $ABCD$ — прямоугольник. $\\angle A=\\angle B=90°$. Нужно доказать: $AC=BD$.', h:''}, + {text:'Шаг 1. Рассмотрим $\\triangle ABC$ и $\\triangle BAD$. $AB=BA$ — общая сторона.', h:'t1'}, + {text:'Шаг 2. $\\angle ABC=\\angle BAD=90°$ — прямые углы прямоугольника. $BC=AD$ — как в параллелограмме.', h:'t1'}, + {text:'Шаг 3. По признаку «угол–сторона–угол» (или двум катетам): $\\triangle ABC=\\triangle BAD$.', h:'both7'}, + {text:'Вывод. $AC=BD$ — диагонали прямоугольника равны. $\\square$', h:'both7'}, + ]; + let step=0; + function draw(h){ + let s=''; + const t1=(h==='t1'||h==='both7')?'rgba(124,58,237,.18)':'rgba(124,58,237,.06)'; + const t2=h==='both7'?'rgba(16,185,129,.18)':'rgba(124,58,237,.06)'; + s+=''; + if(h){ s+=''; s+=''; } + if(h==='both7'){ s+=''; s+=''; } + ['A','B','C','D'].forEach((lbl,i)=>{ const v=[A,B,C,D][i]; s+=''; const lx=v.x+(v.x-cx)*0.28,ly=v.y+(v.y-cy)*0.28; s+=''+lbl+''; }); + s+=''; + document.getElementById('p7-proof-svg').innerHTML=s; + } + function show(){ const st=steps[step]; document.getElementById('p7-proof-step').innerHTML=st.text; renderMath(document.getElementById('p7-proof-step')); draw(st.h); document.getElementById('p7-proof-next').textContent=step{ if(step{step=0;show();document.getElementById('p7-proof-next').disabled=false;}); + show(); + })(); + + /* == Калькулятор диагонали == */ + (function(){ + function calc(){ + const a=+document.getElementById('p7-ca').value, b=+document.getElementById('p7-cb').value; + if(a<=0||b<=0||isNaN(a)||isNaN(b)){ document.getElementById('p7-calc-out').innerHTML='Введи положительные числа.'; return; } + const d=Math.sqrt(a*a+b*b); + const dStr=Number.isInteger(d)?String(d):d.toFixed(4).replace(/0+$/,''); + document.getElementById('p7-calc-out').innerHTML=`$d = \\sqrt{a^2+b^2} = \\sqrt{${a}^2+${b}^2} = \\sqrt{${a*a}+${b*b}} = \\sqrt{${a*a+b*b}}$
$d = ${dStr}$`; + renderMath(document.getElementById('p7-calc-out')); + addXp(2,'p7-calc'); + } + document.getElementById('p7-calc-go').addEventListener('click',calc); + document.getElementById('p7-ca').addEventListener('keydown',e=>{if(e.key==='Enter')calc();}); + document.getElementById('p7-cb').addEventListener('keydown',e=>{if(e.key==='Enter')calc();}); + calc(); + })(); + + /* == Тренажёр == */ + (function(){ + const tasks=[ + {q:'Стороны прямоугольника $a=6$, $b=8$. Найди диагональ.', ans:10, hint:'d=√(36+64)=√100=10'}, + {q:'Диагональ прямоугольника $d=13$, сторона $a=5$. Найди $b$.', ans:12, hint:'b=√(169-25)=√144=12'}, + {q:'Периметр прямоугольника $P=20$, сторона $a=3$. Найди площадь $S$.', ans:21, hint:'b=P/2-a=10-3=7, S=3·7=21'}, + {q:'В прямоугольнике $\\angle A=90°$. Найди $\\angle B$.', ans:90, hint:'Все углы прямоугольника = 90°'}, + {q:'Стороны прямоугольника $a=9$, $b=12$. Найди диагональ.', ans:15, hint:'d=√(81+144)=√225=15'}, + ]; + let idx=0,score=0; + function show(){ document.getElementById('p7-tr-i').textContent=idx+1; document.getElementById('p7-tr-task').innerHTML=tasks[idx].q; renderMath(document.getElementById('p7-tr-task')); document.getElementById('p7-tr-ans').value=''; document.getElementById('p7-tr-fb').style.display='none'; } + document.getElementById('p7-tr-start').addEventListener('click',()=>{idx=0;score=0;document.getElementById('p7-tr-score').textContent=0;show();}); + document.getElementById('p7-tr-go').addEventListener('click',()=>{ + const ans=+document.getElementById('p7-tr-ans').value; const fb=document.getElementById('p7-tr-fb'); + if(ans===tasks[idx].ans){ score++;document.getElementById('p7-tr-score').textContent=score;addXp(3,'p7-train');bumpProgress('p7',5); if(idxshow(),900);}else{feedback(fb,true,'Все задачи! +5 XP');addXp(5,'p7-train-all');} } + else feedback(fb,false,'Неверно. Подсказка: '+tasks[idx].hint); + }); + document.getElementById('p7-tr-ans').addEventListener('keydown',e=>{if(e.key==='Enter')document.getElementById('p7-tr-go').click();}); + show(); + })(); + + /* == DnD == */ + (function(){ + const items=[ + {id:'sq',html:'Квадрат', ans:'yes'}, + {id:'rect',html:'Параллелограмм с углом 90°', ans:'yes'}, + {id:'rhm',html:'Ромб с углом 90°', ans:'yes'}, + {id:'pgr',html:'Произвольный параллелограмм (угол ≠ 90°)', ans:'no'}, + {id:'trap',html:'Трапеция', ans:'no'}, + {id:'rhm2',html:'Ромб с углом 60°', ans:'no'}, + ]; + const sorter=setupSorter({poolId:'p7-dnd-pool',scopeSelector:'#p7-dnd-wrap',items,cats:['yes','no']}); + document.getElementById('p7-dnd-reset').addEventListener('click',()=>{sorter.reset();document.getElementById('p7-dnd-fb').style.display='none';}); + document.getElementById('p7-dnd-check').addEventListener('click',()=>{ + let ok=0; items.forEach(it=>{if(sorter.placed[it.id]===it.ans)ok++;}); + const fb=document.getElementById('p7-dnd-fb'); + if(ok===items.length){feedback(fb,true,'Все верно! +5 XP');addXp(5,'p7-dnd');bumpProgress('p7',15);} + else feedback(fb,false,'Верно: '+ok+' из '+items.length+'. Квадрат — тоже прямоугольник!'); + }); + })(); + + /* == Босс §7 == */ + (function(){ + const tasks=[ + {q:'Стороны прямоугольника $a=5$, $b=12$. Найди диагональ.', ans:13, hint:'d=√(25+144)=√169=13'}, + {q:'В прямоугольнике диагональ $d=10$, сторона $a=6$. Найди вторую сторону $b$.', ans:8, hint:'b=√(100-36)=√64=8'}, + {q:'Периметр прямоугольника равен $34$, одна сторона $= 7$. Найди площадь.', ans:70, hint:'b=17-7=10, S=7·10=70'}, + {q:'Все углы прямоугольника. Чему равна сумма всех углов прямоугольника?', ans:360, hint:'4·90°=360°'}, + ]; + const bossBox=document.getElementById('p7-boss-tasks'); + bossBox.innerHTML=tasks.map((t,i)=>` +
+
${t.q}
+
+ + +
+ +
`).join(''); + window.p7BossSolved=new Set(); + })(); + renderMath(box); +} +function buildP8(){ + const box = document.getElementById('p8-body'); + let html = ''; + + html += makeCard('theory','Признак прямоугольника','8.1',` +

Теорема. Если у параллелограмма диагонали равны, то он является прямоугольником.

+

Доказательство. Пусть в параллелограмме $ABCD$ дано $AC=BD$. Рассмотрим $\\triangle ABD$ и $\\triangle BAC$:

+
    +
  • $AB=BA$ — общая сторона
  • +
  • $AD=BC$ — противоположные стороны параллелограмма
  • +
  • $BD=AC$ — по условию
  • +
+

По признаку «три стороны»: $\\triangle ABD=\\triangle BAC$. Следовательно, $\\angle DAB=\\angle CBA$.

+

Но $\\angle DAB+\\angle CBA=180°$ (смежные в параллелограмме). Значит $\\angle DAB=\\angle CBA=90°$. Параллелограмм — прямоугольник. $\\square$

`); + + /* --- INTERACTIVE 1: SVG-демонстрация признака --- */ + html += `
+
ИНТЕРАКТИВ 1
Признак прямоугольника — живая демонстрация
+
Тащи вершину D. Когда диагонали сравняются — оба индикатора загорятся зелёным.
+
+
+
`; + + /* --- INTERACTIVE 2: Пошаговое доказательство --- */ + html += `
+
ИНТЕРАКТИВ 2
Доказательство признака прямоугольника
+
+
+
+ + +
+
`; + + /* --- INTERACTIVE 3: Mini-quiz --- */ + html += `
+
ИНТЕРАКТИВ 3
Верно или нет?
+
Для каждого утверждения выбери «Верно» или «Неверно».
+
+
`; + + /* --- INTERACTIVE 4: Тренажёр --- */ + html += `
+
ИНТЕРАКТИВ 4
Тренажёр: прямоугольник или нет?
+
Задача 1 / 4Очки: 0
+
+
+ + + +
+ +
`; + + /* --- INTERACTIVE 5: Босс §8 --- */ + html += `
+
БОСС §8
Итоговые задачи
+
+5 XP за каждую верную задачу.
+
+
`; + + html += `
+ +
`; + + html += secNav('p7','p9'); + box.innerHTML = html; + + /* == SVG-демонстрация признака == */ + (function(){ + const W=380, H=280; + let A={x:55,y:215}, B={x:215,y:215}, D={x:100,y:85}; + function getC(){ return {x:D.x+(B.x-A.x),y:D.y+(B.y-A.y)}; } + function dist(a,b){ return Math.hypot(b.x-a.x,b.y-a.y); } + function redraw(){ + const C=getC(); const pts=[A,B,C,D]; const labels=['A','B','C','D']; + const cx=(A.x+B.x+C.x+D.x)/4,cy=(A.y+B.y+C.y+D.y)/4; + const ac=dist(A,C), bd=dist(B,D); + const eq=Math.abs(ac-bd)<4; + const col=eq?'#10b981':'#2563eb'; + let s=''; + s+=''; + s+=''; + s+=''; + pts.forEach((v,i)=>{ + const m=(i===3); + s+=''; + s+=''; + const lx=v.x+(v.x-cx)*0.28,ly=v.y+(v.y-cy)*0.28; + s+=''+labels[i]+''; + }); + s+=''; + const wrap=document.getElementById('p8-demo-svg'); + wrap.innerHTML=s; + const svgEl=wrap.querySelector('svg'); + svgEl.querySelectorAll('.p8-vh').forEach(el=>{ + el.style.cursor='grab'; + el.addEventListener('pointerdown',ev=>{ + if(ev.button!==undefined&&ev.button!==0)return; + try{el.setPointerCapture(ev.pointerId);}catch(e){} + function onMove(e){ const rect=svgEl.getBoundingClientRect(); const sx=W/rect.width,sy=H/rect.height; D={x:Math.max(10,Math.min(W-10,(e.clientX-rect.left)*sx)),y:Math.max(10,Math.min(H-10,(e.clientY-rect.top)*sy))}; redraw(); } + function onUp(){ el.removeEventListener('pointermove',onMove);el.removeEventListener('pointerup',onUp);el.removeEventListener('pointercancel',onUp); } + el.addEventListener('pointermove',onMove); el.addEventListener('pointerup',onUp); el.addEventListener('pointercancel',onUp); + }); + }); + const okCol=eq?'#10b981':'#94a3b8'; + document.getElementById('p8-demo-indicators').innerHTML=` +
Диагонали равны: ${eq?'ДА':'НЕТ'} (AC=${ac.toFixed(1)}, BD=${bd.toFixed(1)})
+
Прямоугольник: ${eq?'ДА':'НЕТ'}
`; + } + redraw(); + })(); + + /* == Доказательство == */ + (function(){ + const A={x:40,y:155},B={x:230,y:155},C={x:265,y:55},D={x:75,y:55}; + const cx=(A.x+B.x+C.x+D.x)/4,cy=(A.y+B.y+C.y+D.y)/4; + const steps=[ + {text:'Дано: $ABCD$ — параллелограмм, $AC=BD$. Доказать: $\\angle DAB=90°$.', h:''}, + {text:'Шаг 1. Рассмотрим $\\triangle ABD$ и $\\triangle BAC$: $AB=BA$ (общая), $AD=BC$ (стороны ||грамма), $BD=AC$ (по условию).', h:'t1'}, + {text:'Шаг 2. По признаку «три стороны»: $\\triangle ABD=\\triangle BAC$.', h:'t2'}, + {text:'Шаг 3. Следовательно $\\angle DAB=\\angle CBA$. Но они смежные в параллелограмме: $\\angle DAB+\\angle CBA=180°$.', h:'t2'}, + {text:'Вывод. $2\\angle DAB=180°$, $\\angle DAB=90°$. $ABCD$ — прямоугольник. $\\square$', h:'t2'}, + ]; + let step=0; + function draw(h){ + let s=''; + s+=''; + if(h==='t1'){ s+=''; s+=''; } + if(h==='t2'){ s+=''; s+=''; s+=''; s+=''; } + ['A','B','C','D'].forEach((lbl,i)=>{ const v=[A,B,C,D][i]; s+=''; const lx=v.x+(v.x-cx)*0.28,ly=v.y+(v.y-cy)*0.28; s+=''+lbl+''; }); + s+=''; + document.getElementById('p8-proof-svg').innerHTML=s; + } + function show(){ const st=steps[step]; document.getElementById('p8-proof-step').innerHTML=st.text; renderMath(document.getElementById('p8-proof-step')); draw(st.h); document.getElementById('p8-proof-next').textContent=step{ if(step{step=0;show();document.getElementById('p8-proof-next').disabled=false;}); + show(); + })(); + + /* == Mini-quiz == */ + (function(){ + const items=[ + {text:'Параллелограмм с равными диагоналями — прямоугольник.', ans:true}, + {text:'У любого параллелограмма диагонали равны.', ans:false}, + {text:'Прямоугольник — частный случай параллелограмма.', ans:true}, + {text:'Ромб с равными диагоналями является квадратом.', ans:true}, + ]; + const solved=new Set(); + document.getElementById('p8-quiz-list').innerHTML=items.map((it,i)=>` +
+

${it.text}

+
+ + +
+ +
`).join(''); + window.p8QuizCheck=function(i,v){ + const it=items[i]; const fb=document.getElementById('p8-qi-fb-'+i); + if(v===it.ans){ feedback(fb,true,'Верно! +3 XP'); if(!solved.has(i)){solved.add(i);addXp(3,'p8-quiz'+i);bumpProgress('p8',6);} } + else feedback(fb,false,'Неверно. '+( it.ans?'Утверждение истинно.':'Утверждение ложно.')); + }; + })(); + + /* == Тренажёр == */ + (function(){ + const tasks=[ + {q:'В параллелограмме $AC=14$, $BD=14$. Прямоугольник? Введи 1 (да) или 0 (нет).', ans:1, hint:'Признак: равные диагонали → прямоугольник'}, + {q:'В параллелограмме $AC=10$, $BD=12$. Прямоугольник? Введи 1 (да) или 0 (нет).', ans:0, hint:'Диагонали не равны → не прямоугольник'}, + {q:'В прямоугольнике $a=8$, $b=15$. Найди диагональ.', ans:17, hint:'d=√(64+225)=√289=17'}, + {q:'В прямоугольнике диагональ $d=25$, сторона $a=7$. Найди $b$.', ans:24, hint:'b=√(625-49)=√576=24'}, + ]; + let idx=0,score=0; + function show(){ document.getElementById('p8-tr-i').textContent=idx+1; document.getElementById('p8-tr-task').innerHTML=tasks[idx].q; renderMath(document.getElementById('p8-tr-task')); document.getElementById('p8-tr-ans').value=''; document.getElementById('p8-tr-fb').style.display='none'; } + document.getElementById('p8-tr-start').addEventListener('click',()=>{idx=0;score=0;document.getElementById('p8-tr-score').textContent=0;show();}); + document.getElementById('p8-tr-go').addEventListener('click',()=>{ + const ans=+document.getElementById('p8-tr-ans').value; const fb=document.getElementById('p8-tr-fb'); + if(ans===tasks[idx].ans){ score++;document.getElementById('p8-tr-score').textContent=score;addXp(3,'p8-train');bumpProgress('p8',5); if(idxshow(),900);}else{feedback(fb,true,'Все задачи! +5 XP');addXp(5,'p8-train-all');} } + else feedback(fb,false,'Неверно. Подсказка: '+tasks[idx].hint); + }); + document.getElementById('p8-tr-ans').addEventListener('keydown',e=>{if(e.key==='Enter')document.getElementById('p8-tr-go').click();}); + show(); + })(); + + /* == Босс §8 == */ + (function(){ + const tasks=[ + {q:'У параллелограмма диагонали $AC=BD=20$. Прямоугольник? (1=да, 0=нет)', ans:1, hint:'Признак: равные диагонали'}, + {q:'В прямоугольнике $a=3$, $b=4$. Найди $d$.', ans:5, hint:'d=√(9+16)=5'}, + {q:'В прямоугольнике $d=26$, $a=10$. Найди $b$.', ans:24, hint:'b=√(676-100)=√576=24'}, + {q:'Периметр прямоугольника $P=26$, $a=5$. Найди $d$.', ans:13, hint:'b=13-5=8, d=√(25+64)=√169=13'}, + ]; + const bossBox=document.getElementById('p8-boss-tasks'); + bossBox.innerHTML=tasks.map((t,i)=>` +
+
${t.q}
+
+ + +
+ +
`).join(''); + window.p8BossSolved=new Set(); + })(); + renderMath(box); +} +function buildP9(){ + const box = document.getElementById('p9-body'); + let html = ''; + + html += makeCard('theory','Ромб — определение и свойства','9.1',` +

Ромб — параллелограмм, у которого все стороны равны: $AB=BC=CD=DA$.

+

Свойство диагоналей ромба:

+
    +
  • Диагонали ромба взаимно перпендикулярны: $AC \\perp BD$.
  • +
  • Каждая диагональ является биссектрисой соответствующих углов.
  • +
  • Диагонали точкой пересечения делятся пополам (как в любом параллелограмме).
  • +
`); + + html += makeCard('rule','Доказательство: диагонали ромба перпендикулярны','9.2',` +

Рассмотрим $\\triangle AOB$ и $\\triangle COB$, где $O$ — точка пересечения диагоналей.

+

$AO=OC$ (диагональ делится пополам), $OB=OB$ (общая), $AB=CB$ (стороны ромба).

+

По признаку «три стороны»: $\\triangle AOB=\\triangle COB$. Следовательно, $\\angle AOB=\\angle COB$.

+

Но $\\angle AOB+\\angle COB=180°$ (смежные). Значит $\\angle AOB=90°$, т.е. $AC\\perp BD$. $\\square$

`); + + html += makeCard('rule','Признаки ромба','9.3',` +

Признак 1. Если у параллелограмма диагонали взаимно перпендикулярны, то он является ромбом.

+

Признак 2. Если у параллелограмма диагональ является биссектрисой угла, то он является ромбом.

+

Площадь ромба: $S = \\dfrac{d_1 \\cdot d_2}{2}$, где $d_1$, $d_2$ — диагонали.

+

Также: $S = a^2 \\sin\\alpha$, где $a$ — сторона, $\\alpha$ — угол ромба.

`); + + /* --- INTERACTIVE 1: SVG-ромб с draggable вершиной --- */ + html += `
+
ИНТЕРАКТИВ 1
Живой ромб — все стороны равны, диагонали ⊥
+
Тащи вершину B или D. Все стороны остаются равными, диагонали — всегда перпендикулярны.
+
+
+
`; + + /* --- INTERACTIVE 2: Пошаговое доказательство --- */ + html += `
+
ИНТЕРАКТИВ 2
Доказательство: диагонали ромба перпендикулярны
+
+
+
+ + +
+
`; + + /* --- INTERACTIVE 3: Калькулятор площади ромба --- */ + html += `
+
ИНТЕРАКТИВ 3
Калькулятор площади ромба
+
Введи диагонали — получи площадь и сторону ромба.
+
+ + + +
+
+
`; + + /* --- INTERACTIVE 4: DnD — свойства ромба, прямоугольника, параллелограмма --- */ + html += `
+
ИНТЕРАКТИВ 4
Чьё это свойство?
+
Разложи свойства: только ромба, только прямоугольника, или любого параллелограмма.
+ ${DND_HINT_HTML} +
+
+
Любой параллелограмм
+
Только прямоугольник
+
Только ромб
+
+
+ +
`; + + /* --- INTERACTIVE 5: Тренажёр --- */ + html += `
+
ИНТЕРАКТИВ 5
Тренажёр задач на ромб
+
Задача 1 / 5Очки: 0
+
+
+ + + +
+ +
`; + + /* --- INTERACTIVE 6: Босс §9 --- */ + html += `
+
БОСС §9
Итоговые задачи
+
+5 XP за каждую верную задачу.
+
+
`; + + html += `
+ +
`; + + html += secNav('p8','p10'); + box.innerHTML = html; + + /* == SVG-ромб == */ + (function(){ + const W=360, H=300, cx=180, cy=150; + let half1=110, half2=70; // half-diagonals + let dragV=null; + function getVerts(h1,h2){ return {A:{x:cx-h1,y:cy},B:{x:cx,y:cy-h2},C:{x:cx+h1,y:cy},D:{x:cx,y:cy+h2}}; } + function dist(a,b){ return Math.hypot(b.x-a.x,b.y-a.y); } + function angDeg(O,P,Q){ const ax=P.x-O.x,ay=P.y-O.y,bx=Q.x-O.x,by=Q.y-O.y; return Math.acos(Math.max(-1,Math.min(1,(ax*bx+ay*by)/(Math.hypot(ax,ay)*Math.hypot(bx,by)))))*180/Math.PI; } + function redraw(){ + const {A,B,C,D}=getVerts(half1,half2); + const side=dist(A,B); + const angA=angDeg(A,D,B)*2; + let s=''; + s+=''; + s+=''; + s+=''; + // right angle mark at O + const sq=8; + s+=''; + s+=''; + const labels=['A','B','C','D']; const pts=[A,B,C,D]; + pts.forEach((v,i)=>{ + const m=(i===1||i===3); + s+=''; + s+=''; + const lx=v.x+(v.x-cx)*0.22,ly=v.y+(v.y-cy)*0.22; + s+=''+labels[i]+''; + }); + s+=''; + const wrap=document.getElementById('p9-rhombus-svg'); wrap.innerHTML=s; + const svgEl=wrap.querySelector('svg'); + svgEl.querySelectorAll('.p9-vh').forEach(el=>{ + el.style.cursor='grab'; + el.addEventListener('pointerdown',ev=>{ + if(ev.button!==undefined&&ev.button!==0)return; + const vname=el.dataset.v; + try{el.setPointerCapture(ev.pointerId);}catch(e){} + function onMove(e){ const rect=svgEl.getBoundingClientRect(); const sx=W/rect.width,sy=H/rect.height; const nx=(e.clientX-rect.left)*sx; const ny=(e.clientY-rect.top)*sy; if(vname==='B'){ half2=Math.max(20,Math.min(H/2-10,cy-ny)); } else if(vname==='D'){ half2=Math.max(20,Math.min(H/2-10,ny-cy)); } else if(vname==='A'){ half1=Math.max(20,Math.min(W/2-10,cx-nx)); } else if(vname==='C'){ half1=Math.max(20,Math.min(W/2-10,nx-cx)); } redraw(); } + function onUp(){ el.removeEventListener('pointermove',onMove);el.removeEventListener('pointerup',onUp);el.removeEventListener('pointercancel',onUp); } + el.addEventListener('pointermove',onMove); el.addEventListener('pointerup',onUp); el.addEventListener('pointercancel',onUp); + }); + }); + const {A:A2,B:B2}=getVerts(half1,half2); const side2=dist(A2,B2); + const S=half1*half2*2; + document.getElementById('p9-rhombus-info').innerHTML=` +
Сторона AB=BC=CD=DA
${side2.toFixed(1)}
+
Диагональ AC
${(half1*2).toFixed(1)}
+
Диагональ BD
${(half2*2).toFixed(1)}
+
Угол между диаг.
90°
+
Площадь S = d₁d₂/2
${S.toFixed(1)}
`; + } + redraw(); + })(); + + /* == Доказательство == */ + (function(){ + const cx=150,cy=110; + const A={x:cx-100,y:cy},B={x:cx,y:cy-70},C={x:cx+100,y:cy},D={x:cx,y:cy+70}; + const O={x:cx,y:cy}; + const steps=[ + {text:'Дано: $ABCD$ — ромб (все стороны равны). $O$ — точка пересечения диагоналей. Доказать: $AC\\perp BD$.', h:''}, + {text:'Шаг 1. Рассмотрим $\\triangle AOB$ и $\\triangle COB$. $AO=OC$ (диагональ делится пополам), $OB=OB$ (общая), $AB=CB$ (стороны ромба).', h:'tri'}, + {text:'Шаг 2. По признаку «три стороны»: $\\triangle AOB=\\triangle COB$.', h:'tri'}, + {text:'Шаг 3. $\\angle AOB=\\angle COB$. Но $\\angle AOB+\\angle COB=180°$ (смежные). Значит $\\angle AOB=90°$.', h:'right'}, + {text:'Вывод. $AC\\perp BD$ — диагонали ромба взаимно перпендикулярны. $\\square$', h:'right'}, + ]; + let step=0; + function draw(h){ + let s=''; + s+=''; + s+=''; + s+=''; + if(h==='tri'||h==='right'){ s+=''; s+=''; } + if(h==='right'){ const sq=8; s+=''; } + s+=''; + s+='O'; + ['A','B','C','D'].forEach((lbl,i)=>{ const v=[A,B,C,D][i]; s+=''; const lx=v.x+(v.x-cx)*0.22,ly=v.y+(v.y-cy)*0.22; s+=''+lbl+''; }); + s+=''; + document.getElementById('p9-proof-svg').innerHTML=s; + } + function show(){ const st=steps[step]; document.getElementById('p9-proof-step').innerHTML=st.text; renderMath(document.getElementById('p9-proof-step')); draw(st.h); document.getElementById('p9-proof-next').textContent=step{ if(step{step=0;show();document.getElementById('p9-proof-next').disabled=false;}); + show(); + })(); + + /* == Калькулятор площади ромба == */ + (function(){ + function calc(){ + const d1=+document.getElementById('p9-cd1').value, d2=+document.getElementById('p9-cd2').value; + if(d1<=0||d2<=0||isNaN(d1)||isNaN(d2)){ document.getElementById('p9-calc-out').innerHTML='Введи положительные числа.'; return; } + const S=d1*d2/2; + const side=Math.sqrt((d1/2)*(d1/2)+(d2/2)*(d2/2)); + const sideStr=Number.isInteger(side)?String(side):side.toFixed(4).replace(/0+$/,''); + document.getElementById('p9-calc-out').innerHTML=`$S = \\dfrac{d_1 \\cdot d_2}{2} = \\dfrac{${d1} \\cdot ${d2}}{2} = ${S}$
Сторона: $a = \\sqrt{\\left(\\dfrac{d_1}{2}\\right)^2+\\left(\\dfrac{d_2}{2}\\right)^2} = \\sqrt{${d1/2}^2+${d2/2}^2} = ${sideStr}$`; + renderMath(document.getElementById('p9-calc-out')); + addXp(2,'p9-calc'); + } + document.getElementById('p9-calc-go').addEventListener('click',calc); + calc(); + })(); + + /* == DnD == */ + (function(){ + const items=[ + {id:'pr1',html:'Противоположные стороны равны', ans:'any'}, + {id:'pr2',html:'Диагонали делятся пополам', ans:'any'}, + {id:'pr3',html:'Сумма соседних углов 180°', ans:'any'}, + {id:'re1',html:'Все углы 90°', ans:'rect'}, + {id:'re2',html:'Диагонали равны', ans:'rect'}, + {id:'rh1',html:'Все стороны равны', ans:'rhm'}, + {id:'rh2',html:'Диагонали перпендикулярны', ans:'rhm'}, + {id:'rh3',html:'Диагонали — биссектрисы углов', ans:'rhm'}, + ]; + const sorter=setupSorter({poolId:'p9-dnd-pool',scopeSelector:'#p9-dnd-wrap',items,cats:['any','rect','rhm']}); + document.getElementById('p9-dnd-reset').addEventListener('click',()=>{sorter.reset();document.getElementById('p9-dnd-fb').style.display='none';}); + document.getElementById('p9-dnd-check').addEventListener('click',()=>{ + let ok=0; items.forEach(it=>{if(sorter.placed[it.id]===it.ans)ok++;}); + const fb=document.getElementById('p9-dnd-fb'); + if(ok===items.length){feedback(fb,true,'Все верно! +5 XP');addXp(5,'p9-dnd');bumpProgress('p9',15);} + else feedback(fb,false,'Верно: '+ok+' из '+items.length+'.'); + }); + })(); + + /* == Тренажёр == */ + (function(){ + const tasks=[ + {q:'Диагонали ромба $d_1=10$, $d_2=24$. Найди сторону ромба.', ans:13, hint:'a=√(5²+12²)=√169=13'}, + {q:'Диагонали ромба $d_1=10$, $d_2=24$. Найди площадь.', ans:120, hint:'S=10·24/2=120'}, + {q:'Периметр ромба $P=40$, диагональ $d_1=12$. Найди вторую диагональ $d_2$.', ans:16, hint:'a=10, d2=2√(100-36)=2·8=16'}, + {q:'Угол между диагоналями ромба (в градусах)?', ans:90, hint:'Диагонали ромба всегда ⊥'}, + {q:'Площадь ромба $d_1=6$, $d_2=8$. Чему равна площадь?', ans:24, hint:'S=6·8/2=24'}, + ]; + let idx=0,score=0; + function show(){ document.getElementById('p9-tr-i').textContent=idx+1; document.getElementById('p9-tr-task').innerHTML=tasks[idx].q; renderMath(document.getElementById('p9-tr-task')); document.getElementById('p9-tr-ans').value=''; document.getElementById('p9-tr-fb').style.display='none'; } + document.getElementById('p9-tr-start').addEventListener('click',()=>{idx=0;score=0;document.getElementById('p9-tr-score').textContent=0;show();}); + document.getElementById('p9-tr-go').addEventListener('click',()=>{ + const ans=+document.getElementById('p9-tr-ans').value; const fb=document.getElementById('p9-tr-fb'); + if(ans===tasks[idx].ans){ score++;document.getElementById('p9-tr-score').textContent=score;addXp(3,'p9-train');bumpProgress('p9',5); if(idxshow(),900);}else{feedback(fb,true,'Все задачи! +5 XP');addXp(5,'p9-train-all');} } + else feedback(fb,false,'Неверно. Подсказка: '+tasks[idx].hint); + }); + document.getElementById('p9-tr-ans').addEventListener('keydown',e=>{if(e.key==='Enter')document.getElementById('p9-tr-go').click();}); + show(); + })(); + + /* == Босс §9 == */ + (function(){ + const tasks=[ + {q:'Диагонали ромба $d_1=16$, $d_2=12$. Найди сторону.', ans:10, hint:'a=√(8²+6²)=√100=10'}, + {q:'Диагонали ромба $d_1=16$, $d_2=12$. Найди площадь.', ans:96, hint:'S=16·12/2=96'}, + {q:'Сторона ромба $a=10$, одна диагональ $d_1=12$. Найди вторую диагональ $d_2$.', ans:16, hint:'d2=2√(100-36)=2·8=16'}, + {q:'Периметр ромба $P=52$. Найди сторону.', ans:13, hint:'a=P/4=52/4=13'}, + ]; + const bossBox=document.getElementById('p9-boss-tasks'); + bossBox.innerHTML=tasks.map((t,i)=>` +
+
${t.q}
+
+ + +
+ +
`).join(''); + window.p9BossSolved=new Set(); + })(); + renderMath(box); +} +function buildP10(){ + const box = document.getElementById('p10-body'); + let html = ''; + + html += makeCard('theory','Квадрат — определение','10.1',` +

Квадрат — прямоугольник, у которого все стороны равны.

+

Эквивалентно: квадрат — это ромб с прямыми углами.

+

Таким образом, квадрат одновременно является:

+
    +
  • Параллелограммом
  • +
  • Прямоугольником
  • +
  • Ромбом
  • +
`); + + html += makeCard('rule','Свойства квадрата','10.2',` +

В квадрате со стороной $a$:

+
    +
  • Все стороны равны: $AB=BC=CD=DA=a$
  • +
  • Все углы прямые: $\\angle A=\\angle B=\\angle C=\\angle D=90°$
  • +
  • Диагонали равны: $AC=BD=a\\sqrt{2}$
  • +
  • Диагонали взаимно перпендикулярны: $AC\\perp BD$
  • +
  • Диагонали делятся пополам и делят углы пополам
  • +
  • Площадь: $S=a^2$
  • +
  • Периметр: $P=4a$
  • +
`); + + html += makeCard('example','Формулы квадрата','10.3',` +

$a$ — сторона, $d$ — диагональ, $P$ — периметр, $S$ — площадь:

+ \\[d = a\\sqrt{2} \\qquad a = \\dfrac{d}{\\sqrt{2}} = \\dfrac{d\\sqrt{2}}{2}\\] + \\[P = 4a \\qquad S = a^2 = \\dfrac{d^2}{2}\\]`); + + /* --- INTERACTIVE 1: SVG-квадрат со слайдером --- */ + html += `
+
ИНТЕРАКТИВ 1
Живой квадрат — все свойства сразу
+
Меняй сторону слайдером — все свойства обновляются мгновенно.
+
+
+
+
`; + + /* --- INTERACTIVE 2: Иерархия фигур --- */ + html += `
+
ИНТЕРАКТИВ 2
Иерархия: параллелограмм ⊃ прямоугольник/ромб ⊃ квадрат
+
Нажимай на фигуры — увидишь, какие свойства ей принадлежат.
+
+ + + + +
+
+
`; + + /* --- INTERACTIVE 3: Калькулятор квадрата --- */ + html += `
+
ИНТЕРАКТИВ 3
Калькулятор квадрата
+
Введи сторону или диагональ — получи все остальные значения.
+
+ + + +
+
+
`; + + /* --- INTERACTIVE 4: DnD — категоризация фигур --- */ + html += `
+
ИНТЕРАКТИВ 4
Наиболее конкретное название фигуры
+
Для каждой фигуры выбери самое точное название (квадрат → квадрат, не «прямоугольник»).
+ ${DND_HINT_HTML} +
+
+
Параллелограмм
+
Прямоугольник
+
Ромб
+
Квадрат
+
+
+ +
`; + + /* --- INTERACTIVE 5: Тренажёр --- */ + html += `
+
ИНТЕРАКТИВ 5
Тренажёр задач на квадрат
+
Задача 1 / 5Очки: 0
+
+
+ + + +
+ +
`; + + /* --- INTERACTIVE 6: Босс §10 --- */ + html += `
+
БОСС §10
Итоговые задачи
+
+5 XP за каждую верную задачу.
+
+
`; + + html += `
+ +
`; + + html += secNav('p9','p11'); + box.innerHTML = html; + + /* == SVG-квадрат со слайдером == */ + (function(){ + const W=300, H=300, cx=150, cy=150; + function redraw(){ + const sl=document.getElementById('p10-sq-sl'); + const a=+sl.value; + document.getElementById('p10-sq-aval').textContent=a; + const half=a/2; + const A={x:cx-half,y:cy+half},B={x:cx+half,y:cy+half},C={x:cx+half,y:cy-half},D={x:cx-half,y:cy-half}; + const d=a*Math.sqrt(2); + let s=''; + s+=''; + // diagonals + s+=''; + s+=''; + // right-angle at O + const sq=7; + s+=''; + // right-angle marks at corners + s+=''; + // center dot + s+=''; + // side labels + s+='a='+a+''; + // diagonal label + s+='d'; + // vertices + ['A','B','C','D'].forEach((lbl,i)=>{ const v=[A,B,C,D][i]; s+=''; const lx=v.x+(v.x-cx)*0.28,ly=v.y+(v.y-cy)*0.28; s+=''+lbl+''; }); + s+=''; + document.getElementById('p10-sq-svg').innerHTML=s; + const dStr=(d%1===0)?String(d):d.toFixed(4).replace(/0+$/,''); + document.getElementById('p10-sq-info').innerHTML=` +
Сторона a
${a}
+
Периметр P=4a
${4*a}
+
Площадь S=a²
${a*a}
+
Диагональ d=a√2
${dStr}
`; + } + document.getElementById('p10-sq-sl').addEventListener('input',redraw); + redraw(); + })(); + + /* == Иерархия == */ + (function(){ + const data={ + pg:{label:'Параллелограмм',props:['Противоположные стороны попарно параллельны','Противоположные стороны равны ($AB=CD$, $BC=AD$)','Противоположные углы равны','Сумма соседних углов $= 180°$','Диагонали делятся пополам']}, + re:{label:'Прямоугольник',props:['Все свойства параллелограмма','Все углы прямые ($90°$)','Диагонали равны ($AC=BD$)']}, + rh:{label:'Ромб',props:['Все свойства параллелограмма','Все стороны равны','Диагонали взаимно перпендикулярны','Диагонали делят углы пополам']}, + sq:{label:'Квадрат',props:['Все свойства параллелограмма','Все стороны равны','Все углы прямые','Диагонали равны $d=a\\sqrt{2}$','Диагонали взаимно перпендикулярны','Диагонали делят углы пополам по $45°$','$S=a^2$, $P=4a$']}, + }; + function show(k){ + const d=data[k]; + document.getElementById('p10-hier-out').innerHTML=''+d.label+':
    '+d.props.map(p=>'
  • '+p+'
  • ').join('')+'
'; + renderMath(document.getElementById('p10-hier-out')); + Object.keys(data).forEach(kk=>{ const btn=document.getElementById('p10-hier-'+kk); btn.className='btn'+(kk===k?' primary':''); }); + } + ['pg','re','rh','sq'].forEach(k=>document.getElementById('p10-hier-'+k).addEventListener('click',()=>show(k))); + show('sq'); + })(); + + /* == Калькулятор квадрата == */ + (function(){ + function calc(){ + let a=+document.getElementById('p10-ca').value; + const dInp=+document.getElementById('p10-cd').value; + if(dInp>0){ a=dInp/Math.sqrt(2); } + if(a<=0||isNaN(a)){ document.getElementById('p10-calc-out').innerHTML='Введи положительное значение.'; return; } + const d=a*Math.sqrt(2), P=4*a, S=a*a; + const fmt2=x=>Number.isInteger(x)?String(x):x.toFixed(4).replace(/0+$/,''); + document.getElementById('p10-calc-out').innerHTML=`$a = ${fmt2(a)}$
$P = 4a = ${fmt2(P)}$
$S = a^2 = ${fmt2(S)}$
$d = a\\sqrt{2} = ${fmt2(d)}$`; + renderMath(document.getElementById('p10-calc-out')); + addXp(2,'p10-calc'); + } + document.getElementById('p10-calc-go').addEventListener('click',calc); + calc(); + })(); + + /* == DnD == */ + (function(){ + const items=[ + {id:'f1',html:'Параллелограмм с углом 60° и сторонами 5 и 8', ans:'pg'}, + {id:'f2',html:'Параллелограмм, у которого все углы 90°, стороны 4 и 7', ans:'re'}, + {id:'f3',html:'Параллелограмм, все стороны = 6, угол 120°', ans:'rh'}, + {id:'f4',html:'Параллелограмм, все стороны = 5, все углы 90°', ans:'sq'}, + {id:'f5',html:'Прямоугольник со сторонами 3 и 3', ans:'sq'}, + {id:'f6',html:'Ромб с углом 90°', ans:'sq'}, + ]; + const sorter=setupSorter({poolId:'p10-dnd-pool',scopeSelector:'#p10-dnd-wrap',items,cats:['pg','re','rh','sq']}); + document.getElementById('p10-dnd-reset').addEventListener('click',()=>{sorter.reset();document.getElementById('p10-dnd-fb').style.display='none';}); + document.getElementById('p10-dnd-check').addEventListener('click',()=>{ + let ok=0; items.forEach(it=>{if(sorter.placed[it.id]===it.ans)ok++;}); + const fb=document.getElementById('p10-dnd-fb'); + if(ok===items.length){feedback(fb,true,'Все верно! +5 XP');addXp(5,'p10-dnd');bumpProgress('p10',15);} + else feedback(fb,false,'Верно: '+ok+' из '+items.length+'. Подсказка: квадрат — ромб с прямыми углами.'); + }); + })(); + + /* == Тренажёр == */ + (function(){ + const tasks=[ + {q:'Сторона квадрата $a=7$. Найди периметр.', ans:28, hint:'P=4·7=28'}, + {q:'Сторона квадрата $a=9$. Найди площадь.', ans:81, hint:'S=9²=81'}, + {q:'Площадь квадрата $S=49$. Найди сторону.', ans:7, hint:'a=√49=7'}, + {q:'Сторона квадрата $a=5$. Найди диагональ (округли до целого).', ans:7, hint:'d=5√2≈7.07≈7'}, + {q:'Периметр квадрата $P=36$. Найди сторону.', ans:9, hint:'a=P/4=36/4=9'}, + ]; + let idx=0,score=0; + function show(){ document.getElementById('p10-tr-i').textContent=idx+1; document.getElementById('p10-tr-task').innerHTML=tasks[idx].q; renderMath(document.getElementById('p10-tr-task')); document.getElementById('p10-tr-ans').value=''; document.getElementById('p10-tr-fb').style.display='none'; } + document.getElementById('p10-tr-start').addEventListener('click',()=>{idx=0;score=0;document.getElementById('p10-tr-score').textContent=0;show();}); + document.getElementById('p10-tr-go').addEventListener('click',()=>{ + const ans=+document.getElementById('p10-tr-ans').value; const fb=document.getElementById('p10-tr-fb'); + if(ans===tasks[idx].ans){ score++;document.getElementById('p10-tr-score').textContent=score;addXp(3,'p10-train');bumpProgress('p10',5); if(idxshow(),900);}else{feedback(fb,true,'Все задачи! +5 XP');addXp(5,'p10-train-all');} } + else feedback(fb,false,'Неверно. Подсказка: '+tasks[idx].hint); + }); + document.getElementById('p10-tr-ans').addEventListener('keydown',e=>{if(e.key==='Enter')document.getElementById('p10-tr-go').click();}); + show(); + })(); + + /* == Босс §10 == */ + (function(){ + const tasks=[ + {q:'Диагональ квадрата $d=10\\sqrt{2}$. Найди сторону.', ans:10, hint:'a=d/√2=10√2/√2=10'}, + {q:'Площадь квадрата $S=144$. Найди периметр.', ans:48, hint:'a=12, P=4·12=48'}, + {q:'Периметр квадрата $P=32$. Найди площадь.', ans:64, hint:'a=8, S=64'}, + {q:'Сторона квадрата $a=10$. Найди площадь.', ans:100, hint:'S=10²=100'}, + ]; + const bossBox=document.getElementById('p10-boss-tasks'); + bossBox.innerHTML=tasks.map((t,i)=>` +
+
${t.q}
+
+ + +
+ +
`).join(''); + window.p10BossSolved=new Set(); + })(); + renderMath(box); +} function buildP11stub(){ document.getElementById('p11-body').innerHTML = '

§11 — Волна 1: содержимое появится в следующем обновлении.

' + secNav('p10','p12'); } function buildP12stub(){ document.getElementById('p12-body').innerHTML = '

§12 — Волна 1: содержимое появится в следующем обновлении.

' + secNav('p11','p13'); } function buildP13stub(){ document.getElementById('p13-body').innerHTML = '

§13 — Волна 1: содержимое появится в следующем обновлении.

' + secNav('p12','p14'); }