Spaces:
Sleeping
Sleeping
Download server/static/js/app.js from ArshPathan/material_forge_env: direct link, hf CLI and curl.
- Browser
- Download file 2.92 kB
-
https://huggingface.co/spaces/ArshPathan/material_forge_env/resolve/main/server/static/js/app.js
- Command line
-
hf download hf://spaces/ArshPathan/material_forge_env/server/static/js/app.js
-
curl -L -o app.js https://huggingface.co/spaces/ArshPathan/material_forge_env/resolve/main/server/static/js/app.js
2.92 kB
| import { LabAPI } from './modules/api.js'; | |
| import { LatticeRenderer } from './modules/renderer.js'; | |
| import { TelemetryUI } from './modules/ui.js'; | |
| class DiscoveryLab { | |
| constructor() { | |
| this.api = new LabAPI(window.location.host); | |
| this.ui = new TelemetryUI(); | |
| this.renderer = new LatticeRenderer( | |
| document.getElementById('lattice-canvas'), | |
| { 'A': '#ef4444', 'B': '#3b82f6', 'C': '#f59e0b', 'P': '#8b5cf6' } | |
| ); | |
| this.state = { | |
| selectedAtom: 'A', | |
| bestReward: 0 | |
| }; | |
| this.init(); | |
| } | |
| async init() { | |
| this.bindEvents(); | |
| try { | |
| await this.api.connect('/ws'); | |
| this.ui.log('Lab connection established', 'ok'); | |
| this.reset(); | |
| } catch (e) { | |
| this.ui.log('Failed to connect to lab engine', 'err'); | |
| } | |
| this.api.onMessage((msg) => this.handleMessage(msg)); | |
| } | |
| bindEvents() { | |
| document.getElementById('btn-reset').onclick = () => this.reset(); | |
| // Canvas interaction | |
| this.renderer.canvas.onclick = (e) => this.handleCanvasClick(e); | |
| this.renderer.canvas.oncontextmenu = (e) => { | |
| e.preventDefault(); | |
| this.handleCanvasClick(e, true); | |
| }; | |
| // Atom selection | |
| document.querySelectorAll('.atom-btn').forEach(btn => { | |
| btn.onclick = () => { | |
| document.querySelectorAll('.atom-btn').forEach(b => b.classList.remove('selected')); | |
| btn.classList.add('selected'); | |
| this.state.selectedAtom = btn.dataset.atom; | |
| }; | |
| }); | |
| } | |
| handleMessage(msg) { | |
| if (msg.type === 'observation') { | |
| const { observation, reward } = msg.data; | |
| if (reward > this.state.bestReward) this.state.bestReward = reward; | |
| this.renderer.draw(observation.grid); | |
| this.ui.updateKPIs(observation, reward, this.state.bestReward); | |
| this.ui.updatePropertyBars(observation); | |
| } | |
| } | |
| reset() { | |
| const scenario = document.getElementById('sel-scenario').value; | |
| const difficulty = document.getElementById('sel-difficulty').value; | |
| this.api.send('reset', { scenario_name: scenario, difficulty }); | |
| this.state.bestReward = 0; | |
| this.ui.log(`Workspace re-initialized: ${scenario || 'random'}`, 'info'); | |
| } | |
| handleCanvasClick(e, isRightClick = false) { | |
| const rect = this.renderer.canvas.getBoundingClientRect(); | |
| const x = e.clientX - rect.left; | |
| const y = e.clientY - rect.top; | |
| const cellSize = this.renderer.canvas.width / 8; | |
| const col = Math.floor(x / cellSize); | |
| const row = Math.floor(y / cellSize); | |
| const action = isRightClick ? 'remove' : 'place'; | |
| this.api.send('step', { | |
| action_type: action, | |
| row, col, | |
| atom: this.state.selectedAtom | |
| }); | |
| } | |
| } | |
| // Start lab | |
| window.addEventListener('load', () => { | |
| window.lab = new DiscoveryLab(); | |
| document.getElementById('loading-overlay').classList.add('hidden'); | |
| }); | |