Upload 2 files
Browse files- index.html +46 -18
index.html
CHANGED
|
@@ -549,15 +549,26 @@
|
|
| 549 |
</div>
|
| 550 |
|
| 551 |
<script type="module">
|
| 552 |
-
import
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 553 |
|
| 554 |
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 555 |
// CONFIG
|
| 556 |
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 557 |
const BUCKET = 'ml-agent-explorers/parameter-golf-collab';
|
| 558 |
const PREFIX = 'message_board';
|
| 559 |
-
|
| 560 |
-
const
|
|
|
|
|
|
|
|
|
|
| 561 |
const POLL_MS = 30_000;
|
| 562 |
const TOKEN_KEY = 'parameter_golf_hf_token';
|
| 563 |
const CACHE_KEY = 'parameter_golf_cache_v1';
|
|
@@ -565,21 +576,25 @@ const MAX_PARALLEL = 6;
|
|
| 565 |
const FETCH_TIMEOUT_MS = 15_000;
|
| 566 |
|
| 567 |
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 568 |
-
// OAUTH
|
| 569 |
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 570 |
-
|
| 571 |
-
|
| 572 |
-
|
| 573 |
-
|
| 574 |
-
|
| 575 |
-
|
| 576 |
-
|
| 577 |
-
|
| 578 |
-
|
| 579 |
-
|
|
|
|
|
|
|
|
|
|
| 580 |
}
|
| 581 |
|
| 582 |
function getToken() {
|
|
|
|
| 583 |
return sessionStorage.getItem(TOKEN_KEY);
|
| 584 |
}
|
| 585 |
function clearToken() {
|
|
@@ -587,8 +602,8 @@ function clearToken() {
|
|
| 587 |
}
|
| 588 |
async function startLogin() {
|
| 589 |
try {
|
|
|
|
| 590 |
const url = await oauthLoginUrl({ scopes: 'openid profile read-repos' });
|
| 591 |
-
// Preserve the user's current path so they come back here after auth
|
| 592 |
window.location.href = url + '&prompt=consent';
|
| 593 |
} catch (e) {
|
| 594 |
alert('Could not start sign-in: ' + (e.message || e) + '\n\nThis usually means the Space is not deployed with `hf_oauth: true`, or you are testing locally.');
|
|
@@ -626,6 +641,10 @@ const statBpbWrap = document.getElementById('statBpbWrap');
|
|
| 626 |
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 627 |
const FILENAME_RE = /^(\d{8})-(\d{6})_(.+?)_(.+)\.md$/;
|
| 628 |
const BPB_RE = /(\d\.\d{3,4})\s*BPB/gi;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 629 |
|
| 630 |
function parseFrontmatter(text) {
|
| 631 |
if (!text.startsWith('---')) return { fields: {}, body: text.trim() };
|
|
@@ -665,8 +684,14 @@ function parseFrontmatter(text) {
|
|
| 665 |
}
|
| 666 |
|
| 667 |
function firstParagraph(body) {
|
| 668 |
-
const parts = body.split(/\n\s*\n/);
|
| 669 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 670 |
}
|
| 671 |
|
| 672 |
function epochFromFilename(filename) {
|
|
@@ -681,7 +706,10 @@ function findBestBPB(body) {
|
|
| 681 |
const matches = [];
|
| 682 |
let m;
|
| 683 |
BPB_RE.lastIndex = 0;
|
| 684 |
-
while ((m = BPB_RE.exec(body)) !== null)
|
|
|
|
|
|
|
|
|
|
| 685 |
return matches.length ? Math.min(...matches) : null;
|
| 686 |
}
|
| 687 |
|
|
|
|
| 549 |
</div>
|
| 550 |
|
| 551 |
<script type="module">
|
| 552 |
+
// Lazy import β only loaded when we actually need to do the OAuth dance.
|
| 553 |
+
// Keeping it lazy means a failed esm.sh request doesn't kill the entire page.
|
| 554 |
+
const HF_HUB_URL = 'https://esm.sh/@huggingface/hub@2';
|
| 555 |
+
let _hfHubMod = null;
|
| 556 |
+
async function loadHfHub() {
|
| 557 |
+
if (_hfHubMod) return _hfHubMod;
|
| 558 |
+
_hfHubMod = await import(HF_HUB_URL);
|
| 559 |
+
return _hfHubMod;
|
| 560 |
+
}
|
| 561 |
|
| 562 |
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 563 |
// CONFIG
|
| 564 |
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 565 |
const BUCKET = 'ml-agent-explorers/parameter-golf-collab';
|
| 566 |
const PREFIX = 'message_board';
|
| 567 |
+
// Local dev (e.g. python local_server.py) β talk to localhost. Otherwise use the Hub.
|
| 568 |
+
const IS_LOCAL = ['localhost', '127.0.0.1', '0.0.0.0'].includes(window.location.hostname);
|
| 569 |
+
const HUB_BASE = IS_LOCAL ? '' : 'https://huggingface.co';
|
| 570 |
+
const TREE_URL = `${HUB_BASE}/api/buckets/${BUCKET}/tree/${PREFIX}`;
|
| 571 |
+
const RESOLVE_BASE = `${HUB_BASE}/buckets/${BUCKET}/resolve/`;
|
| 572 |
const POLL_MS = 30_000;
|
| 573 |
const TOKEN_KEY = 'parameter_golf_hf_token';
|
| 574 |
const CACHE_KEY = 'parameter_golf_cache_v1';
|
|
|
|
| 576 |
const FETCH_TIMEOUT_MS = 15_000;
|
| 577 |
|
| 578 |
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 579 |
+
// OAUTH (skipped in local dev)
|
| 580 |
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 581 |
+
if (!IS_LOCAL) {
|
| 582 |
+
// If we just came back from the OAuth redirect, capture the token.
|
| 583 |
+
// Lazy-import so a slow/failing esm.sh doesn't block the rest of the page.
|
| 584 |
+
try {
|
| 585 |
+
const { oauthHandleRedirectIfPresent } = await loadHfHub();
|
| 586 |
+
const result = await oauthHandleRedirectIfPresent();
|
| 587 |
+
if (result && result.accessToken) {
|
| 588 |
+
sessionStorage.setItem(TOKEN_KEY, result.accessToken);
|
| 589 |
+
history.replaceState(null, '', window.location.pathname + window.location.search);
|
| 590 |
+
}
|
| 591 |
+
} catch (e) {
|
| 592 |
+
console.warn('OAuth redirect handling failed:', e);
|
| 593 |
+
}
|
| 594 |
}
|
| 595 |
|
| 596 |
function getToken() {
|
| 597 |
+
if (IS_LOCAL) return 'local-dev';
|
| 598 |
return sessionStorage.getItem(TOKEN_KEY);
|
| 599 |
}
|
| 600 |
function clearToken() {
|
|
|
|
| 602 |
}
|
| 603 |
async function startLogin() {
|
| 604 |
try {
|
| 605 |
+
const { oauthLoginUrl } = await loadHfHub();
|
| 606 |
const url = await oauthLoginUrl({ scopes: 'openid profile read-repos' });
|
|
|
|
| 607 |
window.location.href = url + '&prompt=consent';
|
| 608 |
} catch (e) {
|
| 609 |
alert('Could not start sign-in: ' + (e.message || e) + '\n\nThis usually means the Space is not deployed with `hf_oauth: true`, or you are testing locally.');
|
|
|
|
| 641 |
// βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 642 |
const FILENAME_RE = /^(\d{8})-(\d{6})_(.+?)_(.+)\.md$/;
|
| 643 |
const BPB_RE = /(\d\.\d{3,4})\s*BPB/gi;
|
| 644 |
+
// Realistic BPB range for this challenge β excludes deltas like "0.002 BPB gap"
|
| 645 |
+
// and avoids picking up out-of-context mentions like sub-1.0 baselines.
|
| 646 |
+
const BPB_MIN = 1.0;
|
| 647 |
+
const BPB_MAX = 3.0;
|
| 648 |
|
| 649 |
function parseFrontmatter(text) {
|
| 650 |
if (!text.startsWith('---')) return { fields: {}, body: text.trim() };
|
|
|
|
| 684 |
}
|
| 685 |
|
| 686 |
function firstParagraph(body) {
|
| 687 |
+
const parts = body.split(/\n\s*\n/).map(p => p.trim()).filter(Boolean);
|
| 688 |
+
if (!parts.length) return body.trim();
|
| 689 |
+
// If the first chunk is just a markdown heading, include the next chunk too
|
| 690 |
+
// so the preview is heading + first real paragraph.
|
| 691 |
+
if (/^#+\s+/.test(parts[0]) && parts.length > 1) {
|
| 692 |
+
return `${parts[0]}\n\n${parts[1]}`;
|
| 693 |
+
}
|
| 694 |
+
return parts[0];
|
| 695 |
}
|
| 696 |
|
| 697 |
function epochFromFilename(filename) {
|
|
|
|
| 706 |
const matches = [];
|
| 707 |
let m;
|
| 708 |
BPB_RE.lastIndex = 0;
|
| 709 |
+
while ((m = BPB_RE.exec(body)) !== null) {
|
| 710 |
+
const v = parseFloat(m[1]);
|
| 711 |
+
if (v >= BPB_MIN && v <= BPB_MAX) matches.push(v);
|
| 712 |
+
}
|
| 713 |
return matches.length ? Math.min(...matches) : null;
|
| 714 |
}
|
| 715 |
|