diff --git a/backend/src/db/migrations/050_math5_hub.sql b/backend/src/db/migrations/050_math5_hub.sql new file mode 100644 index 0000000..9b36a8b --- /dev/null +++ b/backend/src/db/migrations/050_math5_hub.sql @@ -0,0 +1,36 @@ +-- Math 5 hub migration. +-- Creates math-5 as a full hub textbook (3 chapters) in the style of math-6: +-- math-5 (hub, html_path = math_5_hub.html) +-- math-5-ch1 (Натуральные числа, §§1–17) → math_5_ch1.html +-- math-5-ch2 (Выражения. Уравнения, §§1–9) → math_5_ch2.html +-- math-5-ch3 (Обыкновенные дроби, §§1–18) → math_5_ch3.html +-- +-- Source: Герасимов В. Д., Пирютко О. Н., Лобанов А. П., «Математика. 5 класс», +-- в 2 частях, Минск: Адукацыя і выхаванне, 2020 (2-е изд.). Контент авторский (наш). +-- Author left empty per project policy. + +-- 1. Parent hub row. +INSERT OR IGNORE INTO textbooks + (slug, subject, grade, title, author, description, html_path, para_count, color, sort_order, is_active, parent_slug) +VALUES + ('math-5', 'math', 5, 'Математика — 5 класс', + '', + 'Полный курс математики 5 класса: натуральные числа и действия с ними, делимость, степень, выражения и уравнения, углы, обыкновенные дроби и смешанные числа, периметр, площадь и объём. 3 главы, 44 параграфа, интерактивные тренажёры, визуализации и финалы-боссы.', + 'math_5_hub.html', 47, 'indigo', 5, 1, NULL); + +-- 2. Three chapters. +INSERT OR IGNORE INTO textbooks + (slug, subject, grade, title, author, description, html_path, para_count, color, sort_order, is_active, parent_slug) +VALUES + ('math-5-ch1', 'math', 5, 'Математика 5 · Натуральные числа', + '', + '§§1–17: как решать задачу, чтение и запись чисел и разряды, сравнение, точка/прямая/луч/отрезок, измерение отрезков, координатный луч, округление, сложение/вычитание/умножение/деление, степень, деление с остатком, делители, НОД и НОК, признаки делимости, простые и составные числа, разложение на множители.', + 'math_5_ch1.html', 18, 'indigo', 1, 1, 'math-5'), + ('math-5-ch2', 'math', 5, 'Математика 5 · Выражения. Уравнения', + '', + '§§1–9: числовые выражения и порядок действий, выражения с переменными, уравнение и его корень, формулы, решение задач с помощью уравнений, угол — измерение и построение углов транспортиром.', + 'math_5_ch2.html', 10, 'teal', 2, 1, 'math-5'), + ('math-5-ch3', 'math', 5, 'Математика 5 · Обыкновенные дроби', + '', + '§§1–18: обыкновенные дроби и доли, основное свойство дроби, правильные/неправильные и смешанные числа, сравнение, сложение и вычитание, умножение и деление дробей, задачи на дроби, параллельные и перпендикулярные прямые, ломаная и многоугольник, периметр, площадь и площадь треугольника, среднее арифметическое, диаграммы, прямоугольный параллелепипед и объём.', + 'math_5_ch3.html', 19, 'rose', 3, 1, 'math-5'); diff --git a/backend/tests/math5-page.test.js b/backend/tests/math5-page.test.js new file mode 100644 index 0000000..2c6f6fd --- /dev/null +++ b/backend/tests/math5-page.test.js @@ -0,0 +1,97 @@ +'use strict'; +/* + * Phase 0 jsdom-каркас «Математика 5»: хаб и 3 главы выполняются на ОБЩЕМ движке + * math6_engine.js (учебник 5 класса переиспользует тот же движок/SVG/anim через + * собственный window.M6 с slug 'math-5-chN'). Проверяется: страницы грузятся без + * ошибок скриптов, para-selector строится с нужным числом карточек, активен § 1, + * заглушка с кнопкой прочтения на месте, финал помечен. Содержание §§ наполняется + * по главам отдельными билдерами — здесь проверяется фундамент. + */ +const test = require('node:test'); +const assert = require('node:assert'); +const fs = require('node:fs'); +const path = require('node:path'); +const { JSDOM, VirtualConsole } = require('jsdom'); + +const ROOT = path.join(__dirname, '..', '..'); +const readF = p => fs.readFileSync(path.join(ROOT, p), 'utf8'); +const wait = ms => new Promise(r => setTimeout(r, ms)); + +/* Инлайним внешние скрипты (CDN убираем, api/xp заменяем заглушками). */ +function buildPage(file) { + let html = readF('frontend/textbooks/' + file); + const inl = { + '/js/math6_svg.js': readF('frontend/js/math6_svg.js'), + '/js/math6_anim.js': readF('frontend/js/math6_anim.js'), + '/js/math6_engine.js': readF('frontend/js/math6_engine.js') + }; + html = html + .replace(/') + .replace(/'); + }); + return html; +} + +async function loadDom(file) { + const errors = []; + const vc = new VirtualConsole(); + vc.on('jsdomError', e => errors.push(e.message)); + const dom = new JSDOM(buildPage(file), { + runScripts: 'dangerously', pretendToBeVisual: true, virtualConsole: vc, url: 'http://localhost/', + beforeParse(w) { w.scrollTo = function () {}; } + }); + await wait(160); + return { dom, errors, doc: dom.window.document }; +} + +const CHAPTERS = [ + { file: 'math_5_ch1.html', cards: 18 }, + { file: 'math_5_ch2.html', cards: 10 }, + { file: 'math_5_ch3.html', cards: 19 } +]; + +test('engine: init() вызывается ПОСЛЕ экспортов (общий движок math6 — guard от sync-defer бага)', () => { + const src = readF('frontend/js/math6_engine.js'); + const exportIdx = src.indexOf('window.makeCard = makeCard'); + const initCallIdx = src.lastIndexOf('else init();'); + assert.ok(exportIdx > 0, 'есть экспорт window.makeCard'); + assert.ok(initCallIdx > exportIdx, 'else init() должен идти ПОСЛЕ window.makeCard = makeCard'); +}); + +for (const ch of CHAPTERS) { + test(`${ch.file}: SPA без ошибок, ${ch.cards} карточек, активен § 1, заглушка`, async () => { + const { doc, errors } = await loadDom(ch.file); + assert.deepEqual(errors, [], 'нет ошибок: ' + errors.join(' | ')); + assert.equal(doc.querySelectorAll('#psel-grid .psel-card').length, ch.cards, ch.cards + ' карточек'); + const active = doc.querySelector('.sec.active'); + assert.ok(active && active.id === 'sec-p1', 'активен sec-p1'); + const body = doc.querySelector('#p1-body'); + assert.ok(body && body.children.length > 0, 'тело § 1 заполнено'); + assert.ok(doc.querySelector('#p1-body .m6-placeholder'), 'заглушка § 1 (нет билдера — ожидаемо в каркасе)'); + assert.ok(doc.querySelector('#p1-body [data-read]'), 'кнопка прочтения § 1'); + assert.ok(doc.querySelector('#psel-grid .psel-card.final'), 'есть карточка финала'); + }); +} + +test('хаб math-5: 3 главы, курсовой финал, ачивка-полоса', async () => { + const { doc, errors } = await loadDom('math_5_hub.html'); + assert.deepEqual(errors, [], 'нет ошибок: ' + errors.join(' | ')); + assert.equal(doc.querySelectorAll('.ch-grid .ch-card').length, 3, '3 карточки глав'); + assert.ok(doc.querySelector('a[href="/textbook/math-5-ch1"]'), 'ссылка на главу 1'); + assert.ok(doc.querySelector('a[href="/textbook/math-5-ch3"]'), 'ссылка на главу 3'); + assert.ok(doc.querySelector('#cf-go') && doc.querySelector('#cf-q'), 'арена курсового финала'); + assert.ok(doc.querySelector('#ach-strip'), 'полоса звания «Математик 5 класса»'); +}); + +test('движок 5 класса: прогресс/XP считаются на math5_*-ключах', async () => { + const { doc } = await loadDom('math_5_ch1.html'); + const win = doc.defaultView; + assert.ok(win.M6 && win.M6.slug === 'math-5-ch1', 'M6.slug = math-5-ch1'); + assert.equal(win.M6.lsPrefix, 'math5_ch1', 'lsPrefix = math5_ch1'); + assert.equal(win.M6.xpKey, 'math5_xp', 'xpKey = math5_xp'); + win.bumpProgress('final', 100); await wait(20); + assert.ok(win.M6STATE.achievements.has('ch1_done'), 'достижение «Глава 1 пройдена» при финале 100%'); +}); diff --git a/frontend/textbooks/math_5_ch1.html b/frontend/textbooks/math_5_ch1.html new file mode 100644 index 0000000..339c20e --- /dev/null +++ b/frontend/textbooks/math_5_ch1.html @@ -0,0 +1,106 @@ + + + + + + + +Математика 5 · Глава 1 · Натуральные числа + + + + + + + + + + + + + + + + +
+
+
+

