From dcdcde5b4e2595e715df034e91c65bb4c2d704a4 Mon Sep 17 00:00:00 2001 From: Maxim Dolgolyov Date: Sat, 30 May 2026 08:55:00 +0300 Subject: [PATCH] =?UTF-8?q?fix(textbooks):=20=D0=A4=D0=B8=D0=B7=D0=B8?= =?UTF-8?q?=D0=BA=D0=B0=209=20=E2=80=94=20escape=20=C2=A7=20=D0=B2=20num?= =?UTF-8?q?=20+=20phys9=5Flegacy.js=20+=20=D1=84=D0=B8=D0=BD=D0=B0=D0=BB?= =?UTF-8?q?=D1=8B=205=20=D0=B3=D0=BB=D0=B0=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Багфиксы: - gen_phys9_ch.js: убран двойной escape \u00a7 → литерал § (раньше карточка показывала '\u00a7 1' вместо '§ 1') - phys9_legacy.js (262 КБ): извлечён весь JS монолита для глобальных onclick- обработчиков (startAnim1, lab11add/all/reset, checkNum, togglePend36 и пр.). Setup-код в конце обёрнут в try/catch — он рассчитан на DOM монолита. - migrate_phys9_ch4.js + migrate_phys9_content.js: подключают phys9_legacy.js во все 5 ch-файлов перед закрытием . Финалы глав (write_phys9_finals.js): - ch1: 5 задач (кинематика — поезд, разгон, окружность, лодка/река) - ch2: 5 задач (динамика — трение, Гук, свободное падение, перегрузка) - ch3: 5 задач (статика — рычаг, Архимед, блок, КПД накл. плоск., льдина) - ch4: 5 задач (импульс — неупр. удар, ЗСЭ, мощность крана, пуля, бросок) - ch5: 5 контрольных по практикуму (среднее, ЛР2, ЛР4, ЛР6, ЛР10) Все задачи с автопроверкой через checkNum() (теперь работает из legacy.js). --- backend/scripts/gen_phys9_ch.js | 2 +- backend/scripts/migrate_phys9_ch4.js | 9 + backend/scripts/migrate_phys9_content.js | 14 + backend/scripts/write_phys9_finals.js | 386 ++ frontend/js/phys9_legacy.js | 5859 ++++++++++++++++++++++ frontend/textbooks/physics_9_ch1.html | 97 +- frontend/textbooks/physics_9_ch2.html | 89 +- frontend/textbooks/physics_9_ch3.html | 81 +- frontend/textbooks/physics_9_ch4.html | 81 +- frontend/textbooks/physics_9_ch5.html | 69 +- 10 files changed, 6625 insertions(+), 62 deletions(-) create mode 100644 backend/scripts/write_phys9_finals.js create mode 100644 frontend/js/phys9_legacy.js diff --git a/backend/scripts/gen_phys9_ch.js b/backend/scripts/gen_phys9_ch.js index 766018e..a24eb8d 100644 --- a/backend/scripts/gen_phys9_ch.js +++ b/backend/scripts/gen_phys9_ch.js @@ -321,7 +321,7 @@ function buildCh(chKey) { return ` { id:${JSON.stringify(pid)}, num:'\\u2605', name:'Финал главы', sub:${JSON.stringify('Итоги · боссы главы ' + C.chNum)}, final:true }`; } const sub = subOf(pid); - const num = pid.startsWith('lr') ? `ЛР ${pid.slice(2)}` : `\\u00a7 ${pid.slice(1)}`; + const num = pid.startsWith('lr') ? `ЛР ${pid.slice(2)}` : `§ ${pid.slice(1)}`; return ` { id:${JSON.stringify(pid)}, num:${JSON.stringify(num)}, name:${JSON.stringify(nameOf(pid))}, sub:${JSON.stringify(sub)} }`; }).join(',\n'); diff --git a/backend/scripts/migrate_phys9_ch4.js b/backend/scripts/migrate_phys9_ch4.js index 63c8575..046924b 100644 --- a/backend/scripts/migrate_phys9_ch4.js +++ b/backend/scripts/migrate_phys9_ch4.js @@ -120,6 +120,15 @@ if (!ch4.includes('font-awesome')) { console.log('Font Awesome CDN linked'); } +// === 8. phys9_legacy.js === +if (!ch4.includes('phys9_legacy.js')) { + ch4 = ch4.replace( + '', + '\n' + ); + console.log('phys9_legacy.js linked'); +} + fs.writeFileSync(DST, ch4); console.log('OK ch4 →', DST, 'bytes:', ch4.length); diff --git a/backend/scripts/migrate_phys9_content.js b/backend/scripts/migrate_phys9_content.js index 8f47e57..f2c2bbf 100644 --- a/backend/scripts/migrate_phys9_content.js +++ b/backend/scripts/migrate_phys9_content.js @@ -155,6 +155,14 @@ function migrateChapter(chN, paraNums) { ); } + // phys9_legacy.js (provides startAnim1, lab11*, checkNum, togglePend36, etc.) + if (!h.includes('phys9_legacy.js')) { + h = h.replace( + '', + '\n' + ); + } + fs.writeFileSync(dstPath, h); console.log(`ch${chN}: ${before} → ${h.length} bytes`); @@ -204,6 +212,12 @@ function migrateCh5(chN = 5) { '\n' ); } + if (!h.includes('phys9_legacy.js')) { + h = h.replace( + '', + '\n' + ); + } fs.writeFileSync(dstPath, h); console.log(`ch5: ${before} → ${h.length} bytes`); diff --git a/backend/scripts/write_phys9_finals.js b/backend/scripts/write_phys9_finals.js new file mode 100644 index 0000000..8a8ef73 --- /dev/null +++ b/backend/scripts/write_phys9_finals.js @@ -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: ` +
+

