EgoSieve / app.mjs
itspublu's picture
Release EgoSieve manifest inspector v0.1.0
9b4ace6 verified
Raw
History Blame Contribute Delete
34.7 kB
import {
READINESS_LABELS,
aggregateIssues,
buildSegmentExport,
decisionFor,
formatDuration,
parseManifest,
summarizeManifest,
} from "./manifest.mjs";
const SVG_NS = "http://www.w3.org/2000/svg";
const MAX_MANIFEST_BYTES = 32 * 1024 * 1024;
const CHART = Object.freeze({ width: 1000, height: 360, left: 58, right: 20, top: 28, bottom: 45 });
const COLORS = Object.freeze({ KEEP: "#d7ff35", REVIEW: "#ff5b26", REJECT: "#898b83" });
const state = {
parsed: null,
manifestText: "",
manifestFileName: "",
manifestUrl: null,
videoUrl: null,
videoFileName: "",
videoDurationWarning: null,
selectedSegmentIndex: null,
routeFilter: "all",
toastTimer: null,
};
function byId(id) {
const element = document.getElementById(id);
if (!element) throw new Error(`Missing required element #${id}`);
return element;
}
function clear(element) {
element.replaceChildren();
}
function node(tagName, className = "", text = null) {
const element = document.createElement(tagName);
if (className) element.className = className;
if (text !== null) element.textContent = text;
return element;
}
function svgNode(tagName, attributes = {}) {
const element = document.createElementNS(SVG_NS, tagName);
for (const [name, value] of Object.entries(attributes)) {
element.setAttribute(name, String(value));
}
return element;
}
function safeFileName(value, fallback) {
const leaf = String(value || fallback).split(/[\\/]/u).pop() || fallback;
const safe = leaf.replace(/[^a-zA-Z0-9._-]+/gu, "-").replace(/^-+|-+$/gu, "");
return safe || fallback;
}
function displayPathLeaf(value) {
return String(value || "unknown source").split(/[\\/]/u).pop() || "unknown source";
}
function formatPercent(value, digits = 0) {
return typeof value === "number" && Number.isFinite(value)
? `${(value * 100).toFixed(digits)}%`
: "—";
}
function formatTimecode(seconds) {
if (typeof seconds !== "number" || !Number.isFinite(seconds) || seconds < 0) return "00:00.0";
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const remainder = seconds % 60;
const base = `${String(minutes).padStart(2, "0")}:${remainder.toFixed(1).padStart(4, "0")}`;
return hours > 0 ? `${hours}:${base}` : base;
}
function prettyIssue(name) {
return String(name).replaceAll("_", " ");
}
function routeClass(route) {
return `route-${route === "discard" ? "discard" : route}`;
}
function decisionRoute(segment) {
if (["keep", "review", "discard"].includes(segment.route)) return segment.route;
return { KEEP: "keep", REVIEW: "review", REJECT: "discard" }[decisionFor(segment)] ?? "review";
}
function showNotice(message, isError = false) {
const notice = byId("notice");
notice.textContent = message;
notice.classList.toggle("is-error", isError);
notice.hidden = false;
}
function hideNotice() {
byId("notice").hidden = true;
}
function showToast(message) {
const toast = byId("toast");
toast.textContent = message;
toast.hidden = false;
if (state.toastTimer !== null) window.clearTimeout(state.toastTimer);
state.toastTimer = window.setTimeout(() => {
toast.hidden = true;
state.toastTimer = null;
}, 2600);
}
async function copyText(text, successMessage) {
try {
if (navigator.clipboard && window.isSecureContext) {
await navigator.clipboard.writeText(text);
} else {
const helper = document.createElement("textarea");
helper.value = text;
helper.setAttribute("readonly", "");
helper.style.position = "fixed";
helper.style.opacity = "0";
document.body.append(helper);
helper.select();
const copied = document.execCommand("copy");
helper.remove();
if (!copied) throw new Error("copy command was refused");
}
showToast(successMessage);
} catch {
showToast("Copy was blocked. Select the text and copy it manually.");
}
}
function revokeManifestUrl() {
if (state.manifestUrl) URL.revokeObjectURL(state.manifestUrl);
state.manifestUrl = null;
}
function updateManifestDownload() {
revokeManifestUrl();
const link = byId("download-manifest");
if (!state.manifestText) {
link.removeAttribute("href");
return;
}
state.manifestUrl = URL.createObjectURL(
new Blob([state.manifestText], { type: "application/x-ndjson;charset=utf-8" }),
);
link.href = state.manifestUrl;
link.download = safeFileName(state.manifestFileName, "egosieve-manifest.jsonl");
}
function visibleSegments() {
if (!state.parsed) return [];
if (state.routeFilter === "all") return [...state.parsed.segments];
return state.parsed.segments.filter((segment) => decisionRoute(segment) === state.routeFilter);
}
function renderWarnings() {
const stack = byId("warning-stack");
clear(stack);
const warnings = [...(state.parsed?.warnings ?? [])];
if (state.videoDurationWarning) warnings.push(state.videoDurationWarning);
if (warnings.length === 0) {
stack.hidden = true;
return;
}
for (const warning of warnings) stack.append(node("p", "", `⚠ ${warning}`));
stack.hidden = false;
}
function checkVideoDuration() {
const video = byId("video");
const manifestDuration = state.parsed?.header.source.duration_s;
if (!state.videoUrl || !manifestDuration || !Number.isFinite(video.duration)) {
state.videoDurationWarning = null;
return;
}
const difference = Math.abs(video.duration - manifestDuration);
const tolerance = Math.max(0.5, manifestDuration * 0.01);
state.videoDurationWarning = difference > tolerance
? `Local video duration (${formatDuration(video.duration)}) differs from the manifest (${formatDuration(manifestDuration)}). Verify that the files match.`
: null;
}
function readinessPoint(windowRecord, label) {
const value = windowRecord.readiness?.[label];
return typeof value === "number" && Number.isFinite(value) ? value : null;
}
function renderTimeline(parsed) {
const svg = byId("timeline");
clear(svg);
const title = svgNode("title", { id: "timeline-title" });
title.textContent = "Readiness probabilities over time";
const description = svgNode("desc", { id: "timeline-description" });
const evidenceWindows = parsed.windows.filter((windowRecord) =>
READINESS_LABELS.every((label) => readinessPoint(windowRecord, label) !== null),
);
description.textContent = evidenceWindows.length > 0
? `${evidenceWindows.length} scored windows across ${formatDuration(parsed.header.source.duration_s)}.`
: "This manifest contains no window-level readiness probability maps.";
svg.append(title, description);
const chartWidth = CHART.width - CHART.left - CHART.right;
const chartHeight = CHART.height - CHART.top - CHART.bottom;
const duration = Math.max(parsed.header.source.duration_s, 0.001);
const x = (seconds) => CHART.left + (Math.max(0, Math.min(duration, seconds)) / duration) * chartWidth;
const y = (probability) => CHART.top + (1 - probability) * chartHeight;
for (const probability of [0, 0.25, 0.5, 0.75, 1]) {
svg.append(
svgNode("line", {
x1: CHART.left,
y1: y(probability),
x2: CHART.left + chartWidth,
y2: y(probability),
stroke: "rgba(239,238,230,.13)",
"stroke-width": 1,
"vector-effect": "non-scaling-stroke",
}),
);
const label = svgNode("text", { x: CHART.left - 12, y: y(probability) + 4, "text-anchor": "end" });
label.textContent = `${Math.round(probability * 100)}`;
svg.append(label);
}
const tickCount = duration > 900 ? 4 : 6;
for (let index = 0; index <= tickCount; index += 1) {
const seconds = (duration * index) / tickCount;
svg.append(
svgNode("line", {
x1: x(seconds),
y1: CHART.top,
x2: x(seconds),
y2: CHART.top + chartHeight,
stroke: "rgba(239,238,230,.075)",
"stroke-width": 1,
"vector-effect": "non-scaling-stroke",
}),
);
const label = svgNode("text", {
x: x(seconds),
y: CHART.top + chartHeight + 25,
"text-anchor": index === 0 ? "start" : index === tickCount ? "end" : "middle",
});
label.textContent = formatTimecode(seconds);
svg.append(label);
}
if (evidenceWindows.length === 0) {
const empty = svgNode("text", {
x: CHART.left + chartWidth / 2,
y: CHART.top + chartHeight / 2,
"text-anchor": "middle",
});
empty.textContent = "NO WINDOW PROBABILITY CURVES IN THIS MANIFEST";
svg.append(empty);
} else {
for (const label of [...READINESS_LABELS].reverse()) {
const coordinates = evidenceWindows.map((windowRecord) => ({
x: x((windowRecord.start_s + windowRecord.end_s) / 2),
y: y(readinessPoint(windowRecord, label)),
}));
const path = svgNode("path", {
d: coordinates.map((point, index) => `${index === 0 ? "M" : "L"}${point.x.toFixed(2)},${point.y.toFixed(2)}`).join(" "),
fill: "none",
stroke: COLORS[label],
"stroke-width": label === "KEEP" ? 3.5 : 2,
"stroke-linejoin": "round",
"stroke-linecap": "round",
opacity: label === "KEEP" ? 1 : 0.82,
"vector-effect": "non-scaling-stroke",
});
svg.append(path);
if (label === "KEEP") {
for (const point of coordinates) {
svg.append(
svgNode("circle", {
cx: point.x,
cy: point.y,
r: 3.5,
fill: COLORS.KEEP,
stroke: "#10110f",
"stroke-width": 1.5,
"vector-effect": "non-scaling-stroke",
}),
);
}
}
}
}
svg.append(
svgNode("line", {
id: "playhead-line",
x1: CHART.left,
y1: CHART.top,
x2: CHART.left,
y2: CHART.top + chartHeight,
stroke: "#efeee6",
"stroke-width": 1,
"stroke-dasharray": "4 4",
opacity: 0,
"vector-effect": "non-scaling-stroke",
"pointer-events": "none",
}),
);
byId("timeline-end").textContent = formatTimecode(duration);
}
function renderSegmentTrack(parsed) {
const track = byId("segment-track");
clear(track);
const duration = Math.max(parsed.header.source.duration_s, 0.001);
if (parsed.segments.length === 0) {
track.setAttribute("aria-label", "No compiled segments in this manifest");
return;
}
for (const segment of parsed.segments) {
const route = decisionRoute(segment);
const button = node("button", `track-segment ${routeClass(route)}`);
button.type = "button";
button.dataset.segmentIndex = String(segment.segment_index);
button.style.left = `${Math.max(0, Math.min(100, (segment.start_s / duration) * 100))}%`;
button.style.width = `${Math.max(0.2, Math.min(100, ((segment.end_s - segment.start_s) / duration) * 100))}%`;
button.title = `${decisionFor(segment)} · ${formatTimecode(segment.start_s)}${formatTimecode(segment.end_s)}`;
button.setAttribute("aria-label", `Select ${decisionFor(segment)} segment ${segment.segment_index}, ${formatTimecode(segment.start_s)} to ${formatTimecode(segment.end_s)}`);
button.addEventListener("click", () => selectSegment(segment, true));
track.append(button);
}
}
function renderSegments() {
const list = byId("segment-list");
clear(list);
const segments = visibleSegments();
byId("download-segments").textContent = state.routeFilter === "all"
? "Export all segments"
: `Export ${state.routeFilter === "discard" ? "reject" : state.routeFilter} segments`;
if (segments.length === 0) {
list.append(node("p", "empty-list", "No compiled segments match this route."));
return;
}
for (const segment of segments) {
const route = decisionRoute(segment);
const decision = decisionFor(segment);
const button = node("button", "segment-row");
button.type = "button";
button.dataset.segmentIndex = String(segment.segment_index);
button.setAttribute("aria-label", `Inspect ${decision} segment ${segment.segment_index} at ${formatTimecode(segment.start_s)}`);
button.append(node("span", "segment-row-index", String(segment.segment_index).padStart(2, "0")));
button.append(node("span", `segment-route ${routeClass(route)}`, decision));
const time = node("span", "segment-time");
time.append(
node("strong", "", `${formatTimecode(segment.start_s)}${formatTimecode(segment.end_s)}`),
node("small", "", `${formatDuration(segment.end_s - segment.start_s)} · ${segment.reason ?? "stable"}`),
);
button.append(time);
const confidence = segment.readiness?.[decision] ?? segment.mean_score;
const score = node("span", "segment-score");
score.append(node("strong", "", formatPercent(confidence)), node("small", "", "route confidence"));
button.append(score);
const reports = Array.isArray(segment.reported_issues) ? segment.reported_issues.length : 0;
button.append(node("span", "segment-issue-count", `${reports} SIGNAL${reports === 1 ? "" : "S"}`));
button.addEventListener("click", () => selectSegment(segment, true));
list.append(button);
}
updateSelectedClasses();
}
function renderIssues(parsed) {
const list = byId("issue-list");
clear(list);
const issues = aggregateIssues(parsed.segments.length > 0 ? parsed.segments : parsed.windows);
if (issues.length === 0) {
list.append(node("p", "empty-list", "No issue probabilities were recorded."));
return;
}
for (const issue of issues) {
const row = node("div", "issue-row");
const heading = node("div", "issue-row-head");
heading.append(
node("span", "issue-name", prettyIssue(issue.name)),
node("span", "issue-value", `${formatPercent(issue.max)} / ${formatPercent(issue.mean)}`),
);
const meter = node("div", "issue-meter");
meter.title = `Maximum ${formatPercent(issue.max, 1)}; mean ${formatPercent(issue.mean, 1)} across ${issue.samples} record${issue.samples === 1 ? "" : "s"}`;
const maximum = node("span");
maximum.style.width = `${Math.min(100, issue.max * 100)}%`;
const mean = node("i");
mean.style.left = `${Math.min(100, issue.mean * 100)}%`;
meter.append(maximum, mean);
row.append(heading, meter);
list.append(row);
}
}
function metadataValue(value) {
if (value === null || value === undefined || value === "") return "—";
if (typeof value === "object") return JSON.stringify(value);
return String(value);
}
function renderMetadata(header) {
const source = header.source ?? {};
const model = header.model ?? {};
const sampling = header.sampling ?? {};
const policy = header.policy ?? {};
const geometry = source.display_width && source.display_height
? `${source.display_width} × ${source.display_height}${source.rotation_degrees ? ` · ${source.rotation_degrees}° display rotation` : ""}`
: "—";
const metadata = [
["Source file", displayPathLeaf(source.source_path)],
["Source SHA-256", source.source_sha256 ?? "not recorded"],
["Display geometry", geometry],
["Codec / FPS", `${source.codec_name ?? "unknown"} / ${source.fps ? Number(source.fps).toFixed(3) : "unknown"}`],
["Model", model.id ?? "not recorded"],
["Resolved revision", model.revision ?? "not recorded"],
["Processor revision", model.processor_revision ?? "not recorded"],
["Generator", header.generator ?? "not recorded"],
["Created", header.created_at ?? "not recorded"],
["Window sampling", sampling.window_duration_s ? `${sampling.window_duration_s}s / stride ${sampling.stride_s}s / ${sampling.frames_per_window} frames` : "not recorded"],
["Keep hysteresis", policy.enter_threshold !== undefined ? `enter ${policy.enter_threshold} / exit ${policy.exit_threshold}` : "not recorded"],
["Uncertainty route", policy.uncertainty_threshold !== undefined ? `${policy.uncertainty_route ?? "review"} at ${policy.uncertainty_threshold}` : "not recorded"],
];
const grid = byId("metadata-grid");
clear(grid);
for (const [label, value] of metadata) {
const item = node("div", "metadata-item");
item.append(node("span", "", label), node("strong", "", metadataValue(value)));
grid.append(item);
}
byId("raw-header").textContent = JSON.stringify(header, null, 2);
}
function renderSelected(segment) {
const panel = byId("selected-panel");
if (!segment) {
panel.hidden = true;
return;
}
const decision = decisionFor(segment);
const route = decisionRoute(segment);
panel.hidden = false;
byId("selected-title").textContent = `Segment ${String(segment.segment_index).padStart(2, "0")}`;
const routeLabel = byId("selected-route");
routeLabel.textContent = decision;
routeLabel.className = routeClass(route);
byId("selected-time").textContent = `${formatTimecode(segment.start_s)}${formatTimecode(segment.end_s)}`;
byId("selected-reason").textContent = `${formatDuration(segment.end_s - segment.start_s)} · ${segment.reason ?? "stable"}`;
const scores = byId("selected-scores");
clear(scores);
for (const label of READINESS_LABELS) {
const item = node("div");
item.append(node("dt", "", label), node("dd", "", formatPercent(segment.readiness?.[label], 1)));
scores.append(item);
}
const issues = byId("selected-issues");
clear(issues);
const ranked = Object.entries(segment.issues ?? {}).sort((left, right) => right[1] - left[1]);
if (ranked.length === 0) {
issues.append(node("span", "issue-chip", "No issue evidence recorded"));
} else {
for (const [name, probability] of ranked) {
issues.append(node("span", "issue-chip", `${prettyIssue(name)} ${formatPercent(probability)}`));
}
}
}
function updateSelectedClasses() {
for (const element of document.querySelectorAll("[data-segment-index]")) {
element.classList.toggle(
"is-selected",
Number(element.dataset.segmentIndex) === state.selectedSegmentIndex,
);
}
}
function selectSegment(segment, seekVideo) {
state.selectedSegmentIndex = segment.segment_index;
renderSelected(segment);
updateSelectedClasses();
if (seekVideo) seekTo(segment.start_s);
}
function seekTo(seconds) {
const video = byId("video");
if (!state.videoUrl) {
showToast(`Segment starts at ${formatTimecode(seconds)}. Open the matching video to seek.`);
return;
}
const target = Number.isFinite(video.duration)
? Math.max(0, Math.min(seconds, Math.max(0, video.duration - 0.01)))
: Math.max(0, seconds);
video.currentTime = target;
byId("video-timecode").textContent = formatTimecode(target);
showToast(`Video set to ${formatTimecode(target)}.`);
}
function updatePlayhead(seconds) {
const line = document.getElementById("playhead-line");
if (!line || !state.parsed) return;
const duration = Math.max(state.parsed.header.source.duration_s, 0.001);
const chartWidth = CHART.width - CHART.left - CHART.right;
const position = CHART.left + (Math.max(0, Math.min(duration, seconds)) / duration) * chartWidth;
line.setAttribute("x1", String(position));
line.setAttribute("x2", String(position));
line.setAttribute("opacity", "0.7");
}
function renderWorkspace() {
const parsed = state.parsed;
if (!parsed) return;
const header = parsed.header;
const summary = summarizeManifest(parsed);
const source = header.source;
const model = header.model ?? {};
byId("identity-file").textContent = state.manifestFileName;
byId("identity-model").textContent = model.id
? `${model.id} @ ${model.revision ?? model.requested_revision ?? "unresolved revision"}`
: "Model identity not recorded";
byId("metric-duration").textContent = formatDuration(summary.duration);
byId("metric-geometry").textContent = source.display_width && source.display_height
? `${source.display_width} × ${source.display_height} · ${source.fps ? `${Number(source.fps).toFixed(2)} fps` : "fps unknown"}`
: "geometry not recorded";
byId("metric-windows").textContent = String(summary.windows).padStart(2, "0");
byId("metric-window-mix").textContent = `${summary.windowDecisions.KEEP} keep / ${summary.windowDecisions.REVIEW} review / ${summary.windowDecisions.REJECT} reject`;
byId("metric-segments").textContent = String(summary.segments).padStart(2, "0");
byId("metric-keep").textContent = formatDuration(summary.routedSeconds.KEEP);
byId("metric-review").textContent = `${formatDuration(summary.routedSeconds.REVIEW)} routed to review`;
checkVideoDuration();
renderWarnings();
renderTimeline(parsed);
renderSegmentTrack(parsed);
renderSegments();
renderIssues(parsed);
renderMetadata(header);
updateManifestDownload();
const selected = parsed.segments.find((segment) => segment.segment_index === state.selectedSegmentIndex)
?? parsed.segments[0]
?? null;
state.selectedSegmentIndex = selected?.segment_index ?? null;
renderSelected(selected);
updateSelectedClasses();
byId("workspace").hidden = false;
}
function acceptManifestText(text, fileName, isDemo = false) {
const parsed = parseManifest(text);
state.parsed = parsed;
state.manifestText = text.endsWith("\n") ? text : `${text}\n`;
state.manifestFileName = safeFileName(fileName, "egosieve-manifest.jsonl");
state.selectedSegmentIndex = null;
state.routeFilter = "all";
for (const button of document.querySelectorAll("[data-route]")) {
button.setAttribute("aria-pressed", button.dataset.route === "all" ? "true" : "false");
}
byId("manifest-file-name").textContent = state.manifestFileName;
renderWorkspace();
showNotice(
isDemo
? "Illustrative evidence loaded. It demonstrates the inspector and is not a checkpoint result."
: `${parsed.windows.length} windows and ${parsed.segments.length} compiled segments loaded locally.`,
);
byId("workspace").scrollIntoView({ behavior: "smooth", block: "start" });
}
async function loadManifestFile(file) {
if (!file) return;
if (file.size > MAX_MANIFEST_BYTES) {
showNotice("That manifest is larger than 32 MB. Open a smaller EgoSieve JSONL file.", true);
return;
}
try {
acceptManifestText(await file.text(), file.name);
} catch (error) {
showNotice(error instanceof Error ? error.message : "The manifest could not be parsed.", true);
}
}
function loadVideoFile(file) {
if (!file) return;
if (file.type && !file.type.startsWith("video/")) {
showNotice("The optional media file must be a video supported by this browser.", true);
return;
}
if (state.videoUrl) URL.revokeObjectURL(state.videoUrl);
state.videoUrl = URL.createObjectURL(file);
state.videoFileName = file.name;
state.videoDurationWarning = null;
const video = byId("video");
video.src = state.videoUrl;
video.hidden = false;
video.load();
byId("video-empty").hidden = true;
byId("video-timecode").hidden = false;
byId("video-file-name").textContent = file.name;
byId("video-state").textContent = "LOCAL VIDEO";
byId("media-footnote").textContent = "Click any segment or timeline position to seek this local file.";
showToast(`${file.name} opened locally.`);
}
function resetWorkspace() {
state.parsed = null;
state.manifestText = "";
state.manifestFileName = "";
state.selectedSegmentIndex = null;
state.routeFilter = "all";
state.videoDurationWarning = null;
revokeManifestUrl();
if (state.videoUrl) URL.revokeObjectURL(state.videoUrl);
state.videoUrl = null;
state.videoFileName = "";
const video = byId("video");
video.pause();
video.removeAttribute("src");
video.load();
video.hidden = true;
byId("video-empty").hidden = false;
byId("video-timecode").hidden = true;
byId("video-state").textContent = "NO VIDEO";
byId("manifest-input").value = "";
byId("video-input").value = "";
byId("manifest-file-name").textContent = "Drop JSONL here or choose a file";
byId("video-file-name").textContent = "Drop video here or choose a file";
byId("media-footnote").textContent = "Segment selections still work without media; their timestamps remain inspectable.";
byId("workspace").hidden = true;
hideNotice();
showToast("Workspace cleared.");
}
function exportVisibleSegments() {
if (!state.parsed) return;
const selectedIndexes = new Set(visibleSegments().map((segment) => segment.segment_index));
const payload = JSON.stringify(buildSegmentExport(state.parsed, selectedIndexes), null, 2) + "\n";
const url = URL.createObjectURL(new Blob([payload], { type: "application/json;charset=utf-8" }));
const anchor = document.createElement("a");
const stem = safeFileName(state.manifestFileName, "egosieve-manifest").replace(/\.(jsonl|ndjson)$/iu, "");
anchor.href = url;
anchor.download = `${stem}.${state.routeFilter === "all" ? "segments" : state.routeFilter}.json`;
document.body.append(anchor);
anchor.click();
anchor.remove();
window.setTimeout(() => URL.revokeObjectURL(url), 1000);
showToast(`${selectedIndexes.size} segment${selectedIndexes.size === 1 ? "" : "s"} exported.`);
}
function chartPosition(event) {
const svg = byId("timeline");
const bounds = svg.getBoundingClientRect();
const x = ((event.clientX - bounds.left) / Math.max(bounds.width, 1)) * CHART.width;
const duration = state.parsed?.header.source.duration_s ?? 0;
const fraction = (x - CHART.left) / (CHART.width - CHART.left - CHART.right);
return Math.max(0, Math.min(duration, fraction * duration));
}
function nearestWindow(seconds) {
if (!state.parsed || state.parsed.windows.length === 0) return null;
let nearest = null;
let nearestDistance = Infinity;
for (const windowRecord of state.parsed.windows) {
const midpoint = (windowRecord.start_s + windowRecord.end_s) / 2;
const distance = Math.abs(midpoint - seconds);
if (distance < nearestDistance) {
nearest = windowRecord;
nearestDistance = distance;
}
}
return nearest;
}
function handleChartPointer(event) {
if (!state.parsed) return;
const windowRecord = nearestWindow(chartPosition(event));
const tooltip = byId("chart-tooltip");
if (!windowRecord?.readiness) {
tooltip.hidden = true;
return;
}
const stageBounds = byId("timeline-stage").getBoundingClientRect();
tooltip.textContent = [
`${formatTimecode(windowRecord.start_s)}${formatTimecode(windowRecord.end_s)}`,
...READINESS_LABELS.map((label) => `${label} ${formatPercent(windowRecord.readiness[label], 1)}`),
`UNCERTAINTY ${formatPercent(windowRecord.routing_uncertainty ?? windowRecord.uncertainty, 1)}`,
].join("\n");
tooltip.style.whiteSpace = "pre-line";
tooltip.style.left = `${Math.min(stageBounds.width - 175, Math.max(8, event.clientX - stageBounds.left + 14))}px`;
tooltip.style.top = `${Math.max(8, event.clientY - stageBounds.top - 88)}px`;
tooltip.hidden = false;
}
function demoManifestText() {
const duration = 42;
const probabilities = [
[0.82, 0.13, 0.05],
[0.88, 0.09, 0.03],
[0.52, 0.41, 0.07],
[0.24, 0.63, 0.13],
[0.72, 0.23, 0.05],
[0.91, 0.07, 0.02],
[0.86, 0.1, 0.04],
[0.68, 0.28, 0.04],
[0.37, 0.55, 0.08],
[0.18, 0.32, 0.5],
];
const issueNames = [
"acting_hand_not_visible",
"low_hand_activity",
"camera_instability",
"blur",
"exposure",
"scene_cut",
"duplicate_frames",
];
const windows = probabilities.map((values, index) => {
const start = index * 4;
const end = Math.min(duration, start + 6);
const readiness = Object.fromEntries(READINESS_LABELS.map((label, labelIndex) => [label, values[labelIndex]]));
const issues = Object.fromEntries(issueNames.map((name, issueIndex) => [
name,
Math.min(0.92, 0.03 + (((index + 2) * (issueIndex + 3)) % 11) * 0.035),
]));
if (index === 3) issues.blur = 0.68;
if (index === 8) issues.duplicate_frames = 0.57;
return {
record_type: "window",
schema_version: 1,
window_index: index,
start_s: start,
end_s: end,
source_start_s: start,
source_end_s: end,
timestamps_s: Array.from({ length: 12 }, (_, frame) => start + ((frame + 0.5) * (end - start)) / 12),
decision: READINESS_LABELS[values.indexOf(Math.max(...values))],
readiness,
score: readiness.KEEP,
uncertainty: 0.2 + index * 0.025,
routing_uncertainty: Math.max(0.2 + index * 0.025, readiness.REVIEW),
issues,
reported_issues: Object.entries(issues).filter(([, value]) => value >= 0.35).map(([name]) => name),
boundary: [],
};
});
const makeSegment = (segment_index, start_s, end_s, route, window_indices, readiness, issues, reported_issues = []) => ({
record_type: "segment",
schema_version: 1,
segment_index,
segment_id: `sha256:example-${segment_index}`,
start_s,
end_s,
source_start_s: start_s,
source_end_s: end_s,
duration_s: end_s - start_s,
route,
decision: { keep: "KEEP", review: "REVIEW", discard: "REJECT" }[route],
reason: route === "review" ? "uncertain" : "stable",
window_indices,
mean_score: readiness.KEEP,
min_score: Math.max(0, readiness.KEEP - 0.08),
max_score: Math.min(1, readiness.KEEP + 0.08),
readiness,
issues,
reported_issues,
});
const baseIssues = Object.fromEntries(issueNames.map((name) => [name, 0.12]));
const segments = [
makeSegment(0, 0, 10, "keep", [0, 1], { KEEP: 0.85, REVIEW: 0.11, REJECT: 0.04 }, { ...baseIssues, low_hand_activity: 0.08 }),
makeSegment(1, 10, 16, "review", [2, 3], { KEEP: 0.38, REVIEW: 0.52, REJECT: 0.1 }, { ...baseIssues, blur: 0.68, camera_instability: 0.41 }, ["blur", "camera_instability"]),
makeSegment(2, 16, 30, "keep", [4, 5, 6, 7], { KEEP: 0.79, REVIEW: 0.17, REJECT: 0.04 }, { ...baseIssues, exposure: 0.29 }),
makeSegment(3, 30, 36, "review", [7, 8], { KEEP: 0.39, REVIEW: 0.53, REJECT: 0.08 }, { ...baseIssues, duplicate_frames: 0.57 }, ["duplicate_frames"]),
];
const header = {
record_type: "manifest",
schema: "egosieve.video-compilation",
schema_version: 1,
created_at: "2026-08-23T12:00:00Z",
generator: "egosieve static-inspector example",
example: "illustrative interface data; not a checkpoint result",
source: {
source_path: "example/assembly-pass.mp4",
source_sha256: "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
source_size_bytes: 18420000,
duration_s: duration,
start_time_s: 0,
width: 1920,
height: 1080,
display_width: 1920,
display_height: 1080,
rotation_degrees: 0,
fps: 29.97,
frame_count: 1259,
codec_name: "h264",
},
model: {
id: "itspublu/EgoSieve-S",
revision: "illustrative-example",
requested_revision: "illustrative-example",
processor_revision: "illustrative-example",
readiness_labels: READINESS_LABELS,
},
counts: {
windows: windows.length,
unique_samples: 84,
segments: segments.length,
window_decisions: { KEEP: 7, REVIEW: 2, REJECT: 1 },
segment_decisions: { KEEP: 2, REVIEW: 2, REJECT: 0 },
},
sampling: {
window_duration_s: 6,
stride_s: 4,
frames_per_window: 12,
window_count: windows.length,
unique_sample_count: 84,
},
policy: {
enter_threshold: 0.7,
exit_threshold: 0.5,
merge_gap_s: 0.5,
min_duration_s: 1,
uncertainty_threshold: 0.5,
uncertainty_route: "review",
short_segment_route: "discard",
include_discard: false,
},
issue_labels: issueNames,
issue_reporting_thresholds: Object.fromEntries(issueNames.map((name) => [name, 0.35])),
};
return [header, ...windows, ...segments].map((record) => JSON.stringify(record)).join("\n") + "\n";
}
function configureDropZone(zoneId, handler) {
const zone = byId(zoneId);
for (const eventName of ["dragenter", "dragover"]) {
zone.addEventListener(eventName, (event) => {
event.preventDefault();
event.dataTransfer.dropEffect = "copy";
zone.classList.add("is-dragging");
});
}
for (const eventName of ["dragleave", "drop"]) {
zone.addEventListener(eventName, (event) => {
event.preventDefault();
zone.classList.remove("is-dragging");
});
}
zone.addEventListener("drop", (event) => handler(event.dataTransfer.files?.[0] ?? null));
}
function init() {
byId("manifest-input").addEventListener("change", (event) => loadManifestFile(event.target.files?.[0]));
byId("video-input").addEventListener("change", (event) => loadVideoFile(event.target.files?.[0]));
configureDropZone("manifest-drop", loadManifestFile);
configureDropZone("video-drop", loadVideoFile);
byId("demo-button").addEventListener("click", () => {
try {
acceptManifestText(demoManifestText(), "illustrative.egosieve.jsonl", true);
} catch (error) {
showNotice(error instanceof Error ? error.message : "The example could not be loaded.", true);
}
});
byId("reset-button").addEventListener("click", resetWorkspace);
byId("copy-cli").addEventListener("click", () => copyText(byId("cli-command").textContent, "CLI command copied."));
byId("copy-segment").addEventListener("click", () => {
const segment = state.parsed?.segments.find((row) => row.segment_index === state.selectedSegmentIndex);
if (segment) copyText(JSON.stringify(segment, null, 2), "Segment JSON copied.");
});
byId("download-segments").addEventListener("click", exportVisibleSegments);
for (const button of document.querySelectorAll("[data-route]")) {
button.addEventListener("click", () => {
state.routeFilter = button.dataset.route;
for (const peer of document.querySelectorAll("[data-route]")) {
peer.setAttribute("aria-pressed", peer === button ? "true" : "false");
}
renderSegments();
});
}
const video = byId("video");
video.addEventListener("loadedmetadata", () => {
checkVideoDuration();
renderWarnings();
});
video.addEventListener("timeupdate", () => {
byId("video-timecode").textContent = formatTimecode(video.currentTime);
updatePlayhead(video.currentTime);
});
video.addEventListener("error", () => showNotice("This browser could not decode the selected video. The manifest remains available.", true));
const timeline = byId("timeline");
timeline.addEventListener("pointermove", handleChartPointer);
timeline.addEventListener("pointerleave", () => {
byId("chart-tooltip").hidden = true;
});
timeline.addEventListener("click", (event) => {
if (state.parsed) seekTo(chartPosition(event));
});
window.addEventListener("beforeunload", () => {
revokeManifestUrl();
if (state.videoUrl) URL.revokeObjectURL(state.videoUrl);
});
}
init();