Spaces:
Running
Running
Deploy conversion @ d936f3c-space
Browse files
app.js
CHANGED
|
@@ -24,7 +24,7 @@ import { oauthLoginUrl, oauthHandleRedirectIfPresent, uploadFiles, downloadFile,
|
|
| 24 |
// the ?v= stamp — an unversioned nested import could load a stale module.
|
| 25 |
import { keyOf, latestByKey, mergeEvents, orderItems, firstUngraded as
|
| 26 |
firstUngradedPure, countComplete, stampClass, nextEpoch,
|
| 27 |
-
standsDownTo } from "./logic.mjs?v=
|
| 28 |
|
| 29 |
// Test seam: Playwright installs window.__testHub (an in-memory hub) before
|
| 30 |
// any page script runs; production never defines it, so this is one inert
|
|
@@ -217,9 +217,9 @@ async function pushGuarded() {
|
|
| 217 |
}
|
| 218 |
banner(/403|401/.test(String(err))
|
| 219 |
? "Your work is saved in this browser, but publishing was refused (permissions). "
|
| 220 |
-
+ "Nothing is lost — use the save button
|
| 221 |
: "Your work is saved in this browser, but publishing to the server failed "
|
| 222 |
-
+ `(${String(err).slice(0, 80)}). Use the save button (s
|
| 223 |
true, [{ label: "Download your log (send it to Samuel if this persists)",
|
| 224 |
onClick: downloadLog }]);
|
| 225 |
}
|
|
@@ -586,6 +586,24 @@ async function boot() {
|
|
| 586 |
if (!state.auth) {
|
| 587 |
const main = $("#main");
|
| 588 |
main.replaceChildren(el("p", null, CONFIG.landing));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 589 |
main.append(el("p", "independence", CONFIG.independence));
|
| 590 |
const button = el("button", "signin", "Sign in with Hugging Face");
|
| 591 |
button.addEventListener("click", signIn);
|
|
|
|
| 24 |
// the ?v= stamp — an unversioned nested import could load a stale module.
|
| 25 |
import { keyOf, latestByKey, mergeEvents, orderItems, firstUngraded as
|
| 26 |
firstUngradedPure, countComplete, stampClass, nextEpoch,
|
| 27 |
+
standsDownTo } from "./logic.mjs?v=d936f3c-space";
|
| 28 |
|
| 29 |
// Test seam: Playwright installs window.__testHub (an in-memory hub) before
|
| 30 |
// any page script runs; production never defines it, so this is one inert
|
|
|
|
| 217 |
}
|
| 218 |
banner(/403|401/.test(String(err))
|
| 219 |
? "Your work is saved in this browser, but publishing was refused (permissions). "
|
| 220 |
+
+ "Nothing is lost — use the save button to retry once it's fixed (s on a keyboard)."
|
| 221 |
: "Your work is saved in this browser, but publishing to the server failed "
|
| 222 |
+
+ `(${String(err).slice(0, 80)}). Use the save button to retry (s on a keyboard).`,
|
| 223 |
true, [{ label: "Download your log (send it to Samuel if this persists)",
|
| 224 |
onClick: downloadLog }]);
|
| 225 |
}
|
|
|
|
| 586 |
if (!state.auth) {
|
| 587 |
const main = $("#main");
|
| 588 |
main.replaceChildren(el("p", null, CONFIG.landing));
|
| 589 |
+
// A returning annotator (new tab, expired login, reclaimed mobile tab)
|
| 590 |
+
// must never mistake this screen for a fresh start: their log is here.
|
| 591 |
+
let stored = 0;
|
| 592 |
+
for (let i = 0; i < localStorage.length; i++) {
|
| 593 |
+
const key = localStorage.key(i);
|
| 594 |
+
if (!key || !key.startsWith(`audit:${CONFIG.task}:`)) continue;
|
| 595 |
+
try {
|
| 596 |
+
const events = JSON.parse(localStorage.getItem(key) ?? "[]");
|
| 597 |
+
stored += [...latestByKey(events).values()]
|
| 598 |
+
.filter((ev) => !ev.warmup && CONFIG.isComplete(ev)).length;
|
| 599 |
+
} catch { /* unreadable log — claim nothing */ }
|
| 600 |
+
}
|
| 601 |
+
if (stored) {
|
| 602 |
+
main.append(el("p", "resume-note",
|
| 603 |
+
`Welcome back — ${stored} of your judgments are safely stored in this `
|
| 604 |
+
+ "browser. Sign in with the same Hugging Face account to pick up "
|
| 605 |
+
+ "exactly where you left off."));
|
| 606 |
+
}
|
| 607 |
main.append(el("p", "independence", CONFIG.independence));
|
| 608 |
const button = el("button", "signin", "Sign in with Hugging Face");
|
| 609 |
button.addEventListener("click", signIn);
|
config.js
CHANGED
|
@@ -2,7 +2,7 @@ window.CONFIG = {
|
|
| 2 |
task: "conversion",
|
| 3 |
title: "Pass 2 · rewrite fidelity — 152 items",
|
| 4 |
itemsPath: "conversion_items.json",
|
| 5 |
-
build: "
|
| 6 |
landing: "You will judge whether each rewritten exam question still asks the same "
|
| 7 |
+ "question as the original, and whether it stands on its own without the answer "
|
| 8 |
+ "options. 152 items plus 3 discussable warm-ups; expect roughly 1.5–2 hours, "
|
|
|
|
| 2 |
task: "conversion",
|
| 3 |
title: "Pass 2 · rewrite fidelity — 152 items",
|
| 4 |
itemsPath: "conversion_items.json",
|
| 5 |
+
build: "d936f3c-space",
|
| 6 |
landing: "You will judge whether each rewritten exam question still asks the same "
|
| 7 |
+ "question as the original, and whether it stands on its own without the answer "
|
| 8 |
+ "options. 152 items plus 3 discussable warm-ups; expect roughly 1.5–2 hours, "
|
index.html
CHANGED
|
@@ -5,8 +5,8 @@
|
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1">
|
| 6 |
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'self'; style-src 'self'; style-src-attr 'unsafe-inline'; font-src 'self'; connect-src https://huggingface.co https://*.hf.co; img-src 'self' data:; base-uri 'none'; form-action 'none'">
|
| 7 |
<title>LocalGate audit</title>
|
| 8 |
-
<link rel="stylesheet" href="style.css?v=
|
| 9 |
-
<link rel="stylesheet" href="katex/katex.min.css?v=
|
| 10 |
</head>
|
| 11 |
<body>
|
| 12 |
<header>
|
|
@@ -22,9 +22,9 @@
|
|
| 22 |
<pre id="rubric-body"></pre></details>
|
| 23 |
</div>
|
| 24 |
<div id="controls" hidden></div>
|
| 25 |
-
<script src="katex/katex.min.js?v=
|
| 26 |
-
<script src="katex/auto-render.min.js?v=
|
| 27 |
-
<script src="config.js?v=
|
| 28 |
-
<script type="module" src="app.js?v=
|
| 29 |
</body>
|
| 30 |
</html>
|
|
|
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1">
|
| 6 |
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'self'; style-src 'self'; style-src-attr 'unsafe-inline'; font-src 'self'; connect-src https://huggingface.co https://*.hf.co; img-src 'self' data:; base-uri 'none'; form-action 'none'">
|
| 7 |
<title>LocalGate audit</title>
|
| 8 |
+
<link rel="stylesheet" href="style.css?v=d936f3c-space">
|
| 9 |
+
<link rel="stylesheet" href="katex/katex.min.css?v=d936f3c-space">
|
| 10 |
</head>
|
| 11 |
<body>
|
| 12 |
<header>
|
|
|
|
| 22 |
<pre id="rubric-body"></pre></details>
|
| 23 |
</div>
|
| 24 |
<div id="controls" hidden></div>
|
| 25 |
+
<script src="katex/katex.min.js?v=d936f3c-space"></script>
|
| 26 |
+
<script src="katex/auto-render.min.js?v=d936f3c-space"></script>
|
| 27 |
+
<script src="config.js?v=d936f3c-space"></script>
|
| 28 |
+
<script type="module" src="app.js?v=d936f3c-space"></script>
|
| 29 |
</body>
|
| 30 |
</html>
|
style.css
CHANGED
|
@@ -227,3 +227,46 @@ details#rubric[open]::after { content: ""; position: sticky; display: block;
|
|
| 227 |
|
| 228 |
/* note grows into free bench space instead of truncating at 13rem */
|
| 229 |
#controls #note { flex: 1 1 13rem; min-width: 9rem; max-width: 24rem; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 227 |
|
| 228 |
/* note grows into free bench space instead of truncating at 13rem */
|
| 229 |
#controls #note { flex: 1 1 13rem; min-width: 9rem; max-width: 24rem; }
|
| 230 |
+
|
| 231 |
+
/* ── mobile compatibility batch (2026-08-15) ── */
|
| 232 |
+
/* Fixed-layer stack: bench over rubric over banner — the sticky response
|
| 233 |
+
label used to paint on top of all three (it has z-index:1; they had none). */
|
| 234 |
+
#controls { z-index: 30; }
|
| 235 |
+
details#rubric { z-index: 20; }
|
| 236 |
+
#banner { position: sticky; top: 0; z-index: 10; max-height: 40vh; overflow-y: auto;
|
| 237 |
+
display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; }
|
| 238 |
+
#banner[hidden] { display: none; }
|
| 239 |
+
#banner .banner-act { order: -1; margin-left: 0; } /* recovery actions first, above the fold */
|
| 240 |
+
|
| 241 |
+
/* content must always clear the bench's real height, not a guessed 12rem */
|
| 242 |
+
main { margin-bottom: calc(var(--bench-h, 8rem) + 4rem); }
|
| 243 |
+
#controls button { white-space: nowrap; }
|
| 244 |
+
#controls .grp { flex-wrap: wrap; }
|
| 245 |
+
|
| 246 |
+
/* screens without a bench (landing, locked, done) also need no rubric strip */
|
| 247 |
+
body:has(#controls[hidden]) details#rubric { display: none; }
|
| 248 |
+
|
| 249 |
+
@media (max-width: 1239px) {
|
| 250 |
+
#controls button { min-height: 44px; } /* the 250-500x buttons were 36px */
|
| 251 |
+
#controls #note { min-height: 44px; }
|
| 252 |
+
#banner .banner-act { min-height: 44px; }
|
| 253 |
+
details#rubric { max-height: min(38vh, calc(100dvh - var(--bench-h, 5.9rem) - 9rem)); }
|
| 254 |
+
}
|
| 255 |
+
/* small phones / landscape: compact the bench to give the item room to breathe */
|
| 256 |
+
@media (max-width: 380px), (max-height: 420px) {
|
| 257 |
+
#controls { padding: .4rem .6rem; gap: .35rem; }
|
| 258 |
+
#controls .lbl { flex-basis: 100%; margin: 0; }
|
| 259 |
+
#controls #note { order: 9; flex: 1 1 100%; }
|
| 260 |
+
#controls .last { display: none; }
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
/* onward links (unlock, completion, locked gate) — buttons, not bare anchors */
|
| 264 |
+
a.open-out { display: inline-block; margin-top: .8rem; padding: .7rem 1.3rem;
|
| 265 |
+
font: 600 .9rem var(--mono); text-decoration: none;
|
| 266 |
+
color: var(--ground); background: var(--ink); border: 2px solid var(--ink); }
|
| 267 |
+
a.open-out:hover { background: transparent; color: var(--ink); }
|
| 268 |
+
|
| 269 |
+
/* the signed-out "your work is safe" reassurance */
|
| 270 |
+
.resume-note { font-family: var(--mono); font-size: .8rem; padding: .6rem .9rem;
|
| 271 |
+
border: 1px solid var(--match); border-left-width: 4px;
|
| 272 |
+
color: var(--ink); background: color-mix(in srgb, var(--match) 7%, var(--field)); }
|