@@ -0,0 +1,386 @@
// Заполняет final1..final5 в physics_9_ch1..ch5.html — итоги главы:
// шпаргалка ключевых формул + 4-5 интегрированных задач с автопроверкой.
// Использует существующую функцию checkNum() из phys9_legacy.js для автопроверки.
'use strict' ;
const fs = require ( 'fs' ) ;
const path = require ( 'path' ) ;
const TBOOKS = path . join ( _ _dirname , '..' , '..' , 'frontend' , 'textbooks' ) ;
// === Контент финалов ===
const FINALS = {
ch1 : {
title : 'Финал главы 1' ,
num : '★' ,
body : `
<div class="formula-grid" style="margin-bottom:20px">
<div class="fcard highlight"><h3>Равномерное движение</h3>
<div class="main-f"> $ \\ vec{v} = \\ text{const} $ </div>
<p> $ \\ Delta \\ vec{r} = \\ vec{v} \\ ,t $ · $ x = x_0 + v_x t $ · $ s = vt $ </p>
</div>
<div class="fcard"><h3>Равноускоренное</h3>
<div class="main-f"> $ \\ vec{v} = \\ vec{v}_0 + \\ vec{a} \\ ,t $ </div>
<p> $ \\ Delta \\ vec{r} = \\ vec{v}_0 t + \\ dfrac{ \\ vec{a} t^2}{2} $ · $ v^2 - v_0^2 = 2a_x \\ Delta x $ </p>
</div>
<div class="fcard"><h3>По окружности</h3>
<div class="main-f"> $ a_n = \\ dfrac{v^2}{R} = \\ omega^2 R $ </div>
<p> $ \\ omega = \\ dfrac{2 \\ pi}{T} = 2 \\ pi \\ nu $ · $ v = \\ omega R $ </p>
</div>
</div>
<div class="section-title"><i class="fas fa-star"></i> Интегрированные задачи</div>
<div class="task-card">
<div class="task-num">Задача 1</div>
<div class="task-text">Автомобиль за $ t_1 = 20 $ с разгоняется до $ v_1 = 20 $ м/с , далее едет $ t_2 = 60 $ с с постоянной скоростью. Найдите средний модуль скорости за всё время движения. Начальная скорость $ v_0 = 0 $ .</div>
<div class="task-hint">Сложите путь на каждом участке: $ s_1 = v_1 t_1 / 2 $ , $ s_2 = v_1 t_2 $ . Средняя $ \\ langle v \\ rangle = (s_1 + s_2)/(t_1 + t_2) $ .</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin1-q1" step="any"><span class="unit-lbl">м/с </span>
<button class="btn btn-pri" onclick="checkNum('fin1-q1', 17.5, 'м/с ', 0.5)">Проверить</button></div>
<div class="feedback" id="fb-fin1-q1"></div>
</div>
<div class="task-card">
<div class="task-num">Задача 2</div>
<div class="task-text">Тело движется с ускорением $ a = 2 $ м/с². Через $ t = 5 $ с его скорость стала $ v = 14 $ м/с. Найдите начальную скорость тела.</div>
<div class="task-hint"> $ v = v_0 + at $ , откуда $ v_0 = v - at $ .</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin1-q2" step="any"><span class="unit-lbl">м/с </span>
<button class="btn btn-pri" onclick="checkNum('fin1-q2', 4, 'м/с ', 0.1)">Проверить</button></div>
<div class="feedback" id="fb-fin1-q2"></div>
</div>
<div class="task-card">
<div class="task-num">Задача 3</div>
<div class="task-text">Шарик движется по окружности радиуса $ R = 0{,}5 $ м с периодом $ T = 2{,}0 $ с. Найдите модуль центростремительного ускорения.</div>
<div class="task-hint"> $ a_n = \\ dfrac{4 \\ pi^2 R}{T^2} $ . Подставьте $ \\ pi \\ approx 3{,}14 $ .</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin1-q3" step="any"><span class="unit-lbl">м/с²</span>
<button class="btn btn-pri" onclick="checkNum('fin1-q3', 4.93, 'м/с²', 0.1)">Проверить</button></div>
<div class="feedback" id="fb-fin1-q3"></div>
</div>
<div class="task-card">
<div class="task-num">Задача 4</div>
<div class="task-text">Катер движется по реке со скоростью $ v_к = 5 $ м/с относительно воды. Скорость течения $ v_р = 2 $ м/с. Найдите модуль скорости катера относительно берега при движении против течения.</div>
<div class="task-hint">Против течения скорости вычитаются: $ v = v_к - v_р $ .</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin1-q4" step="any"><span class="unit-lbl">м/с </span>
<button class="btn btn-pri" onclick="checkNum('fin1-q4', 3, 'м/с ', 0.05)">Проверить</button></div>
<div class="feedback" id="fb-fin1-q4"></div>
</div>
<div class="task-card">
<div class="task-num">Задача 5 (повышенный уровень)</div>
<div class="task-text">Поезд проходит мимо пешехода за $ t_1 = 8 $ с, а мимо платформы длиной $ L = 200 $ м — за $ t_2 = 18 $ с. Найдите скорость поезда. Поезд движется равномерно.</div>
<div class="task-hint">За $ t_1 $ поезд проходит свою длину $ \\ ell $ , за $ t_2 $ — $ \\ ell + L $ . Имеем $ \\ ell = v t_1 $ и $ \\ ell + L = v t_2 $ . Отсюда $ v = L/(t_2 - t_1) $ .</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin1-q5" step="any"><span class="unit-lbl">м/с </span>
<button class="btn btn-pri" onclick="checkNum('fin1-q5', 20, 'м/с ', 0.1)">Проверить</button></div>
<div class="feedback" id="fb-fin1-q5"></div>
</div>
` ,
} ,
ch2 : {
title : 'Финал главы 2' ,
num : '★' ,
body : `
<div class="formula-grid" style="margin-bottom:20px">
<div class="fcard highlight"><h3>Законы Ньютона</h3>
<div class="main-f"> $ \\ vec{F} = m \\ vec{a} $ </div>
<p>1-й: ИСО; 2-й: $ \\ vec{a} = \\ vec{F}/m $ ; 3-й: $ \\ vec{F}_{12} = - \\ vec{F}_{21} $ </p>
</div>
<div class="fcard"><h3>Силы</h3>
<div class="main-f"> $ F_{ \\ text{упр}} = -kx $ , $ F_{ \\ text{тр}} = \\ mu N $ </div>
<p>Тяжести: $ mg $ · Гравит.: $ F = G m_1 m_2/r^2 $ </p>
</div>
<div class="fcard"><h3>Вес</h3>
<div class="main-f"> $ P = m(g \\ pm a) $ </div>
<p>Свободное падение → $ P = 0 $ (невесомость)</p>
</div>
</div>
<div class="section-title"><i class="fas fa-star"></i> Интегрированные задачи</div>
<div class="task-card">
<div class="task-num">Задача 1</div>
<div class="task-text">На тело массой $ m = 2 $ кг действует сила $ F = 10 $ Н в горизонтальном направлении. Сила трения $ F_{ \\ text{тр}} = 4 $ Н. Найдите модуль ускорения тела.</div>
<div class="task-hint">Равнодействующая $ F_{ \\ text{рез}} = F - F_{ \\ text{тр}} $ , ускорение $ a = F_{ \\ text{рез}}/m $ .</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin2-q1" step="any"><span class="unit-lbl">м/с²</span>
<button class="btn btn-pri" onclick="checkNum('fin2-q1', 3, 'м/с²', 0.05)">Проверить</button></div>
<div class="feedback" id="fb-fin2-q1"></div>
</div>
<div class="task-card">
<div class="task-num">Задача 2</div>
<div class="task-text">Под действием груза пружина с жёсткостью $ k = 200 $ Н/м растянулась на $ x = 5 $ см. Найдите массу груза. $ g = 9{,}81 $ м/с².</div>
<div class="task-hint">В равновесии $ kx = mg $ , отсюда $ m = kx/g $ .</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin2-q2" step="any"><span class="unit-lbl">кг</span>
<button class="btn btn-pri" onclick="checkNum('fin2-q2', 1.02, 'кг', 0.05)">Проверить</button></div>
<div class="feedback" id="fb-fin2-q2"></div>
</div>
<div class="task-card">
<div class="task-num">Задача 3</div>
<div class="task-text">Брусок массой $ m = 5 $ кг скользит по горизонтальной поверхности с коэффициентом трения $ \\ mu = 0{,}3 $ . Найдите силу трения скольжения. $ g = 10 $ м/с².</div>
<div class="task-hint"> $ F_{ \\ text{тр}} = \\ mu mg $ .</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin2-q3" step="any"><span class="unit-lbl">Н </span>
<button class="btn btn-pri" onclick="checkNum('fin2-q3', 15, 'Н ', 0.1)">Проверить</button></div>
<div class="feedback" id="fb-fin2-q3"></div>
</div>
<div class="task-card">
<div class="task-num">Задача 4</div>
<div class="task-text">Тело свободно падает с высоты $ h = 45 $ м. Найдите время падения. $ g = 10 $ м/с².</div>
<div class="task-hint"> $ h = gt^2/2 $ , отсюда $ t = \\ sqrt{2h/g} $ .</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin2-q4" step="any"><span class="unit-lbl">с </span>
<button class="btn btn-pri" onclick="checkNum('fin2-q4', 3, 'с ', 0.05)">Проверить</button></div>
<div class="feedback" id="fb-fin2-q4"></div>
</div>
<div class="task-card">
<div class="task-num">Задача 5 (повышенный уровень)</div>
<div class="task-text">Космонавт массой $ m = 80 $ кг стоит на полу лифта. Лифт движется вверх с ускорением $ a = 2{,}0 $ м/с². Найдите вес космонавта. $ g = 10 $ м/с².</div>
<div class="task-hint"> $ P = m(g + a) $ при движении вверх с положительным ускорением (перегрузка).</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin2-q5" step="any"><span class="unit-lbl">Н </span>
<button class="btn btn-pri" onclick="checkNum('fin2-q5', 960, 'Н ', 5)">Проверить</button></div>
<div class="feedback" id="fb-fin2-q5"></div>
</div>
` ,
} ,
ch3 : {
title : 'Финал главы 3' ,
num : '★' ,
body : `
<div class="formula-grid" style="margin-bottom:20px">
<div class="fcard highlight"><h3>Равновесие</h3>
<div class="main-f"> $ \\ sum \\ vec{F} = 0 $ и $ \\ sum M = 0 $ </div>
<p>Момент: $ M = F \\ cdot \\ ell $ (плечо)</p>
</div>
<div class="fcard"><h3>Простые механизмы</h3>
<div class="main-f"> $ F_1 \\ ell_1 = F_2 \\ ell_2 $ </div>
<p>Рычаг · подв. блок (выигрыш в 2 раза) · накл. плоскость</p>
</div>
<div class="fcard"><h3>Архимед</h3>
<div class="main-f"> $ F_A = \\ rho_ж g V_{ \\ text{погр}} $ </div>
<p>КПД: $ \\ eta = A_{ \\ text{пол}}/A_{ \\ text{сов}} \\ cdot 100 \\ % $ </p>
</div>
</div>
<div class="section-title"><i class="fas fa-star"></i> Интегрированные задачи</div>
<div class="task-card">
<div class="task-num">Задача 1</div>
<div class="task-text">Рычаг в равновесии. На левое плечо длиной $ \\ ell_1 = 0{,}3 $ м действует сила $ F_1 = 60 $ Н. Правое плечо длиной $ \\ ell_2 = 0{,}9 $ м. Найдите силу $ F_2 $ на правом плече.</div>
<div class="task-hint"> $ F_1 \\ ell_1 = F_2 \\ ell_2 $ , отсюда $ F_2 = F_1 \\ ell_1 / \\ ell_2 $ .</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin3-q1" step="any"><span class="unit-lbl">Н </span>
<button class="btn btn-pri" onclick="checkNum('fin3-q1', 20, 'Н ', 0.2)">Проверить</button></div>
<div class="feedback" id="fb-fin3-q1"></div>
</div>
<div class="task-card">
<div class="task-num">Задача 2</div>
<div class="task-text">Куб со стороной $ a = 10 $ см полностью погружён в воду. Плотность воды $ \\ rho = 1000 $ кг/м³, $ g = 10 $ м/с². Найдите выталкивающую силу.</div>
<div class="task-hint"> $ V = a^3 $ , $ F_A = \\ rho g V $ .</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin3-q2" step="any"><span class="unit-lbl">Н </span>
<button class="btn btn-pri" onclick="checkNum('fin3-q2', 10, 'Н ', 0.1)">Проверить</button></div>
<div class="feedback" id="fb-fin3-q2"></div>
</div>
<div class="task-card">
<div class="task-num">Задача 3</div>
<div class="task-text">Подвижный блок поднимает груз весом $ P = 200 $ Н на высоту $ h_1 = 1 $ м. Найдите силу тяги $ F $ , прикладываемую к нити (без учёта трения и веса блока).</div>
<div class="task-hint">Подвижный блок даёт выигрыш в силе в 2 раза: $ F = P/2 $ .</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin3-q3" step="any"><span class="unit-lbl">Н </span>
<button class="btn btn-pri" onclick="checkNum('fin3-q3', 100, 'Н ', 1)">Проверить</button></div>
<div class="feedback" id="fb-fin3-q3"></div>
</div>
<div class="task-card">
<div class="task-num">Задача 4</div>
<div class="task-text">Тело весом $ P = 50 $ Н поднимают по наклонной плоскости длиной $ \\ ell = 3 $ м на высоту $ h = 1 $ м. Сила тяги $ F = 20 $ Н. Найдите КПД наклонной плоскости.</div>
<div class="task-hint"> $ A_{ \\ text{пол}} = Ph $ , $ A_{ \\ text{сов}} = F \\ ell $ , $ \\ eta = A_{ \\ text{пол}}/A_{ \\ text{сов}} \\ cdot 100 \\ % $ .</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin3-q4" step="any"><span class="unit-lbl">%</span>
<button class="btn btn-pri" onclick="checkNum('fin3-q4', 83.3, '%', 1)">Проверить</button></div>
<div class="feedback" id="fb-fin3-q4"></div>
</div>
<div class="task-card">
<div class="task-num">Задача 5 (повышенный уровень)</div>
<div class="task-text">Льдина имеет объём $ V = 2{,}0 $ м³ и плавает в пресной воде. Плотность льда $ \\ rho_л = 900 $ кг/м³, воды $ \\ rho_в = 1000 $ кг/м³. Какой объём льдины находится над водой?</div>
<div class="task-hint">Условие плавания: $ mg = F_A $ , откуда $ \\ rho_л V g = \\ rho_в V_{ \\ text{погр}} g $ . Объём над водой: $ V - V_{ \\ text{погр}} $ .</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin3-q5" step="any"><span class="unit-lbl">м³</span>
<button class="btn btn-pri" onclick="checkNum('fin3-q5', 0.2, 'м³', 0.01)">Проверить</button></div>
<div class="feedback" id="fb-fin3-q5"></div>
</div>
` ,
} ,
ch4 : {
title : 'Финал главы 4' ,
num : '★' ,
body : `
<div class="formula-grid" style="margin-bottom:20px">
<div class="fcard highlight"><h3>Импульс</h3>
<div class="main-f"> $ \\ vec{p} = m \\ vec{v} $ </div>
<p>ЗСИ: $ \\ sum \\ vec{p}_{ \\ text{до}} = \\ sum \\ vec{p}_{ \\ text{после}} $ </p>
</div>
<div class="fcard"><h3>Работа · мощность</h3>
<div class="main-f"> $ A = F \\ Delta r \\ cos \\ alpha $ </div>
<p> $ P = A/ \\ Delta t $ · $ E_к = mv^2/2 $ · $ E_п = mgh $ </p>
</div>
<div class="fcard"><h3>ЗСЭ</h3>
<div class="main-f"> $ E_к + E_п = \\ text{const} $ </div>
<p>В замкнутой консерв. сист. полная мех. энергия сохраняется</p>
</div>
</div>
<div class="section-title"><i class="fas fa-star"></i> Интегрированные задачи</div>
<div class="task-card">
<div class="task-num">Задача 1</div>
<div class="task-text">Тележка массой $ m_1 = 3 $ кг движется со скоростью $ v_1 = 4 $ м/с и сталкивается с покоящейся тележкой массой $ m_2 = 1 $ кг. После сцепления они движутся вместе. Найдите их общую скорость.</div>
<div class="task-hint">ЗСИ: $ m_1 v_1 = (m_1 + m_2) v $ , отсюда $ v = m_1 v_1 / (m_1 + m_2) $ .</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin4-q1" step="any"><span class="unit-lbl">м/с </span>
<button class="btn btn-pri" onclick="checkNum('fin4-q1', 3, 'м/с ', 0.05)">Проверить</button></div>
<div class="feedback" id="fb-fin4-q1"></div>
</div>
<div class="task-card">
<div class="task-num">Задача 2</div>
<div class="task-text">Тело массой $ m = 2 $ кг падает с высоты $ h = 5 $ м без начальной скорости. Найдите кинетическую энергию тела в момент удара о землю (сопротивлением воздуха пренебречь). $ g = 10 $ м/с².</div>
<div class="task-hint">ЗСЭ: вся потенциальная энергия переходит в кинетическую. $ E_к = mgh $ .</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin4-q2" step="any"><span class="unit-lbl">Дж</span>
<button class="btn btn-pri" onclick="checkNum('fin4-q2', 100, 'Дж', 1)">Проверить</button></div>
<div class="feedback" id="fb-fin4-q2"></div>
</div>
<div class="task-card">
<div class="task-num">Задача 3</div>
<div class="task-text">Подъёмный кран поднимает груз массой $ m = 500 $ кг на высоту $ h = 12 $ м за $ t = 30 $ с. Найдите среднюю мощность крана. $ g = 10 $ м/с².</div>
<div class="task-hint"> $ A = mgh $ , $ P = A/t $ .</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin4-q3" step="any"><span class="unit-lbl">Вт</span>
<button class="btn btn-pri" onclick="checkNum('fin4-q3', 2000, 'Вт', 10)">Проверить</button></div>
<div class="feedback" id="fb-fin4-q3"></div>
</div>
<div class="task-card">
<div class="task-num">Задача 4</div>
<div class="task-text">Пуля массой $ m = 10 $ г летит со скоростью $ v = 400 $ м/с. Найдите модуль её импульса.</div>
<div class="task-hint"> $ p = mv $ . Не забудьте перевести массу в кг.</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin4-q4" step="any"><span class="unit-lbl">кг·м/с </span>
<button class="btn btn-pri" onclick="checkNum('fin4-q4', 4, 'кг·м/с ', 0.05)">Проверить</button></div>
<div class="feedback" id="fb-fin4-q4"></div>
</div>
<div class="task-card">
<div class="task-num">Задача 5 (повышенный уровень)</div>
<div class="task-text">Камень бросают вертикально вверх со скоростью $ v_0 = 20 $ м/с. На какой высоте $ h $ кинетическая энергия камня станет в 3 раза меньше начальной? $ g = 10 $ м/с².</div>
<div class="task-hint">ЗСЭ: $ \\ dfrac{mv_0^2}{2} = \\ dfrac{mv^2}{2} + mgh $ . По условию $ \\ dfrac{mv^2}{2} = \\ dfrac{1}{3} \\ dfrac{mv_0^2}{2} $ . Отсюда $ mgh = \\ dfrac{2}{3} \\ dfrac{mv_0^2}{2} $ , т. е . $ h = \\ dfrac{v_0^2}{3g} $ .</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin4-q5" step="any"><span class="unit-lbl">м</span>
<button class="btn btn-pri" onclick="checkNum('fin4-q5', 13.3, 'м', 0.3)">Проверить</button></div>
<div class="feedback" id="fb-fin4-q5"></div>
</div>
` ,
} ,
ch5 : {
title : 'Финал главы 5' ,
num : '★' ,
body : `
<div class="formula-grid" style="margin-bottom:20px">
<div class="fcard highlight"><h3>Погрешности</h3>
<div class="main-f"> $ \\ Delta x = \\ Delta x_{ \\ text{сист}} + \\ Delta x_{ \\ text{случ}} $ </div>
<p> $ \\ varepsilon_x = \\ dfrac{ \\ Delta x}{ \\ langle x \\ rangle} \\ cdot 100 \\ % $ · итог: $ x = \\ langle x \\ rangle \\ pm \\ Delta x $ </p>
</div>
<div class="fcard"><h3>Ключевые формулы 12 ЛР</h3>
<div class="main-f"> $ a = \\ dfrac{2l}{t^2} $ , $ \\ mu = \\ dfrac{F_{ \\ text{тр}}}{P} $ , $ F_A = F_1 - F_2 $ </div>
<p> $ k = F/x $ · $ \\ eta = \\ dfrac{A_{ \\ text{пол}}}{A_{ \\ text{сов}}} $ · $ v_0 = l \\ sqrt{g/(2h)} $ </p>
</div>
<div class="fcard"><h3>Проверка законов</h3>
<div class="main-f">ЗСИ · ЗСЭ · условие равновесия</div>
<p>ЛР7: $ F_1 \\ ell_1 = F_2 \\ ell_2 $ · ЛР11: $ m_1 l_1 = m_1 l_1' + m_2 l_2' $ · ЛР12: $ F|x| = ml^2 g/(2h) $ </p>
</div>
</div>
<div class="section-title"><i class="fas fa-star"></i> Контрольные вопросы по практикуму</div>
<div class="task-card">
<div class="task-num">Вопрос 1</div>
<div class="task-text">При пяти повторных измерениях времени получены значения: $ 4{,}8 $ · $ 5{,}0 $ · $ 5{,}2 $ · $ 4{,}9 $ · $ 5{,}1 $ с. Найдите среднее значение $ \\ langle t \\ rangle $ .</div>
<div class="task-hint"> $ \\ langle t \\ rangle = (t_1 + t_2 + t_3 + t_4 + t_5)/5 $ .</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin5-q1" step="any"><span class="unit-lbl">с </span>
<button class="btn btn-pri" onclick="checkNum('fin5-q1', 5.0, 'с ', 0.02)">Проверить</button></div>
<div class="feedback" id="fb-fin5-q1"></div>
</div>
<div class="task-card">
<div class="task-num">Вопрос 2</div>
<div class="task-text">В ЛР2 шарик прошёл по жёлобу длину $ l = 0{,}80 $ м за $ t = 1{,}0 $ с. Найдите модуль ускорения шарика.</div>
<div class="task-hint"> $ a = 2l/t^2 $ .</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin5-q2" step="any"><span class="unit-lbl">м/с²</span>
<button class="btn btn-pri" onclick="checkNum('fin5-q2', 1.6, 'м/с²', 0.05)">Проверить</button></div>
<div class="feedback" id="fb-fin5-q2"></div>
</div>
<div class="task-card">
<div class="task-num">Вопрос 3</div>
<div class="task-text">В ЛР4 при подвешивании груза массой $ m = 0{,}2 $ кг пружина растянулась на $ x = 4 $ см. Найдите жёсткость пружины. $ g = 10 $ м/с².</div>
<div class="task-hint"> $ k = mg/x $ .</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin5-q3" step="any"><span class="unit-lbl">Н /м</span>
<button class="btn btn-pri" onclick="checkNum('fin5-q3', 50, 'Н /м', 0.5)">Проверить</button></div>
<div class="feedback" id="fb-fin5-q3"></div>
</div>
<div class="task-card">
<div class="task-num">Вопрос 4</div>
<div class="task-text">В ЛР6 шарик упал на пол с высоты $ h = 0{,}8 $ м, пройдя по горизонтали $ l = 1{,}6 $ м. Найдите начальную горизонтальную скорость шарика. $ g = 10 $ м/с².</div>
<div class="task-hint"> $ v_0 = l \\ sqrt{g/(2h)} $ . Подставьте численно.</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin5-q4" step="any"><span class="unit-lbl">м/с </span>
<button class="btn btn-pri" onclick="checkNum('fin5-q4', 4, 'м/с ', 0.1)">Проверить</button></div>
<div class="feedback" id="fb-fin5-q4"></div>
</div>
<div class="task-card">
<div class="task-num">Вопрос 5</div>
<div class="task-text">В ЛР10 цилиндр в воздухе весил $ F_1 = 1{,}0 $ Н, а полностью погружённый в воду — $ F_2 = 0{,}6 $ Н. Найдите модуль выталкивающей силы.</div>
<div class="task-hint"> $ F_A = F_1 - F_2 $ .</div>
<div class="ans-row"><input type="number" class="ans-inp" id="fin5-q5" step="any"><span class="unit-lbl">Н </span>
<button class="btn btn-pri" onclick="checkNum('fin5-q5', 0.4, 'Н ', 0.02)">Проверить</button></div>
<div class="feedback" id="fb-fin5-q5"></div>
</div>
` ,
} ,
} ;
// === Замена STUB в ch-файле ===
for ( const [ chKey , fin ] of Object . entries ( FINALS ) ) {
const chN = parseInt ( chKey . slice ( 2 ) ) ;
const finId = 'final' + chN ;
const dstPath = path . join ( TBOOKS , ` physics_9_ ${ chKey } .html ` ) ;
let h = fs . readFileSync ( dstPath , 'utf8' ) ;
const before = h . length ;
// STUB builder для finalN использует makeCard('theory', 'Финал главы N', '★', `...`)
const stubRegex = new RegExp (
` makeCard \\ ('theory', "Финал главы ${ chN } ", " \\ u2605", \` [ \\ s \\ S]*? \` \\ ); `
) ;
const match = h . match ( stubRegex ) ;
if ( ! match ) {
console . error ( ` Final STUB not found for ${ chKey } (looking for 'Финал главы ${ chN } ') ` ) ;
continue ;
}
// Экранируем для template literal
const esc = fin . body . replace ( /\\/g , '\\\\' ) . replace ( /`/g , '\\`' ) . replace ( /\$\{/g , '\\${' ) ;
const replacement = ` makeCard('theory', "Финал главы ${ chN } ", "★", \` \n ${ esc } \n \` ); ` ;
h = h . replace ( stubRegex , ( ) => replacement ) ;
fs . writeFileSync ( dstPath , h ) ;
console . log ( ` ${ chKey } final: ${ before } → ${ h . length } bytes (+ ${ h . length - before } ) ` ) ;
// Sanity parse
const scripts = [ ... h . matchAll ( /<script>([\s\S]*?)<\/script>/g ) ] ;
for ( const m of scripts ) {
try { new Function ( m [ 1 ] ) ; }
catch ( e ) { console . error ( ` JS PARSE FAIL in ${ chKey } : ` , e . message ) ; process . exit ( 1 ) ; }
}
}
console . log ( 'Finals written.' ) ;