// Main page glue: static-deployment build. // - episode list comes from /index.json // - per-sample assets live at //{depth.mp4, recording.viser, ...} // - the 3D viewer is the viser-build-client iframe loading recording.viser import { SignalPanel, StateTimelinePanel } from './timeseries.js'; // Where to fetch episode data from. Resolution order: // 1. ?base= query param (manual override) // 2. localhost: ./samples (local dev via symlink to _dist) // 3. otherwise: HF Dataset resolve URL (Private dataset uses cookie auth // from the same huggingface.co origin - user must be logged in) const ASSET_BASE = (() => { const u = new URL(window.location.href); const explicit = u.searchParams.get('base'); if (explicit) return explicit; if (location.hostname === 'localhost' || location.hostname.startsWith('127.')) { return './samples'; } return 'https://huggingface.co/datasets/Rice-RobotPI-Lab/egoinfinity/resolve/main/samples'; })(); const INDEX_URL = `${ASSET_BASE}/index.json`; // Build an absolute URL to a sample's recording.viser. The viser client iframe // lives at viser-client/, so a relative ASSET_BASE like ./samples would resolve // against viser-client/ instead of the page. We resolve against location.href // (not document.baseURI) because HF Static Spaces sandbox the page's baseURI // to a different origin than the URL we actually want to anchor to. function viserPlaybackUrl(name) { return new URL( `${ASSET_BASE}/${encodeURIComponent(name)}/recording.viser`, location.href ).href; } // Absolute URL of the viser-client iframe's index.html, with the playbackPath // query already attached. Two non-obvious bits: // - Anchored to location.href so the iframe loads from the same origin as // app.js (HF Static Spaces sandbox baseURI to a different origin). // - Path explicitly ends in /index.html - HF's static-file server does // NOT auto-serve directory indexes, so requesting "viser-client/" 404s. function viserClientUrl(name) { return new URL( `viser-client/index.html?playbackPath=${encodeURIComponent(viserPlaybackUrl(name))}`, location.href ).href; } // === YouTube IFrame API integration ========================================= // YouTube is the master clock - the local