File size: 7,320 Bytes
b50f36e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | <!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Trace Viewer</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
:root { --fg:#111; --muted:#888; --new:#0a7f2e; --mask:#aaa; --border:#ddd; }
body { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; margin:16px; color:var(--fg); }
h1 { font-size:18px; margin:0 0 12px 0; }
.controls { display:flex; flex-wrap:wrap; gap:8px; align-items:center; margin-bottom:12px; }
.controls > * { font-size:14px; }
#viewer { border:1px solid var(--border); padding:12px; height:60vh; overflow:auto;
white-space:pre-wrap; overflow-wrap:anywhere; word-break:normal; }
.masked { color:transparent; text-shadow:0 0 0 var(--mask); }
.unmasked { color:inherit; }
.new { background:#e9f7ee; outline:1px dashed #b7e1c3; }
.special { color:var(--muted); }
.meta { color:var(--muted); font-size:12px; margin-bottom:6px; }
.row { display:flex; gap:8px; align-items:center; }
input[type="range"] { width:300px; }
button { padding:4px 10px; }
select { padding:2px 6px; }
label { user-select:none; }
.maskToken { display:inline-block; width:7ch; text-align:center; white-space:nowrap; word-break:keep-all; }
</style>
</head>
<body>
<h1>Unmask Viewer</h1>
<div class="meta" id="meta"></div>
<div class="controls">
<div class="row">
<button id="play">Play</button>
<button id="prev">-1</button>
<input id="step" type="range" min="0" max="0" value="0">
<button id="next">+1</button>
</div>
<div class="row">
<label>Step: <span id="stepNum">0</span>/<span id="stepMax">0</span></label>
<label style="margin-left:12px;">Speed:
<select id="speed">
<option value="1200">0.8×</option>
<option value="800" selected>1×</option>
<option value="500">1.6×</option>
<option value="300">2.6×</option>
</select>
</label>
<label style="margin-left:12px;">
<input id="hideSpecial" type="checkbox"> Hide special tokens
</label>
<label style="margin-left:12px;">
<input id="showMaskedShapes" type="checkbox" checked> Show masked placeholders
</label>
</div>
</div>
<div id="viewer"></div>
<script id="data" type="application/json">{"pieces": ["Re", "in", "forcement", " learning", " is", " a", " type", " of", " machine", " learning", " where", " an", " agent", " learns", " to", " make", " decisions", " by", " interacting", " with", " an", " environment", ".", " The", " agent", " receives", " feedback", " in", " the", " form", " of", " rewards", " or", " punishments", " for", " its", " actions", ",", " and", " uses", " this", " feedback", " to", " adjust", " its", " behavior", " in", " order", " to", " maximize", " its", " total", " reward", " over", " time", ".", " This", " process", " is", " achieved", " through", " trial", " and", " error", ",", " and", " the", " agent", " gradually", " learns", " to", " make", " decisions", " that", " lead", " to", " the", " highest", " possible", " reward", ".", "<|im_end|>", "\n", "<|endoftext|>"], "step_map": [2, 1, 3, 3, 3, 3, 4, 4, 4, 5, 6, 7, 8, 8, 9, 11, 10, 12, 13, 14, 15, 14, 17, 17, 16, 18, 21, 20, 20, 19, 22, 22, 23, 24, 25, 27, 26, 28, 29, 30, 32, 31, 33, 36, 34, 35, 37, 38, 39, 39, 40, 43, 41, 42, 44, 44, 45, 46, 49, 50, 48, 47, 51, 51, 52, 53, 55, 54, 56, 57, 58, 60, 59, 60, 61, 62, 63, 64, 67, 68, 66, 65, 69, 69], "is_special": [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, true]}</script>
<script>
const DATA = JSON.parse(document.getElementById('data').textContent);
const pieces = DATA.pieces;
const steps = DATA.step_map;
const isSpec = DATA.is_special;
const maxStep = Math.max(...steps);
const viewer = document.getElementById('viewer');
const stepInput = document.getElementById('step');
const stepNum = document.getElementById('stepNum');
const stepMax = document.getElementById('stepMax');
const playBtn = document.getElementById('play');
const prevBtn = document.getElementById('prev');
const nextBtn = document.getElementById('next');
const speedSel = document.getElementById('speed');
const hideSpecial = document.getElementById('hideSpecial');
const showMaskedShapes = document.getElementById('showMaskedShapes');
const meta = document.getElementById('meta');
stepInput.max = String(maxStep);
stepMax.textContent = String(maxStep);
function render(t) {
stepNum.textContent = String(t);
const frag = document.createDocumentFragment();
let revealed = 0, newly = 0;
for (let i = 0; i < pieces.length; i++) {
if (hideSpecial.checked && isSpec[i]) continue;
const span = document.createElement('span');
const piece = pieces[i];
if (steps[i] <= t) {
span.className = 'unmasked' + (steps[i] === t ? ' new' : '');
span.textContent = piece;
if (steps[i] === t) newly++;
revealed++;
} else {
span.className = 'masked maskToken' + (isSpec[i] ? ' special' : '');
span.textContent = showMaskedShapes.checked ? '|<MASK>|' : '';
}
if (isSpec[i]) span.classList.add('special');
frag.appendChild(span);
}
viewer.innerHTML = '';
viewer.appendChild(frag);
meta.textContent = `Tokens revealed: ${revealed} / ${pieces.length} | Newly at step ${t}: ${newly}`;
}
let timer = null;
function play() {
if (timer) return;
playBtn.textContent = 'Pause';
timer = setInterval(() => {
let v = Number(stepInput.value);
if (v >= maxStep) {
pause();
return;
}
stepInput.value = String(v + 1);
render(v + 1);
}, Number(speedSel.value));
}
function pause() {
if (timer) {
clearInterval(timer);
timer = null;
}
playBtn.textContent = 'Play';
}
stepInput.addEventListener('input', () => render(Number(stepInput.value)));
playBtn.addEventListener('click', () => (timer ? pause() : play()));
prevBtn.addEventListener('click', () => {
const v = Math.max(0, Number(stepInput.value) - 1);
stepInput.value = String(v);
render(v);
});
nextBtn.addEventListener('click', () => {
const v = Math.min(maxStep, Number(stepInput.value) + 1);
stepInput.value = String(v);
render(v);
});
speedSel.addEventListener('change', () => {
if (timer) { pause(); play(); }
});
hideSpecial.addEventListener('change', () => render(Number(stepInput.value)));
showMaskedShapes.addEventListener('change', () => render(Number(stepInput.value)));
render(0);
</script>
</body>
</html> |