Равномерное движение

+
$\\vec{v} = \\text{const}$
+

$\\Delta\\vec{r} = \\vec{v}\\,t$ · $x = x_0 + v_x t$ · $s = vt$

+
+

Равноускоренное

+
$\\vec{v} = \\vec{v}_0 + \\vec{a}\\,t$
+

$\\Delta\\vec{r} = \\vec{v}_0 t + \\dfrac{\\vec{a} t^2}{2}$ · $v^2 - v_0^2 = 2a_x\\Delta x$

+
+

По окружности

+
$a_n = \\dfrac{v^2}{R} = \\omega^2 R$
+

$\\omega = \\dfrac{2\\pi}{T} = 2\\pi\\nu$ · $v = \\omega R$

+
+
+ +
Интегрированные задачи
+ +
+
Задача 1
+
Автомобиль за $t_1 = 20$ с разгоняется до $v_1 = 20$ м/с, далее едет $t_2 = 60$ с с постоянной скоростью. Найдите средний модуль скорости за всё время движения. Начальная скорость $v_0 = 0$.
+
Сложите путь на каждом участке: $s_1 = v_1 t_1 / 2$, $s_2 = v_1 t_2$. Средняя $\\langle v\\rangle = (s_1 + s_2)/(t_1 + t_2)$.
+
м/с +
+ +
+ +
+
Задача 2
+
Тело движется с ускорением $a = 2$ м/с². Через $t = 5$ с его скорость стала $v = 14$ м/с. Найдите начальную скорость тела.
+
$v = v_0 + at$, откуда $v_0 = v - at$.
+
м/с +
+ +
+ +
+
Задача 3
+
Шарик движется по окружности радиуса $R = 0{,}5$ м с периодом $T = 2{,}0$ с. Найдите модуль центростремительного ускорения.
+
$a_n = \\dfrac{4\\pi^2 R}{T^2}$. Подставьте $\\pi \\approx 3{,}14$.
+
м/с² +
+ +
+ +
+
Задача 4
+
Катер движется по реке со скоростью $v_к = 5$ м/с относительно воды. Скорость течения $v_р = 2$ м/с. Найдите модуль скорости катера относительно берега при движении против течения.
+
Против течения скорости вычитаются: $v = v_к - v_р$.
+
м/с +
+ +
+ +
+
Задача 5 (повышенный уровень)
+
Поезд проходит мимо пешехода за $t_1 = 8$ с, а мимо платформы длиной $L = 200$ м — за $t_2 = 18$ с. Найдите скорость поезда. Поезд движется равномерно.
+
За $t_1$ поезд проходит свою длину $\\ell$, за $t_2$ — $\\ell + L$. Имеем $\\ell = v t_1$ и $\\ell + L = v t_2$. Отсюда $v = L/(t_2 - t_1)$.
+
м/с +
+ +
+`, +}, + +ch2: { + title: 'Финал главы 2', + num: '★', + body: ` +
+

Законы Ньютона

+
$\\vec{F} = m\\vec{a}$
+

1-й: ИСО; 2-й: $\\vec{a} = \\vec{F}/m$; 3-й: $\\vec{F}_{12} = -\\vec{F}_{21}$

+
+

Силы

+
$F_{\\text{упр}} = -kx$, $F_{\\text{тр}} = \\mu N$
+

Тяжести: $mg$ · Гравит.: $F = G m_1 m_2/r^2$

+
+

Вес

+
$P = m(g \\pm a)$
+

Свободное падение → $P = 0$ (невесомость)

