Commit Graph

70 Commits

Author SHA1 Message Date
Maxim Dolgolyov c4ca8bcae7 refactor(labs): Фаза0 фундамент — убрать мёртвый SimUtil, добавить LabPalette + SimBase
- Удалён _util.js (SimUtil): 0 использований во всех симуляциях (проверено),
  грузился впустую.
- LabPalette (_palette.js): единый источник цветов canvas + PX_PER_M вместо
  хардкода в каждом файле; задел под светлую тему.
- SimBase (_simbase.js): опциональная база жизненного цикла (DPR-fit + RAF
  play/pause/reset/destroy). Существующие симуляции не трогаются; «дробовик»
  остаётся fallback. Адаптация — постепенно, по мере правок (нет фронт-тестов).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 10:52:27 +03:00
Maxim Dolgolyov c0442d6803 feat(labs): задания ещё для 12 симуляций + прогресс плана
LAB_TASKS расширен: waves, circuit, radioactive, heatengine, hydrostatics,
isoprocess, probability, emfield, geometry, photosynthesis, celldivision (+
ранее quadratic/trigcircle/normaldist/projectile/pendulum) — итого 17.
Только валидные single-concept id (мульти-модули molphys/chemistry пропущены).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 10:44:28 +03:00
Maxim Dolgolyov 15282c50b3 feat(labs): Фаза1 — фреймворк учебных заданий (LabTasks)
Превращает песочницы в учебные инструменты: задание → ответ числом с допуском →
проверка/подсказка/прогресс (по образцу race.js, но переиспользуемо).
- _tasks.js: LabTasks (панель, прогресс-точки, проверка с tol, KaTeX в условии).
- Интеграция в loadTheory (одна точка): панель «Задания» дописывается в теорию,
  бейдж на кнопке теории когда задания есть.
- Данные на 5 симуляций: quadratic, trigcircle, normaldist, projectile, pendulum.
Проверка на клиенте (учебные, не оценочные). XP — отдельным инкрементом.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 10:42:17 +03:00
Maxim Dolgolyov 28db2de74f feat(labs): Фаза0 — эконом-режим FX + выбор симуляции из списка в редакторе
План улучшения симуляций — plans/simulations-improvement/README.md.
- LabFX: reduced-motion/эконом-режим (prefers-reduced-motion + тумблер
  localStorage labfx-economy). Тряска отключается, частицы ×0.25 — доступность
  и экономия на слабых устройствах сразу для всех ~50 симуляций. Кнопка-тумблер
  в lab.html рядом со звуком.
- lesson-editor: блок «Симуляция» — выпадающий список из /api/lab/sims
  (сгруппирован по предметам) вместо сырого ввода simId; неизвестный id не
  теряется, помечается «(не найдена)». Закрывает хрупкую вставку в урок.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 10:33:50 +03:00
Maxim Dolgolyov 5b103ab606 refactor(lab): превью симуляций вынесены в общий lab-previews.js (единый источник)
~45 SVG-превью (P_*) и хелперы _grid/_axes/_svg вынесены из lab-glue.js в
общий /js/lab-previews.js: window.LabPreviews (карта id→SVG, 40 симуляций) +
window.__LabP (по имени, lab-glue берёт алиасы оттуда). SIMS не тронут.
lab.html подключает lab-previews.js перед lab-glue.js. Теперь дашборд берёт
настоящие превью симуляций из того же источника → «Лаборатория дня» крутит
весь каталог, а не 6 захардкоженных. Дублирование 6 превью устранено.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 09:34:29 +03:00
Maxim Dolgolyov 6b0d556347 feat(lab-content-engine): phase 5 frontend — чип «Связано с программой»
Реальный фронт Ф5 (ранее ошибочно считал его сделанным параллельной сессией —
его не было). _loadRelated(simId) в lab-glue.js: GET /api/lab/sims/:id/related,
рендерит чипы-ссылки рядом с заголовком симуляции; контейнер #sim-related
создаётся динамически (без правок lab.html/CSS). Вызов из openSim (lab-init.js).
Тихо прячется при отсутствии связей/ошибке. Иконка — inline SVG .ic, без эмодзи.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 17:18:06 +03:00
Maxim Dolgolyov 9754773324 fix(lab-content-engine): браузерные баги Фаз 3-4 + чинка сломанного merge
1. cirSim ReferenceError в _pauseAllSims/closeSim (регрессия Фазы 3): глобалы
   экземпляров симуляций объявлены в ленивых файлах -> не существуют до открытия.
   Предсоздаём их как window-свойства (null) -> guard'ы безопасны. (lab-init.js)
2. theory-data.js (вынос THEORY параллельной сессией) не подключался в lab.html
   -> панель теории и fallback loadTheory ломались. Добавил перед _register-all.
3. _pilots.js удалён в Фазе 1, но lab.html ссылался -> 404. Убрал ссылку.
4. /api/lab/sims 500 на неотмигрированном/устаревшем инстансе -> деградация:
   возвращаем пустой каталог + needs_migration вместо 500. (routes/lab.js)

Проверка: vm-доказательство (_pauseAllSims без throw), node --check всех файлов,
lab-sims тесты 11/11. ВАЖНО: на работающем dev-сервере нужен ПЕРЕЗАПУСК (сервер
не авто-мигрирует) — таблица lab_sims уже в live БД.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 16:02:30 +03:00
Maxim Dolgolyov 201e94ea81 fix(lab-content-engine): phase 3 - устранён блокер ревью (loader не был подключён)
Два edit'а Фазы 3 не применились в fc1139f (упали по отступу), запушив
сломанное состояние: lab.html убрал eager sim-скрипты, но open остался
синхронным -> ReferenceError при клике на любую симуляцию кроме graph.

