Commit Graph

519 Commits

Author SHA1 Message Date
Maxim Dolgolyov ebb2a9b37b feat(lab-content-engine): phase 1 - data-driven регистрация всех симуляций
- _register-all.js: строит манифесты из SIMS + THEORY + карта OPEN (40 id),
  регистрирует все симуляции в LabRegistry; LAB_SIM_ALIASES для deep-link
- openSim(): удалена if-цепочка (~60 строк), замена на нормализацию алиасов +
  диспетчеризацию через реестр (early return)
- lab.html: _pilots.js -> _register-all.js (defer, последним)
- _pilots.js удалён (поглощён _register-all.js)

Паритет проверен: исполняемый harness (40 регистраций, dispatch, алиасы,
:arg) ALL PASS; независимое ревью PASS (coverage 40/40, dispatch byte-for-byte).
Lifecycle пока на _pauseAllSims/closeSim (дробовик) — паритет.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:49:19 +03:00
Maxim Dolgolyov 81d4c15442 feat(opticsbench): учебное построение характеристических лучей
Для «Предмет» + «Характ. лучи» (один предмет, одна линза):
- подписи лучей 1/2/3 у предмета
- точка изображения = пересечение финальных отрезков лучей 1 и 2
- стрелка-изображение (основание на оси → вершина в точке изображения)
- мнимое изображение: пунктирные продления расходящихся лучей назад к
  мнимой точке (слева от линзы); подпись «изображение»/«мнимое изобр.»