+
+
+ +
Интегрированные задачи
+ +
+
Задача 1
+
На тело массой $m = 2$ кг действует сила $F = 10$ Н в горизонтальном направлении. Сила трения $F_{\\text{тр}} = 4$ Н. Найдите модуль ускорения тела.
+
Равнодействующая $F_{\\text{рез}} = F - F_{\\text{тр}}$, ускорение $a = F_{\\text{рез}}/m$.
+
м/с² +
+ +
+ +
+
Задача 2
+
Под действием груза пружина с жёсткостью $k = 200$ Н/м растянулась на $x = 5$ см. Найдите массу груза. $g = 9{,}81$ м/с².
+
В равновесии $kx = mg$, отсюда $m = kx/g$.
+
кг +
+ +
+ +
+
Задача 3
+
Брусок массой $m = 5$ кг скользит по горизонтальной поверхности с коэффициентом трения $\\mu = 0{,}3$. Найдите силу трения скольжения. $g = 10$ м/с².
+
$F_{\\text{тр}} = \\mu mg$.
+
Н +
+ +
+ +
+
Задача 4
+
Тело свободно падает с высоты $h = 45$ м. Найдите время падения. $g = 10$ м/с².
+
$h = gt^2/2$, отсюда $t = \\sqrt{2h/g}$.
+
с +
+ +
+ +
+
Задача 5 (повышенный уровень)
+
Космонавт массой $m = 80$ кг стоит на полу лифта. Лифт движется вверх с ускорением $a = 2{,}0$ м/с². Найдите вес космонавта. $g = 10$ м/с².
+
$P = m(g + a)$ при движении вверх с положительным ускорением (перегрузка).
+
Н +
+ +
+`, +}, + +ch3: { + title: 'Финал главы 3', + num: '★', + body: ` +
+

Равновесие

+
$\\sum\\vec{F} = 0$ и $\\sum M = 0$
+

Момент: $M = F \\cdot \\ell$ (плечо)

+
+

Простые механизмы

+
$F_1 \\ell_1 = F_2 \\ell_2$
+

Рычаг · подв. блок (выигрыш в 2 раза) · накл. плоскость

+
+

Архимед

+
$F_A = \\rho_ж g V_{\\text{погр}}$
+

КПД: $\\eta = A_{\\text{пол}}/A_{\\text{сов}} \\cdot 100\\%$

+
+
+ +
Интегрированные задачи
+ +
+
Задача 1
+
Рычаг в равновесии. На левое плечо длиной $\\ell_1 = 0{,}3$ м действует сила $F_1 = 60$ Н. Правое плечо длиной $\\ell_2 = 0{,}9$ м. Найдите силу $F_2$ на правом плече.
+
$F_1 \\ell_1 = F_2 \\ell_2$, отсюда $F_2 = F_1 \\ell_1 / \\ell_2$.
+
Н +
+ +
+ +
+
Задача 2
+
Куб со стороной $a = 10$ см полностью погружён в воду. Плотность воды $\\rho = 1000$ кг/м³, $g = 10$ м/с². Найдите выталкивающую силу.
+
$V = a^3$, $F_A = \\rho g V$.
+
Н +
+ +
+ +
+
Задача 3
+
Подвижный блок поднимает груз весом $P = 200$ Н на высоту $h_1 = 1$ м. Найдите силу тяги $F$, прикладываемую к нити (без учёта трения и веса блока).
+
Подвижный блок даёт выигрыш в силе в 2 раза: $F = P/2$.
+
Н +
+ +
+ +
+
Задача 4
+
Тело весом $P = 50$ Н поднимают по наклонной плоскости длиной $\\ell = 3$ м на высоту $h = 1$ м. Сила тяги $F = 20$ Н. Найдите КПД наклонной плоскости.
+
$A_{\\text{пол}} = Ph$, $A_{\\text{сов}} = F\\ell$, $\\eta = A_{\\text{пол}}/A_{\\text{сов}} \\cdot 100\\%$.
+
% +
+ +
+ +
+
Задача 5 (повышенный уровень)
+
Льдина имеет объём $V = 2{,}0$ м³ и плавает в пресной воде. Плотность льда $\\rho_л = 900$ кг/м³, воды $\\rho_в = 1000$ кг/м³. Какой объём льдины находится над водой?
+
Условие плавания: $mg = F_A$, откуда $\\rho_л V g = \\rho_в V_{\\text{погр}} g$. Объём над водой: $V - V_{\\text{погр}}$.
+
м³ +
+ +
+`, +}, + +ch4: { + title: 'Финал главы 4', + num: '★', + body: ` +
+

Импульс

+
$\\vec{p} = m\\vec{v}$
+

ЗСИ: $\\sum\\vec{p}_{\\text{до}} = \\sum\\vec{p}_{\\text{после}}$

+
+

Работа · мощность

+
$A = F\\Delta r\\cos\\alpha$
+