ИСПРАВЛЕНО:
- _register-all.js: open-обёртка LabLoader.ensure(id).then(rawOpen) + sync-фолбэк
- lab-init.js openSim: обработка Promise от open() (.then -> lucide, .catch -> log)

E2E vm-harness: click->ensure->load->rawOpen после загрузки; pendulum/stereo:cube/
molphys(4 файла)/alias magnetic — ALL PASS; node --check OK.
Независимое ревью поймало этот блокер.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 15:06:40 +03:00
Maxim Dolgolyov fc1139f51d feat(lab-content-engine): phase 3 - ленивая загрузка кода симуляций
Старт /lab грузит только каркас (~530KB) вместо ~2.9MB + three.js(~600KB):
- _loader.js — LabLoader.ensure(id): грузит файлы симуляции по манифесту +
  three.js при необходимости; кеш по URL; САМОВОССТАНОВЛЕНИЕ (если open-функция
  не определена после загрузки — грузит все ленивые файлы -> корректность
  гарантирована независимо от точности манифеста)
- _sim_deps.js — сгенерированный манифест SIM_DEPS{id:{open,files,three}} +
  LAB_LAZY_FILES; three:true только для crystal/orbitals/stereo/periodic
- _register-all.js — open-обёртка: LabLoader.ensure(id).then(rawOpen)
- lab-init.js openSim — обработка Promise от open() (lucide после init)
- lab.html — убраны 45 ленивых <script> + three.js из eager; каркас: registry,
  loader, sim_deps, fx-движки, общие визуалы, graph.js (GRID для 15 сим)

Проверка: vm-harness (per-sim load, three only 3D, кеш, self-heal) ALL PASS;
инвариант owner-in-files для всех 40; нет утечки ленивых в eager; node --check OK.
В БРАУЗЕРЕ НЕ ПРОВЕРЕНО.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 15:02:29 +03:00
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 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 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 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 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 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 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 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 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 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 af46290ca3 feat(labs): новая симуляция «Гонка с задачами» — кинематика 1D с геймификацией
race.js (1357 строк):
- 8 сценариев: встречи (поезд+машина, 2 лодки), догон (мотоциклист, поезда), кто первый (авто vs поезд, 3 спортсмена), свободное падение vs парашют, обгон с разгоном
- Иконки movers inline SVG: car, train, bike, moto, runner, ball, boat
- Аналитический поиск точки встречи: линейный + квадратный + численный (если задержка)
- Стробоскоп положений каждые 0.5-1 с
- Canvas-графики x(t) и v(t) с маркером встречи (красная точка + бейдж)
- Проверка ответа с tolerance ±5%, verdict зелёный/красный
- Слайдеры x₀/v₀/a для каждого мовера + кнопка 'Сброс к сценарию'
- Stats bar 5 ячеек: Время, t_встречи, x_встречи, Лидер, Расстояние между

UI (lab.html):
- Sticky quick-bar: Старт/Пауза/Сброс
- Карточка вопроса вверху + answer-bar внизу с input + verdict
- Collapsible-секции (race-acc): Параметры мовера 1, 2, 3, Настройки

Интеграция:
- lab-init.js: 'sim-race' в ALL_SIM_BODIES + роутинг _openRace
- admin/sims.js: запись в ADMIN_SIMS (cat: Физика, title: 'Гонка с задачами')
- lab-glue.js: P_RACE preset с SVG-превью (дорожка + кривые x(t))
- lab.css: ~200 строк стилей .race-* по паттерну elec/geo/dyn-acc
2026-05-26 19:49:08 +03:00
Maxim Dolgolyov 218baef4ad refactor(labs): полная переработка симуляции Электролиз
electrolysis.js (556 → 1072 строк):
- База электролитов с 3 до 6: NaCl/CuSO4/H2SO4 + KI/ZnSO4/AgNO3
- Стеклянный сосуд с бликами, волнующаяся поверхность раствора (sin-анимация)
- Ионы со стробоскопным шлейфом (4 точки) и радиальным свечением
- Пузырьки: растут при подъёме + pop-эффект на поверхности (LabFX)
- Осадок: градиент по металлу (Cu медь / Zn серый / Ag серебро) + метка
- Электроды с bevel и polarity badge (− / +)
- Внешняя цепь: батарея + провода + анимированные жёлтые электроны
- Закон Фарадея: панель с живой подстановкой U/I/t/Q/m/V в формулу
- Графики m(t)/V(t): мини-холст 200×75 с двумя трендами
- info() добавлены Q (Кл) и n_электронов

lab.html (sim-electrolysis):
- Панель 220 → 280px, класс elec-panel-modern
- elec-quick-bar: Старт/Сброс всегда видны
- 4 collapsible-секции elec-acc: Электролит / Скорость / Отображение / Уравнения
- Stats bar 4 → 6: добавлены Q и e⁻

