diff --git a/backend/tests/math6-page.test.js b/backend/tests/math6-page.test.js index b8c973f..23207e5 100644 --- a/backend/tests/math6-page.test.js +++ b/backend/tests/math6-page.test.js @@ -68,6 +68,23 @@ for (const ch of CHAPTERS) { }); } +test('ch2: проценты и пропорции — интерактивы + финал', async () => { + const { doc, errors } = await loadDom('math_6_ch2.html'); + const win = doc.defaultView; + assert.ok(doc.querySelector('#p1-fig svg rect') && doc.querySelector('#p1-q'), 'сетка 100 и конвертер §1'); + win.goTo('p2'); await wait(80); + assert.ok(doc.querySelectorAll('#p2-iv1 [data-t]').length === 3 && doc.querySelector('#p2-cq'), 'типы задач §2'); + win.goTo('p3'); await wait(80); + assert.ok(doc.querySelector('#p3-q') && doc.querySelectorAll('#p3-iv2 [data-v]').length === 2, 'пропорция §3'); + win.goTo('p7'); await wait(80); + assert.ok(doc.querySelector('#p7-fig svg') && doc.querySelector('#p7-pick [data-k]'), 'круговая диаграмма §7'); + win.goTo('final'); await wait(80); + assert.ok(doc.querySelector('#fin-go'), 'арена боссов §2'); + win.bumpProgress('final', 100); await wait(20); + assert.ok(win.M6STATE.achievements.has('ch2_done'), 'достижение «Глава 2 пройдена»'); + assert.deepEqual(errors, [], 'нет ошибок: ' + errors.join(' | ')); +}); + test('ch5: координатная плоскость — интерактивы §1–§3 + финал', async () => { const { doc, errors } = await loadDom('math_6_ch5.html'); const win = doc.defaultView; diff --git a/frontend/js/math6_svg.js b/frontend/js/math6_svg.js index dbb92db..76a5551 100644 --- a/frontend/js/math6_svg.js +++ b/frontend/js/math6_svg.js @@ -153,4 +153,28 @@ M.plane = function (opts) { return M.box(S, S, s, { maxw: opts.maxw || S, bg: opts.bg }); }; +/* === КРУГОВАЯ ДИАГРАММА === + * segs: [{value,label,color}]. opts: {size, r}. Возвращает boxed SVG (проценты в секторах). + */ +M.pie = function (segs, opts) { + opts = opts || {}; + var S = opts.size || 220, cx = S / 2, cy = S / 2, r = opts.r || (S / 2 - 8); + var total = segs.reduce(function (a, s) { return a + s.value; }, 0) || 1; + var palette = ['#4f46e5', '#0891b2', '#e11d48', '#059669', '#d97706', '#7c3aed', '#db2777']; + var ang = -Math.PI / 2, s = ''; + segs.forEach(function (seg, i) { + var frac = seg.value / total, a2 = ang + frac * 2 * Math.PI; + var col = seg.color || palette[i % palette.length]; + if (frac >= 0.999) { s += ''; } + else { + var x1 = cx + r * Math.cos(ang), y1 = cy + r * Math.sin(ang), x2 = cx + r * Math.cos(a2), y2 = cy + r * Math.sin(a2), large = frac > 0.5 ? 1 : 0; + s += ''; + } + var mid = ang + frac * Math.PI, lx = cx + r * 0.62 * Math.cos(mid), ly = cy + r * 0.62 * Math.sin(mid); + if (frac > 0.05) s += '' + Math.round(frac * 100) + '%'; + ang = a2; + }); + return M.box(S, S, s, { maxw: opts.maxw || S }); +}; + })(); diff --git a/frontend/textbooks/math_6_ch2.html b/frontend/textbooks/math_6_ch2.html index 1b0d50d..f0dcf68 100644 --- a/frontend/textbooks/math_6_ch2.html +++ b/frontend/textbooks/math_6_ch2.html @@ -96,6 +96,510 @@ window.M6 = { sidebars: {}, tips: [], glossary: [], builders: {}, footer: 'Интерактивный учебник «Математика 6» · Глава 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('.','{,}'); } +function _round(n,d){ var p=Math.pow(10,d); return Math.round(n*p)/p; } +function svgWrap(w,h,inner){ return '
'+inner+'
'; } +function grid100(p){ var s=''; for(var r=0;r<10;r++)for(var c=0;c<10;c++){ var idx=r*10+c, fill=idx'; } return svgWrap(166,166,s); } + +/* ===================== § 1. ПРОЦЕНТЫ ===================== */ +function buildP1(){ + var box=document.getElementById('p1-body'); var h=''; + h+=makeCard('theory','Что такое процент','1.1', + '

Процент — это сотая доля числа. $1\\% = \\dfrac{1}{100} = 0{,}01$. Знак процента — $\\%$.

' + +'

Всё число — это $100\\%$. Половина — $50\\%$, четверть — $25\\%$, пятая часть — $20\\%$.

'); + h+=makeCard('rule','Перевод процентов','1.2', + '

Проценты $\\to$ десятичная дробь: делим на $100$ (запятая влево на 2 знака): $35\\% = 0{,}35$.

' + +'

Десятичная дробь $\\to$ проценты: умножаем на $100$: $0{,}7 = 70\\%$.

' + +'

Обыкновенная дробь $\\to$ проценты: $\\dfrac{1}{4} = 0{,}25 = 25\\%$.

'); + h+='
Интерактив 1
Процент наглядно
' + +'
Двигай ползунок — закрашенные клетки из 100 показывают процент.
' + +'
' + +'
'; + h+='
Интерактив 2
Переводи проценты
' + +'
Переведи между процентами и десятичной дробью. Ответ — число.
' + +'
Вопрос 1 / 6Очки: 0 / 6
' + +'
' + +'
' + +'
'; + h+=secNav(null,'p2')+readBtn('p1'); + box.innerHTML=h; renderMath(box); + + (function(){ + var sl=document.getElementById('p1-p'), fig=document.getElementById('p1-fig'), out=document.getElementById('p1-out'); + function render(){ var p=+sl.value; document.getElementById('p1-pv').textContent=p; fig.innerHTML=grid100(p); + out.innerHTML='
$'+p+'\\% = \\dfrac{'+p+'}{100} = '+_kf(p/100)+'$
'; renderMath(out); } + sl.oninput=render; render(); + })(); + + (function(){ + var i=0,score=0,cur=null; + function gen(){ var t=_pick(['p2d','d2p','f2p']); + if(t==='p2d'){ var p=_pick([5,10,25,40,75,8,150]); cur={q:'$'+p+'\\%$ = ? (десятичная дробь)', ans:p/100}; } + else if(t==='d2p'){ var d=_pick([0.3,0.07,0.5,1.2,0.25,0.9]); cur={q:'$'+_kf(d)+'$ = ? $\\%$', ans:_round(d*100,2)}; } + else { var f=_pick([[1,4,25],[1,2,50],[1,5,20],[3,4,75],[1,10,10],[1,20,5]]); cur={q:'$\\dfrac{'+f[0]+'}{'+f[1]+'}$ = ? $\\%$', ans:f[2]}; } } + function show(){ if(i>=6){ document.getElementById('p1-q').innerHTML='Готово! '+score+' / 6'; if(score>=5){addXp(15,'p1-iv2');bumpProgress('p1',30);}else if(score>=3){addXp(8,'p1-iv2');bumpProgress('p1',16);} return; } + gen(); 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=parseFloat(document.getElementById('p1-a').value.replace(',','.').replace('%','').trim()); + if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; } + if(Math.abs(v-cur.ans)<1e-9){ score++; feedback(fb,true,'✓ Верно: $'+_kf(cur.ans)+'$.'); } else feedback(fb,false,'✗ Нет. Правильно: $'+_kf(cur.ans)+'$.'); + 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(); + })(); +} + +/* ===================== § 2. ОСНОВНЫЕ ЗАДАЧИ НА ПРОЦЕНТЫ ===================== */ +function buildP2(){ + var box=document.getElementById('p2-body'); var h=''; + h+=makeCard('rule','Три типа задач на проценты','2.1', + '

1) Процент от числа. Найти $m\\%$ от $a$: $\\;b = \\dfrac{a}{100}\\cdot m$.

' + +'

2) Число по его проценту. $b$ — это $m\\%$ от $a$, найти $a$: $\\;a = \\dfrac{b}{m}\\cdot 100$.