Математика 5 · Глава 1

+
Натуральные числа: запись и разряды · сравнение и округление · действия · делимость · простые числа
+
+
+ К математике 5 + + + +
+
+
+ +
+
+
+

Натуральные числа

+

Натуральные числа — те, которыми мы считаем предметы: $1, 2, 3, \dots$ В этой главе мы научимся читать и записывать большие числа по разрядам, сравнивать и округлять их, выполнять все четыре действия, возводить в степень, делить с остатком, а также разберём делимость: делители и кратные, НОД и НОК, признаки делимости, простые и составные числа.

+
+ +
Прогресс по главе
0%
+
+
+
+ +
Параграфы главы
+ +
+
+ + +
+
+ + + +
Достижение!
+
+ + + + + + diff --git a/frontend/textbooks/math_5_ch2.html b/frontend/textbooks/math_5_ch2.html new file mode 100644 index 0000000..a37761b --- /dev/null +++ b/frontend/textbooks/math_5_ch2.html @@ -0,0 +1,98 @@ + + + + + + + +Математика 5 · Глава 2 · Выражения. Уравнения + + + + + + + + + + + + + + + + +
+
+
+

Математика 5 · Глава 2

+
Выражения и уравнения: порядок действий · переменные · корень уравнения · формулы · углы
+
+
+ К математике 5 + + + +
+
+
+ +
+
+
+