lab.css: стили .elec-panel-modern, .elec-quick-bar, .elec-acc по паттерну geo-acc/dyn-acc
2026-05-26 19:31:00 +03:00
Maxim Dolgolyov 970276915c fix(opticsbench): призма теперь даёт радугу — фикс геометрии + белый свет по умолчанию
Причины 'один луч, работает неправильно':
1. tangDir = efVec/efLen давал тангенциальное направление, при котором преломлённый луч внутри призмы уходил вниз в основание (sFace > 1), а не в выходную правую грань → внешнего луча не было
2. По умолчанию был включён моно-режим — пользователь видел один луч без дисперсии

Исправлено:
- tangDir = 90° по часовой от efNorm (efNorm.y, -efNorm.x) — теперь падающий луч при стандартных углах попадает в выходную грань правильно
- При первом входе в режим призмы window._obWhiteLight = true → 6 спектральных лучей сразу видны (расхождение цветов)
- Добавлена кнопка 'Белый / Моно' в панель призмы для переключения
2026-05-26 18:45:06 +03:00
Maxim Dolgolyov ce54d3576d fix(opticsbench): починка физики призмы — луч теперь правильно входит и преломляется
PrismSim был сломан в 3 местах:
1. incDir строился с -efNorm (наружу), а не efNorm (внутрь) → падающий луч рисовался не с той стороны
2. cosI = -(incDir·efNorm) с уже-перевёрнутым incDir давал противоречивые знаки
3. Формула Снелла rDir имела + вместо - на коэффициенте efNorm

Итог: при incAngle≈0 преломлённый луч уходил в обратную сторону, точка пересечения с выходной гранью не находилась (tRay<0), и наружный луч с дисперсией не отрисовывался → визуально 'призма не работает'.

Теперь incDir — направление распространения (внутрь призмы), cosI = +(incDir·efNorm), формула: r = (1/n)·l + (cosR − cosI/n)·n
2026-05-26 18:38:04 +03:00
Maxim Dolgolyov be1e558be9 fix(labs): таблица Менделеева + UX качественных реакций + анимации стехиометрии
- Менделеев: clamp() для font-size символа элемента (2.4rem..4.4rem) + padding-top 28px → символ не обрезается на узких панелях
- Качественные реакции: в Свободно/Тренировке Проб1-4 содержат известные ионы (видна подпись), в Тренировке Образец — отдельный неизвестный; в Экзамене можно переключаться между пробирками и ответить отдельно для каждой (verdict сохраняется)
- Стехиометрия: непрерывный анимационный цикл — волна на поверхности жидкости, пузырьки в газах/растворах, пульсирующая красная рамка + ЛИМИТ-лейбл у лимитирующего реагента, искры вдоль стрелки реакции, glow на стрелке во время реакции
2026-05-26 16:26:10 +03:00
Maxim Dolgolyov 4dce6d0d8f refactor(labs): третий редизайн стехиометрии и качественных реакций
- Стехиометрия: single-page dashboard (Реагенты слева + Продукты справа + канва + ИТОГИ), без шагов, без KaTeX
- Качественные реакции: стол-лаборатория с 4 пробирками + Образец, drag&drop реагентов, режимы Свободно/Тренировка/Экзамен
2026-05-26 16:17:17 +03:00
Maxim Dolgolyov 2552c8a90e fix(labs): убрать перекрытие соседних элементов при выборе ячейки в таблице Менделеева
outline:2px + outlineOffset:1px давал 3px рамку поверх 2px-зазора → визуально перекрывал соседей.
Заменил на inset box-shadow — рамка внутри ячейки.
2026-05-26 16:06:49 +03:00
Maxim Dolgolyov 9aa8c76932 refactor(labs): полная переработка стехиометрии и качественных реакций
- Стехиометрия → 4-шаговый wizard (Реакция → Количества → Лимит → Продукты), KaTeX в displayMode, крупные карточки
- Качественные реакции → центрированная сцена с большой пробиркой, журнал справа 290px, нижняя полка реагентов, убран список ионов
- Контраст: основной текст rgba(.92), вторичный (.7), шрифты от .85rem
2026-05-26 15:51:25 +03:00
Maxim Dolgolyov 9ef9443096 fix: три бага — drawGlow closure, replaceChild null guard, stoich text overflow 2026-05-26 15:38:37 +03:00
Maxim Dolgolyov 7a323f8fe0 feat(labs): универсальные инструменты для физических симуляций (Раунд 2)
ФУНДАМЕНТ — frontend/js/labs/_phys_visuals.js (новый файл, 871 строк):
- LSPhysFX.FORCE_COLORS: стандарт 10 цветов (mg красный, N циан, F_тр оранжевый,
  T фиолетовый, F_упр зелёный, F_сопр серый, F_прил жёлтый, импульс, v, a)
- drawVector / drawForceArrow / drawSpring / drawRope / drawSurface
- drawCoordSystem / drawScale / drawClock / drawAngleArc / drawPivot
- drawEnergyBars (KE/PE/W_тр/E_упр стеком с авто-масштабированием)
- LSTimeControl class (pause/play/0.1×-5×/scrubber для одного DOF)
- LSMotionTrail class (gradient line с alpha fade)
- LSBuildTimeControlUI helper для DOM-UI бара

ГРАФИКИ — frontend/js/labs/_graph_panel.js (новый файл, 415 строк):
- LSGraphPanel: 3 stacked time-series плота, авто-scale, freeze/export PNG
- LSGraphPanelUI: overlay-виджет 320×248 в углу canvas, body-selector,
  кнопки Сброс/Стоп/PNG download