- проверено численно: предмет за 2F → реальное справа, внутри F → мнимое слева
- bump opticsbench.js?v=10

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:33:46 +03:00
Maxim Dolgolyov 4b7939aba8 fix(lab): восстановлен _pilots.js (случайно удалён из общего индекса)
lab.html подключает _pilots.js; файл попал в предыдущий коммит как удаление
(был в общем индексе от параллельной сессии). Возвращаю, чтобы не ломать
ссылку. Впредь коммичу строго по путям.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:29:22 +03:00
Maxim Dolgolyov 6a3d1e04d0 feat(opticsbench): режим лучей предмета — характеристические vs пучок
- источник «Предмет»: тумблер «Характ. лучи» (по умолчанию) / «Пучок»
- характеристические: 3 луча от вершины (параллельный→F', через центр,
  через F→параллельно) + осевой от основания — как в учебнике; проверено
  численно (F'=lensX+f, центр прямо, через F выход параллелен)
- пучок: прежний физичный веер + ползунок «Лучей» (густота) и «Раствор»
- setSource: rayMode как строковый ключ; bump opticsbench.js?v=9

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:28:15 +03:00
Maxim Dolgolyov af25a845c9 feat(biochem): Фаза 7 — импорт SMILES + экспорт PNG/JSON
BIO.parseSmiles — парсер учебного подмножества SMILES (органические атомы
верхнего регистра, связи -=#, ветви (), замыкание циклов цифрами/%nn,
неявные H по валентности, 2D-укладка BFS). BIO.toJSON/download.

biochem.html: поле ввода SMILES + кнопка Импорт (Enter), кнопки экспорта
PNG (текущий холст 2D/3D) и JSON.

Проверено: CCO→C2H6O, CC(=O)O→C2H4O2, C1=CC=CC=C1→C6H6 (Кекуле),
ClC(Cl)(Cl)Cl→CCl4, OCC(O)CO→C3H8O3 (глицерин); мусор отсекается.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:24:55 +03:00
Maxim Dolgolyov a97896d293 fix(opticsbench): источник — вертикальное положение + фикс плавающего FX
- источник можно двигать по вертикали: слайдер «Положение ↕» (для любого
  типа) + вертикальное перетаскивание; эмиссия/отрисовка/хит-тест через _sy()
- фикс бага: FX-вспышка рисовалась на ay−source.h даже для точечного
  источника (h оставалась 70) → «звезда» улетала вверх; теперь FX привязан
  к реальной точке источника (поднятая вершина только у стрелки-предмета)
- object «Высота» → «Размер стрелки» (чтобы не путать с вертик. положением)
- bump opticsbench.js?v=8

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:21:30 +03:00
Maxim Dolgolyov cc7332c7ce feat(biochem): Фаза 6 — график молярных масс + экспорт сравнения в CSV
biochem-properties.html: при сравнении 2+ молекул — столбчатый график
молярных масс (canvas, градиентные столбцы с подписями) и кнопка «Экспорт
CSV» (UTF-8 BOM, экранирование, скачивание таблицы свойств).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:19:49 +03:00
Maxim Dolgolyov d46966c24d feat(biochem): Фаза 3 — авто-балансировщик + энергодиаграммы реакций
BIO.balance(reactants, products) — балансировка уравнений через матрицу
«элемент×вещество» и дробный метод Гаусса (RREF) + НОК/НОД, целочисленные
коэффициенты. Проверено: 2H2+O2→2H2O, CH4+2O2→CO2+2H2O, 4Fe+3O2→2Fe2O3,
фотосинтез 6/6/1/6, Ca(OH)2+2HCl→CaCl2+2H2O (скобки), N2+3H2→2NH3.

biochem-reactions.html: в развёрнутой карточке —
- энергетический профиль (реагенты → переходное состояние → продукты) на
  canvas из energy_kj, экзо вниз/эндо вверх, стрелка ΔH, подпись типа;
- бейдж проверки баланса (BIO.balance по формулам молекул реакции).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:18:12 +03:00
Maxim Dolgolyov 4173ae1bff feat(biochem): Фаза 2 — химический движок (заряды, диполь, полярность)
В biochem-core.js добавлен расчёт химии из структуры (client-side, для всех
страниц): partialCharges (по разнице электроотрицательностей на связях),
dipole (векторная сумма q·r по 3D-координатам VSEPR), polarity (классификация
по дипольному моменту), massFractions, functionalGroups, analyze (единая точка).
chargeColor + поддержка opts.charges в render2D/render3D + стрелка диполя.

biochem.html: крудные эвристики _detectFG/_polarity/ATOMIC_MASS заменены на
BIO.analyze (−95 строк дублей); в панель свойств добавлен дипольный момент;
тумблер δ± — тепловая карта частичных зарядов (синий δ+/красный δ−) в 2D и 3D
плюс стрелка диполя.

Проверено: H2O O=−0.52/H=+0.26; CO2/CH4/CCl4 диполь 0 (неполярны);
H2O/CHCl3 полярны — симметрия гасит вектора за счёт настоящей 3D-геометрии.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:12:08 +03:00
Maxim Dolgolyov bb58141c76 fix(opticsbench): полный конструктор (Фаза 4) на feature-ветке + чип «Источник»
Ветка feature/lab-content-engine отделилась до Фазы 4 оптики, из-за чего
кнопки «+ Граница/+ Пластина» были без логики. Принёс полную Фазу 4
opticsbench.js с master (граница сред со Снеллиусом/ПВО, пластина, источники
луч/лазер, отсечение апертурой, F/2F, числовые слайдеры) и заново наложил
фикс выбора источника: постоянный чип «Источник» + выбор по умолчанию.
bump opticsbench.js?v=7

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:08:12 +03:00
Maxim Dolgolyov 0888a707cc fix(lab-content-engine): phase 0 - устранены 3 блокера ревью
- подключён _registry.js в lab.html (был отсутствует -> LabRegistry был undefined)
- регистрация 3 пилотов в _pilots.js (graph/quadratic/pendulum), подключён последним
- loadTheory (lab-glue.js) адаптирован: реестр в приоритете, иначе THEORY

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:04:39 +03:00
Maxim Dolgolyov dfce94fbf7 fix(opticsbench): постоянный чип «Источник» + восстановлены кнопки Граница/Пластина
- выбор источника теперь всегда доступен: чип «Источник» в списке схемы
  (раньше — только кликом по точке на холсте); источник выбран по умолчанию
- восстановлены потерянные кнопки палитры «+ Граница» / «+ Пластина»
- bump opticsbench.js?v=6

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:00:42 +03:00
Maxim Dolgolyov 410eb8a862 fix(biochem 3D): корректная глубина + объёмные связи-цилиндры
Два дефекта, из-за которых 3D читался как плоская диаграмма:
- painter-сортировка была по возрастанию z (ближние первыми) — дальние
  атомы рисовались поверх ближних. Теперь единый список примитивов
  (атомы + половинки связей) сортируется по убыванию z (дальние первыми).
- связи были тонкими плоскими линиями. Теперь — затенённые «цилиндры»:
  толстый штрих с поперечным градиентом (центр светлее, края темнее),
  двухцветные (каждая половина под цвет своего атома) — фирменный вид
  ball-and-stick. Ширина зависит от перспективы (ближе — толще).
- усилена перспектива (fov 900→700), добавлен тёмный ободок сфер для объёма.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 12:58:39 +03:00
Maxim Dolgolyov 3b6481b1df feat(biochem): единый рендер BIO.render2D + 3D-превью молекул в библиотеке и свойствах
Фаза 0.2 (DRY) + Фаза 1.5 (3D-превью) плана BIOCHEM_UPGRADE:
- library/properties/reactions подключают biochem-core.js; локальные
  дубль-рендереры молекул заменены вызовами BIO.render2D; удалены
  дублирующиеся таблицы ELEM_COLORS/CPK и hexToRgb/cpkColor (~250 строк).
- Библиотека: в детальной панели тумблер 2D/3D — вращающаяся VSEPR-модель
  с подписью формы/гибридизации/угла.
- Свойства: на каждой карточке сравнения тумблер 2D/3D с вращением и
  геометрией; thumbnail-и тоже через общий рендер.
- Fallback-и сохранены (колба в библиотеке, «?» в реакциях, «Нет
  структуры» в свойствах).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 12:48:39 +03:00
Maxim Dolgolyov 76df3b4594 feat(access): вид «по классу», массовые действия, бейджи состояния + чистка orphan-правил
По итогам ревью системы прав:
- админка: переключатель режимов «По контенту» / «По классу»
- кнопки «Открыть всем классам» / «Закрыть у всех» (и зеркально по классу)
- бейджи N/M (сколько классов открыто) в списке контента
- эндпоинты /api/access/summary и /api/access/class/:id
- вкладка «Доступ к учебникам» перенесена к «Права доступа» (группа Пользователи)
- чистка content_access при удалении класса/ученика (нет FK)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 12:47:05 +03:00
Maxim Dolgolyov 5dc9164ee3 feat(biochem): ядро biochem-core.js + настоящая 3D-геометрия (VSEPR)
Фаза 0 (фундамент) + Фаза 1 (3D) плана BIOCHEM_UPGRADE:
- Новый общий модуль frontend/js/biochem-core.js (window.BIO): реестр
  элементов (CPK, масса, валентность, электроотрицательность, ковалентный/
  ван-дер-ваальсов радиусы), hillFormula/molarMass/parseFormula/dbe,
  нормализация связей (bF/bT/bO — чинит расхождение полей f/from, o/order),
  render2D, vsepr (генератор 3D по ОЭПВО), render3D (ball-and-stick с
  глубиной и затенением), safe (обёртка API с тостом), RING_TEMPLATES.
- biochem.html: подключён core; фейковый 3D (плоская проекция a.z||0)
  заменён на честную VSEPR-геометрию через BIO.render3D; в панель свойств
  добавлены форма молекулы, гибридизация и валентный угол; фикс бага
  порядка связи в getBondSum.

VSEPR проверен: вода — угловая, метан — тетраэдр 109.5°, CO2 — линейная
180°, NH3 — пирамидальная; sp/sp2/sp3 верно.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 12:42:44 +03:00
Maxim Dolgolyov 1c7d8e9d95 feat(opticsbench): конструктор Фаза 3 — изображение на экране + экспорт PNG
- _drawScreenHits: светящиеся пятна (additive) в точках попадания лучей на
  экран, по длине волны — видно формирование изображения и спектр
- benchExportPng + кнопка «Снимок PNG»; подсказка про λ/белый свет
- bump opticsbench.js?v=4

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 12:40:37 +03:00
Maxim Dolgolyov 353a6cb8a9 feat(opticsbench): конструктор Фаза 2 — призма со Снеллиусом и дисперсией
- _prismInteract: тонкопризменное отклонение δ=(n−1)·A к основанию +
  хроматическая дисперсия n(λ) через _nAtWavelength
- белый свет: пучки по OB_SPECTRAL, каждый луч красится по длине волны
  (до призмы совпадают, после — расходятся в спектр); управление общим λ-баром
- _obRedraw для freebuild переключён на benchSim (был freeSim)
- сферические зеркала уже из Фазы 1; проверено численно (фиолет>красный)
- bump opticsbench.js?v=3

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 12:38:40 +03:00
Maxim Dolgolyov 832efc0907 feat(opticsbench): конструктор оптических систем — Фаза 1 (общий трассировщик)
Режим «Цепочка линз» → «Конструктор» на базе нового класса BenchSim:
- общий 2D-трассировщик: линза, зеркало (плоск./вогн./выпукл.), диафрагма,
  экран; источники предмет/точка/параллель; лимит отражений
- фокус линзы в x+f и терминация зеркала проверены численно
- динамический инспектор: палитра элементов, список схемы, свойства
  выбранного, удаление; слайдеры перерисовывают только холст (не ломают drag)
- pointer-слушатели на canvas (capture, dispose), выбор/перетаскивание
- пресеты: микроскоп/телескоп/проектор/зеркальная; сохранение состояния
  в снимок (_obGetState/_obApplyState); bump opticsbench.js?v=2
- призма — пока грубый placeholder (Снеллиус/дисперсия в Фазе 2)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 12:35:41 +03:00
Maxim Dolgolyov 471171b77c feat(access): доступ к учебникам и экзаменам по классам/ученикам из админ-панели
Модель allowlist (закрыто по умолчанию), правило ученика важнее класса.
Управляют админ (все) и учителя (свои классы/ученики).

- миграция 040: таблица content_access + непрерывный переход
  (всем существующим классам открыт текущий контент)
- сервис contentAccess: резолвинг доступа, главы наследуют хаб
- API /api/access (catalog/targets/rules) для admin+teacher
- гейты: каталог учебников, router.param slug/examKey, фильтр tracks
- клиентские редиректы на /403 (textbook-tracker, exam-prep boot)
- раздел админки «Доступ к учебникам»: классы + ученики (tri-state)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 12:33:05 +03:00
Maxim Dolgolyov 98f955a85e fix(phys7): главный визуал курса работает + §22, §24 интерактивы улучшены
1. БАГ В HillSlideSim (phys.js):
   - При reset() начальное состояние x=0, h=hStart, v=0.
   - Первый step(): dropped=0 → v=0 → x не растёт → h не падает → тележка
     навсегда стоит на вершине (бесконечный нуль). Анимация ничего не показывала.
   - Фикс: reset() даёт начальный толчок (x = L*0.01) и v по энергии для
     этой малой высоты падения. step() теперь корректно ускоряет тележку.
   - Тест node: за 2.05 с тележка проходит 11.7 м, h падает с 4.9 м до 0.86 м,
     v растёт с 1.4 до 9.0 м/с. Е_полн ≈ const.

2. §22 «Сила тяжести» — новый IV-2 «Падение на 4 планетах»:
   - SVG 4-колоночная сцена, 4 шарика стартуют с одной высоты.
   - Slider высоты 2..20 м, кнопки «Уронить» / «Сброс».
   - Свободное падение по h(t) = h₀ − gt²/2 для каждой планеты (Земля 9.8,
     Луна 1.6, Марс 3.7, Юпитер 24.8).
   - Видно: Юпитер падает первым, Луна последней; для каждого сохраняется
     время падения √(2h/g) и итоговая v = g·t.
   - Live info: текущее t, статус каждого шарика (падает / упал за X с,
     v = Y м/с).

3. §24 «Вес тела» — переработан IV-1 «Лифт с динамометром»:
   - Было: 4 статичных схемы покой/падение/верх/вниз.
   - Стало: динамический симулятор. Кабина лифта со стрелкой ускорения
     снаружи, внутри — груз на пружинном динамометре с шкалой.
   - 2 slider'а: масса 0.5..10 кг, ускорение −10..+10 м/с².
   - 4 кнопки-пресета: Покой / Едет вверх / Едет вниз / Свободное падение.
   - Формула P = m(g + a) считается в реальном времени.
   - 4 режима с автоопределением: ПОКОЙ / НЕВЕСОМОСТЬ / ПЕРЕГРУЗКА /
     ПОНИЖЕННЫЙ ВЕС с разной цветовой индикацией.
   - Пружина динамометра реально растягивается/сжимается в зависимости
     от P; указатель и шкала тоже.

Parse OK, smoke (15 экспортов CH3) OK.
2026-05-30 12:14:48 +03:00
Maxim Dolgolyov a60349d339 fix(textbooks catalog): добавил классы sky/red/orange/yellow для обложек
Карточка Физики 7 в каталоге показывалась с прозрачной обложкой и
нечитаемым (белым на светло-голубом) заголовком — потому что миграция
039_physics_7_hub.sql указывает color='sky', а класса .tb-cover.sky
в textbooks.html не было.

Добавлено 4 новых цвета в 3 секциях CSS (tb-cover / tb-progress / tb-btn.primary):
- sky    (#0284c7) — для Физики 7 и других учебников с sky-палитрой
- red    (#dc2626) — на будущее для огненных тем
- orange (#ea580c) — для активных физических курсов
- yellow (#ca8a04) — для математических курсов

Теперь карточка Физики 7 показывает читаемый белый текст на градиенте
sky-700 → sky-400, совпадающем с темой хаба физики 7.
2026-05-30 12:04:39 +03:00
Maxim Dolgolyov e4050fcaed feat(phys7): Phase 8 — финал курса. Панель 7 ачивок + confetti + завершение плана
ХАБ physics_7_hub.html:
- Подключён canvas-confetti с CDN (jsdelivr 1.6.0)
- Заменена старая ach-strip с одной ачивкой на полную панель .ach-section
  с сеткой из 7 карточек: 5 ачивок глав + лаб + master
- Master-карточка выделена (grid-column: 1/-1, фиолетовый градиент при .lit)
- Каждая карточка: иконка (★ при .lit, ? до получения), название, описание условия
- Счётчик «N / 7 ачивок получено»
- renderAchievements() читает все 7 ключей из localStorage и подсвечивает
  получённые, обновляется при focus
- При первом получении «Магистр физики 7» — confetti-залп в 3 волны (через
  sessionStorage флаг, чтобы не запускать повторно при ре-открытии хаба)
- Текст финального аккордеона: «...по всем 5 главам» вместо «3»

ПЛАН plans/textbooks-7/PLAN_PHYSICS_7.md:
- Заголовок отмечен как « ЗАВЕРШЁН» (Phase 0..8)
- Добавлена итоговая сводка реализации:
  * Таблица 9 фаз с файлами, строками и коммитами
  * Список 6 главных визуалов с указанием §
  * Таблица 7 ачивок (slug / название / условие / XP)
  * Оценка XP за полное прохождение (~3 550)
  * Список фактически использованных хелперов phys.js
  * Список уроков, учтённых с первого коммита (cache-busting, sidebar-фикс,
    delimiters, скобки в KaTeX, self-sufficient миграция, без эмоджи)

Итог: 5-й физический курс в проекте, первый учебник 7 класса по физике.
8 фаз × несколько волн каждая = ~14 100 строк кода. Все интерактивы работают.
parse-check, smoke-test и pre-commit хуки пройдены на каждом этапе.
2026-05-30 12:01:50 +03:00
Maxim Dolgolyov d63f6eec67 fix(stereo3d): ревью метода следов — центрирование следа, фикс скрытия сечения
- _traceLine: p0 = основание перпендикуляра из начала координат (след
  рисуется у фигуры, а не у далёкого пересечения с осью)
- фикс: после сброса/смены фигуры в пошаговом режиме step мог стать 0 →
  сечение скрыто и шаги не рисуются; нормализация step≥1 в _drawSection3P
- подпись шага обновляется сразу после 3-го клика (в step-режиме)
- bump stereo.js?v=10

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 11:54:32 +03:00
Maxim Dolgolyov 2bf7ff7ef1 feat(phys7 lab): Phase 7 — Лабораторный практикум, 6 виртуальных ЛР
Все 6 ЛР физики 7 закрыты. Файл phys7_lab_widgets.js (726 строк, 6 экспортов:
lr1..lr6). Палитра cyan. Подключение через обновлённый gen_phys7_lab.js:
script-тег + hook в goTo (удаление placeholder + вызов widgets).

Каждая ЛР содержит:
- Цель (goal card, голубая)
- Оборудование (equip card, оранжевая)
- Ход работы (steps card, фиолетовая) — пронумерованный список
- СИМ-виджет (интерактивная симуляция прибора)
- ТБЛ-виджет (таблица измерений)
- ВОПР-виджет (3 контрольных вопроса с авто-проверкой)
- Вывод (concl card, зелёная)
- Кнопка «Сдать ЛР» (+30 XP, localStorage-фиксация)

ЛР-1 «Цена деления» (§7):
- 4 виртуальных прибора (линейка/термометр/мензурка/динамометр) с SVG-шкалами
- Таблица C для всех 4
- 3 контрольных вопроса

ЛР-2 «Измерение длины» (§4, §7):
- 3 предмета на выбор (карандаш/тетрадь/брусок), SVG с линейкой ниже,
  риска на длине + запись (l ± 0,5) мм
- Таблица 3 измерений

ЛР-3 «Объём вытеснением» (§4):
- 3 тела (камень/гайка/болт), 2 SVG-мензурки рядом (V1=100 и V2=100+V),
  стрелка «опускаем» между ними, авто-расчёт V = V2 − V1
- Таблица 3 измерений

ЛР-4 «Неравномерное движение» (§18):
- Шарик на наклонной плоскости, slider угла 10..60°, кнопка «Запустить»,
  анимация скатывания (квадратичная по времени, эмпирически быстрее на больших углах)
- Таблица 3 углов с разной средней скоростью

ЛР-5 «Плотность» (§20):
- 3 образца на выбор (54г/156г/272г, V=20 см³ каждый), SVG-весы+мензурка,
  расчёт ρ = m/V и автоопределение материала (алюминий/железо/золото)
- Таблица плотностей 9 веществ

ЛР-6 «Сила трения» (§27):
- SVG: брусок с грузами, динамометр, разные поверхности из <select>
  (дерево/пластик/резина/лёд: μ от 0.04 до 0.5)
- slider массы 100..500 г → авто N и Ftr через динамометр
- Таблица 5 измерений с разными грузами → видно Ftr ~ N

АЧИВКА «Лаборант 7 класса» +80 XP — автоматически при сдаче всех 6 ЛР
(проверка через localStorage в wireSubmit).

Парсинг OK, smoke (6 экспортов) OK.
2026-05-30 11:53:51 +03:00
Maxim Dolgolyov 8786cf5e20 fix(textbooks): убраны лишние слэши в LaTeX-формулах (over-escaping)
Формулы в JS-литералах имели \\\\dfrac / \\\\\\\\dfrac (4/8 слэшей) вместо
\\dfrac (2). После JS-анескейпа KaTeX получал \\dfrac, трактовал \\ как
перенос строки и печатал dfrac/cdot/sqrt/pi как текст (карточка пирамиды и
конуса в geometry_11_ch2, и др.).

Схлопнуты прогоны слэшей кратные 4 перед LaTeX-командой -> 2. Прогоны из
3 слэшей (\\ перенос строки + \cmd в \begin{cases}) и перед x/цифрой не
тронуты. 150 правок в 7 файлах (algebra_11_ch1/ch2/ch3, geometry_11_ch1..ch4).

БД чиста: questions (1398) text/explanation/correct_text + options (5187) -
0 багов. Скрипт: backend/scripts/fix_overescaped_latex.js (идемпотентный,
dry-run по умолчанию, --apply, с KaTeX-валидацией).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 11:53:17 +03:00
Maxim Dolgolyov 3801d0cfa8 feat(stereo3d): Фаза 6 — построение сечения «по следам» (метод следов)
Путь (b): надёжный полигон (есть) + аналитический след и вспом. точки.
- _traceLine(): след = π ∩ плоскость основания y=0 (проверено численно)
- _auxiliaryPoints(): продление сторон сечения до следа (dist=0 на следе)
- _hasBase()/_sameFace(): топология тел с основанием
- настоящий пошаговый _drawSection3PStep: 6 подписанных шагов, финал скрыт
  до шага 5 (showFull); подписи в #sect3p-hint через _stepCaption
- scope: куб, параллелепипед, призма, пирамида, усеч. пирамида, тетраэдр
- bump stereo.js?v=9

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 11:49:16 +03:00
Maxim Dolgolyov f471463911 feat(phys7 ch5): Phase 6 — Работа/Мощность/Энергия §§36-42 + финал «Энергетик»
Глава 5 «Работа. Мощность. Энергия» закрыта целиком. Файл phys7_ch5_widgets.js
(1275 строк, 8 экспортов: p36..p42 + final5). Палитра emerald.

§36 Механическая работа A=Fs:
- 3 карточки (определение / знак работы +/-/0 / толкаем ящик)
- IV-1 СИМ: SVG-сцена с бруском, стрелками F и s, slider F=0..200/s=0..20
- IV-2 КАЛЬК A=Fs
- IV-3 DnD 6→3 (положит/отрицат/нулевая)
- IV-4 ТРН 5

§37 Полезная и совершённая работа. КПД:
- 3 карточки + таблица КПД устройств (5..95%)
- IV-1 КАЛЬК с warning при η>100% и расчётом потерь
- IV-2 СИМ: наклонная плоскость, slider угла → расчёт КПД с трением
- DnD 6→3 (низкий/средний/высокий КПД) / ТРН 5

§38 Мощность P=A/t:
- 3 карточки + таблица 8 объектов (лампа..атомная станция)
- IV-1 КАЛЬК P=A/t с автоопределением уровня (телефон..МВт)
- IV-2 СИМ: 2 спортсмена с одинаковой A но разным t → определение мощнейшего
- DnD 6→3 / ТРН 5

§39 Кинетическая энергия Eк=mv²/2:
- 3 карточки (формула / квадратичная зависимость / автомобиль)
- IV-1 КАЛЬК с автосравнением (мяч..грузовик)
- IV-2 СИМ: интерактивный график Eк(v) с парабалой и красной точкой
- DnD 6→3 (Дж/кДж/сотни кДж) / ТРН 5

§40 Потенциальная энергия (введение):
- 3 карточки (запас работы / гравит и упругая / ГЭС-пружина-лук)
- IV-1 СИМ: подъём груза с шкалой высоты и индикатором Eп
- DnD 6→3 (Eк/Eп.грав/Eп.упр) / квиз 4 / ТРН 4

§41 Eп=mgh:
- 3 карточки + IV-1 КАЛЬК с большим диапазоном
- IV-2 СИМ: 2 тела на разных высотах (slider mA/hA/mB/hB) — кто запасает больше
- DnD 6→3 / ТРН 5

§42 ЗАКОН СОХРАНЕНИЯ — ГЛАВНЫЙ ВИЗУАЛ КУРСА:
- 3 карточки (E=Eк+Eп=const / как меняется при движении / свободное падение)
- IV-1 СИМ ГЛАВНЫЙ: тележка скатывается с горки через PHYS.HillSlideSim,
  slider h0/m/friction, кнопки «Запустить/Сброс», 3 цветных progress-bar'а
  для Eк/Eп/Eполн с текущими значениями в реальном времени
- IV-2 СИМ: маятник через PHYS.PendulumSim, slider начального угла,
  Etot сохраняется автоматически
- КВИЗ 4 / ТРН 5

ФИНАЛ ГЛАВЫ 5 (7 боссов + ачивка «Энергетик» +50 XP):
1. A=Fs (960 Дж)
2. КПД 80%
3. P=A/t (300 Вт)
4. Eк (25 Дж)
5. Eп=mgh (240 Дж)
6. Закон сохранения: v=√(2gh) при падении (20 м/с)
7. Энергетик: потери на трение на горке (8 Дж)

Parse OK, smoke (8 экспортов) OK.
2026-05-30 11:47:06 +03:00
Maxim Dolgolyov ccfb6116c0 feat(stereo3d): Фаза 5 — deep-link фигур из учебников + клавиатурная a11y
- openSim('stereo:<figure>') и /lab?stereofig=<figure> открывают нужное тело
  (без изменения общего hash-роутера)
- клавиатура на canvas: стрелки=орбита, +/-=зум, R/Home=сброс
- aria-live на readout; bump stereo.js?v=8
- дробление файла на модули отложено по решению пользователя (в бэклоге)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 11:34:51 +03:00
Maxim Dolgolyov c7345a71cf feat(phys7 ch4): Phase 5 — Давление, §§28-35 + финал «Властелин давления»
Глава 4 «Давление» закрыта целиком. Файл phys7_ch4_widgets.js (1300 строк,
9 экспортов: p28..p35 + final4). Палитра amber.

§28 Давление и единицы:
- 3 карточки + таблица сравнения 5 объектов (гвоздь / балерина / человек / лыжник / трактор)
- IV-1 КАЛЬК p=F/S с автосравнением (лыжник на снегу / каблук на паркете / ГПа гвоздь)
- IV-2 СИМ: 3 сценария «один человек — разные опоры» (ботинки / лыжи / каблук)
- DnD 6→3 / тренажёр 5

§29 Давление газа:
- 3 карточки (удары молекул / что увеличивает p / шар и шина)
- IV-1 СИМ: анимация молекул в сосуде, slider N и T, подсчёт ударов о стенки в реальном времени
- DnD 6→2 (растёт/падает) / квиз 4 / тренажёр 4

§30 Закон Паскаля + гидравлический пресс:
- 3 карточки (закон / формула F2/F1=S2/S1 / применения)
- IV-1 СИМ: использует PHYS.hydraulicPress, 3 slider'а S1/S2/F1, вывод F2 + выигрыш
- IV-2 КАЛЬК с формулой
- DnD 6→2 / тренажёр 4

§31 Гидростатика:
- 3 карточки + таблица «глубина / давление»
- IV-1 КАЛЬК ρgh с выбором жидкости (вода/бензин/морская/ртуть/спирт)
- IV-2 СИМ: гидростатический парадокс — 3 сосуда разной формы (цилиндр/широкий/узкий),
  один уровень → одинаковое p на дне
- DnD 6→2 / тренажёр 5

§32 Сообщающиеся сосуды:
- 3 карточки + IV-1 СИМ: использует PHYS.connectedVessels, 3 варианта форм
  (2 цилиндра / цилиндр+широкий / узкий+широкий), slider уровня
- DnD 6→2 / квиз 3 / тренажёр 4

§33 Газы и их вес:
- 3 карточки (m=ρV / опыт со взвешиванием шара)
- IV-1 КАЛЬК: 3 slider'а a/b/c комнаты → V, m, P воздуха с автосравнением
  (школьник / человек / пианино / автомобиль)
- DnD 6→2 (легче/тяжелее воздуха): He/H2/CH4 vs CO2/Cl2/Rn
- квиз 3 / тренажёр 4

§34 Атмосферное давление:
- 3 карточки (опыт Торричелли / падение с высотой 1мм/12м)
- IV-1 СИМ: PHYS.mercuryBarometer, slider 400..800 мм рт.ст. с описанием погоды
- IV-2 КАЛЬК: slider высоты 0..5000 м → давление с автоописанием места
- DnD 6→3 (норма/выше/ниже) / тренажёр 5

§35 БАРОМЕТРЫ И МАНОМЕТРЫ — ГЛАВНЫЙ ВИЗУАЛ ГЛАВЫ 4:
- 3 карточки (3 прибора / где какой / манометр на баллоне)
- IV-1 СИМ: три прибора рядом — Торричелли + Анероид + U-манометр (все 3
  PHYS-хелпера). Один slider давления → видишь одно давление в трёх формах.
- DnD 6→2 (баро/мано) / квиз 4 / тренажёр 4

ФИНАЛ ГЛАВЫ 4 (7 боссов + ачивка «Властелин давления» +50 XP):
1. p кирпича (5000 Па)
2. Гидравлический пресс (8000 Н)
3. Дайвер 20 м в море (206 кПа)
4. Сообщ. сосуды (одинаковый уровень 18 см)
5. Давление на высоте 480 м (720 мм)
6. Барометр → Па (98 400 Па)
7. Властелин: полное давление дайвера = атмосферное + гидростатич. (400 кПа)

Parse OK, smoke (9 экспортов) OK.
2026-05-30 11:34:12 +03:00
Maxim Dolgolyov b46c761373 feat(stereo3d): Фаза 4 — визуал (подписи осей, свечение вершин, контраст рёбер)
- подписи осей X/Y/Z цветами AxesHelper
- мягкое additive-свечение вершин (без текстур), вершины поверх рёбер
- рёбра контрастнее (opacity 0.9, renderOrder над полупрозрачным телом)
- bump stereo.js?v=7

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 11:32:21 +03:00
Maxim Dolgolyov dbb6a6fa11 feat(stereo3d): Фаза 3 — readout-панель, точки на гранях, подписи вершин сечения
- live-readout overlay: тип сечения, площадь, периметр, последнее измерение
  (через info().readout; _notify добавлен в section/measure-пути)
- _raycastFace(): в режиме точек клик по грани ставит точку на поверхности
- подписи вершин сечения буквами K,L,M… (наклонное/произвольное/3-точки, ≤12 вершин)
- bump stereo.js?v=6

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 11:29:25 +03:00
Maxim Dolgolyov 799f651777 feat(phys7 ch3): Phase 4 — силы §§21-27 + финал «Мастер движения»
Глава 3 «Движение и силы» закрыта целиком. Файл вырос с 1082 до 2124 строк
(+1042). Экспортирует 15 функций: p14..p27 + final3.

§21 Сила:
- 3 карточки (что такое сила / стрелка-вектор / 4 силы из жизни)
- IV-1 СИМ: интерактивная стрелка силы с slider модуля и угла (0..360°)
- DnD 8→4 (Ft/Fупр/Fтр/N) / квиз 4 / тренажёр 4

§22 Сила тяжести:
- 3 карточки + IV-1 КАЛЬК: 4 кнопки планет (Земля/Луна/Марс/Юпитер) + slider m
  → Ft = mg с правильным g, выводом и подписью планеты
- DnD 6→3 (1Н/10Н/100Н) / квиз 4 / тренажёр 5

§23 Сила упругости:
- 3 карточки (когда возникает / Гук качественно / примеры)
- IV-1 СИМ: SVG-пружина с подвешенным грузом, slider Δl=0..20 см → растягивается,
  стрелки Fупр↑ (зелёная) и Fт↓ (фиолетовая)
- DnD 6→2 (есть/нет деформации) / квиз 3 / тренажёр 4

§24 Вес тела:
- 3 карточки (P vs Ft / невесомость / взвешивание)
- IV-1 СИМ: 4 ситуации (покой / падение / ускорение вверх=перегрузка / вниз),
  для каждой — стрелки Ft (фиолет, на тело) и P (индиго, на опору)
- DnD 6→3 (Ft/P/P=0) / квиз 4 / тренажёр 4

§25 Динамометр:
- 3 карточки + IV-1 СИМ: использует window.PHYS.dynamometer из phys.js,
  slider F и Fmax → SVG с пружиной, шкалой, указателем; warning при превышении
- IV-2 КАЛЬК m = F/g с выбором планеты
- DnD 6→3 (школьный/мед./пром.) / тренажёр 4

§26 СЛОЖЕНИЕ СИЛ — ГЛАВНЫЙ ВИЗУАЛ ГЛАВЫ 3:
- 3 карточки (равнодействующая / сонапр/противопол / перетягивание каната)
- IV-1 «Конструктор сил на теле»: 4 slider'а Ft↓ + N↑ + Fтяги→ + Fтр←,
  SVG-сцена с цветными стрелками от центра кубика и большой красной стрелкой R;
  вердикт «уравновешены / ускоряется вправо/влево/падает/подпрыгнет/под углом»
- IV-2 КАЛЬК сложения 2 сил с переключателем сонапр./противопол.
- IV-3 DnD 6→3 (R вправо/влево/0) / тренажёр 5

§27 Сила трения:
- 3 карточки (откуда / виды / польза vs вред)
- IV-1 СИМ-симулятор: slider m, F, выбор μ из 4 поверхностей (лёд / сталь /
  дерево / резина-асфальт). SVG с бруском, стрелками F→ и Fтр←, вердикт
  «ЕДЕТ / ПОКОИТСЯ» по сравнению F с μN
- DnD 6→2 (полезно/мешает) / квиз 4 / тренажёр 5

ФИНАЛ ГЛАВЫ 3 (10 боссов + ачивка «Мастер движения» +50 XP):
1. v = s/t (20 м/с)
2. Средняя скорость с равным временем (7 м/с)
3. Плотность бруска → железо (7.8 г/см³)
4. Ft на Земле (39.2 Н)
5. Ft того же тела на Луне (6.4 Н)
6. Динамометр → масса (750 г)
7. R двух сил противоположных (12 Н)
8. R трёх сил на одной прямой (10 Н)
9. Сила трения скольжения (6 Н)
10. Магистр: брусок едет, Fтр_max < F, R = ? (2 Н)

Все интерактивы wireDnd/wireQuiz/слайдеры/SVG привязаны. Parse OK, smoke OK.
2026-05-30 11:24:21 +03:00
Maxim Dolgolyov c802fe552a feat(stereo3d): Фаза 2 — точные сечения кривых, унификация пикинга, HiDPI-метки
- _sliceCurvedByNormal(): аналитическое сечение шара (окружность) и
  цилиндра/конуса/усеч.конуса (гладкая кривая через точное y(θ)); старый
  сэмплинг оставлен fallback'ом для почти вертикальных плоскостей
- _edgePickNDC(): корректный пикинг ребра по всей длине (было — по середине)
- _makeTextSprite: DPR-aware, аспект по тексту, обводка, анизотропия
- тип сечения кривых = окружность/эллипс; вершинные маркеры cap ≤12 точек
- bump stereo.js?v=5

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 11:19:40 +03:00
Maxim Dolgolyov 7c598d6430 feat(stereo3d): Фаза 1 — камера и навигация (инерция, pan, пресеты, скриншот)
- инерция орбиты с затуханием; панорамирование (ПКМ/СКМ/Shift+ЛКМ, 2 пальца)
- орбита вокруг сдвигаемого таргета (_panOffset)
- overlay-тулбар: сброс вида + пресеты ракурса (Изо/Спереди/Сбоку/Сверху)
- тумблер авто-вращения с реальным засыпанием loop, fullscreen, снимок PNG
- a11y-атрибуты на кнопках; bump stereo.js?v=4

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 11:13:04 +03:00
Maxim Dolgolyov 96a2097e70 feat(phys7 ch3): Phase 3 — кинематика, §§14-20
Глава 3 «Движение и силы», часть 1 (без сил — Phase 4).
Файл: phys7_ch3_widgets.js (1082 строк, экспорт p14..p20).

§14 Мех. движение, относительность:
- 3 карточки (СО / относительность / самолёт-облако)
- IV-1 СИМ: переключатель СО (Земля/Поезд) с анимацией поезда vs дерева
- IV-2 КВИЗ 4 / IV-3 DnD 6→2 / IV-4 ТРН 4

§15 Траектория, путь, время:
- 3 карточки + IV-1 СИМ: интерактивная сетка SVG, клик → точка → построение
  ломаной траектории + автоподсчёт пути (1 клетка = 1 м), кнопка «Сброс»
- DnD 6→3 (прямолин/криволин/замкн) + квиз 3 + тренажёр 5

§16 Равномерное движение, скорость:
- 3 карточки (определение / 4 единицы скорости / расчёт)
- IV-1 СИМ: автомобиль на дороге, slider v=1..30 м/с, анимация движения с
  пересчётом пройденного пути в реальном времени
- IV-2 КАЛЬК v=s/t, slider s и t, вывод в м/с и км/ч
- DnD 6→3 (пешеход/машина/самолёт) + тренажёр 5

§17 Графики s(t) и v(t) — ГЛАВНЫЙ ВИЗУАЛ КИНЕМАТИКИ:
- 3 карточки (наклон=v / горизонталь / параллельные = равные v)
- IV-1 СИМ: рядом 2 графика SVG — s(t) с двумя прямыми (v1, v2) и v(t) с
  двумя горизонтальными + заливка площади под v1 как «s = v·t»; slider v1, v2
- КВИЗ 4 / DnD 6 → 4 типа линий / ТРН 4

§18 Средняя скорость:
- 3 карточки (формула / ловушка ≠ среднеарифм. / пешеход + метро)
- IV-1 КАЛЬК: 4 slider'а v1/t1/v2/t2, средневзвешенная vs ловушка с авто-
  индикатором «СОВПАЛО (t1=t2) / НЕВЕРНО»
- КВИЗ 3 / DnD 6→2 / ТРН 4

§19 Инерция:
- 3 карточки (закон Галилея / масса как мера инертности / пассажиры в автобусе)
- IV-1 СИМ: шарик на поверхности SVG с кнопкой «Запустить» и переключателем
  «Трение ВКЛ/ВЫКЛ»: с трением — тормозит и останавливается; без — катится вечно
- КВИЗ 4 / DnD 6→3 (легко/средне/тяжело) / ТРН 4

§20 Масса. Плотность:
- 3 карточки (масса / формула ρ=m/V / таблица 11 веществ)
- IV-1 КАЛЬК ρ=m/V: slider m=1..20000 г и V=1..2000 см³, вывод в г/см³ и кг/м³
  + автоопределение вещества (газ/пенопласт/дерево/вода/.../золото)
- IV-2 СИМ: 8 кнопок материалов → SVG-куб 1 дм³ меняет цвет и подпись массы
- DnD 6→3 (лёгкий/средний/тяжёлый) / ТРН 5

Парсинг OK, smoke-test (7 экспортов) OK.

Phase 3 — 7 из 14 § главы 3. Силы (§§21-27) + финал «Мастер движения» — Phase 4.
2026-05-30 11:10:48 +03:00
Maxim Dolgolyov 8af85961b5 perf(stereo3d): Фаза 0 — render-on-demand, остановка фонового рендера, dispose
- lab-init: _pauseAllSims() паузит активный rAF-сим при переключении (раньше стерео рендерило невидимый canvas вечно)
- stereo: render-on-demand через _invalidate()/_needsRender, loop засыпает и просыпается по взаимодействию
- pointer/touch-слушатели перенесены с window на canvas (pointer-capture), трекаются и снимаются в dispose()
- обработка webglcontextlost/restored + метод dispose()
- _clearGroup стал рекурсивным (устранена утечка вложенных групп), a11y-атрибуты на canvas
- bump stereo.js?v=3

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 11:05:35 +03:00
Maxim Dolgolyov ed97b6d90b feat(phys7 ch2): Phase 2 целиком — §§8-13 + финал «Знаток вещества»
Полная глава 2 «Строение вещества» в одном файле (1195 строк, 7 экспортов).

§8 Дискретное строение:
- 3 карточки (молекулы и атомы / шкала размеров от 1 м до ядра / доказательства)
- IV-1 СИМ: визуальная шкала размеров (8 объектов с цветными барами)
- IV-2 СИМ: конструктор молекул H₂O/CO₂/O₂/N₂/CH4/NaCl с SVG-схемами и описаниями
- IV-3 DnD: 8 объектов по 3 корзинам (атом/молекула/тело)
- IV-4 ТРН: 5 вопросов

§9 Тепловое движение. Диффузия:
- 3 карточки (хаотическое движение / диффузия и её скорость / примеры)
- IV-1 СИМ: анимированная диффузия 60 частиц (20 чернил + 40 воды), slider T → ускорение броуновского движения, кнопка «Сброс», requestAnimationFrame
- IV-2 КВИЗ: 3 вопроса о диффузии и броун. движении
- IV-3 DnD: 6 примеров → 3 скорости (быстро газ / средне жидк / медленно тверд)
- IV-4 ТРН: 5 вопросов

§10 Взаимодействие частиц:
- 3 карточки (отталкивание/равновесие/притяжение / зачем знать / опыт со свинцом)
- IV-1 СИМ: интерактивный график F(r) (Леннард-Джонс-подобная кривая), slider положения → автоматическое определение «отталкивание / равновесие / притяжение / силы малы»
- IV-2 КВИЗ: 4 вопроса
- IV-3 DnD: 6 ситуаций по 4 корзинам
- IV-4 ТРН: 4 вопроса

§11 Три состояния — ГЛАВНЫЙ ВИЗУАЛ ГЛАВЫ 2:
- 3 карточки (таблица состояний / поведение молекул / вода во всех 3 состояниях)
- IV-1 СИМ: переключатель solid/liquid/gas с 3 разными режимами анимации
  50 частиц: solid — крист. решётка 10×5 + дрожание; liquid — отскоки + гравитация
  к дну + плоский уровень; gas — свободное хаотическое движение по всему объёму
- IV-2 КВИЗ: 4 вопроса о свойствах
- IV-3 DnD: 9 веществ → 3 состояния
- IV-4 ТРН: 5 вопросов

§12 Тепловое расширение:
- 3 карточки (почему / где важно / аномалия воды)
- IV-1 СИМ: стержень со slider ΔT (0..200°C), цвет по температуре (HSL 240→0),
  пунктир базовой длины, индикатор Δl
- IV-2 СИМ: биметаллическая пластина с slider ΔT (-50..100°C), изгиб ±30°
- IV-3 DnD: 6 веществ → 3 уровня расширения
- IV-4 ТРН: 5 вопросов

§13 Температура. Термометры:
- 3 карточки (T и тепловое движение / шкала Цельсия / 4 вида термометров)
- IV-1 СИМ: виртуальный термометр SVG (-50..150 °C), столбик меняет цвет по
  температуре, шкала с делениями, указатель-стрелка, контекстная подсказка
  (мороз/комфорт/жарко/кипяток...) + конвертер в Кельвины
- IV-2 КАЛЬК: slider t°C → T(K) = t + 273.15, упоминание абс. нуля
- IV-3 DnD: 6 температур → 3 диапазона
- IV-4 ТРН: 5 вопросов (включая °C↔K)

ФИНАЛ ГЛАВЫ 2 (5 боссов + ачивка «Знаток вещества» +50 XP):
1. Молекула vs волос: во сколько раз меньше (10⁶)
2. Диффузия в горячей воде (/T_2$ через Кельвины)
3. Сжатие газа в шприце (20/50 = 40%)
4. Удлинение рельса при ΔT=60°C (18 мм)
5. 27 °C → 300.2 K

Все интерактивы wireDnd/wireQuiz/слайдеры/симы привязаны. parse-check, smoke-test (7 экспортов) пройдены.
2026-05-30 11:00:40 +03:00
Maxim Dolgolyov 903bc5cf42 feat(phys7 ch1): Phase 1 Wave 3 — §6, §7, Финал главы 1 «Юный физик»
WIDGETS (+390 строк, теперь 1139 строк, экспорт p1..p7 + final1):

§6 «Действия над физическими величинами»:
- 3 карточки (однородные величины / переводы скорости/плотности/мощности/энергии /
  умножение единиц m·V → плотность)
- IV-1 СИМ: таблица типичных скоростей (улитка → звук в воздухе) в м/с и км/ч
- IV-2 КАЛЬК конвертер (главный визуал §6): 5 типов величин (скорость/плотность/
  мощность/энергия/время), slider значения → перевод во все связанные единицы
- IV-3 DnD: 8 эквивалентных пар (1 мин=60 с, 1 кВт=1000 Вт, и т.д.)
- IV-4 ТРН: 5 задач (км/ч↔м/с, г/см³→кг/м³, ч+мин→с, сумма в разных приставках)

§7 «Цена деления. Погрешность»:
- 3 карточки (C = (X2-X1)/N / ΔX = C/2, запись X±ΔX / правила снятия отсчёта)
- IV-1 СИМ (главный визуал §7): виртуальная линейка SVG со сменой цены деления
  (10/5/2/1 мм) и подвижной красной риской; авто-округление до ближайшего деления,
  запись результата с погрешностью в KaTeX
- IV-2 КАЛЬК: 3 slider'а X1/X2/N → формула C и ΔX
- IV-3 DnD: 6 приборов (линейка/штангенциркуль/микрометр/термометры/секундомер)
  → 6 типичных цен деления
- IV-4 ТРН: 5 задач на цену деления и погрешность

ФИНАЛ ГЛАВЫ 1 (5 боссов + ачивка «Юный физик» +50 XP):
- Боссы (синтез §4-§7):
  1. Площадь листа A4 в м² (перевод см→м + S=ab)
  2. Плотность бруска с m=135 г и V=50 см³ (алюминий)
  3. Скорость 90 км/ч в м/с
  4. Цена деления (5 см = 50 делений → 1 мм)
  5. Погрешность мензурки (C=2 мл → ΔV=1 мл) — Магистр-задача
- Прогресс-бар «Побеждено: N/5», localStorage-сохранение между сессиями,
  +20 XP за каждого босса, ачивка +50 XP при 5/5 победах.
- Все боссы с подсказками (toggle), Enter-submit, валидация числа.

Все 4 IV в §6 и §7 wireDnd/wireQuiz/калькуляторы привязаны. parse-check, smoke-test (8 экспортов) пройдены.
2026-05-30 10:50:45 +03:00
Maxim Dolgolyov 83aad34e8b feat(phys7 ch1): Phase 1 Wave 2 — §3, §4, §5
WIDGETS (+347 строк к phys7_ch1_widgets.js, теперь 749 строк, экспорт p1..p5):

§3 «Методы исследования в физике»:
- 3 карточки (3 метода / отличия / опыт Галилея на Пизанской башне)
- IV-1 СИМ: timeline-список 5 исторических опытов (Архимед→Галилей→Торричелли→Паскаль→Ньютон) с раскрывающимися деталями
- IV-2 КВИЗ: 4 вопроса «опыт vs наблюдение vs гипотеза vs теория»
- IV-3 DnD: 8 ситуаций по 3 корзинам (наблюдение / эксперимент / гипотеза)
- IV-4 ТРН: 5 вопросов закрепления

§4 «Прямые и косвенные измерения» (S=ab, V=abc, rho=m/V):
- 3 карточки (типы измерений / основные формулы / объём картофеля по вытеснению)
- IV-1 СИМ: палитра 6 приборов (линейка/весы/термометр/секундомер/мензурка/динамометр) с единицами
- IV-2 КАЛЬК (главный визуал §4): 4 slider'а a, b, c (см) и m (г) →
  пересчёт S, V, плотности с угадыванием вещества (дерево / алюминий / железо / свинец / золото)
- IV-3 DnD: 8 примеров измерений → прямое / косвенное
- IV-4 ТРН: 5 расчётных задач (площадь, объём кирпича, плотность, скорость, вытеснение)

§5 «Единицы измерения. СИ»:
- 3 карточки (зачем СИ / 7 основных единиц в таблице / приставки от нано до гига)
- IV-1 СИМ: 7 цветных карт основных единиц СИ
- IV-2 КАЛЬК конвертер: число × приставка (Г/М/к/—/с/м/мк/н) × единица (м/г/с/Вт/Гц/Н)
  → результат с автоформатированием (экспоненциальная запись для больших/малых)
- IV-3 DnD: 8 величин → 5 основных единиц СИ
- IV-4 ТРН: 5 задач на перевод (км→м, кг→г, ч→с, мс→с, см²→м²)

Pre-commit, parse-check, KaTeX-аудит (одиночные backslash =0), smoke-test (экспорт=5) пройдены.
2026-05-30 10:47:15 +03:00
Maxim Dolgolyov 65c2e7dac1 feat(phys7 ch1): Phase 1 Wave 1 — §1, §2 + интеграция widgets
GEN: gen_phys7_ch.js теперь подключает <script src=phys7_chN_widgets.js> и
вызывает PHYS7_CHN_WIDGETS[id] в ensureBuilt, удаляя placeholder. Все 5 chN
регенерированы под этот hook.

WIDGETS (frontend/js/phys7_ch1_widgets.js, 402 строки, экспорт p1+p2):
- §1 «Физика — наука о природе»:
  * 3 теор. карточки (что изучает / связь с науками / 6 примеров явлений)
  * IV-1 СИМ: галерея 8 областей физики с hover-эффектом
  * IV-2 КВИЗ: 3 вопроса о предмете физики и слове «фюзис»
  * IV-3 DnD: 8 карточек → 4 науки (астро/химия/био/физика)
  * IV-4 ТРН: 5 вопросов тренажёр
- §2 «Физическое тело, явление, величина»:
  * 3 теор. карточки (4-понятийная таблица / как отличать / стакан-пример)
  * IV-1 СИМ (главный): DnD 12 карточек → 4 корзины (тело/вещество/явление/величина),
    в т.ч. KaTeX-величины (=5$ кг, =-10$ °C, =30$ км/ч)
  * IV-2 КВИЗ: «найди величину/явление/вещество» (3 вопроса)
  * IV-3 ТЕСТ: 5 быстрых вопросов на классификацию
  * IV-4 ТРН: 4 расчётных + концептуальных вопроса
- Кнопка «Я прочитал §» (+10 XP), localStorage-фиксация, серая «Прочитано»
  после первого нажатия.

ИНФРАСТРУКТУРА:
- Общие хелперы внутри файла: makeCard (theory/rule/example), wgWrap, dndPool,
  wireDnd, quizQuestion, wireQuiz, readButton, wireReadBtn, renderMath с правильными
  delimiters $..$ и $$..$$.
- XP: DnD +15, квиз +10, тренажёр +15, прочитал +10. Прогресс параграфа +30 при
  «прочитал», +10 базово при открытии. Цвета §1+§2 единые с темой главы 1 (indigo).
- Parse-check, KaTeX-аудит ($$ только двойной backslash), smoke-test пройдены.
2026-05-30 10:41:27 +03:00
Maxim Dolgolyov e76485cadc feat(phys7): Phase 0 — фундамент учебника Физики 7
Полная инфраструктура: hub, 5 ch-скелетов, lab-скелет, миграция 039,
расширение phys.js на 11 хелперов + 2 класса симуляций для новых тем 7-го класса.

ФАЙЛЫ:
- backend/src/db/migrations/039_physics_7_hub.sql — self-sufficient миграция
  (parent physics-7 + 6 children: ch1..ch5 + lab). Palette: sky/blue для hub,
  глав: indigo/violet/red/amber/emerald/cyan.
- frontend/textbooks/physics_7_hub.html (862 строки) — hub с прогресс-картами
  6 разделов, шпаргалкой курса в 5 mini-карточках, 10 интегрированных боссов
  финала курса (через ачивку «Магистр физики 7», +150 XP), темой/lang storage
  через ключи physics7_*. Sidebar-фикс на десктопе встроен.
- frontend/textbooks/physics_7_ch1..ch5.html (350-390 строк каждый) —
  скелеты глав с header, paragraph selector, sidebar, прогресс/XP, goTo,
  search-модалом, KaTeX с delimiters, sidebar-фиксом, cache-busting ?v=20260530.
  Каждая глава имеет правильное число параграфов (7/6/14/8/7) + sec-finalN.
- frontend/textbooks/physics_7_lab.html (306 строк) — скелет лаб. практикума
  на 6 ЛР с teal/cyan палитрой и ачивкой «Лаборант 7 класса» (+80 XP).
- backend/scripts/gen_phys7_ch.js / gen_phys7_lab.js — генераторы из единого
  шаблона (для регенерации при правках инфраструктуры).

PHYS.JS НОВЫЕ ХЕЛПЕРЫ (всё работает, smoke-test пройден):
- forceVector(x,y,F,angle,color,label) — стрелка силы с подписью
- dynamometer(x,y,h,Fmax,F) — динамометр с пружиной и шкалой
- blockOnSurface(x,y,w,h,label,weights) — брусок со стопкой гирь
- connectedVessels(x,y,kindA,kindB,levelY) — сообщающиеся сосуды
- hydraulicPress(x,y,sSmall,sLarge,fSmall) — гидравлический пресс
- mercuryBarometer(x,y,hMm) — ртутный барометр Торричелли
- aneroidBarometer(cx,cy,r,p) — стрелочный барометр-анероид
- uManometer(x,y,w,h,deltaH) — U-образный жидкостный манометр
- rulerWithError(x,y,lenCm,mmPerDiv) — линейка со шкалой и ценой деления
- bimetal(x,y,w,h,deltaT) — биметаллическая пластина (гнётся от ΔT)
- expandingRod(x,y,l0,alpha,deltaT) — стержень с тепловым расширением
- class HillSlideSim — тележка на горке (§42, закон сохранения; графики Ek/Ep/Etot)
- class PendulumSim — математический маятник (§42, осцилляции)

Все 13 экспортированы в window.PHYS, smoke-test показал физически разумные
значения энергий. Parse-check + node --check проходят.

Уроки phys 9 учтены сразу: cache-busting на phys.js, sidebar-фикс @media
min-width:981px, delimiters для renderMathInElement.

PHASE 0 DONE. Дальше: Phase 1 Wave 1 — §§1-2 (Физика как наука + Тело/явление/величина).
2026-05-30 10:32:37 +03:00
Maxim Dolgolyov 29a2bae7d9 feat(phys8 hub): Phase 5 — hub polish + cross-cutting
Hub улучшения:
- .ch-card: подъём на hover (-6px scale 1.01) с тематической box-shadow
  по цвету главы.
- .ch-cover::after: shimmer-overlay при наведении (diagonal sweep).
- .ch-cover-wm: micro-перемещение и scale на hover.
- .ch-action svg: стрелка едет вправо на hover.
- .po-xp: пульсирующая тень для overall progress XP-badge (3s loop).

Accessibility:
- aria-label на каждой ch-card с понятным названием темы.
- :focus-visible с 3px outline в brand-цвете для chapter cards.
- :focus-visible с белым outline для hdr-btn на градиенте.
- prefers-reduced-motion: блокирует все анимации.

Mobile responsiveness:
- @media ≤580px: уменьшение шрифта h1 1.4rem, ch-cover-wm 3.8rem.

Footer: '40 параграфов, 7 ЛР, 47 IV-6 интерактивов'.
2026-05-30 10:31:05 +03:00
Maxim Dolgolyov 382dff3879 feat(phys8 lab): Phase 4 — Лабораторный практикум (визуал + 7 IV-6)
Hero: emerald-зелёный градиент (стиль 'химической лаборатории'),
flask SVG-watermark, live meter '7/7 ЛР'.

7 section watermarks: термометр, печь, цепь, посл/парал, P, угол.

7 IV-6 интерактивов:
ЛР1 Теплообмен: 2 ёмкости (0.5 кг + 1 кг), scrubbers T₁/T₂,
кнопка 'Смешать' с tween-анимацией, формула баланса.
ЛР2 Удельная теплоёмкость: scrubbers P/m/t, нагреватель,
термометр с цветовой картой, c=Q/(mΔT) для воды (4200).
ЛР3 Простейшая цепь: батарея+амперметр+лампа+вольтметр,
scrubber U, live показания приборов.
ЛР4 Последовательное соединение: U=U₁+U₂, I одинаков.
ЛР5 Параллельное соединение: U одинаков, I=I₁+I₂.
ЛР6 Работа и мощность: U·I·t, лампа brightness ∝ P,
лучи при P>100 Вт.
ЛР7 Закон отражения: луч + нормаль + угловые дуги,
verdict 'α=β'.
2026-05-30 10:29:50 +03:00
Maxim Dolgolyov aa2e869b93 feat(phys9 flagships): F18 Магистр-симулятор (финал курса)
F18. Магистр-симулятор сценария движения (final5 в ch5):
- Конструктор из 4 типов этапов:
  - Равномерное (slider v)
  - Равноускоренное (slider a)
  - Свободное падение (a = -g)
  - Стоп/покой
- Drag&drop карточек этапов с inline-input'ами:
  - Δt длительность
  - Параметр (v / a / —)
- Кнопка [×] удалить этап
- Шаблон «разгон + равном. + торможение»
- Реальная физика: Эйлер dt=0.05 с
- 3 синхронных графика: x(t), v(t), a(t)
  - Автоматический масштаб по min/max
- Stats: число этапов, общая длительность, итог x и v
- Проверка согласованности скоростей между этапами (предупреждение
  о «рывке» если v не сшивается)
- Сохранение/загрузка сценария в localStorage
  (phys9_F18_scenario)

Подключение: ch5 + хук на final5.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 10:29:42 +03:00
Maxim Dolgolyov ca67ae6e0d feat(phys8 ch3): Phase 3 — Световые явления (визуал + 9 IV-6)
Hero: spectrum-drift градиент (18s), солнце SVG-watermark
(rotate-анимация 40s), live-meter длины волны (400/470/550/600/700 нм
с цветами цикла).

9 section watermarks: лампа, тень, угол, зеркало, парабола,
рефракция, линза, призма, глаз.

9 IV-6 интерактивов:
§32 Источники — кнопки 'Точечный/Протяжённый' с динамической
тенью (точечный — чёткая, протяжённый — с полутенью).
§33 Тени — drag-источника по X, размер тени пересчитывается
проективно.
§34 Закон отражения — scrubber угла, лучи + нормаль.
§35 Плоское зеркало — drag-d объекта, мнимое изображение за
зеркалом на том же расстоянии (штриховая стрелка).
§36 Сферическое зеркало — drag-d, формула 1/v+1/d=1/F,
изображение с правильным знаком/размером.
§37 Преломление — scrubber угла, закон Снеллиуса (n₁=1, n₂=1.33).
§38 Линза — 3 главных луча от объекта, формула v=dF/(d-F),
изображение по принципу геометрической оптики.
§39 Дисперсия — призма с разложением белого света на 7 цветов
видимого спектра.
§40 Глаз — кнопки 'Норма/Близорукость/Дальнозоркость' с
fokus-точкой и корректирующей линзой (рассеив/собир).
2026-05-30 10:26:17 +03:00
Maxim Dolgolyov e316d39264 feat(phys9 flagships): F6 дорога + F13 Фуко + F14 резонанс
F6. Симулятор скоростной дороги (§20 в ch2):
- 5 покрытий: сухой/мокрый асфальт, гравий, снег, лёд (μ=0.7..0.08)
- Slider скорости 20..180 км/ч
- Автомобиль едет по дороге, кнопка ТОРМОЗ → тормозит до 0
- Расчёт: s = v²/(2μg), t = v/(μg)
- На льду тормозной путь в ~8 раз длиннее асфальта

F13. Маятник Фуко (§36 в ch4):
- Маятник в виде розетки, плоскость вращается со скоростью
  ω = sin(φ) · 2π / 24h
- Slider широты 0..90° (от экватора до полюса)
- На полюсе — 24ч полного оборота, на экваторе — никогда
- Slider «ускорение времени» × (100..20000) — чтобы увидеть розетку
- Места: экватор/Каир/Рим/Минск/Москва/Заполярье/полюс

F14. Резонанс пружинного маятника (§36 в ch4):
- Слева: пружина с грузом + внешняя гармоническая сила
- Slider'ы: m, k, ν_внешн, γ затухание
- Кнопка «Настроить на резонанс» (ν_внешн = ν_собств)
- Реальная физика затухания: m·x'' = -kx - γv + F0·cos(ωt)
- Справа: график x(t) за последние 20 с
- Классификация: вынужденные / близко к резонансу / РЕЗОНАНС!

Подключение:
- ch2: F6 на p20
- ch4: F13 + F14 оба на p36 (маятники)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 10:23:57 +03:00
Maxim Dolgolyov 0d9226f6d5 feat(phys8 ch2): Phase 2.3 — оставшиеся 14 IV-6 (Ch2 завершена)
scrubberWidget() helper в скрипте — генерирует виджет с N
scrubbers + 1 readout + live SVG render.

§13 Проводники/диэлектрики: 2 стержня, движущиеся электроны в меди,
застрявшие в стекле. Анимация через setInterval.

§14 Электростатическая индукция: + палочка + проводник, при
сближении видны индуцированные −/+ заряды на сторонах.

§15 q=ne: сфера тела с радиально размещёнными ±зарядами,
расчёт n = q/e.

§16 Строение атома: ядро + N электронов на orbitals (2-8-8-2 shells).

§18 A=qU: 2 пластины + drag-arrow с подписью работы.

§19 ЭДС: батарея с readout ε = A/q.

§20 I=q/t: провод с анимированными носителями.

§21 Замкнутая цепь: батарея + switch + лампа, кнопка открыть/замкнуть.

§23 R=ρl/S: динамический wire с длиной/толщиной по scrubberу,
R вычисляется для меди.

§24 Последовательное: 2 резистора, общее R=R1+R2, I.

§26 P=UI: светящаяся лампа brightness ∝ P, лучи при P>120 Вт.

§27 A=UIt: time-bar 0-24 ч, A в кВт·ч.

§29 B≈I вокруг провода: концентрические штриховые круги, opacity ∝ |I|.

§31 Электромагнит: соленоид (число катушек по N), железный сердечник,
полевые линии-параболы с интенсивностью по B=NI.
2026-05-30 10:20:49 +03:00
Maxim Dolgolyov 4d53919e9a feat(phys9 flagships): F9 мост + F11 бильярд + F19 ракета (Wave C+D+финал)
F9. Конструктор моста (§28 в ch3):
- Canvas 700×380: балка на 2 опорах
- Палитра грузов 50/100/200/500 кг (drag&drop) + тест 1000 кг
- Расчёт реакций опор через ΣF=0 + ΣM=0
- При перегрузке (>8000 Н) балка ломается визуально

F11. Бильярдная физика (§32 в ch4):
- Canvas 700×380, зелёный стол, 4 шара
- Тяни мышью от битка → прицельный вектор, отпусти → удар
- Реальные упругие столкновения по нормали
- Трение поля, отскоки от бортов, trails
- Stats: Σ p, Σ Ek

F19. Полёт ракеты (final4, финальный босс):
- Canvas 700×420 — космос со звёздами, Земля внизу
- 4 slider'а: m₀, m_f, v_газов, расход q
- Реальная физика: тяга F = q·u, g(h), сопротивление ρ(h)e^(-h/8000)
- Анимация ракеты с пламенем + перемещение по высоте
- Цель: 400 км (МКС)
- При успехе: +150 XP, localStorage 'phys9_F19_success'

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 10:19:55 +03:00
Maxim Dolgolyov da6dd96aac feat(phys8 ch2): Phase 2.2 — 6 флагман-интерактивов
§12 Charge Sandbox: canvas с динамическим добавлением зарядов.
Click → +заряд (или - через кнопку), drag для перемещения,
стрелки взаимодействия по Кулону (красные=отталкивание,
зелёные=притяжение). Кнопки '+/-', 'Очистить'.

§17 Field Visualizer: drag-зарядов с live перерисовкой
силовых линий. От каждого + рисуются 16 линий, идущих
по полю E через интегрирование шагами. Линии останавливаются
у − зарядов или вылетают за canvas.

§22 Закон Ома: SVG цепь батарея + резистор + лампа.
Scrubbers U (0.5-12 В), R (1-100 Ом). I=U/R обновляется
live, яркость лампы ∝ I (glow при I>0.3).

§25 Параллельные резисторы: SVG цепь с разветвлением.
Scrubbers R₁, R₂. Live расчёт R_общ = R₁R₂/(R₁+R₂),
I₁, I₂ для каждой ветви, общий I.

§28 Магниты: canvas с 2 drag-магнитами (N-S полюса).
При сближении inner полюсов (S-N) рисуются стрелки
притяжения с величиной по F~1/d².

§30 Опыт Эрстеда: SVG провод с током (scrubber -5..+5 А)
и компас под ним. Силовые линии магн. поля вокруг провода
(концентрические штриховые круги) с opacity ∝ |I|.
Стрелка компаса отклоняется по arctan(I), угол выводится.
2026-05-30 10:17:23 +03:00