' + +'

3) Процентное отношение. Какой процент $b$ от $a$: $\\;m\\% = \\dfrac{b}{a}\\cdot 100\\%$.

'); + h+=makeCard('example','Примеры','2.2', + '

$20\\%$ от $150$: $\\dfrac{150}{100}\\cdot 20 = 30$.   $15$ — это $30\\%$ от $\\dfrac{15}{30}\\cdot 100 = 50$.   $30$ от $120$: $\\dfrac{30}{120}\\cdot 100 = 25\\%$.

'); + h+='
Интерактив 1
Определи тип задачи
' + +'
К какому из трёх типов относится задача?
' + +'
Вопрос 1 / 5Очки: 0 / 5
' + +'
' + +'
' + +'
'; + h+='
Интерактив 2
Найди процент от числа
' + +'
Вычисли $m\\%$ от числа $a$ по формуле $\\dfrac{a}{100}\\cdot m$.
' + +'
Задача 1 / 6Очки: 0 / 6
' + +'
' + +'
' + +'
'; + h+=secNav('p1','p3')+readBtn('p2'); + box.innerHTML=h; renderMath(box); + + (function(){ + var Q=[ + {t:1,q:'В классе 25 учеников, 40% из них — девочки. Сколько девочек?'}, + {t:2,q:'12 страниц — это 30% книги. Сколько страниц в книге?'}, + {t:3,q:'Из 50 задач решено 30. Какой процент задач решён?'}, + {t:1,q:'Цена 800 руб., скидка 15%. Какова величина скидки в рублях?'}, + {t:2,q:'Со счёта сняли 200 руб., это 25% вклада. Каков был вклад?'}, + {t:3,q:'Из 200 семян взошло 180. Какой процент семян взошёл?'} + ]; + var order=Q.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;} + var i=0,score=0,cur=null; + function show(){ if(i>=5){ document.getElementById('p2-q').innerHTML='Готово! '+score+' / 5'; if(score>=4){addXp(15,'p2-iv1');bumpProgress('p2',30);}else if(score>=2){addXp(8,'p2-iv1');bumpProgress('p2',16);} return; } + cur=Q[order[i]]; document.getElementById('p2-i').textContent=i+1; document.getElementById('p2-q').innerHTML=cur.q; document.getElementById('p2-fb').style.display='none'; } + function ans(t){ if(i>=5)return; var fb=document.getElementById('p2-fb'), names={1:'процент от числа',2:'число по проценту',3:'процентное отношение'}; + if(t===cur.t){ score++; feedback(fb,true,'✓ Верно — тип '+cur.t+' ('+names[cur.t]+').'); } else feedback(fb,false,'✗ Нет. Это тип '+cur.t+' ('+names[cur.t]+').'); + document.getElementById('p2-s').textContent=score; i++; setTimeout(show,1400); } + document.querySelectorAll('#p2-iv1 [data-t]').forEach(function(b){ b.addEventListener('click',function(){ ans(+b.getAttribute('data-t')); }); }); show(); + })(); + + (function(){ + var i=0,score=0,cur=null; + function gen(){ var a=_pick([20,40,60,80,100,120,200,500]), m=_pick([5,10,15,20,25,50]); cur={a:a,m:m,ans:a*m/100}; } + function show(){ if(i>=6){ document.getElementById('p2-cq').innerHTML='Готово! '+score+' / 6'; if(score>=5){addXp(15,'p2-iv2');bumpProgress('p2',30);}else if(score>=3){addXp(8,'p2-iv2');bumpProgress('p2',16);} return; } + gen(); document.getElementById('p2-ci').textContent=i+1; document.getElementById('p2-cq').innerHTML='Найди $'+cur.m+'\\%$ от $'+cur.a+'$.'; renderMath(document.getElementById('p2-cq')); + document.getElementById('p2-ca').value=''; document.getElementById('p2-cfb').style.display='none'; } + function go(){ if(i>=6)return; var fb=document.getElementById('p2-cfb'), v=parseFloat(document.getElementById('p2-ca').value.replace(',','.').trim()); + if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; } + if(Math.abs(v-cur.ans)<1e-9){ score++; feedback(fb,true,'✓ Верно: '+_kf(cur.ans)+'.'); } else feedback(fb,false,'✗ Нет. $\\dfrac{'+cur.a+'}{100}\\cdot'+cur.m+' = '+_kf(cur.ans)+'$.'); + document.getElementById('p2-cs').textContent=score; i++; setTimeout(show,1300); } + document.getElementById('p2-cgo').addEventListener('click',go); + document.getElementById('p2-ca').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); }); show(); + })(); +} + +/* ===================== § 3. ПРОПОРЦИЯ И ЕЁ СВОЙСТВА ===================== */ +function buildP3(){ + var box=document.getElementById('p3-body'); var h=''; + h+=makeCard('theory','Отношение и пропорция','3.1', + '