FBD (свободные силовые диаграммы) интегрированы в:
- projectile.js: mg + drag + wind + elastic (bounce)
- pendulum.js: mg + T (math), mg + F_упр (spring vert/horiz)
- collision.js: стрелки скорости каждого шара + flash импульса
- newton.js: все сцены законов I-III + новые Атвуд/наклон/скатывание
- forcesandbox.js: gravity/N/friction/spring/applied на каждом теле

ENERGY BARS интегрированы в 5 сим с расчётами:
- projectile: ΔE_drag = F_d·v·dt (cumulative)
- pendulum: для math/spring/double/physical с учётом γ-затухания
- collision: KE loss при каждом столкновении
- newton: все 8 сцен включая Атвуд + наклон + скатывание (с моментом инерции)
- forcesandbox: + E_упр от пружин

GRAPHS PANEL — в 5 сим:
- pendulum: θ/ω/E (режим-aware)
- collision: |v₁|, |v₂|, v_цм
- newton: x/v/a (зависит от закона)
- forcesandbox: x/|v|/|a| выбранного тела
- hydrostatics: depth/vy/submergedFrac (только Архимед)

TIME CONTROL + MOTION TRAILS в 5 сим:
- pendulum (полный scrubber для math), collision, newton, forcesandbox (speed+pause)
- projectile (layered speed+pause, свой trail сохранён)
- LSMotionTrail на bob/балах/блоках с alpha gradient

Заменено рисование пружин на LSPhysFX.drawSpring везде.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 14:37:48 +03:00
Maxim Dolgolyov e46548d06b feat(labs): механика V2 — 4 ключевые симы школьной физики расширены
pendulum V2 (472 → 1651 строк):
- Математический (default, сохранён)
- Двойной маятник (Lagrangian RK4, ghost-копия для демо хаоса)
- Связанные маятники (биения, чарт θ₁/θ₂)
- Пружинный (вертикальный/горизонтальный, T=2π√(m/k))
- Физический (4 формы: стержень/обруч/диск/прямоугольник, с моментом инерции)
- Маятник Фуко (Кориолис, slider широты, период прецессии)
- Резонанс (внешняя F₀·cos(ω_d·t), резонансная кривая A(ω))
- Фазовый портрет (универсальный toggle для всех режимов)

collision V2 (~1000 → 2416 строк):
- 1D (default, сохранён)
- 2D под углом (импульс по осям, slider e, до/после стат)
- Multi-ball (N=2-10, стены с отскоками, перемешать)
- Бильярдный стол (6 луз, кий с прицелом, треугольник шаров, реалистичное трение)
- Реф.фрейм ЦМ (universal toggle)

newton V2 (1693 → 2585 строк):
- 4-й закон-таб «Классические задачи»
- Машина Атвуда (a=(m₂-m₁)g/(m₁+m₂), идеальный/массивный блок)
- Тело на наклонной плоскости (FBD, статика/скольжение, slider α/μ/F_app)
- Скатывание шара/цилиндра/обруча (момент инерции, гонка, наглядно почему обруч медленнее)

projectile V2 (1900 → 2400 строк):
- Парашют: F_d = ½C_d·ρ·A·v² с терминальной скоростью v_t = √(2mg/(C_d·ρ·A))
- C_d selector: парашют/куб/сфера/полусфера/диск; раскрытие парашюта на заданной высоте
- Горка-катапульта: v_0 = √(2gL(sinα-μcosα)) автомат
- 10 планет: Земля/Луна/Марс/Юпитер/Меркурий/Венера/Сатурн/Уран/Нептун/Плутон
  с реальными g + плотностью атмосферы (для drag)
- Сравнительный режим: 3 планеты одновременно с разными цветами

Все 4 симы — additive, существующая функциональность сохранена.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 14:14:42 +03:00
Maxim Dolgolyov 7ffed45974 feat(labs): максимальное улучшение периодической таблицы — 5 волн
ВОЛНА A — Расширенная база данных:
- Новый файл _periodic_data.js (~70 KB): PERIODIC_EXT_DATA + ISOTOPES + SPECTRA
- 30 элементов полностью (H..Au): радиусы, ионизация, теплоёмкость, теплопроводность,
  кристалл, распространённость, биология, токсичность, пламя, применения, история,
  этимология, минералы, типичные реакции
- 9 элементов с минимумом (Sc, Ti, V, As, Se, Kr, Hg, Pb, I)
- 60 изотопов в 20 элементах (включая ¹³¹I, ¹³⁷Cs, ⁶⁰Co, ⁹⁰Sr, ¹⁴C, ³H, U-235/238)
- 43 эмиссионных линий для 8 элементов (H, He, Li, Na, K, Ne, Ar, Hg)

ВОЛНА B — Визуальные режимы:
- Heatmap по 9 свойствам (En, mass, density, melt, boil, discovered + расширенные)
  с jet-colormap, lin/log toggle, легендой, анимацией 400ms
- 3D-таблица через Three.js: bar / wave / stack modes, orbit camera, raycaster hover
- Морф между формами таблицы: standard / long (32-col, f-block inline) / short (8-col)
  с staggered fade-in 800ms
- Тренды стрелками: радиус / ЭО / ИЕ / металличность с градиентными arrows