Выражения. Уравнения

+

Математика говорит на языке выражений и формул. В этой главе мы научимся вычислять числовые выражения, соблюдая порядок действий, работать с выражениями с переменными, решать уравнения (искать неизвестное), пользоваться формулами периметра, площади и пути, а ещё — измерять и строить углы транспортиром.

+
+ +
Прогресс по главе
0%
+
+
+
+ +
Параграфы главы
+ +
+
+ + +
+
+ + + +
Достижение!
+
+ + + + + + diff --git a/frontend/textbooks/math_5_ch3.html b/frontend/textbooks/math_5_ch3.html new file mode 100644 index 0000000..0c878fb --- /dev/null +++ b/frontend/textbooks/math_5_ch3.html @@ -0,0 +1,107 @@ + + + + + + + +Математика 5 · Глава 3 · Обыкновенные дроби + + + + + + + + + + + + + + + + +
+
+
+

Математика 5 · Глава 3

+
Обыкновенные дроби: доли · смешанные числа · действия · многоугольники · площадь и объём
+
+
+ К математике 5 + + + +
+
+
+ +
+
+
+

Обыкновенные дроби

+

Дробь показывает часть целого: половина пиццы, четверть часа, две трети пути. В этой главе мы научимся записывать и сокращать дроби, переводить неправильные дроби в смешанные числа, сравнивать дроби, выполнять сложение, вычитание, умножение и деление дробей, а попутно изучим геометрию: параллельные и перпендикулярные прямые, периметр многоугольников, площадь и объём параллелепипеда.