Отношение двух чисел — их частное: $a:b=\\dfrac{a}{b}$. Пропорция — равенство двух отношений: $a:b = c:d$ (читается «$a$ относится к $b$, как $c$ к $d$»).

' + +'

$a$ и $d$ — крайние члены, $b$ и $c$ — средние.

'); + h+=makeCard('rule','Основное свойство пропорции','3.2', + '

Произведение крайних членов равно произведению средних: $\\;a\\cdot d = b\\cdot c$ («крест-накрест»).

' + +'

Отсюда находят неизвестный член: из $a:b=c:x$ получаем $x = \\dfrac{b\\cdot c}{a}$.

'); + h+='
Интерактив 1
Найди неизвестный член
' + +'
Реши пропорцию «крест-накрест»: $x = \\dfrac{b\\cdot c}{a}$.
' + +'
Задача 1 / 6Очки: 0 / 6
' + +'
' + +'
' + +'
'; + h+='
Интерактив 2
Верна ли пропорция?
' + +'
Проверь основное свойство: равны ли произведения крайних и средних членов?
' + +'
Вопрос 1 / 5Очки: 0 / 5
' + +'
' + +'
' + +'
'; + h+=secNav('p2','p4')+readBtn('p3'); + box.innerHTML=h; renderMath(box); + + (function(){ + var i=0,score=0,cur=null; + function gen(){ var a=_ri(2,6), b=_ri(2,9), m=_ri(2,6); cur={a:a,b:b,c:a*m,x:b*m}; } + function show(){ if(i>=6){ document.getElementById('p3-q').innerHTML='Готово! '+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.a+' : '+cur.b+' = '+cur.c+' : x$. Найди $x$.'; 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=parseFloat(document.getElementById('p3-a').value.replace(',','.').trim()); + if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; } + if(Math.abs(v-cur.x)<1e-9){ score++; feedback(fb,true,'✓ Верно: $x = \\dfrac{'+cur.b+'\\cdot'+cur.c+'}{'+cur.a+'} = '+cur.x+'$.'); } else feedback(fb,false,'✗ Нет. $x = \\dfrac{'+cur.b+'\\cdot'+cur.c+'}{'+cur.a+'} = '+cur.x+'$.'); + document.getElementById('p3-s').textContent=score; i++; setTimeout(show,1400); } + 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 a=_ri(2,6),b=_ri(2,6),m=_ri(2,5),c=a*m,d=b*m, ok=_pick([true,true,false]); if(!ok){ d+=_pick([1,2,-1,3]); if(a*d===b*c) d+=1; } cur={a:a,b:b,c:c,d:d,ok:a*d===b*c}; } + function show(){ if(i>=5){ document.getElementById('p3-vq').innerHTML='Готово! '+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-vi').textContent=i+1; document.getElementById('p3-vq').innerHTML='Верна ли пропорция $'+cur.a+':'+cur.b+' = '+cur.c+':'+cur.d+'$?'; renderMath(document.getElementById('p3-vq')); + document.getElementById('p3-vfb').style.display='none'; } + function ans(v){ if(i>=5)return; var fb=document.getElementById('p3-vfb'), correct=cur.ok?1:0; + if(v===correct){ score++; feedback(fb,true,'✓ Верно! $'+cur.a+'\\cdot'+cur.d+' = '+(cur.a*cur.d)+'$, $'+cur.b+'\\cdot'+cur.c+' = '+(cur.b*cur.c)+'$.'); } else feedback(fb,false,'✗ Нет. $'+cur.a+'\\cdot'+cur.d+'='+(cur.a*cur.d)+'$, $'+cur.b+'\\cdot'+cur.c+'='+(cur.b*cur.c)+'$ — '+(cur.ok?'равны':'не равны')+'.'); + document.getElementById('p3-vs').textContent=score; i++; setTimeout(show,1600); } + document.querySelectorAll('#p3-iv2 [data-v]').forEach(function(b){ b.addEventListener('click',function(){ ans(+b.getAttribute('data-v')); }); }); show(); + })(); +} + +/* ===================== § 4. ПРЯМАЯ И ОБРАТНАЯ ЗАВИСИМОСТИ ===================== */ +function buildP4(){ + var box=document.getElementById('p4-body'); var h=''; + h+=makeCard('theory','Прямая пропорциональность','4.1', + '

Величины прямо пропорциональны, если при увеличении одной в несколько раз другая увеличивается во столько же раз. Их отношение постоянно: $\\dfrac{y}{x}=k$.

' + +'

Пример: при постоянной цене стоимость покупки прямо пропорциональна количеству товара.

'); + h+=makeCard('theory','Обратная пропорциональность','4.2', + '

Величины обратно пропорциональны, если при увеличении одной в несколько раз другая во столько же раз уменьшается. Их произведение постоянно: $x\\cdot y=k$.

' + +'

Пример: при постоянном пути время обратно пропорционально скорости.

'); + h+='
Интерактив 1
Прямая или обратная?
' + +'
Определи вид зависимости в ситуации.
' + +'
Вопрос 1 / 6Очки: 0 / 6
' + +'
' + +'
' + +'
'; + h+='
Интерактив 2
Достройте таблицу (прямая)
' + +'
Величины прямо пропорциональны ($y=kx$). Найди недостающее значение.
' + +'
Задача 1 / 5Очки: 0 / 5
' + +'
' + +'
' + +'
'; + h+=secNav('p3','p5')+readBtn('p4'); + box.innerHTML=h; renderMath(box); + + (function(){ + var Q=[ + {t:'d',q:'Количество тетрадей и их общая стоимость (цена постоянна).'}, + {t:'o',q:'Скорость автомобиля и время в пути (расстояние постоянно).'}, + {t:'o',q:'Число рабочих и время выполнения работы (объём постоянен).'}, + {t:'d',q:'Время движения и пройденный путь (скорость постоянна).'}, + {t:'o',q:'Число друзей и доля пирога каждому (пирог один).'}, + {t:'d',q:'Масса покупки и её стоимость (цена за кг постоянна).'}, + {t:'d',q:'Число одинаковых коробок и общее число книг в них.'}, + {t:'o',q:'Длина шага и число шагов на одну и ту же дистанцию.'} + ]; + var order=Q.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;} + var i=0,score=0,cur=null; + function show(){ if(i>=6){ document.getElementById('p4-q').innerHTML='Готово! '+score+' / 6'; if(score>=5){addXp(15,'p4-iv1');bumpProgress('p4',30);}else if(score>=3){addXp(8,'p4-iv1');bumpProgress('p4',16);} return; } + cur=Q[order[i]]; document.getElementById('p4-i').textContent=i+1; document.getElementById('p4-q').innerHTML=cur.q; document.getElementById('p4-fb').style.display='none'; } + function ans(t){ if(i>=6)return; var fb=document.getElementById('p4-fb'); + if(t===cur.t){ score++; feedback(fb,true,'✓ Верно — '+(cur.t==='d'?'прямая':'обратная')+' пропорциональность.'); } else feedback(fb,false,'✗ Нет. Здесь '+(cur.t==='d'?'прямая':'обратная')+' зависимость.'); + document.getElementById('p4-s').textContent=score; i++; setTimeout(show,1400); } + document.querySelectorAll('#p4-iv1 [data-t]').forEach(function(b){ b.addEventListener('click',function(){ ans(b.getAttribute('data-t')); }); }); show(); + })(); + + (function(){ + var i=0,score=0,cur=null; + function gen(){ var k=_ri(2,9), x1=_ri(2,6), x2=_ri(2,8); cur={k:k,x1:x1,y1:k*x1,x2:x2,y2:k*x2}; } + function show(){ if(i>=5){ document.getElementById('p4-tq').innerHTML='Готово! '+score+' / 5'; if(score>=4){addXp(15,'p4-iv2');bumpProgress('p4',30);}else if(score>=2){addXp(8,'p4-iv2');bumpProgress('p4',16);} return; } + gen(); document.getElementById('p4-ti').textContent=i+1; + document.getElementById('p4-tq').innerHTML='
$x$'+cur.x1+''+cur.x2+'
$y$'+cur.y1+'?
Найди недостающее $y$.
'; renderMath(document.getElementById('p4-tq')); + document.getElementById('p4-ta').value=''; document.getElementById('p4-tfb').style.display='none'; } + function go(){ if(i>=5)return; var fb=document.getElementById('p4-tfb'), v=parseFloat(document.getElementById('p4-ta').value.replace(',','.').trim()); + if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; } + if(Math.abs(v-cur.y2)<1e-9){ score++; feedback(fb,true,'✓ Верно: $k='+cur.k+'$, $y='+cur.k+'\\cdot'+cur.x2+'='+cur.y2+'$.'); } else feedback(fb,false,'✗ Нет. $k=\\dfrac{'+cur.y1+'}{'+cur.x1+'}='+cur.k+'$, значит $y='+cur.y2+'$.'); + document.getElementById('p4-ts').textContent=score; i++; setTimeout(show,1500); } + document.getElementById('p4-tgo').addEventListener('click',go); + document.getElementById('p4-ta').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); }); show(); + })(); +} + +/* ===================== § 5. РЕШЕНИЕ ЗАДАЧ С ПОМОЩЬЮ ПРОПОРЦИЙ ===================== */ +function buildP5(){ + var box=document.getElementById('p5-body'); var h=''; + h+=makeCard('rule','Как решать задачи пропорцией','5.1', + '

1) Обозначают неизвестное буквой $x$. 2) Записывают условие в две строки. 3) Если зависимость прямая — стрелки в одну сторону, составляют пропорцию напрямую; если обратная — одно из отношений переворачивают. 4) Решают «крест-накрест».