ВОЛНА C — Карточка элемента 2.0 (11 табов):
- Обзор (hero 96px символ + Z + категория-бейдж + quick stats)
- Свойства (17-row таблица расширенных параметров)
- Электроника (Bohr + статичная конфигурация)
- Изотопы (список + bar chart + weighted average mass)
- История (timeline + этимология)
- Применения (15 SVG иконок-сфер + текст)
- Биология (badge: macro/micro/trace/toxic/inert/radioactive)
- Минералы (формулы)
- Спектр (rainbow 380-780nm + линии эмиссии)
- Пламя (цвет + название)
- Реакции (типовые уравнения по типу элемента)
- Hero header с цветом типа; smooth fade transitions между табами

ВОЛНА D — Интерактивные режимы:
- Бинарные соединения: drag 2 элемента → формула (NaCl, Fe₂O₃) + тип связи (ΔЭО)
- Сравнить до 4 элементов: side-by-side + min/max highlight + chart
- Ряд активности металлов: 28 элементов от Li до Au, разделитель H
- Таблица Менделеева 1869: 63 элемента + 4 предсказанных (Ga, Sc, Ge, Tc)
  с popup «предсказано vs реально»
- Таймлайн открытий 1660-2024 с slider и auto-play

ВОЛНА G — Электронные конфигурации углубление:
- Orbital filling diagram: квадратики с электронами по Хунду/Паули, glow на валентном
- Aufbau diagram с slider Z 1-118 и анимированным указателем порядка заполнения
- Квантовые числа (n, l, m_l, m_s) — hover на электрон → tooltip
- Возбуждение электронов: click на электрон в Bohr → выбор уровня → анимация
  перехода с фотоном (цвет ∝ длине волны через ΔE = 13.6 eV × ...)

periodic.js: 750 → 3239 строк. Все 5 волн ADDITIVE — старая база сохранена.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 13:45:35 +03:00
Maxim Dolgolyov ea2526dc73 feat(labs): 4 школьные хим. симы + визуальная прокачка лаборатории
4 НОВЫЕ СИМЫ (школьная программа 8-11 классов):

Органика (organic.js, 1545 строк):
- Конструктор молекул: drag атомов C/H/O/N/Cl/S, валентности, click-pair bonds
- Авто-определение класса: алкан/алкен/алкин/спирт/альдегид/кислота/эфир/амин/аромат
- IUPAC-имена для C1-C10
- Гомологические ряды: 7 рядов с slider количества углеродов, M, T_кип, T_пл
- 6 качественных реакций: Br₂ вода, KMnO₄, Ag₂O/NH₃ (серебряное зеркало), Cu(OH)₂, FeCl₃, I₂

Периодическая таблица (periodic.js, 118 элементов):
- Стандартный вид 18×9 + лантаноиды/актиноиды
- Карточка элемента: Z, M, конфигурация, степени окисления, ЭО, ρ, T_пл/T_кип
- Боровская модель электронных оболочек (анимированная)
- Подсветка: 11 типов / s/p/d/f-блоки / без подсветки
- Графики свойств по периоду/группе (ЭО, M, плотность, T_пл/T_кип)
- Поиск по символу/имени/Z/массе

Качественный анализ (qualanalysis.js, 24 иона):
- 15 катионов: Na/K/NH₄/Mg/Ca/Ba/Al/Fe²⁺/Fe³⁺/Cu/Ag/Pb/Zn/H/OH
- 10 анионов: Cl/Br/I/SO₄/SO₃/CO₃/NO₃/PO₄/S²/CH₃COO
- 9 реактивов + пламя
- 2 режима: «определи ион» и «неизвестное вещество» с логом наблюдений
- Анимация капли, осадка с цветом, газовых пузырей, пламени

Растворы (solutions.js, 4 режима):
- Калькулятор: m_в, m_р-ра, ρ, T → ω, ν, C_М, C_Н с понятной логикой пересчёта
- Разбавление с before/after визуализацией
- Смешивание двух растворов с правилом рычага
- Кривые растворимости 8 веществ + задача перекристаллизации
- 15 пресетов веществ (NaCl, NaOH, H₂SO₄, CuSO₄·5H₂O, глюкоза, сахароза, ...)

ВИЗУАЛЬНАЯ ПРОКАЧКА (_chem_visuals.js, helper file):

12 функций школьной лабораторной графики:
- drawErlenmeyer / drawBeaker / drawBurette / drawTube — proper SVG-paths со шкалой
- drawSpiritLamp — стеклянный резервуар + фитиль + анимированное пламя
- animateGasBubbles / animatePrecipitateFall — анимация продуктов
- drawProductLabel — fade-in/out стрелка ↑/↓ с подписью
- drawEduTooltip — bubble с пояснением реакции
- drawDeskBackground / drawVesselShadow — лабораторный фон
- drawPHStrip — pH-индикаторная полоса с маркером

Прокачено 6 chem-сим: chemsandbox, flask, titration, electrolysis, ionexchange, redox
Каждая получила: фон парты, тени под колбами, анимированные стрелки продуктов,
educational tooltips из поля 'why' реакции. Спиртовка с пламенем в flask.
pH-полоса в titration.

Каталог теперь: 39 симуляций (было 35 + 4 новых).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 13:08:35 +03:00
Maxim Dolgolyov add17b1bb4 feat(labs): opticsbench round 2 — wave optics + interference + visual depth
Новый режим «Волны» (DiffractionSim, ~400 строк):
- Опыт Юнга: I = I₀·cos²(πd·sinθ/λ), полосы Δy = λL/d, концентрические волновые фронты
- Однощелевая дифракция: (sin α/α)², центральный максимум 2λ/a, минимумы
- Дифракционная решётка: (sin Nψ/N sin ψ)², главные порядки 0,±1,±2,±3, white-light спектр