+
+ +
Прогресс по главе
0%
+
+
+
+ +
Параграфы главы
+ +
+
+ + +
+
+ + + +
Достижение!
+
+ + + + + + diff --git a/frontend/textbooks/math_5_hub.html b/frontend/textbooks/math_5_hub.html new file mode 100644 index 0000000..94c2ab6 --- /dev/null +++ b/frontend/textbooks/math_5_hub.html @@ -0,0 +1,328 @@ + + + + + + + + +Математика 5 класс — учебник + + + + + + + +
+
+
+ + + К каталогу + +
+
+

Математика — 5 класс

+
Натуральные числа · делимость · выражения и уравнения · углы · обыкновенные дроби · площадь и объём
+
+
+ +
+
+
+ +
+ +
+
+
+
Общий прогресс по курсу
+
Загрузка...
+
+
+ +
+ +
+ + +
123
+
Глава 1
+
Натуральные числа
+
§1–§17
+
+
+
Чтение и запись чисел, разряды, сравнение и округление, все четыре действия, степень, деление с остатком, делимость, НОД и НОК, простые числа.
+
Прогресс0%
+
Открыть главу
+
+
+ + +
x=
+
Глава 2
+
Выражения. Уравнения
+
§1–§9
+
+
+
Числовые выражения и порядок действий, выражения с переменными, уравнение и его корень, формулы, решение задач уравнением, измерение и построение углов.
+
Прогресс0%
+
Открыть главу
+
+
+ + +
¾
+
Глава 3
+
Обыкновенные дроби
+
§1–§18
+
+
+
Доли и обыкновенные дроби, основное свойство, смешанные числа, сравнение и все действия, задачи на дроби, прямые, многоугольники, периметр, площадь и объём.
+
Прогресс0%
+
Открыть главу
+
+
+ +
+ +
+
+
+
+ Курсовой финал +
3 испытания — по одному из каждой главы
+
Победи 2 из 3 и получи звание «Математик 5 класса» (+150 XP)
+
+
+
+
+
+
Испытание 1 / 3Пройдено: 0 / 3
+
+
+
+
+
+
+ +
+
+ +
+
+
Математик 5 класса
+
Пройдите все параграфы трёх глав, чтобы получить достижение
+
+
+ +
+ + + + + + + diff --git a/plans/textbooks-5/PLAN_MATH_5.md b/plans/textbooks-5/PLAN_MATH_5.md new file mode 100644 index 0000000..e5a262e --- /dev/null +++ b/plans/textbooks-5/PLAN_MATH_5.md @@ -0,0 +1,191 @@ +# PLAN — Интерактивный учебник «Математика. 5 класс» + +> Составлен 2026-06-03 (Opus). Источник: **Герасимов В. Д., Пирютко О. Н., Лобанов А. П. +> «Математика. 5 класс»**, в 2 частях, Минск: Адукацыя і выхаванне, 2020 (2-е изд.). +> PDF: `G:\Dev\Тесты\Методички\Разное\Книги\matematika_5kl_ch1_gerasimov_rus_2020 (1).pdf` (181 стр.) +> и `…_ch2_… .pdf` (197 стр.). Контент пишем авторский (свой), не копируем книгу. + +Цель: красивый, **интерактивный, визуальный** учебник того же класса качества, что +«Математика 6», — с тренажёрами, canvas/SVG-анимациями, пошаговыми разборами, финалами-боссами +и курсовым финалом. Реализация — Opus делает фундамент + эталонную Главу 1, Главы 2–3 тиражирует +Sonnet по образцу. + +--- + +## 1. Структура книги (оглавление, 3 главы) + +Книга Герасимова **переплетает геометрию внутрь числовых глав** (это её замысел) — не выделяем +геометрию отдельно, а сохраняем авторский порядок. + +### Часть 1 +**Глава 1. Натуральные числа** (§1–17) +1. Как решать задачу +2. Натуральные числа и число нуль. Чтение и запись +3. Сравнение натуральных чисел +4. Точка, прямая, луч, отрезок, плоскость +5. Измерение отрезков. Длина отрезка +6. Изображение натуральных чисел на координатном луче +7. Округление натуральных чисел +8. Сложение и вычитание натуральных чисел +9. Умножение и деление натуральных чисел +10. Степень числа с натуральным показателем +11. Деление с остатком +12. Делители, кратные. НОД и НОК +13. Признаки делимости +14. Простые и составные числа. Разложение на множители +15. *Математика вокруг нас* (прикладной) +16. *Задачи на движение, взвешивание, переливание* (занимательный/прикладной) +17. *Исторические сведения о числах* (история) + +**Глава 2. Выражения. Уравнения** (§1–9) +1. Числовые выражения +2. Выражения с переменными +3. Уравнение +4. Формулы +5. Решение задач с помощью уравнений +6. Угол. Измерение и построение углов +7. *Математика вокруг нас* (прикладной) +8. *Занимательные задачи* +9. *Исторические сведения* + +### Часть 2 +**Глава 3. Обыкновенные дроби** (§1–18) +1. Дробные числа. Обыкновенные дроби +2. Деление и дроби. Основное свойство дроби +3. Правильные и неправильные дроби. Смешанные числа +4. Сравнение дробных чисел +5. Сложение и вычитание обыкновенных дробей +6. Сложение и вычитание смешанных чисел +7. Умножение дробных чисел +8. Деление дробных чисел +9. Задачи на все действия с дробными числами +10. Задачи на применение дробей +11. Параллельные и перпендикулярные прямые *(геом.)* +12. Ломаная. Многоугольник. Периметр *(геом.)* +13. Площадь. Единицы измерения площади *(геом.)* +14. Площадь прямоугольного треугольника и многоугольников *(геом.)* +15. Среднее арифметическое +16. Линейные и столбчатые диаграммы +17. Прямоугольный параллелепипед. Куб *(геом.)* +18. Объём. Единицы измерения объёма. Объём параллелепипеда *(геом.)* + +> Бэк-материя ч.2 (Задачи с геом. фигурами, Повторение и обобщение, Задания для тренировки, +> Задачи для любознательных, Логические задачи, Наглядная геометрия) — **банки упражнений**, не §. +> Из них черпаем задачи для тренажёров и финала, отдельными § не делаем. + +Каждая глава в книге завершается **тестом** («Ответы к тесту: 1в); 2г)…») → в нашем учебнике это +**Финал главы** (бой с боссами). + +--- + +## 2. Архитектура — ПОЛНОЕ переиспользование движка «Математики 6» + +Движок `math6_engine.js` уже **generic**: читает `window.M6` со своими `slug / lsPrefix / xpKey`, +строит para-selector, навигацию, прогресс/XP/достижения, сайдбар, поиск, глоссарий, тему, финалы. +**Ничего форкать не нужно.** Страницы 5 класса подключают те же ассеты: + +``` +/css/math6.css (общий фреймворк) +/js/api.js /js/xp.js +/js/math6_svg.js (window.Math6 — статичные SVG-фигуры) +/js/math6_anim.js (window.Math6Anim — canvas/SVG-демо) ← ПЕРЕД engine +/js/math6_engine.js (window.M6engine — плумбинг) +``` + +> Эти файлы — общая **визуальная библиотека математики**, а не «6 класс». Новые компоненты для +> 5 класса дописываем в `math6_svg.js` / `math6_anim.js` (выигрывают обе параллели). При желании +> позже переименуем в `math_svg.js` — сейчас не трогаем имена, чтобы не плодить churn. + +**Страница главы** = `head` (KaTeX CDN + шрифты + math6.css + 5 скриптов) → inline `:root`-палитра +→ chrome (`hdr / hero / psel / #sections / sidebar / search / ach-popup`) → inline `