- Layout: drop viewport-locking (height:100%, overflow:auto, max-height caps) so panels stack and the page scrolls as one document instead of clipping content; lattice canvas gets an explicit 60vh height. - Active leaf chip: bright outline + glow + bold instead of a teal fill that blended into the leaf text. Highlight now syncs in loadProof so a leaf click on the 3D canvas moves the strip selection too (data-leaf-idx). - Leaf source header: show which source document a leaf's prose belongs to (each context-root leaf maps to a different doc). - Default selection lands on the chunk that fed the answer (used / primary) rather than leaf 0, which surfaced unrelated background sources.
96 lines
3.8 KiB
Django/Jinja
96 lines
3.8 KiB
Django/Jinja
{% extends "base.jinja2" %}
|
|
|
|
{% block body %}
|
|
<div class="proof"
|
|
data-root-hash="{{ root_hash }}"
|
|
data-leaf-index="{{ leaf_index or '' }}"
|
|
data-cache-key="{{ cache_key or '' }}">
|
|
|
|
<aside class="dash-side">
|
|
<h2 class="dash-h2">Root</h2>
|
|
<pre class="root-hash-block" id="root-hash">{{ root_hash | hex_chunk }}</pre>
|
|
|
|
<h2 class="dash-h2">Inclusion proof</h2>
|
|
<div id="proof-card" class="proof-card">
|
|
<p class="muted">select a leaf to compute its inclusion proof…</p>
|
|
</div>
|
|
|
|
<h2 class="dash-h2">Leaf content
|
|
<span class="muted" id="content-mode-label"></span>
|
|
</h2>
|
|
<div id="leaf-source" class="leaf-source" hidden></div>
|
|
<div class="content-toggle" id="content-toggle" hidden>
|
|
<button type="button" data-mode="prose" class="active">prose</button>
|
|
<button type="button" data-mode="raw">raw</button>
|
|
<span class="muted" id="content-base-version"></span>
|
|
</div>
|
|
<div id="leaf-content" class="leaf-content muted">select a leaf to view its chunk text…</div>
|
|
|
|
<h2 class="dash-h2">Audit linkage</h2>
|
|
<div id="audit-link" class="muted">looking up…</div>
|
|
|
|
<h2 class="dash-h2">Live stream</h2>
|
|
<div class="dash-stream" id="sse-status">
|
|
<span class="dot dot-off"></span>
|
|
<span class="lbl">disconnected</span>
|
|
</div>
|
|
<pre class="dash-events" id="sse-events" aria-live="polite"></pre>
|
|
</aside>
|
|
|
|
<section class="proof-stage">
|
|
<div class="lattice-bar">
|
|
<span class="widget-type">[merkle-lattice-3d]</span>
|
|
<span id="lattice-status">loading…</span>
|
|
<button id="btn-pulse" disabled>pulse proof path</button>
|
|
<button id="btn-reset">reset</button>
|
|
<span class="lattice-legend muted">
|
|
<span class="legend-swatch swatch-leaf"></span>leaves
|
|
<span class="legend-swatch swatch-interior"></span>interior
|
|
<span class="legend-swatch swatch-root"></span>root
|
|
<span class="legend-swatch swatch-selected"></span>selected
|
|
</span>
|
|
</div>
|
|
<div id="lattice-canvas" class="lattice-canvas"></div>
|
|
<div id="node-inspect" class="node-inspect muted">click any node — leaves compute an inclusion proof, interior + root reveal their hash here.</div>
|
|
|
|
<div class="leaves-strip" id="leaves-strip">
|
|
<span class="muted">leaves load with the tree…</span>
|
|
</div>
|
|
|
|
<!-- Context-root variant: shown only when /api/root/{hash} returns
|
|
kind=context_root. The Merkle lattice + leaves strip still render
|
|
the tree; this panel adds the QA card + evidence manifest. Each
|
|
source is stamped with its 0-based context-tree leaf index so the
|
|
manifest, leaf chips, and inclusion proof all agree. -->
|
|
<article id="context-panel" class="widget" hidden>
|
|
<header class="widget-head">
|
|
<span class="widget-type">[context-root]</span>
|
|
<span class="widget-title">multi-source evidence</span>
|
|
</header>
|
|
<div class="widget-body">
|
|
<div id="qa-card" class="qa-card" hidden></div>
|
|
<ul id="sources-list" class="sources-list"></ul>
|
|
</div>
|
|
</article>
|
|
</section>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
<script type="module">
|
|
import { mountProofPage } from "{{ request.static_url('arborist_viz:static/viz/proof-page.js') }}?v={{ request.static_version }}";
|
|
import { connectSSE } from "{{ request.static_url('arborist_viz:static/viz/sse-client.js') }}?v={{ request.static_version }}";
|
|
|
|
const root = document.querySelector(".proof");
|
|
const rootHash = root.dataset.rootHash;
|
|
const leafIndex = root.dataset.leafIndex ? parseInt(root.dataset.leafIndex, 10) : null;
|
|
const cacheKey = root.dataset.cacheKey || null;
|
|
|
|
mountProofPage(rootHash, leafIndex, cacheKey);
|
|
|
|
connectSSE(`/sse/root/${encodeURIComponent(rootHash)}`, {
|
|
statusEl: document.getElementById("sse-status"),
|
|
eventsEl: document.getElementById("sse-events"),
|
|
});
|
|
</script>
|
|
{% endblock %}
|