Новый режим «Интерференция» (InterferenceSim):
- Кольца Ньютона: top-down + cross-section, r_n = √(nλR) тёмные / √((n+½)λR) светлые
- Тонкоплёночная интерференция: integrate I=cos²(π·OPD/λ) по спектру → цвет плёнки
  пресеты: мыльная плёнка / масло на воде / антибликовое покрытие
- Поляризация: P1+P2, закон Малюса I=I₀·cos²θ, анимированные E-векторы, гашение при 90°
  + связь с Брюстером из refraction mode

Визуальные эффекты (5 toggle'ов в <details>):
- «Волновые фронты»: перпендикулярные tick-marks вдоль лучей, λ_screen∝1/n в среде
- «Туман»: LabFX smoke partikles по всему canvas — лучи видны через дым
- «Lens flare»: 6-spike starburst + ghost-reflections + chromatic ring (additive composite)
- «Конструкция Гюйгенса»: расходящиеся wavelets на границе для refraction/reflection
- «Каустики»: 20-ray trace через линзу с aberration-shifted f_eff → настоящая caustic curve
- localStorage persist + zero cost when off

THEORY entry расширен 3 секциями (Юнг + однощель + решётка).

Каталог теперь: 7 вкладок в оптической скамье (lens / mirror / refraction / freebuild / prism / waves / interf).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 12:33:10 +03:00
Maxim Dolgolyov 2a8011d68e feat(labs): opticsbench round 1 — instruments + aberrations + dispersion + chain
9 готовых пресетов приборов (OB_PRESETS):
- Лупа, Микроскоп, Телескопы Кеплера/Галилея, Камера, Перископ, Проектор
- Световод (TIR), Согнутая ложка в воде
- HUD с подписью на 5 сек при загрузке + chime/whoosh sounds

ThinLensSim — стрелка-объект + анимация 3 главных лучей:
- Slider высоты объекта h_o, расчёт h_i и Г с учётом знака
- Real (cyan) vs Virtual (pink, dashed) image
- Кнопка «Построить лучи» → tween (easeOutCubic) по 500мс каждый
- Финальный chime при сходимости

ThinLensSim — формула lensmaker (R₁, R₂, n):
- Toggle «Подробный / Простой» переключает между f-слайдером и R₁/R₂/n
- Вычисление f и диоптрий D=1000/f
- Силуэт линзы динамически меняется (биконвекс/мениск/...)

MirrorSim — переменная кривизна R:
- Slider R: -250..+250 (signed, convex/concave/flat)
- Toggle «Параболическое / Сферическое» → 5-ray aberration fan
- На спherической краевые лучи разъезжаются; на параболе — точечный фокус

FreeBuildSim — multi-lens chain (новый класс):
- Каскадный расчёт изображений: image_n становится object_(n+1)
- F_sys = f1·f2 / (f1+f2-d), общее Г = Г1·Г2·...
- 3 ray tracing через всю цепочку
- 3 пресета: микроскоп / телескоп / relay
- Новая вкладка «Цепочка линз»

ThinLensSim — сферическая и хроматическая аберрации:
- Toggle «Сферическая»: 5 параллельных лучей с f_eff(h) = f - h²/(2f), spread видно
- Toggle «Хроматическая»: 3 bundle R/G/B с f×{1.02,1.0,0.98}, focal spread метки

Wavelength slider 380–780 нм:
- wavelengthToRGB() — sRGB-приближение CIE
- Цвет лучей применён во всех 3 модулях (lens/mirror/refraction)
- Toggle «Белый свет» — 3 RGB bundle с физически корректным n(λ) сдвигом
- n(λ) = 1.55 - 0.0002*(λ-550) — линейная дисперсионная модель

PrismSim — призма (новый класс):
- Равносторонняя стеклянная призма, draggable + rotatable
- Double-Snell на двух гранях, n(λ) → веер радуги при белом свете
- Новая вкладка «Призма»

Спектрометр-панель:
- 280×80 панель с rainbow gradient 380–780 nm
- Маркер текущей длины волны + точки выхода после призмы
- Авто-показ в режиме призмы

Все добавления additive — ни один из существующих 4 режимов не сломан.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 12:16:39 +03:00
Maxim Dolgolyov 02009a8c94 fix(labs): unique preview for hydrostatics (was duplicate of dynamics)
Hydrostatics использовал P_SANDBOX как у dynamics — оба показывали одну
и ту же карточку с блоком/шаром и силами. Добавлен P_HYDRO: мензурка
с погруженным телом + F_A, U-образный манометр с Δh, сообщающиеся сосуды.
2026-05-26 11:52:13 +03:00
Maxim Dolgolyov 6afe928c0d feat(labs): visual polish wave — LabFX foundation + 33 sims juiced up
ФУНДАМЕНТ (4 новых файла):
- _fx_core.js: LabFX namespace, glow.drawGlow, glow.pulse, haptic, shake
- _fx_particles.js: пул 1500 объектов, 6 shapes (dot/spark/ring/smoke/splash/dust)
- _fx_motion.js: tween + 12 easings + critically-damped spring
- _fx_sound.js: 9 procedural synth-звуков (click/tick/whoosh/chime/fizz/spark/bounce/pour/drone), Web Audio API
- Sound toggle в шапке lab.html с localStorage-persist

UX МИКРО (CSS + JS):
- Button states: hover scale+brightness, active scale-down, disabled grayscale
- Slider polish: custom thumb с тенью, filled-track gradient, hover/active
- Focus rings через :focus-visible
- Tooltip system .tt-host data-tt= с 400ms hover, fade-in
- Marching ants для selection
- Loading skeleton с shimmer
- Empty state .sim-empty-* паттерн
- Toast: progress bar внизу, icons по типу
- Cursor states utility classes
- View Transitions API для smooth sim-switch, fallback на CSS fade

PHASE 2 — визуальные эффекты для 33 симуляций:

Physics motion: projectile (launch whoosh + landing splash/shake/haptic + target chime), pendulum (max-extension tick + bob glow), collision (bounce + sparks + shake), angrybirds (whoosh/bounce/fizz/chime + confetti), newton (rocket flame trail + scene transitions), forcesandbox (spring glow + impact sparks)

Physics fields: emfield (field-lines glow + particle trail + lightning при high field + Gauss-drag haptic + rod motion sparks), circuit (energized-wire glow ∝ current + LED bloom + short-circuit shake/spark + heat shimmer smoke + place/erase/switch sounds), opticsbench (beam glow на всех режимах + caustics dust у фокуса + TIR/Brewster one-shot sounds)

Thermo+waves: waves (mode-switch whoosh + Mach-cone particles + spectrum harmonic chime + waveform glow), hydrostatics (pour sound + splash при погружении + valve click), isoprocess (PV-trail dust), heatengine (drone цикла + hot/cold reservoir smoke/dust + phase-change ticks), radioactive (Geiger tick throttle + decay sparks + half-life chime + α/β/γ glow)

Chemistry: chemsandbox (pour splash + fizz bubbles/dust/spark по типу реакции + shake при горении), equilibrium/electrolysis/reactions/titration/flask/ionexchange/redox (pour/fizz/spark/chime по событиям, частицы при ключевых моментах), stoichiometry (fizz bubbles + recipe-change click)

Math+geom: geometry (tool-click + object-create tick + locus glow + challenge confetti via LabFX + haptic), triangle (vertex-drop tick + special-point glow), stereo (figure-change whoosh + cross-section chime, no particles — Three.js), trigcircle (drag-haptic + pitch∝angle tick + sin/cos glow), graph/graphtransform/quadratic (slider-tick throttled + curve glow + discriminant-cross chime), probability (bounce + finish-chime burst), normaldist (pulsing shade + bell glow)

Bio+misc: celldivision (phase-change whoosh + prophase dust + anaphase poles spark + cytokinesis chime), photosynthesis (photon tick + ATP chime + glucose sparkle), bohratom (electron-jump chime ∝ levels + photon spark), orbitals/crystal (mode-change whoosh — Three.js, sound only), logic (gate-place + wire-connect + LED bloom + HIGH wire flowing dots + preset chime), gas/brownian/diffusion/states (preset whoosh, throttled tick по событиям)

Все LabFX вызовы обёрнуты в if (window.LabFX) guard — graceful degradation если фундамент не загружен. 47 JS файлов прошли syntax check.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 13:58:49 +03:00
Maxim Dolgolyov 8b3159b529 feat(labs): wave 3 — 5 new sims + optics merger
Оптическая скамья (opticsbench) — merger thinlens + mirror + refraction
- 4 режима: «Свободная сборка» / «Линза» / «Зеркало» / «Преломление»
- Все 3 движка слиты в OpticsBenchSim (1583 строк)
- Backward compat: #thinlens / #mirrors / #refraction → #opticsbench
- Удалены: thinlens.js, mirror.js, refraction.js

Радиоактивный распад (radioactive) — новая сима
- Monte-Carlo распад: λ·dt вероятность на тик, частицы меняют цвет, эмитируются α/β/γ
- Real-time N(t) график с теоретической кривой N₀·exp(-λt)
- 7 изотопов: ¹⁴C, ¹³¹I, ¹³⁷Cs, ²²⁶Ra, ⁴⁰K, ²³⁸U-chain, ²³⁵U-chain
- Цепочки распадов (U-238: 14 шагов сокращены до 5 ключевых)
- Dating mode для C-14: t = ln(N₀/N)/λ
- HUD: периодов прошло, % распалось, активность в Бк

Тепловые двигатели (heatengine) — новая сима
- 4 цикла: Карно / Отто / Дизель / Брайтон
- PV-диаграмма с замкнутым циклом, заполненной площадью работы
- Аналитически точные изотермы (PV=nRT) и адиабаты (PV^γ=const)
- Анимированный поршень с резервуарами (красный T_h / синий T_c)
- Частицы газа, скорость ∝ √T
- Hover-tooltips с формулами для каждого сегмента

Логические схемы (logic) — новая сима для информатики
- Drag-drop конструктор: 12 типов компонентов (INPUT/CLOCK/OUTPUT/AND/OR/NOT/XOR/NAND/NOR/XNOR/BUF/wire)
- Топологическая сортировка для propagation, цветовая подсветка HIGH/LOW
- Авто-генерация булевого выражения (∧ ∨ ¬ ⊕)
- Авто-таблица истинности (до 2^6 = 64 строк)
- 6 пресетов: полусумматор, полный сумматор, RS-триггер, D-триггер, декодер 2-в-4, мультиплексор 2-в-1

Стехиометрия (stoichiometry) — новая сима
- 10 реакций: Zn+HCl, H₂+O₂, CH₄+O₂, N₂+H₂ (Габер), Al+CuSO₄, Mg+O₂, CaCO₃→, HCl+NaOH, KMnO₄→, C₂H₅OH+O₂
- Sliders с переключением m/n/V (для газов V=n·22.4 при н.у.)
- Анимация частиц при реакции, подсветка лимитирующего реагента
- Пошаговый расчёт m→n→n_product→m_product с KaTeX
- HUD: лимит, избытки, теоретический выход

Каталог: 33 → 35 сим (5 новых − 3 удалённых merger)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 13:25:16 +03:00
Maxim Dolgolyov 8f30a8cef6 feat(labs): wave 2 — depth features across 6 sims
Электрические цепи (circuit):
- Индуктивность L как новый компонент (1–1000 мГн, шорт в DC, jωL в AC)
- RLC preset для демонстрации резонанса
- Осциллограф: U(t)/I(t) для выбранного компонента, 100 sample, dual-axis
- Heatmap мощности: радиальный градиент halo от blue→red пропорционально P=UI

Стереометрия 3D (stereo):
- Сечение через 3 произвольные точки: pick на гранях/рёбрах/вершинах
- Плоскость + полигон пересечения с авто-определением типа (3–6-угольник) и площадью
- Step-by-step режим: визуализация P1→линия→P2→линия→P3→плоскость→сечение
- Поддержка всех solids (включая cylinder/cone через sampling fallback)

Планиметрия (geometry):
- Задачник framework: CHALLENGES[] с setup/check функциями
- 5 стартовых задач: серединный перпендикуляр, биссектриса, описанная окружность, ГМТ, касательная
- Авто-checker: толерантности ±0.5° для углов, ±1–5% для расстояний
- UI: collapsible панель с статус-иконками, конфетти + «Молодец!» на success

Электромагнитные поля (emfield):
- Preset «Тороид»: 16+16 проводов в концентрических кольцах
- Поверхность Гаусса: draggable круг, считает Φ = q_enc/ε₀, подсвечивает охваченные заряды
- Motional EMF: draggable rod, arrow-keys управление, считает ε = ∫(v×B)·dl

Химическая песочница (chemsandbox):
- Live-overlay с уравнением реакции: молекулярное / полное ионное / сокращённое ионное
- Coverage: 49/49 молекулярных, 34/49 ионных, 36/49 сокращённых
- Auto-hide через 5 сек, fade-in animation, цветовая кодировка типов

Волны и звук (waves):
- Doppler: source+observer drag, expanding wavefronts, f_obs формула, Mach cone при v>c
- Beats: f1+f2, sum waveform с envelope, индикация f_beat=|f1-f2|
- Spectrum (DFT): N=256 samples pure JS, bar-chart с пиками и labels, «Добавить гармонику»

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 12:48:14 +03:00
Maxim Dolgolyov 7f75c96acd feat(labs): planimetry locus + emfield merger + projectile graphs + UI cleanup
Геометрия (планиметрия):
- Живые измерения как объекты: длина / угол / площадь — auto-recompute, draggable chips
- Инструмент ГМТ: sweep мовера через параметр, рисует кривую места точек
- Новые типы точек: on_segment (скользит по отрезку, _t), on_circle (по окружности, _theta)
- Toolbar: «Длина», «Угол», «Площадь», «ГМТ», «На отрезке», «На окружности»

Электромагнитные поля (emfield):
- Merge magnetic.js + coulomb.js в один EMFieldSim с 3 режимами (E / B / комбинированное)
- Унифицированный pipeline: colormap, field lines, vectors, equipotentials, flux loop, test particle
- Combined-режим: полная сила Лоренца F=q(E+v×B)
- Backward compat: #coulomb и #magnetic хеши и ?sim= параметры редиректят в emfield
- Удалены: magnetic.js, coulomb.js. Добавлен: emfield.js

Бросок тела (projectile):
- Режим целей: 3 окна, hit-детекция, HUD «Цели: N/M / Попыток: K»
- Графики x(t), y(t), vx(t), vy(t) — 2×2 Canvas 2D, real-time
- Двойной бросок: одновременно 2 траектории для сравнения (cyan vs gold)

UI fixes (по результатам аудита):
- Заменены emoji/unicode на inline SVG .ic: switch ⌇, spring 〜 (5 мест), download ⬇ (2), camera 📷
- Убраны декоративные символы ☉ ○ из geometry tool labels
- Добавлены THEORY entries: geometry, hydrostatics (раньше показывали fallback)
- Стандартизирована ширина panel для sim-proj и sim-coll (240px)
- waves перенесён в физический блок SIMS catalog (был после биологии)
- Очищен дефолтный sim-topbar-title (был «График функции»)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 12:09:44 +03:00
Maxim Dolgolyov 0b9685bc5e feat(lab): phase 4 -- hash-router for sim deep-links
URL #sim/<name> deep-links: F5 restores sim, browser back/forward
switches between sims, click on sim-card updates URL.

34 sims mapped via _SIM_HASH_MAP (built dynamically from SIMS array).
Unknown hash -> console.warn fallback.
Recursion guard prevents double-activation on programmatic navigate.
closeSim clears hash via history.pushState (no hashchange loop).
Embed mode excluded from hash updates (?embed=1 workflow unaffected).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 22:56:18 +03:00