# Phase 4: Hash-router для sim deep-links

**Status:** ⬜ Not Started
**Parent plan:** [PLAN.md](./PLAN.md)
**Domain:** frontend

## Objective

Сделать `#sim/projectile`, `#sim/newton`, `#sim/chemsandbox` etc. → открывают конкретный sim в lab. F5 на любом deep-link восстанавливает sim. Browser back/forward переключают между симуляциями. По образцу admin-redesign Phase 1 router.

## Tasks

- [ ] В `frontend/js/labs/lab-glue.js` (или новый `frontend/js/labs/lab-router.js`):
  - На load: прочитать `location.hash`, parsr `#sim/<name>`, активировать соответствующий sim
  - Listen `hashchange`: при изменении hash → переключить sim
  - При программном переключении sim (через sim-switcher UI) → обновить hash без recursion (флаг `_routerNavigating`)
- [ ] Map sim-name → sim-id:
  - `#sim/projectile` → activate `<div id="sim-proj">`
  - `#sim/newton` → activate `<div id="sim-dynamics">` (или какой-там)
  - Полный mapping из существующих sim-ID
- [ ] Fallback: unknown hash → ignore (показать default sim)
- [ ] Verify: F5 на `/lab#sim/projectile` восстанавливает projectile sim

## Files to Modify

- `frontend/js/labs/lab-glue.js` — добавить router code (~50-100L)
- `frontend/lab.html` — без изменений (или + 1 script tag если делаем отдельный lab-router.js)

## Acceptance Criteria

- F5 на `/lab#sim/X` восстанавливает соответствующий sim
- Browser back/forward переключают между sims
- Click на sim-switcher обновляет URL (`#sim/X` в адресной строке)
- Unknown hash (`#sim/nonexistent`) → console.warn + fallback на default
- 5 deep-link проверены вручную (projectile, newton, chemsandbox, gas, mirror)

## Notes

### Recursion guard pattern (из admin-redesign Phase 1)

```js
let _navigating = false;
function navigateTo(simId) {
  _navigating = true;
  location.hash = '#sim/' + simId;
  setTimeout(() => { _navigating = false; }, 0);
  activateSim(simId);
}
window.addEventListener('hashchange', () => {
  if (_navigating) return;
  const m = location.hash.match(/^#sim\/([\w-]+)/);
  if (m) activateSim(m[1]);
});
```

### Reference

`frontend/js/admin/router.js` (admin-redesign Phase 1) — read for inspiration. Adapt to lab context.

## Review Checklist

- [ ] Hash deep-link работает для 5 проверенных симов
- [ ] Browser back/forward работают
- [ ] No console errors
- [ ] No infinite-loop при программной активации
- [ ] Pre-commit hook passes

## Handoff to Next Phase

<!-- Implementer: full mapping #sim/X → sim-ID для Phase 5 (template lazy). -->