$P = A/\\Delta t$ · $E_к = mv^2/2$ · $E_п = mgh$

+
+

ЗСЭ

+
$E_к + E_п = \\text{const}$
+

В замкнутой консерв. сист. полная мех. энергия сохраняется

+
+
+ +
Интегрированные задачи
+ +
+
Задача 1
+
Тележка массой $m_1 = 3$ кг движется со скоростью $v_1 = 4$ м/с и сталкивается с покоящейся тележкой массой $m_2 = 1$ кг. После сцепления они движутся вместе. Найдите их общую скорость.
+
ЗСИ: $m_1 v_1 = (m_1 + m_2) v$, отсюда $v = m_1 v_1 / (m_1 + m_2)$.
+
м/с +
+ +
+ +
+
Задача 2
+
Тело массой $m = 2$ кг падает с высоты $h = 5$ м без начальной скорости. Найдите кинетическую энергию тела в момент удара о землю (сопротивлением воздуха пренебречь). $g = 10$ м/с².
+
ЗСЭ: вся потенциальная энергия переходит в кинетическую. $E_к = mgh$.
+
Дж +
+ +
+ +
+
Задача 3
+
Подъёмный кран поднимает груз массой $m = 500$ кг на высоту $h = 12$ м за $t = 30$ с. Найдите среднюю мощность крана. $g = 10$ м/с².
+
$A = mgh$, $P = A/t$.
+
Вт +
+ +
+ +
+
Задача 4
+
Пуля массой $m = 10$ г летит со скоростью $v = 400$ м/с. Найдите модуль её импульса.
+
$p = mv$. Не забудьте перевести массу в кг.
+
кг·м/с +
+ +
+ +
+
Задача 5 (повышенный уровень)
+
Камень бросают вертикально вверх со скоростью $v_0 = 20$ м/с. На какой высоте $h$ кинетическая энергия камня станет в 3 раза меньше начальной? $g = 10$ м/с².
+
ЗСЭ: $\\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}$.
+
м +
+ +
+`, +}, + +ch5: { + title: 'Финал главы 5', + num: '★', + body: ` +
+

Погрешности

+
$\\Delta x = \\Delta x_{\\text{сист}} + \\Delta x_{\\text{случ}}$
+

$\\varepsilon_x = \\dfrac{\\Delta x}{\\langle x\\rangle}\\cdot 100\\%$ · итог: $x = \\langle x\\rangle \\pm \\Delta x$

+
+

Ключевые формулы 12 ЛР

+
$a = \\dfrac{2l}{t^2}$, $\\mu = \\dfrac{F_{\\text{тр}}}{P}$, $F_A = F_1 - F_2$
+

$k = F/x$ · $\\eta = \\dfrac{A_{\\text{пол}}}{A_{\\text{сов}}}$ · $v_0 = l\\sqrt{g/(2h)}$

+
+

Проверка законов

+
ЗСИ · ЗСЭ · условие равновесия
+

ЛР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)$

+
+
+ +
Контрольные вопросы по практикуму
+ +
+
Вопрос 1
+
При пяти повторных измерениях времени получены значения: $4{,}8$ · $5{,}0$ · $5{,}2$ · $4{,}9$ · $5{,}1$ с. Найдите среднее значение $\\langle t\\rangle$.
+
$\\langle t\\rangle = (t_1 + t_2 + t_3 + t_4 + t_5)/5$.
+
с +
+ +
+ +
+
Вопрос 2
+
В ЛР2 шарик прошёл по жёлобу длину $l = 0{,}80$ м за $t = 1{,}0$ с. Найдите модуль ускорения шарика.
+
$a = 2l/t^2$.
+
м/с² +
+ +
+ +
+
Вопрос 3
+
В ЛР4 при подвешивании груза массой $m = 0{,}2$ кг пружина растянулась на $x = 4$ см. Найдите жёсткость пружины. $g = 10$ м/с².
+
$k = mg/x$.
+
Н/м +
+ +
+ +
+
Вопрос 4
+
В ЛР6 шарик упал на пол с высоты $h = 0{,}8$ м, пройдя по горизонтали $l = 1{,}6$ м. Найдите начальную горизонтальную скорость шарика. $g = 10$ м/с².
+
$v_0 = l\\sqrt{g/(2h)}$. Подставьте численно.
+
м/с +
+ +
+ +
+
Вопрос 5
+
В ЛР10 цилиндр в воздухе весил $F_1 = 1{,}0$ Н, а полностью погружённый в воду — $F_2 = 0{,}6$ Н. Найдите модуль выталкивающей силы.
+
$F_A = F_1 - F_2$.
+
Н +
+ +
+`, +}, + +}; + +// === Замена 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(/ +