'); + h+=makeCard('example','Пример','5.2', + '

За $3$ кг яблок заплатили $12$ руб. Сколько за $5$ кг? (прямая) $\\;3:12 = 5:x$, $x=\\dfrac{12\\cdot5}{3}=20$ руб.

'); + h+='
Интерактив 1
Задачи на прямую пропорцию
' + +'
Реши задачу с помощью прямой пропорции. Ответ — число.
' + +'
Задача 1 / 6Очки: 0 / 6
' + +'
' + +'
' + +'
'; + h+='
Интерактив 2
Задачи на обратную пропорцию
' + +'
Здесь зависимость обратная: произведение величин постоянно.
' + +'
Задача 1 / 5Очки: 0 / 5
' + +'
' + +'
' + +'
'; + h+=secNav('p4','p6')+readBtn('p5'); + box.innerHTML=h; renderMath(box); + + (function(){ + var P=[ + {q:'За 3 кг яблок заплатили 12 руб. Сколько рублей за 5 кг?',a:20}, + {q:'2 л сока стоят 10 руб. Сколько стоят 7 л?',a:35}, + {q:'4 одинаковых коробки весят 20 кг. Сколько весят 6 коробок?',a:30}, + {q:'За 5 ручек заплатили 15 руб. Сколько за 8 ручек?',a:24}, + {q:'3 м ткани стоят 9 руб. Сколько стоят 7 м?',a:21}, + {q:'За 2 ч турист прошёл 8 км. Сколько км за 9 ч (тот же темп)?',a:36} + ]; + var order=P.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;} + var i=0,score=0,cur=null; + function show(){ if(i>=6){ document.getElementById('p5-q').innerHTML='Готово! '+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=P[order[i]]; document.getElementById('p5-i').textContent=i+1; document.getElementById('p5-q').innerHTML=cur.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=parseFloat(document.getElementById('p5-a').value.replace(',','.').trim()); + if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; } + if(Math.abs(v-cur.a)<1e-9){ score++; feedback(fb,true,'✓ Верно: '+cur.a+'.'); } else feedback(fb,false,'✗ Нет. Правильно: '+cur.a+'.'); + document.getElementById('p5-s').textContent=score; i++; setTimeout(show,1300); } + document.getElementById('p5-go').addEventListener('click',go); + document.getElementById('p5-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); }); show(); + })(); + + (function(){ + var P=[ + {q:'5 рабочих выполнят заказ за 12 дней. За сколько дней — 6 рабочих?',a:10}, + {q:'Автомобиль прошёл путь за 4 ч со скоростью 60 км/ч. За сколько часов при 80 км/ч?',a:3}, + {q:'8 одинаковых насосов наполнят бассейн за 6 ч. За сколько часов — 4 насоса?',a:12}, + {q:'6 человек съедят запас за 8 дней. На сколько дней хватит 4 людям?',a:12}, + {q:'3 трубы наполнят бак за 10 мин. За сколько минут — 5 таких труб?',a:6} + ]; + var order=P.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;} + var i=0,score=0,cur=null; + function show(){ if(i>=5){ document.getElementById('p5-iq').innerHTML='Готово! '+score+' / 5'; if(score>=4){addXp(15,'p5-iv2');bumpProgress('p5',30);}else if(score>=2){addXp(8,'p5-iv2');bumpProgress('p5',16);} return; } + cur=P[order[i]]; document.getElementById('p5-ii').textContent=i+1; document.getElementById('p5-iq').innerHTML=cur.q; + document.getElementById('p5-ia').value=''; document.getElementById('p5-ifb').style.display='none'; } + function go(){ if(i>=5)return; var fb=document.getElementById('p5-ifb'), v=parseFloat(document.getElementById('p5-ia').value.replace(',','.').trim()); + if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; } + if(Math.abs(v-cur.a)<1e-9){ score++; feedback(fb,true,'✓ Верно: '+cur.a+'.'); } else feedback(fb,false,'✗ Нет. Правильно: '+cur.a+' (произведение величин постоянно).'); + document.getElementById('p5-is').textContent=score; i++; setTimeout(show,1400); } + document.getElementById('p5-igo').addEventListener('click',go); + document.getElementById('p5-ia').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); }); show(); + })(); +} + +/* ===================== § 6. МАСШТАБ ===================== */ +function buildP6(){ + var box=document.getElementById('p6-body'); var h=''; + h+=makeCard('theory','Что такое масштаб','6.1', + '

Масштаб — отношение длины отрезка на чертеже (карте) к длине соответствующего отрезка в реальности. Запись $1:N$ означает: $1$ см на карте соответствует $N$ см на местности.

' + +'

Карта: реальное расстояние $=$ расстояние на карте $\\times N$. Чертёж детали может быть и крупнее ($N<1$).

'); + h+=makeCard('example','Пример','6.2', + '

Масштаб $1:1000$. На карте $3$ см. Реально $3\\cdot 1000 = 3000$ см $= 30$ м.

'); + h+='
Интерактив 1
Карта → местность
' + +'
По расстоянию на карте найди реальное расстояние (ответ в метрах).
' + +'
Задача 1 / 6Очки: 0 / 6
' + +'
' + +'
' + +'
'; + h+='
Интерактив 2
Местность → карта
' + +'
По реальному расстоянию найди длину на карте (ответ в сантиметрах).
' + +'
Задача 1 / 5Очки: 0 / 5
' + +'
' + +'
' + +'
'; + h+=secNav('p5','p7')+readBtn('p6'); + box.innerHTML=h; renderMath(box); + + (function(){ + var i=0,score=0,cur=null; + function gen(){ var N=_pick([200,500,1000,2000,10000]), d=_ri(2,9); cur={N:N,d:d,ans:d*N/100}; } + function show(){ if(i>=6){ document.getElementById('p6-q').innerHTML='Готово! '+score+' / 6'; if(score>=5){addXp(15,'p6-iv1');bumpProgress('p6',30);}else if(score>=3){addXp(8,'p6-iv1');bumpProgress('p6',16);} return; } + gen(); document.getElementById('p6-i').textContent=i+1; document.getElementById('p6-q').innerHTML='Масштаб $1:'+cur.N+'$. На карте $'+cur.d+'$ см. Реальное расстояние в метрах?'; renderMath(document.getElementById('p6-q')); + document.getElementById('p6-a').value=''; document.getElementById('p6-fb').style.display='none'; } + function go(){ if(i>=6)return; var fb=document.getElementById('p6-fb'), v=parseFloat(document.getElementById('p6-a').value.replace(',','.').trim()); + if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; } + if(Math.abs(v-cur.ans)<1e-9){ score++; feedback(fb,true,'✓ Верно: '+_kf(cur.ans)+' м.'); } else feedback(fb,false,'✗ Нет. '+cur.d+'·'+cur.N+'='+(cur.d*cur.N)+' см = '+_kf(cur.ans)+' м.'); + document.getElementById('p6-s').textContent=score; i++; setTimeout(show,1400); } + document.getElementById('p6-go').addEventListener('click',go); + document.getElementById('p6-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); }); show(); + })(); + + (function(){ + var i=0,score=0,cur=null; + function gen(){ var N=_pick([100,200,500,1000]), m=_pick([10,20,50,100,5]); cur={N:N,m:m,ans:m*100/N}; } + function show(){ if(i>=5){ document.getElementById('p6-rq').innerHTML='Готово! '+score+' / 5'; if(score>=4){addXp(15,'p6-iv2');bumpProgress('p6',30);}else if(score>=2){addXp(8,'p6-iv2');bumpProgress('p6',16);} return; } + gen(); document.getElementById('p6-ri').textContent=i+1; document.getElementById('p6-rq').innerHTML='Масштаб $1:'+cur.N+'$. Реальное расстояние $'+cur.m+'$ м. Длина на карте в см?'; renderMath(document.getElementById('p6-rq')); + document.getElementById('p6-ra').value=''; document.getElementById('p6-rfb').style.display='none'; } + function go(){ if(i>=5)return; var fb=document.getElementById('p6-rfb'), v=parseFloat(document.getElementById('p6-ra').value.replace(',','.').trim()); + if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; } + if(Math.abs(v-cur.ans)<1e-9){ score++; feedback(fb,true,'✓ Верно: '+_kf(cur.ans)+' см.'); } else feedback(fb,false,'✗ Нет. '+cur.m+' м = '+(cur.m*100)+' см; делим на '+cur.N+' → '+_kf(cur.ans)+' см.'); + document.getElementById('p6-rs').textContent=score; i++; setTimeout(show,1400); } + document.getElementById('p6-rgo').addEventListener('click',go); + document.getElementById('p6-ra').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); }); show(); + })(); +} + +/* ===================== § 7. КРУГОВЫЕ ДИАГРАММЫ ===================== */ +function buildP7(){ + var box=document.getElementById('p7-body'); var h=''; + h+=makeCard('theory','Круговая диаграмма','7.1', + '

Круговая диаграмма наглядно показывает, как целое делится на части. Весь круг — это $100\\%$, или $360°$.

' + +'

Сектор в $p\\%$ занимает угол $p\\%\\cdot 360° = 3{,}6\\cdot p$ градусов. Например, $25\\%$ — это $90°$ (четверть круга).

'); + h+='
Интерактив 1
Диаграмма данных
' + +'
Выбери набор данных — построится круговая диаграмма с долями.
' + +'
' + +'
'; + h+='
Интерактив 2
Проценты и градусы
' + +'
Переведи долю сектора между процентами и градусами ($1\\% = 3{,}6°$).
' + +'
Вопрос 1 / 6Очки: 0 / 6
' + +'
' + +'
' + +'
'; + h+=secNav('p6','app')+readBtn('p7'); + box.innerHTML=h; renderMath(box); + + (function(){ + var DS=[ + {name:'Рацион (БЖУ)', segs:[{label:'Углеводы',value:66},{label:'Жиры',value:17},{label:'Белки',value:17}]}, + {name:'Оценки класса', segs:[{label:'«9–10»',value:30},{label:'«7–8»',value:45},{label:'«5–6»',value:25}]}, + {name:'Сутки школьника', segs:[{label:'Сон',value:33},{label:'Учёба',value:25},{label:'Отдых',value:42}]} + ]; + var pick=document.getElementById('p7-pick'), fig=document.getElementById('p7-fig'), leg=document.getElementById('p7-leg'); + var pal=['#4f46e5','#0891b2','#e11d48','#059669','#d97706']; + pick.innerHTML=DS.map(function(d,k){ return ''; }).join(''); + function render(k){ var d=DS[k]; fig.innerHTML=Math6.pie(d.segs,{size:200}); + leg.innerHTML=d.segs.map(function(s,j){ return '
'+s.label+' — '+s.value+'%
'; }).join(''); } + pick.querySelectorAll('[data-k]').forEach(function(b){ b.addEventListener('click',function(){ pick.querySelectorAll('button').forEach(function(x){x.classList.remove('primary');}); b.classList.add('primary'); render(+b.getAttribute('data-k')); }); }); + render(0); + })(); + + (function(){ + var i=0,score=0,cur=null; + function gen(){ if(_pick([true,false])){ var p=_pick([10,20,25,50,75]); cur={q:'Сектор $'+p+'\\%$ — сколько это градусов?', ans:_round(p*3.6,1)}; } else { var g=_pick([36,72,90,180,270]); cur={q:'Сектор $'+g+'°$ — сколько это процентов?', ans:_round(g/3.6,1)}; } } + function show(){ if(i>=6){ document.getElementById('p7-q').innerHTML='Готово! '+score+' / 6'; if(score>=5){addXp(15,'p7-iv2');bumpProgress('p7',30);}else if(score>=3){addXp(8,'p7-iv2');bumpProgress('p7',16);} return; } + gen(); 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=parseFloat(document.getElementById('p7-a').value.replace(',','.').replace('%','').trim()); + if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; } + if(Math.abs(v-cur.ans)<0.051){ score++; feedback(fb,true,'✓ Верно: '+_kf(cur.ans)+'.'); } else feedback(fb,false,'✗ Нет. Правильно: '+_kf(cur.ans)+'.'); + document.getElementById('p7-s').textContent=score; i++; setTimeout(show,1300); } + document.getElementById('p7-go').addEventListener('click',go); + document.getElementById('p7-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); }); show(); + })(); +} + +/* ===================== § 9. МАТЕМАТИКА ВОКРУГ НАС ===================== */ +function buildApp(){ + var box=document.getElementById('app-body'); var h=''; + h+=makeCard('theory','Проценты вокруг нас','9.1', + '

Скидки и распродажи, наценки, банковские вклады под проценты, состав продуктов, статистика и опросы — везде встречаются проценты и пропорции.

'); + h+='
Интерактив 1
Задачи из жизни
' + +'
Реши практическую задачу на проценты. Ответ — число (рубли, штуки, проценты).
' + +'
Задача 1 / 6Очки: 0 / 6
' + +'
' + +'
' + +'
'; + h+=secNav('p7','final')+readBtn('app'); + box.innerHTML=h; renderMath(box); + + (function(){ + var P=[ + {q:'Товар стоил 200 руб. Скидка 10%. Новая цена (руб.)?',a:180}, + {q:'Куртка 800 руб., скидка 25%. Сколько рублей скидка?',a:200}, + {q:'Вклад 1000 руб. под 5% годовых. Сколько рублей процентов за год?',a:50}, + {q:'В магазине 60 товаров, 20% распроданы. Сколько товаров продано?',a:12}, + {q:'Цена выросла с 50 руб. на 20%. Новая цена (руб.)?',a:60}, + {q:'Из 40 учеников 30% занимаются спортом. Сколько это человек?',a:12}, + {q:'Билет 500 руб., детям скидка 40%. Сколько платит ребёнок (руб.)?',a:300} + ]; + var order=P.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;} + var i=0,score=0,cur=null; + function show(){ if(i>=6){ document.getElementById('app-q').innerHTML='Готово! '+score+' / 6'; if(score>=5){addXp(15,'app-iv1');bumpProgress('app',35);}else if(score>=3){addXp(8,'app-iv1');bumpProgress('app',18);} return; } + cur=P[order[i]]; document.getElementById('app-i').textContent=i+1; document.getElementById('app-q').innerHTML=cur.q; + document.getElementById('app-a').value=''; document.getElementById('app-fb').style.display='none'; } + function go(){ if(i>=6)return; var fb=document.getElementById('app-fb'), v=parseFloat(document.getElementById('app-a').value.replace(',','.').trim()); + if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; } + if(Math.abs(v-cur.a)<1e-9){ score++; feedback(fb,true,'✓ Верно: '+cur.a+'.'); } else feedback(fb,false,'✗ Нет. Правильно: '+cur.a+'.'); + document.getElementById('app-s').textContent=score; i++; setTimeout(show,1300); } + document.getElementById('app-go').addEventListener('click',go); + document.getElementById('app-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); }); show(); + })(); +} + +/* ===================== ФИНАЛ ГЛАВЫ — БОССЫ ===================== */ +function buildFinal(){ + var box=document.getElementById('final-body'); var h=''; + h+=makeCard('theory','Финал главы 2','★','

Пять боссов проверят проценты, пропорции, масштаб и круговые диаграммы. Победи всех!

'); + h+='
Боссы
Сразись с главой 2
' + +'
' + +'
Босс 1 / 5Побеждено: 0 / 5
' + +'
' + +'
' + +'
' + +'
'; + h+=secNav('app',null)+readBtn('final','Завершить главу 2 (+10 XP)'); + box.innerHTML=h; renderMath(box); + + (function(){ + var bosses=[ + function(){ var a=_pick([40,60,80,200]), m=_pick([10,20,25,5]); return {name:'Процентщик', q:'Найди $'+m+'\\%$ от $'+a+'$.', ans:a*m/100}; }, + function(){ var b=_pick([10,20,30]), a=_pick([40,50,200]); return {name:'Аналитик', q:'Какой процент число $'+b+'$ составляет от $'+a+'$?', ans:_round(b/a*100,2)}; }, + function(){ var aa=_ri(2,6),bb=_ri(2,8),m=_ri(2,5); return {name:'Пропорция', q:'Реши пропорцию $'+aa+':'+bb+' = '+(aa*m)+':x$. Найди $x$.', ans:bb*m}; }, + function(){ var N=_pick([500,1000,2000]), d=_ri(2,8); return {name:'Картограф', q:'Масштаб $1:'+N+'$. На карте $'+d+'$ см. Реальное расстояние в метрах?', ans:d*N/100}; }, + function(){ var p=_pick([10,20,25,50]); return {name:'Диаграмма', q:'Сектор $'+p+'\\%$ — сколько это градусов?', ans:_round(p*3.6,1)}; } + ]; + 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?'Победа! Глава 2 пройдена. ':'Бой окончен. ')+'Побеждено боссов: '+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)<0.051){ score++; feedback(fb,true,'✓ Босс повержен! Ответ '+_kf(cur.ans)+'.'); } else feedback(fb,false,'✗ Босс устоял. Верно: '+_kf(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:[ ['Процент','$1\\%=\\frac{1}{100}=0{,}01$'], ['$\\%\\to$ дробь','делим на 100'], ['дробь $\\to\\%$','умножаем на 100'], ['Всё число','$100\\%$'] ]}, + p2:{ title:'Шпаргалка § 2', rows:[ ['% от числа','$b=\\frac{a}{100}\\cdot m$'], ['число по %','$a=\\frac{b}{m}\\cdot100$'], ['% отношение','$m\\%=\\frac{b}{a}\\cdot100\\%$'] ]}, + p3:{ title:'Шпаргалка § 3', rows:[ ['Отношение','$a:b=\\frac{a}{b}$'], ['Пропорция','$a:b=c:d$'], ['Осн. свойство','$a\\cdot d=b\\cdot c$'], ['Неизвестный','$x=\\frac{b\\cdot c}{a}$'] ]}, + p4:{ title:'Шпаргалка § 4', rows:[ ['Прямая','$\\frac{y}{x}=k$ (вместе растут)'], ['Обратная','$x\\cdot y=k$ (одна растёт — другая падает)'] ]}, + p5:{ title:'Шпаргалка § 5', rows:[ ['Прямая','стрелки в одну сторону'], ['Обратная','одно отношение переворачиваем'], ['Решаем','крест-накрест'] ]}, + p6:{ title:'Шпаргалка § 6', rows:[ ['Масштаб $1:N$','1 см карты = $N$ см реально'], ['Карта → реал','$\\times N$'], ['Реал → карта','$\\div N$'], ['1 м','$=100$ см'] ]}, + p7:{ title:'Шпаргалка § 7', rows:[ ['Весь круг','$100\\%=360°$'], ['$p\\%$ сектора','$=3{,}6\\cdot p$ градусов'], ['$25\\%$','$=90°$'] ]}, + app:{ title:'Шпаргалка § 9', rows:[ ['Скидка','цена $\\times$ (1 − %/100)'], ['Наценка','цена $\\times$ (1 + %/100)'], ['Проценты вклада','$\\frac{вклад}{100}\\cdot$ ставка'] ]}, + final:{ title:'Финал главы 2', rows:[ ['5 боссов','проценты, пропорции, масштаб, диаграммы'], ['Победа','4 из 5 и больше'], ['Награда','+40 XP и достижение «Глава 2 пройдена»'] ]} +}; +var TIPS = [ + { sec:'p1', html:'Процент — это сотая. Чтобы перевести проценты в дробь, просто сдвинь запятую на 2 знака влево: $7\\%=0{,}07$.' }, + { sec:'p2', html:'Определи тип задачи: ищешь часть от числа (тип 1), само число (тип 2) или сколько процентов (тип 3) — и примени нужную формулу.' }, + { sec:'p3', html:'Основное свойство: перемножь «крест-накрест». Неизвестный член $x=\\frac{b\\cdot c}{a}$ — произведение средних делить на известный крайний.' }, + { sec:'p4', html:'Прямая: «больше — больше» (отношение постоянно). Обратная: «больше — меньше» (произведение постоянно).' }, + { sec:'p5', html:'Запиши условие в две строки. Если зависимость обратная — переверни одно из отношений перед тем, как решать крест-накрест.' }, + { sec:'p6', html:'$1:N$ — карта в $N$ раз меньше. Из карты в реальность умножай на $N$; не забудь перевести см в метры (делить на 100).' }, + { sec:'p7', html:'Весь круг = $360°$ = $100\\%$. Значит $1\\%=3{,}6°$. Чтобы из процентов получить градусы — умножь на $3{,}6$.' } +]; +var GLOSSARY = [ + { term:'процент', def:'Сотая доля числа: $1\\%=\\frac{1}{100}$.', sec:'p1', aliases:['процент','процента','процентов','проценты','процентах'] }, + { term:'пропорция', def:'Равенство двух отношений: $a:b=c:d$.', sec:'p3', aliases:['пропорция','пропорции','пропорцию','пропорций'] }, + { term:'отношение', def:'Частное двух чисел $a:b=\\frac{a}{b}$.', sec:'p3', aliases:['отношение','отношения','отношении'] }, + { term:'крайние члены', def:'Первый и последний члены пропорции ($a$ и $d$).', sec:'p3', aliases:['крайние члены','крайних членов','крайние'] }, + { term:'средние члены', def:'Второй и третий члены пропорции ($b$ и $c$).', sec:'p3', aliases:['средние члены','средних членов','средние'] }, + { term:'прямая пропорциональность', def:'Зависимость, при которой отношение величин постоянно ($y/x=k$).', sec:'p4', aliases:['прямая пропорциональность','прямо пропорциональны','прямой пропорциональности'] }, + { term:'обратная пропорциональность', def:'Зависимость, при которой произведение величин постоянно ($xy=k$).', sec:'p4', aliases:['обратная пропорциональность','обратно пропорциональны','обратной пропорциональности'] }, + { term:'масштаб', def:'Отношение длины на карте к реальной длине; $1:N$.', sec:'p6', aliases:['масштаб','масштаба','масштабе','масштабом'] }, + { term:'круговая диаграмма', def:'Диаграмма-круг, показывающая доли целого; весь круг $=360°=100\\%$.', sec:'p7', aliases:['круговая диаграмма','круговой диаграммы','круговую диаграмму','диаграмма','диаграммы'] } +]; +var BUILDERS = { p1:buildP1, p2:buildP2, p3:buildP3, p4:buildP4, p5:buildP5, p6:buildP6, p7:buildP7, app:buildApp, final:buildFinal }; +Object.assign(window.M6, { sidebars:SIDEBARS, tips:TIPS, glossary:GLOSSARY, builders:BUILDERS });