R = '+fmt(R)+' → прямая НЕ ПЕРЕСЕКАЕТ окружность';}
+ });
+ })();
+
+ /* === INIT ИНТЕРАКТИВ 4: DnD === */
+ (function(){
+ const items=[
+ {label:'R=5, d=3',cat:'sec'},{label:'R=8, d=8',cat:'tan'},{label:'R=6, d=9',cat:'none'},
+ {label:'R=10, d=7',cat:'sec'},{label:'R=4, d=4',cat:'tan'},{label:'R=3, d=5',cat:'none'},
+ ];
+ const pool=document.getElementById('p1-dnd-pool');
+ const boxes={sec:document.getElementById('p1-drop-sec-items'),tan:document.getElementById('p1-drop-tan-items'),none:document.getElementById('p1-drop-none-items')};
+ const fb=document.getElementById('p1-dnd-fb');
+ let placed={};
+ function reset(){
+ pool.innerHTML='';placed={};
+ Object.values(boxes).forEach(b=>b.innerHTML='');
+ fb.style.display='none';
+ items.forEach((it,i)=>{
+ const chip=document.createElement('div');
+ chip.className='dnd-chip';chip.dataset.i=i;chip.textContent=it.label;
+ setupChip(chip,i);
+ pool.appendChild(chip);
+ });
+ }
+ function setupChip(chip,i){
+ chip.addEventListener('click',()=>{
+ if(placed[i]!==undefined){
+ boxes[placed[i]].removeChild(chip);
+ delete placed[i];
+ chip.querySelector('.dnd-x')&&chip.querySelector('.dnd-x').remove();
+ pool.appendChild(chip);
+ return;
+ }
+ chip.classList.add('armed');
+ });
+ Object.entries(boxes).forEach(([cat,box])=>{
+ box.parentElement.addEventListener('click',()=>{
+ if(!chip.classList.contains('armed'))return;
+ chip.classList.remove('armed');
+ if(placed[i]!==undefined) boxes[placed[i]].removeChild(chip);
+ placed[i]=cat;
+ const x=document.createElement('span');x.className='dnd-x';x.textContent='×';
+ x.addEventListener('click',e=>{e.stopPropagation();boxes[cat].removeChild(chip);delete placed[i];x.remove();pool.appendChild(chip);});
+ chip.appendChild(x);
+ box.appendChild(chip);
+ });
+ });
+ }
+ document.getElementById('p1-dnd-check').addEventListener('click',()=>{
+ let ok=0;
+ items.forEach((it,i)=>{if(placed[i]===it.cat)ok++;});
+ feedback(fb,ok===items.length,'Верно: '+ok+'/'+items.length+'. '+(ok===items.length?'Все правильно!':'Попробуй ещё.'));
+ if(ok===items.length){addXp(8,'p1-dnd');bumpProgress('p1',15);}
+ });
+ document.getElementById('p1-dnd-reset').addEventListener('click',reset);
+ reset();
+ })();
+
+ /* === INIT ИНТЕРАКТИВ 5: Тренажёр === */
+ (function(){
+ const tasks=[
+ {q:'Радиус окружности $R = 13$. Расстояние от центра до прямой $d = 5$. Сколько общих точек у прямой с окружностью?',a:'2',hint:'d < R → секущая → 2 точки'},
+ {q:'Радиус $R = 7$. Прямая касается окружности. Расстояние от центра до прямой равно?',a:'7',hint:'При касании d = R = 7'},
+ {q:'От центра до прямой $d = 10$, радиус $R = 6$. Сколько общих точек?',a:'0',hint:'d > R → 0 точек'},
+ {q:'Прямая перпендикулярна радиусу $OT = 4$ в точке $T$ на окружности. Расстояние от центра до прямой равно?',a:'4',hint:'Признак касательной: расстояние = R = 4'},
+ {q:'Прямая касается окружности радиуса $R = 9$. Каково расстояние от центра до точки касания?',a:'9',hint:'Расстояние от центра до точки касания = R'},
+ ];
+ let cur=0,score=0;
+ const iEl=document.getElementById('p1-tr-i');
+ const scEl=document.getElementById('p1-tr-score');
+ const taskEl=document.getElementById('p1-tr-task');
+ const ansEl=document.getElementById('p1-tr-ans');
+ const goBtn=document.getElementById('p1-tr-go');
+ const startBtn=document.getElementById('p1-tr-start');
+ const fb=document.getElementById('p1-tr-fb');
+ function showTask(){
+ if(cur>=tasks.length){taskEl.innerHTML='Тренажёр завершён! Очки: '+score+'/'+tasks.length+' ';ansEl.style.display='none';goBtn.style.display='none';addXp(score*4,'p1-trainer');bumpProgress('p1',20);return;}
+ taskEl.innerHTML=tasks[cur].q;iEl.textContent=cur+1;ansEl.value='';fb.style.display='none';
+ if(window.renderMathInElement) try{renderMath(taskEl);}catch(e){}
+ }
+ goBtn.addEventListener('click',()=>{
+ const ans=ansEl.value.trim().replace(',','.');
+ const ok=Math.abs(parseFloat(ans)-parseFloat(tasks[cur].a))<0.01;
+ feedback(fb,ok,ok?'Верно!':'Неверно. Подсказка: '+tasks[cur].hint);
+ if(ok){score++;scEl.textContent=score;cur++;setTimeout(showTask,900);}
+ });
+ startBtn.addEventListener('click',()=>{cur=0;score=0;scEl.textContent=0;ansEl.style.display='';goBtn.style.display='';showTask();});
+ showTask();
+ })();
+
+ /* === INIT ИНТЕРАКТИВ 6: Босс §1 === */
+ (function(){
+ const tasks=[
+ {q:'Прямая проходит через точку $A(6, 0)$ и параллельна оси $Oy$. Центр окружности $O(0,0)$, радиус $R = 6$. Является ли прямая касательной?',
+ opts:['Да, касательная','Нет, секущая','Нет, не пересекает'],cor:0,
+ exp:'Расстояние от центра $(0,0)$ до прямой $x=6$ равно $6 = R$. Прямая является касательной.'},
+ {q:'Из точки $M$ вне окружности расстояние до центра $|OM| = 10$, радиус $R = 6$. Прямая $MN$ перпендикулярна $OM$. Является ли $MN$ касательной?',
+ opts:['Да','Нет, секущая','Нет, не пересекает'],cor:2,
+ exp:'$MN \\perp OM$, значит расстояние от $O$ до $MN$ равно $|OM| = 10 > R = 6$. Прямая не пересекает окружность.'},
+ {q:'Прямая $\\ell$ перпендикулярна радиусу $OR$ в точке $R$ на окружности. Выбери верное утверждение:',
+ opts:['$\\ell$ — касательная в точке $R$','$\\ell$ — секущая','$\\ell$ не пересекает окружность'],cor:0,
+ exp:'По признаку касательной: прямая, проходящая через точку окружности и перпендикулярная радиусу в этой точке, является касательной.'},
+ {q:'Расстояние от центра окружности до прямой равно диаметру. Прямая является:',
+ opts:['касательной','секущей','не пересекает окружность'],cor:2,
+ exp:'Диаметр $= 2R > R$, значит $d > R$ — прямая не пересекает окружность.'},
+ ];
+ const cont=document.getElementById('p1-boss-tasks');
+ let html='';
+ tasks.forEach((t,i)=>{
+ html+=`
+
${i+1}. ${t.q}
+
+ ${t.opts.map((o,j)=>`${o} `).join('')}
+
+
+
`;
+ });
+ cont.innerHTML=html;
+ if(window.renderMathInElement) try{renderMath(cont);}catch(e){}
+ })();
+}
+function buildP2(){
+ const box=document.getElementById('p2-body');
+ let html='';
+
+ html+=makeCard('theory','Свойство касательной','2.1',`
+ Теорема (свойство касательной). Касательная к окружности перпендикулярна радиусу, проведённому в точку касания.
+ $$OT \\perp \\ell$$
+ где $O$ — центр, $T$ — точка касания, $\\ell$ — касательная.
+ Доказательство — от противного. Предположим, что $OT$ не перпендикулярно $\\ell$. Тогда из $O$ можно опустить перпендикуляр на $\\ell$ в точку $H \\neq T$, и $OH < OT = R$. Значит, $H$ лежит внутри окружности. Но тогда прямая $\\ell$ пересекает окружность в двух точках — противоречие с тем, что $\\ell$ касательная. Следовательно, $OT \\perp \\ell$. ч.т.д.
+
+
+
+
+
+
+
+
+ R
+ T
+ O
+ ℓ
+ ∠OTℓ = 90°
+
+
`);
+
+ html+=makeCard('rule','Следствие: длина касательной из внешней точки','2.2',`
+ Если из внешней точки $A$ проведена касательная до точки касания $T$, то:
+ $$AT = \\sqrt{|OA|^2 - R^2}$$
+ Это следует из теоремы Пифагора для прямоугольного треугольника $OAT$: $|OA|^2 = R^2 + AT^2$.
+
+
+
+
+
+
+
+
+
+ R
+ T
+ O
+ A
+ AT
+ |OA|
+
+
`);
+
+ html+=makeCard('example','Пример','2.3',`
+ Задача. Радиус окружности $R = 5$, расстояние от внешней точки $A$ до центра $|OA| = 13$. Найти длину касательной $AT$.
+ Решение: $AT = \\sqrt{|OA|^2 - R^2} = \\sqrt{169 - 25} = \\sqrt{144} = 12$.
+ Ответ: $AT = 12$.
`);
+
+ /* ИНТЕРАКТИВ 1 — SVG с угловым маркером перпендикулярности */
+ html+=`
+
+
Перемещай точку касания $T$ по окружности — касательная и радиус $OT$ всегда перпендикулярны. Угловой маркер 90° следует за $T$.
+
+ Угол точки $T$: 90 °
+
+
+
+
+
∠OTℓ = 90° всегда
+
`;
+
+ /* ИНТЕРАКТИВ 2 — Пошаговое доказательство от противного */
+ html+=`
+
+
Нажимай «Далее» чтобы пройти доказательство методом от противного.
+
+
+
+ Далее
+ Сначала
+
+
`;
+
+ /* ИНТЕРАКТИВ 3 — Калькулятор длины касательной */
+ html+=`
+
+
Дано $R$ и $|OA|$ — найди $AT = \\sqrt{|OA|^2 - R^2}$.
+
+ R =
+ |OA| =
+ Вычислить AT
+
+
+
`;
+
+ /* ИНТЕРАКТИВ 4 — Тренажёр */
+ html+=`
+
+
5 задач на применение свойства касательной. Введи ответ.
+
Задача 1 / 5 Очки: 0
+
+
+
+ Проверить
+ Начать заново
+
+
+
`;
+
+ /* ИНТЕРАКТИВ 5 — DnD верные/неверные утверждения */
+ html+=`
+
+
Перетащи утверждение в нужную колонку.
+
+
+
Проверить Сбросить
+
+
`;
+
+ /* ИНТЕРАКТИВ 6 — Босс §2 */
+ html+=`
+
+
4 задачи — каждая верная даёт +5 XP.
+
+
`;
+
+ html+=`
+
+
+ Я прочитал §2 (+10 XP)
+
+
`;
+ html+=secNav('p1','p3');
+ box.innerHTML=html;
+ if(window.renderMathInElement) setTimeout(()=>renderMath(box),0);
+
+ /* === INIT ИНТЕРАКТИВ 1: вращение T по окружности === */
+ (function(){
+ const sl=document.getElementById('p2-t-sl');
+ const tVal=document.getElementById('p2-t-val');
+ const svgWrap=document.getElementById('p2-perp-svg');
+ const cx=140, cy=110, R=70, W=280, H=210;
+ function draw(){
+ const angDeg=+sl.value;
+ tVal.textContent=angDeg;
+ const angRad=(angDeg-90)*Math.PI/180;
+ const Tx=cx+R*Math.cos(angRad);
+ const Ty=cy+R*Math.sin(angRad);
+ // unit vectors
+ const urx=(Tx-cx)/R, ury=(Ty-cy)/R;
+ const utx=-ury, uty=urx; // tangent unit vector (perp to radius)
+ const tLen=80;
+ const lx1=Tx-utx*tLen, ly1=Ty-uty*tLen;
+ const lx2=Tx+utx*tLen, ly2=Ty+uty*tLen;
+ // right angle marker at T: 9px square
+ const s=9;
+ const mx1=Tx+urx*s, my1=Ty+ury*s;
+ const mx2=Tx+urx*s+utx*s, my2=Ty+ury*s+uty*s;
+ const mx3=Tx+utx*s, my3=Ty+uty*s;
+ const svg=`
+
+
+
+
+
+
+ O
+ T
+ ℓ (касательная)
+ ∠OTℓ = 90°
+ `;
+ svgWrap.innerHTML=svg;
+ }
+ sl.addEventListener('input',draw);
+ draw();
+ })();
+
+ /* === INIT ИНТЕРАКТИВ 2: доказательство от противного === */
+ (function(){
+ const steps=[
+ {text:'Дано: окружность с центром $O$ и радиусом $R$; прямая $\\ell$ касается окружности в точке $T$ ($\\ell$ имеет с окружностью ровно одну общую точку). Доказать: $OT \\perp \\ell$.',
+ phase:'given'},
+ {text:'Допущение (от противного). Предположим, что $OT$ не перпендикулярно $\\ell$. Тогда из $O$ можно опустить перпендикуляр $OH$ на $\\ell$, где $H \\neq T$.',
+ phase:'contra'},
+ {text:'Шаг 2. В прямоугольном треугольнике $OHT$ гипотенуза $OT = R$, катет $OH < OT$. Значит, $OH < R$ — точка $H$ лежит внутри окружности.',
+ phase:'inside'},
+ {text:'Шаг 3. Прямая $\\ell$, проходящая через точку $H$ внутри окружности, обязана пересекать окружность в двух точках. Но $\\ell$ — касательная (одна общая точка). Противоречие!',
+ phase:'contradiction'},
+ {text:'Вывод. Допущение неверно. Следовательно, $OT \\perp \\ell$. ч.т.д. ',
+ phase:'done'},
+ ];
+ let step=0;
+ const svgEl=document.getElementById('p2-proof-svg');
+ const txtEl=document.getElementById('p2-proof-text');
+ const nextBtn=document.getElementById('p2-proof-next');
+ const resetBtn=document.getElementById('p2-proof-reset');
+ const cx=130, cy=100, R=65;
+ function drawProof(ph){
+ const Tx=cx, Ty=cy-R;
+ let extras='';
+ if(ph==='contra'||ph==='inside'||ph==='contradiction'||ph==='done'){
+ const Hx=cx+40, Hy=Ty;
+ extras+=` `;
+ extras+=`H `;
+ extras+=` `;
+ if(ph==='inside'||ph==='contradiction'){
+ extras+=` `;
+ }
+ }
+ const color=ph==='done'?'#10b981':'#06b6d4';
+ const svg=`
+
+
+
+
+
+
+ O
+ T
+ ℓ
+ ${extras}
+ `;
+ svgEl.innerHTML=svg;
+ txtEl.innerHTML=steps.find(s=>s.phase===ph).text;
+ if(window.renderMathInElement) try{renderMath(txtEl);}catch(e){}
+ }
+ const phases=steps.map(s=>s.phase);
+ function go(){
+ drawProof(phases[step]);
+ nextBtn.textContent=step>=phases.length-1?'Готово':'Далее';
+ if(step{step=0;go();});
+ go();
+ })();
+
+ /* === INIT ИНТЕРАКТИВ 3: калькулятор === */
+ (function(){
+ const btn=document.getElementById('p2-calc-btn');
+ const out=document.getElementById('p2-calc-out');
+ btn.addEventListener('click',()=>{
+ const R=parseFloat(document.getElementById('p2-cr').value);
+ const OA=parseFloat(document.getElementById('p2-coa').value);
+ out.style.display='block';
+ if(isNaN(R)||isNaN(OA)||R<=0||OA<=0){out.style.background='#fee2e2';out.style.color='#7f1d1d';out.textContent='Введите корректные значения';return;}
+ if(OA'+fmt(AT)+'';
+ });
+ })();
+
+ /* === INIT ИНТЕРАКТИВ 4: Тренажёр === */
+ (function(){
+ const tasks=[
+ {q:'Радиус $R = 5$, $|OA| = 13$. Найди длину касательной $AT$.',a:'12',hint:'AT = √(169 − 25) = √144 = 12'},
+ {q:'Радиус $R = 8$, $|OA| = 10$. Найди $AT$.',a:'6',hint:'AT = √(100 − 64) = √36 = 6'},
+ {q:'Касательная $AT = 24$, $|OA| = 26$. Найди радиус $R$.',a:'10',hint:'R = √(26² − 24²) = √(676−576) = √100 = 10'},
+ {q:'Касательная $AT = 15$, радиус $R = 9$. Найди $|OA|$.',a:'√306',hint:'OA = √(225 + 81) = √306 ≈ 17,49. Введи 306 (под корнем)'},
+ {q:'Угол между радиусом $OT$ и прямой $OA$ равен 60°, $|OA| = 10$. Найди радиус $R = |OT|$.',a:'5',hint:'OT = OA·cos60° = 10·0,5 = 5 (касательная AT ⊥ OT)'},
+ ];
+ let cur=0,score=0;
+ const iEl=document.getElementById('p2-tr-i');
+ const scEl=document.getElementById('p2-tr-score');
+ const taskEl=document.getElementById('p2-tr-task');
+ const ansEl=document.getElementById('p2-tr-ans');
+ const goBtn=document.getElementById('p2-tr-go');
+ const startBtn=document.getElementById('p2-tr-start');
+ const fb=document.getElementById('p2-tr-fb');
+ const numAnswers={'√306':Math.sqrt(306)};
+ function showTask(){
+ if(cur>=tasks.length){taskEl.innerHTML='Тренажёр завершён! Очки: '+score+'/'+tasks.length+' ';ansEl.style.display='none';goBtn.style.display='none';addXp(score*4,'p2-trainer');bumpProgress('p2',20);return;}
+ taskEl.innerHTML=tasks[cur].q;iEl.textContent=cur+1;ansEl.value='';fb.style.display='none';
+ if(window.renderMathInElement) try{renderMath(taskEl);}catch(e){}
+ }
+ goBtn.addEventListener('click',()=>{
+ const raw=ansEl.value.trim().replace(',','.');
+ const expected=tasks[cur].a;
+ const expNum=numAnswers[expected]!==undefined?numAnswers[expected]:parseFloat(expected);
+ const ansNum=parseFloat(raw);
+ const ok=Math.abs(ansNum-expNum)<0.5;
+ feedback(fb,ok,ok?'Верно!':'Неверно. '+tasks[cur].hint);
+ if(ok){score++;scEl.textContent=score;cur++;setTimeout(showTask,900);}
+ });
+ startBtn.addEventListener('click',()=>{cur=0;score=0;scEl.textContent=0;ansEl.style.display='';goBtn.style.display='';showTask();});
+ showTask();
+ })();
+
+ /* === INIT ИНТЕРАКТИВ 5: DnD верные/неверные === */
+ (function(){
+ const items=[
+ {label:'Касательная ⊥ радиусу в точке касания',cat:'true'},
+ {label:'Касательная параллельна радиусу',cat:'false'},
+ {label:'Расстояние от центра до касательной = R',cat:'true'},
+ {label:'Из внешней точки можно провести только одну касательную',cat:'false'},
+ {label:'AT = √(|OA|² − R²)',cat:'true'},
+ {label:'AT > |OA|',cat:'false'},
+ ];
+ const pool=document.getElementById('p2-dnd-pool');
+ const boxes={true:document.getElementById('p2-drop-true-items'),false:document.getElementById('p2-drop-false-items')};
+ const fb=document.getElementById('p2-dnd-fb');
+ let placed={};
+ function reset(){
+ pool.innerHTML='';placed={};
+ Object.values(boxes).forEach(b=>b.innerHTML='');
+ fb.style.display='none';
+ items.forEach((it,i)=>{
+ const chip=document.createElement('div');
+ chip.className='dnd-chip';chip.dataset.i=i;chip.textContent=it.label;
+ chip.addEventListener('click',()=>chip.classList.toggle('armed'));
+ Object.entries(boxes).forEach(([cat,box])=>{
+ box.parentElement.addEventListener('click',()=>{
+ if(!chip.classList.contains('armed'))return;
+ chip.classList.remove('armed');
+ if(placed[i]!==undefined) boxes[placed[i]].removeChild(chip);
+ placed[i]=cat;
+ box.appendChild(chip);
+ });
+ });
+ pool.appendChild(chip);
+ });
+ }
+ document.getElementById('p2-dnd-check').addEventListener('click',()=>{
+ let ok=0;
+ items.forEach((it,i)=>{if(placed[i]===it.cat)ok++;});
+ feedback(fb,ok===items.length,'Верно: '+ok+'/'+items.length+(ok===items.length?'. Отлично!':'. Попробуй ещё.'));
+ if(ok===items.length){addXp(8,'p2-dnd');bumpProgress('p2',15);}
+ });
+ document.getElementById('p2-dnd-reset').addEventListener('click',reset);
+ reset();
+ })();
+
+ /* === INIT ИНТЕРАКТИВ 6: Босс §2 === */
+ (function(){
+ const tasks=[
+ {q:'Касательная $AT = 24$, радиус $R = 7$. Найти $|OA|$.',
+ opts:['25','√(576+49)=√625=25','√(24²−7²)=√527'],cor:1,
+ exp:'$|OA| = \\sqrt{AT^2 + R^2} = \\sqrt{576 + 49} = \\sqrt{625} = 25$.'},
+ {q:'Угол $\\angle TOA = 30°$, $|OA| = 20$. Найти длину касательной $AT$.',
+ opts:['10','10√3','20√3'],cor:1,
+ exp:'В прямоугольном треугольнике $OAT$: $AT = OA \\cdot \\sin 30° \\cdot ...$. Нет: $\\angle OTA = 90°$, поэтому $AT = OA \\cdot \\sin(\\angle AOT) \\cdot ...$. Точнее: $\\cos(\\angle TAO) = AT/OA$, $\\angle OAT + \\angle AOT = 90°$, $\\angle OAT = 60°$, $AT = OA \\cdot \\sin 60° = 20 \\cdot \\dfrac{\\sqrt{3}}{2} = 10\\sqrt{3}$.'},
+ {q:'Точка $A$ находится вне окружности. Из $A$ проведены касательные $AT_1$ и $AT_2$. Угол $\\angle T_1OT_2 = 120°$. Найти $\\angle T_1AT_2$.',
+ opts:['30°','60°','120°'],cor:1,
+ exp:'Четырёхугольник $AT_1OT_2$ имеет $\\angle T_1 = \\angle T_2 = 90°$, сумма углов $360°$. Значит $\\angle A + \\angle O = 180°$: $\\angle A = 60°$.'},
+ {q:'Радиус $R = 10$, касательная $AT = 10\\sqrt{3}$. Найти $|OA|$.',
+ opts:['10','20','10√2'],cor:1,
+ exp:'$|OA| = \\sqrt{R^2 + AT^2} = \\sqrt{100 + 300} = \\sqrt{400} = 20$.'},
+ ];
+ const cont=document.getElementById('p2-boss-tasks');
+ let html='';
+ tasks.forEach((t,i)=>{
+ html+=`
+
${i+1}. ${t.q}
+
+ ${t.opts.map((o,j)=>`${o} `).join('')}
+
+
+
`;
+ });
+ cont.innerHTML=html;
+ if(window.renderMathInElement) try{renderMath(cont);}catch(e){}
+ })();
+}
+function buildP3(){
+ const box=document.getElementById('p3-body');
+ let html='';
+
+ html+=makeCard('theory','Свойство касательных из одной точки','3.1',`
+ Теорема. Если из внешней точки $A$ к окружности проведены две касательные с точками касания $T_1$ и $T_2$, то:
+
+ Равенство отрезков: $|AT_1| = |AT_2|$
+ Биссектриса: прямая $OA$ является биссектрисой угла $T_1AT_2$ (и угла $T_1OT_2$).
+
+
+
+
+
+
+
+
+
+
+
+
+
+ O
+ T₁
+ T₂
+ A
+ AT₁
+ AT₂
+ AT₁ = AT₂
+
+
`);
+
+ html+=makeCard('rule','Доказательство через равные треугольники','3.2',`
+ Рассмотрим треугольники $\\triangle OAT_1$ и $\\triangle OAT_2$:
+
+ $OT_1 = OT_2 = R$ (оба радиусы)
+ $OA = OA$ (общая гипотенуза)
+ $\\angle OT_1A = \\angle OT_2A = 90°$ (свойство касательной)
+
+ По признаку равенства прямоугольных треугольников (по гипотенузе и катету): $\\triangle OAT_1 = \\triangle OAT_2$.
+ Следовательно, $AT_1 = AT_2$ и $\\angle T_1AO = \\angle T_2AO$. ч.т.д.
`);
+
+ html+=makeCard('example','Пример','3.3',`
+ Задача. Из точки $A$ проведены касательные к окружности радиуса $R = 8$. Расстояние от $A$ до центра $|OA| = 17$. Найти длины касательных.
+ Решение: $AT_1 = AT_2 = \\sqrt{|OA|^2 - R^2} = \\sqrt{289 - 64} = \\sqrt{225} = 15$.
+ Ответ: $AT_1 = AT_2 = 15$.
`);
+
+ /* ИНТЕРАКТИВ 1 — SVG с двумя касательными из внешней точки A */
+ html+=`
+
+
Двигай слайдер — меняй положение точки $A$. Отрезки $AT_1$ и $AT_2$ всегда равны!
+
+ Расстояние $|OA|$: 130 (R = 65)
+
+
+
+
+
+
`;
+
+ /* ИНТЕРАКТИВ 2 — Пошаговое доказательство */
+ html+=`
+
+
Нажимай «Далее» чтобы пройти доказательство через равенство прямоугольных треугольников.
+
+
+
+ Далее
+ Сначала
+
+
`;
+
+ /* ИНТЕРАКТИВ 3 — Калькулятор */
+ html+=`
+
+
Дано $R$ и $|OA|$ — найди $|AT| = \\sqrt{|OA|^2 - R^2}$.
+
+ R =
+ |OA| =
+ Вычислить |AT|
+
+
+
`;
+
+ /* ИНТЕРАКТИВ 4 — Тренажёр */
+ html+=`
+
+
5 задач на свойство двух касательных. Введи ответ.
+
Задача 1 / 5 Очки: 0
+
+
+
+ Проверить
+ Начать заново
+
+
+
`;
+
+ /* ИНТЕРАКТИВ 5 — DnD верные/неверные утверждения о двух касательных */
+ html+=`
+
+
Перетащи утверждение в нужную колонку.
+
+
+
Проверить Сбросить
+
+
`;
+
+ /* ИНТЕРАКТИВ 6 — Босс §3 */
+ html+=`
+
+
4 задачи — каждая верная даёт +5 XP.
+
+
`;
+
+ html+=`
+
+
+ Я прочитал §3 (+10 XP)
+
+
`;
+ html+=secNav('p2','p4');
+ box.innerHTML=html;
+ if(window.renderMathInElement) setTimeout(()=>renderMath(box),0);
+
+ /* === INIT ИНТЕРАКТИВ 1: две касательные из A === */
+ (function(){
+ const sl=document.getElementById('p3-oa-sl');
+ const oaVal=document.getElementById('p3-oa-val');
+ const svgWrap=document.getElementById('p3-two-svg');
+ const info=document.getElementById('p3-two-info');
+ const R=65, cx=100, cy=130, W=280, H=240;
+ function draw(){
+ const OA=+sl.value;
+ oaVal.textContent=OA;
+ const Ax=cx+OA, Ay=cy;
+ const AT=Math.sqrt(OA*OA-R*R);
+ const sinA=R/OA, cosA=AT/OA;
+ const T1x=cx+R*cosA, T1y=cy-R*sinA;
+ const T2x=cx+R*cosA, T2y=cy+R*sinA;
+ // right angle markers
+ const ur1x=(T1x-cx)/R, ur1y=(T1y-cy)/R;
+ const ut1x=-(ur1y), ut1y=ur1x;
+ const s=8;
+ const rm1=`${(T1x+ur1x*s).toFixed(1)},${(T1y+ur1y*s).toFixed(1)} ${(T1x+ur1x*s+ut1x*s).toFixed(1)},${(T1y+ur1y*s+ut1y*s).toFixed(1)} ${(T1x+ut1x*s).toFixed(1)},${(T1y+ut1y*s).toFixed(1)}`;
+ const ur2x=(T2x-cx)/R, ur2y=(T2y-cy)/R;
+ const ut2x=-(ur2y), ut2y=ur2x;
+ const rm2=`${(T2x+ur2x*s).toFixed(1)},${(T2y+ur2y*s).toFixed(1)} ${(T2x+ur2x*s+ut2x*s).toFixed(1)},${(T2y+ur2y*s+ut2y*s).toFixed(1)} ${(T2x+ut2x*s).toFixed(1)},${(T2y+ut2y*s).toFixed(1)}`;
+ const svg=`
+
+
+
+
+
+
+
+
+
+
+
+
+ T₁
+ T₂
+ O
+ A
+ ${fmt(AT)}
+ ${fmt(AT)}
+ `;
+ svgWrap.innerHTML=svg;
+ info.textContent='AT₁ = AT₂ = '+fmt(AT)+' (при R = '+R+', |OA| = '+OA+')';
+ }
+ sl.addEventListener('input',draw);
+ draw();
+ })();
+
+ /* === INIT ИНТЕРАКТИВ 2: пошаговое доказательство === */
+ (function(){
+ const steps=[
+ {text:'Дано: окружность с центром $O$, радиусом $R$; из внешней точки $A$ проведены касательные $AT_1$ и $AT_2$ с точками касания $T_1$ и $T_2$. Доказать: $AT_1 = AT_2$.',
+ phase:'given'},
+ {text:'Шаг 1. По свойству касательной: $OT_1 \\perp AT_1$ и $OT_2 \\perp AT_2$, то есть $\\angle OT_1A = \\angle OT_2A = 90°$. Треугольники $\\triangle OAT_1$ и $\\triangle OAT_2$ — прямоугольные.',
+ phase:'right'},
+ {text:'Шаг 2. Выпишем элементы для признака равенства: $OA = OA$ (общая гипотенуза), $OT_1 = OT_2 = R$ (катеты — радиусы одной окружности).',
+ phase:'elements'},
+ {text:'Шаг 3. По признаку равенства прямоугольных треугольников (по гипотенузе и катету): $\\triangle OAT_1 = \\triangle OAT_2$.',
+ phase:'equal'},
+ {text:'Вывод. Из равенства треугольников: $AT_1 = AT_2$ (соответственные катеты) и $\\angle T_1AO = \\angle T_2AO$ (прямая $OA$ — биссектриса). ч.т.д. ',
+ phase:'done'},
+ ];
+ let step=0;
+ const svgEl=document.getElementById('p3-proof-svg');
+ const txtEl=document.getElementById('p3-proof-text');
+ const nextBtn=document.getElementById('p3-proof-next');
+ const resetBtn=document.getElementById('p3-proof-reset');
+ const R=55, cx=100, cy=105;
+ const OA=130;
+ const AT=Math.sqrt(OA*OA-R*R);
+ const sinA=R/OA, cosA=AT/OA;
+ const T1x=cx+R*cosA, T1y=cy-R*sinA;
+ const T2x=cx+R*cosA, T2y=cy+R*sinA;
+ const Ax=cx+OA, Ay=cy;
+ function drawProof(ph){
+ let tri1='',tri2='',equal='';
+ if(ph==='right'||ph==='elements'||ph==='equal'||ph==='done'){
+ tri1=` `;
+ tri2=` `;
+ const s=7;
+ const ur1x=(T1x-cx)/R, ur1y=(T1y-cy)/R;
+ const ut1x=-(ur1y), ut1y=ur1x;
+ const rm1=`${(T1x+ur1x*s).toFixed(1)},${(T1y+ur1y*s).toFixed(1)} ${(T1x+ur1x*s+ut1x*s).toFixed(1)},${(T1y+ur1y*s+ut1y*s).toFixed(1)} ${(T1x+ut1x*s).toFixed(1)},${(T1y+ut1y*s).toFixed(1)}`;
+ const ur2x=(T2x-cx)/R, ur2y=(T2y-cy)/R;
+ const ut2x=-(ur2y), ut2y=ur2x;
+ const rm2=`${(T2x+ur2x*s).toFixed(1)},${(T2y+ur2y*s).toFixed(1)} ${(T2x+ur2x*s+ut2x*s).toFixed(1)},${(T2y+ur2y*s+ut2y*s).toFixed(1)} ${(T2x+ut2x*s).toFixed(1)},${(T2y+ut2y*s).toFixed(1)}`;
+ equal=` `;
+ }
+ if(ph==='done'||ph==='equal'){
+ equal+=`✓ `;
+ equal+=`✓ `;
+ }
+ const mainColor=ph==='done'?'#10b981':'#0284c7';
+ const svg=`
+
+ ${tri1}${tri2}
+
+
+
+
+
+ ${equal}
+
+
+
+
+ O
+ T₁
+ T₂
+ A
+ `;
+ svgEl.innerHTML=svg;
+ txtEl.innerHTML=steps.find(s=>s.phase===ph).text;
+ if(window.renderMathInElement) try{renderMath(txtEl);}catch(e){}
+ }
+ const phases=steps.map(s=>s.phase);
+ function go(){
+ drawProof(phases[step]);
+ nextBtn.textContent=step>=phases.length-1?'Готово':'Далее';
+ if(step{step=0;go();});
+ go();
+ })();
+
+ /* === INIT ИНТЕРАКТИВ 3: калькулятор === */
+ (function(){
+ const btn=document.getElementById('p3-calc-btn');
+ const out=document.getElementById('p3-calc-out');
+ btn.addEventListener('click',()=>{
+ const R=parseFloat(document.getElementById('p3-cr').value);
+ const OA=parseFloat(document.getElementById('p3-coa').value);
+ out.style.display='block';
+ if(isNaN(R)||isNaN(OA)||R<=0||OA<=0){out.style.background='#fee2e2';out.style.color='#7f1d1d';out.textContent='Введите корректные значения';return;}
+ if(OA<=R){out.style.background='#fee2e2';out.style.color='#7f1d1d';out.textContent='|OA| должно быть больше R';return;}
+ const AT=Math.sqrt(OA*OA-R*R);
+ out.style.background='#d1fae5';out.style.color='#065f46';
+ out.innerHTML='|AT₁| = |AT₂| = √('+fmt(OA)+'² − '+fmt(R)+'²) = √'+fmt(OA*OA-R*R)+' = '+fmt(AT)+' ';
+ });
+ })();
+
+ /* === INIT ИНТЕРАКТИВ 4: Тренажёр === */
+ (function(){
+ const tasks=[
+ {q:'Из точки $A$ проведены касательные к окружности радиуса $R = 6$, $|OA| = 10$. Найти длину каждой касательной.',a:'8',hint:'AT = √(100 − 36) = √64 = 8'},
+ {q:'Касательная $AT_1 = 15$, $R = 9$. Найти $|OA|$.',a:'√306',hint:'OA = √(225 + 81) = √306. Введи приближение: 17'},
+ {q:'Из точки $A$ проведены две касательные. $AT_1 = 12$, $AT_2 = ?$',a:'12',hint:'Два отрезка касательных из одной точки равны'},
+ {q:'$|OA| = 25$, $AT = 24$. Найти $R$.',a:'7',hint:'R = √(25² − 24²) = √(625−576) = √49 = 7'},
+ {q:'Угол между двумя касательными из точки $A$ равен $60°$. Угол $\\angle T_1OT_2 = ?$ (в градусах)',a:'120',hint:'Сумма углов A и O в четырёхугольнике AT₁OT₂ равна 180°'},
+ ];
+ let cur=0,score=0;
+ const iEl=document.getElementById('p3-tr-i');
+ const scEl=document.getElementById('p3-tr-score');
+ const taskEl=document.getElementById('p3-tr-task');
+ const ansEl=document.getElementById('p3-tr-ans');
+ const goBtn=document.getElementById('p3-tr-go');
+ const startBtn=document.getElementById('p3-tr-start');
+ const fb=document.getElementById('p3-tr-fb');
+ function numOf(s){if(s==='√306')return Math.sqrt(306);return parseFloat(s);}
+ function showTask(){
+ if(cur>=tasks.length){taskEl.innerHTML='Тренажёр завершён! Очки: '+score+'/'+tasks.length+' ';ansEl.style.display='none';goBtn.style.display='none';addXp(score*4,'p3-trainer');bumpProgress('p3',20);return;}
+ taskEl.innerHTML=tasks[cur].q;iEl.textContent=cur+1;ansEl.value='';fb.style.display='none';
+ if(window.renderMathInElement) try{renderMath(taskEl);}catch(e){}
+ }
+ goBtn.addEventListener('click',()=>{
+ const raw=ansEl.value.trim().replace(',','.');
+ const ok=Math.abs(parseFloat(raw)-numOf(tasks[cur].a))<0.6;
+ feedback(fb,ok,ok?'Верно!':'Неверно. '+tasks[cur].hint);
+ if(ok){score++;scEl.textContent=score;cur++;setTimeout(showTask,900);}
+ });
+ startBtn.addEventListener('click',()=>{cur=0;score=0;scEl.textContent=0;ansEl.style.display='';goBtn.style.display='';showTask();});
+ showTask();
+ })();
+
+ /* === INIT ИНТЕРАКТИВ 5: DnD === */
+ (function(){
+ const items=[
+ {label:'AT₁ = AT₂ (из одной внешней точки)',cat:'true'},
+ {label:'AT₁ > AT₂ если T₁ выше T₂',cat:'false'},
+ {label:'OA — биссектриса угла T₁AT₂',cat:'true'},
+ {label:'∠OT₁A = 90°',cat:'true'},
+ {label:'Из одной точки можно провести 3 касательных',cat:'false'},
+ {label:'△OAT₁ = △OAT₂',cat:'true'},
+ ];
+ const pool=document.getElementById('p3-dnd-pool');
+ const boxes={true:document.getElementById('p3-drop-true-items'),false:document.getElementById('p3-drop-false-items')};
+ const fb=document.getElementById('p3-dnd-fb');
+ let placed={};
+ function reset(){
+ pool.innerHTML='';placed={};
+ Object.values(boxes).forEach(b=>b.innerHTML='');
+ fb.style.display='none';
+ items.forEach((it,i)=>{
+ const chip=document.createElement('div');
+ chip.className='dnd-chip';chip.dataset.i=i;chip.textContent=it.label;
+ chip.addEventListener('click',()=>chip.classList.toggle('armed'));
+ Object.entries(boxes).forEach(([cat,box])=>{
+ box.parentElement.addEventListener('click',()=>{
+ if(!chip.classList.contains('armed'))return;
+ chip.classList.remove('armed');
+ if(placed[i]!==undefined) boxes[placed[i]].removeChild(chip);
+ placed[i]=cat;
+ box.appendChild(chip);
+ });
+ });
+ pool.appendChild(chip);
+ });
+ }
+ document.getElementById('p3-dnd-check').addEventListener('click',()=>{
+ let ok=0;
+ items.forEach((it,i)=>{if(placed[i]===it.cat)ok++;});
+ feedback(fb,ok===items.length,'Верно: '+ok+'/'+items.length+(ok===items.length?'. Отлично!':'. Попробуй ещё.'));
+ if(ok===items.length){addXp(8,'p3-dnd');bumpProgress('p3',15);}
+ });
+ document.getElementById('p3-dnd-reset').addEventListener('click',reset);
+ reset();
+ })();
+
+ /* === INIT ИНТЕРАКТИВ 6: Босс §3 === */
+ (function(){
+ const tasks=[
+ {q:'Из точки $A$ проведены касательные к окружности с центром $O$. $\\angle T_1AT_2 = 60°$, $AT_1 = 6\\sqrt{3}$. Найти $R$.',
+ opts:['6','3√3','6√3'],cor:0,
+ exp:'$\\angle T_1AO = 30°$ (биссектриса), $\\tan 30° = R / AT_1$, значит $R = AT_1 \\cdot \\tan 30° = 6\\sqrt{3} \\cdot \\dfrac{1}{\\sqrt{3}} = 6$.'},
+ {q:'Две касательные из $A$, $|OA| = 10$, $R = 8$. Найти периметр четырёхугольника $OT_1AT_2$.',
+ opts:['12+16=28','6+12+6+8=32','6·4=24'],cor:0,
+ exp:'$AT_1 = AT_2 = \\sqrt{100-64} = 6$. $OT_1 = OT_2 = 8$. Периметр $= 6+8+6+8 = 28$.'},
+ {q:'Из точки $P$ проведены касательные, угол между касательными $90°$. $|OP| = 5\\sqrt{2}$. Найти $R$.',
+ opts:['5','5√2','10'],cor:0,
+ exp:'$\\angle T_1PO = 45°$ (половина 90°). $\\sin 45° = R/|OP|$, значит $R = 5\\sqrt{2} \\cdot \\dfrac{\\sqrt{2}}{2} = 5$.'},
+ {q:'Два отрезка касательных из одной точки равны по теореме, доказанной через:',
+ opts:['Равенство прямоугольных треугольников (гипотенуза и катет)','Теорему Пифагора','Теорему Фалеса'],cor:0,
+ exp:'Доказывается через признак равенства прямоугольных треугольников: гипотенуза $OA$ общая, катет $OT_1 = OT_2 = R$.'},
+ ];
+ const cont=document.getElementById('p3-boss-tasks');
+ let html='';
+ tasks.forEach((t,i)=>{
+ html+=`
+
${i+1}. ${t.q}
+
+ ${t.opts.map((o,j)=>`${o} `).join('')}
+
+
+
`;
+ });
+ cont.innerHTML=html;
+ if(window.renderMathInElement) try{renderMath(cont);}catch(e){}
+ })();
+}
function buildP4stub(){ document.getElementById('p4-body').innerHTML='§4 — Волна 1 : содержимое появится в следующем обновлении.
'+secNav('p3','p5'); }
function buildP5stub(){ document.getElementById('p5-body').innerHTML='§5 — Волна 1 : содержимое появится в следующем обновлении.
'+secNav('p4','p6'); }
function buildP6stub(){ document.getElementById('p6-body').innerHTML='§6 — Волна 1 : содержимое появится в следующем обновлении.
'+secNav('p5','p7'); }