# Phase 0: Спека v1 + рантайм (формульные сцены) **Status:** ✅ Implemented (не закоммичено — коммит за оркестратором) **Parent plan:** [PLAN.md](./PLAN.md) **Domain:** frontend ## Objective Заложить ядро: формат JSON-спеки v1, безопасный движок выражений, рантайм `SimEngine`, адаптер регистрации в `LabRegistry`. После фазы рукописная спека «брошенное тело» играет в /lab. ## Tasks - [x] Задокументировать формат спеки v1 в шапке нового файла + в CONTEXT.md (params, objects, viewport, controls). → шапка `_sim_engine.js` (полный JSON-формат) + CONTEXT.md. - [x] `frontend/js/labs/_sim_expr.js` — безопасный движок выражений: токенайзер → AST → `evaluate(ast, env)`. Whitelist математики (см. CONTEXT.md). Парсер расширяет логику `y=f(x)` из `graph.js` (тот же подход к токенам/неявному умножению; добавлены сравнения, логика, тернарник, multi-var env, min/max/mod/log(b,x)). ⛔ без `eval`/`Function`. `compile(src) -> {ast, fn(env), error}`. - [x] `frontend/js/labs/_sim_engine.js` — `window.SimEngine.mount(host, spec)`: - canvas с мир→экран (равные оси, вписан в viewport, Y вверх) + оверлей-слой `
` для подписей (KaTeX `renderToString`, как в graph.js); - объекты: point|segment|vector|circle|rect|polyline|path|label (числовые свойства = число или строка-выражение, компилируются один раз в mount); - rAF-цикл: `t += dt*speed`, loop/duration, перевычисление привязок, перерисовка, трассы (`trail`); - контролы: слайдеры из `params[]` + play/pause/reset; API `{ play, pause, reset, setParam, getParam, isRunning, destroy, el }`. - [x] `frontend/js/labs/_sim_adapter.js` — `registerSpecSim(spec)` строит манифест LabRegistry (`open(ctx)` → ленивый собственный хост-div + `SimEngine.mount`; `stop` прячет хост+pause; `destroy` уничтожает инстанс; `preview` из спеки или авто-SVG) и регистрирует. - [x] Фикстура-демо: рукописная спека «projectile» (слайдеры θ 0..90 / v 0..30, точка x=v·cosθ·t, y=max(0, v·sinθ·t−5t²), вектор v0, земля, подпись) — зарегистрирована как `customdemo` за флагом `?simdemo=1` / `?sim=customdemo` / `LAB_SHOW_SPEC_DEMO` / localStorage `lab-spec-demo=1`. Ученикам не светится (карточки в SIMS нет; добавляется только при включённом флаге). - [x] Подключить новые файлы в /lab прямыми `