AakashJammula/repro-rgvq-graph-vector-quantization-regularization
0
1(function () {2 "use strict";3 4 let MANIFEST = null;5 const PAGE_CACHE = {};6 const UNFURL_CACHE = {};7 const DATA_CACHE = {};8 const LIVE_RELOAD_MS = 1500;9 const FIGURE_FRAME_WINDOWS = new Set();10 let FIGURE_NAVIGATION_READY = false;11 let CURRENT_VIEW = null;12 let RENDER_SEQUENCE = 0;13 14 function esc(s) {15 return String(s)16 .replace(/&/g, "&")17 .replace(/</g, "<")18 .replace(/>/g, ">")19 .replace(/"/g, """)20 .replace(/'/g, "'");21 }22 23 function flattenTree(node, depth, acc) {24 acc.push({ node: node, depth: depth });25 (node.children || []).forEach((c) => flattenTree(c, depth + 1, acc));26 return acc;27 }28 29 function findNode(node, slug) {30 if (node.slug === slug) return node;31 for (const c of node.children || []) {32 const hit = findNode(c, slug);33 if (hit) return hit;34 }35 return null;36 }37 38 /* -------------------- minimal markdown -------------------- */39 40 function inline(text) {41 let t = esc(text);42 t = t.replace(/`([^`]+)`/g, (_, c) => `<code>${c}</code>`);43 t = t.replace(/\*\*([^*]+)\*\*/g, (_, c) => `<strong>${c}</strong>`);44 t = t.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_, txt, url) => {45 const safe = esc(url);46 const attrs = /^https?:/.test(url) ? ' target="_blank" rel="noopener"' : "";47 const item = /^https?:/.test(url) ? classifyResource(url) : null;48 const data = item49 ? ` class="res-link" data-res-url="${esc(item.url)}"`50 : "";51 return `<a href="${safe}"${attrs}${data}>${txt}</a>`;52 });53 t = t.replace(/(^|[\s(])(https?:\/\/[^\s<>)"'`]+)/g, (m, pre, url) => {54 let rest = "";55 const cut = url.search(/"|'|<|>/);56 if (cut !== -1) {57 rest = url.slice(cut);58 url = url.slice(0, cut);59 }60 const trailing = (url.match(/[.,;:!?`]+$/) || [""])[0];61 const clean = trailing ? url.slice(0, -trailing.length) : url;62 if (!clean) return m;63 const item = classifyResource(clean);64 if (item) return `${pre}${resChipHtml(item)}${trailing}${rest}`;65 return `${pre}<a href="${clean}" target="_blank" rel="noopener">${clean}</a>${trailing}${rest}`;66 });67 return t;68 }69 70 function resChipHtml(item) {71 return (72 `<a class="res-chip" href="${esc(item.url)}" target="_blank" ` +73 `rel="noopener" data-res-url="${esc(item.url)}">` +74 `<span class="res-chip-ico">${RESOURCE_ICONS[item.kind]}</span>` +75 `${esc(item.id)}</a>`76 );77 }78 79 const URL_ONLY = /^(https?:\/\/[^\s]+)$/;80 const DETECTED_URL =81 /(https?:\/\/[^\s<>)\]"'`]+|trackio-local-dashboard:\/\/[^\s<>)\]"'`]+|trackio-artifact:\/\/[^\s<>)\]"'`]+|trackio-local-path:\/\/[^\s<>)\]"'`]+)/g;82 83 function renderMarkdown(md, container) {84 const cellRe = /(^|\n)---\n<!-- trackio-cell\n([\s\S]*?)\n-->\n([\s\S]*?)(?=\n---\n<!-- trackio-cell\n|\s*$)/g;85 const tokens = [];86 let pos = 0;87 let found = false;88 let match;89 while ((match = cellRe.exec(md))) {90 found = true;91 tokens.push({92 kind: "md",93 text: md.slice(pos, match.index + match[1].length),94 });95 tokens.push({96 kind: "cell",97 meta: parseCellMeta(match[2]),98 body: match[3],99 });100 pos = match.index + match[0].length;101 }102 tokens.push({ kind: "md", text: found ? md.slice(pos) : md });103 104 for (let i = 0; i < tokens.length; i++) {105 const t = tokens[i];106 if (t.kind === "md") {107 renderMarkdownPlain(t.text, container);108 continue;109 }110 if (t.consumed) continue;111 if (t.meta.type === "code") {112 const arts = [];113 for (let j = i + 1; j < tokens.length; j++) {114 const n = tokens[j];115 if (n.kind === "md") {116 if (n.text.trim() === "") continue;117 break;118 }119 if (n.meta.type === "artifact") {120 arts.push(n);121 n.consumed = true;122 continue;123 }124 break;125 }126 renderCell(t.meta, t.body, container, arts);127 } else {128 renderCell(t.meta, t.body, container);129 }130 }131 }132 133 function parseCellMeta(raw) {134 try {135 return JSON.parse(raw);136 } catch (e) {137 return { type: "markdown", title: "Note" };138 }139 }140 141 function renderMarkdownPlain(md, container) {142 const lines = md.replace(/<!--[\s\S]*?-->/g, "").split("\n");143 let i = 0;144 let para = [];145 146 function flushPara() {147 if (!para.length) return;148 const joined = para.join(" ").trim();149 para = [];150 if (!joined) return;151 if (/^trackio-artifact:\/\/\S+$/.test(joined)) return;152 if (/^trackio-local-path:\/\/\S+$/.test(joined)) return;153 if (joined.indexOf("๐ฆ Artifact") !== -1) {154 const div = document.createElement("div");155 div.className = "artifact-chip";156 div.innerHTML = ARTIFACT_ICON_IMG + inline(joined.replace(/๐ฆ\s*/, ""));157 container.appendChild(div);158 return;159 }160 if (URL_ONLY.test(joined) || IMG_PATH.test(joined)) {161 const el = renderStandaloneUrl(joined);162 if (el) container.appendChild(el);163 return;164 }165 const p = document.createElement("p");166 p.innerHTML = inline(joined);167 container.appendChild(p);168 }169 170 while (i < lines.length) {171 const line = lines[i];172 const trimmed = line.trim();173 174 if (trimmed === "") {175 flushPara();176 i++;177 continue;178 }179 const fence = trimmed.match(/^(`{3,}|~{3,})(.*)$/);180 if (fence) {181 flushPara();182 const marker = fence[1][0];183 const closeRe = new RegExp("^" + marker + "{" + fence[1].length + ",}\\s*$");184 const info = fence[2].trim();185 const buf = [];186 i++;187 while (i < lines.length && !closeRe.test(lines[i].trim())) {188 buf.push(lines[i]);189 i++;190 }191 i++;192 const lang = (info.split(/\s+/)[0] || "").toLowerCase();193 const tm = info.match(/title=(\S+)/);194 container.appendChild(195 renderCode(buf.join("\n"), lang, tm ? tm[1] : null)196 );197 continue;198 }199 if (trimmed === "---") {200 flushPara();201 container.appendChild(document.createElement("hr"));202 i++;203 continue;204 }205 const h = trimmed.match(/^(#{1,4})\s+(.*)$/);206 if (h) {207 flushPara();208 const el = document.createElement("h" + h[1].length);209 el.innerHTML = inline(h[2]);210 container.appendChild(el);211 i++;212 continue;213 }214 if (215 trimmed.startsWith("|") &&216 i + 1 < lines.length &&217 /^\|?[\s:|-]*-{2,}[\s:|-]*\|?$/.test(lines[i + 1].trim())218 ) {219 flushPara();220 const rows = [];221 while (i < lines.length && lines[i].trim().startsWith("|")) {222 rows.push(parseRow(lines[i].trim()));223 i++;224 }225 renderTable(rows, container);226 continue;227 }228 if (trimmed.startsWith("> ")) {229 flushPara();230 const bq = document.createElement("blockquote");231 bq.innerHTML = inline(trimmed.slice(2));232 container.appendChild(bq);233 i++;234 continue;235 }236 if (/^`[^`]+`$/.test(trimmed)) {237 flushPara();238 const el = document.createElement("div");239 el.className = "ts";240 el.textContent = trimmed.replace(/`/g, "");241 container.appendChild(el);242 i++;243 continue;244 }245 if (trimmed.startsWith("- ")) {246 flushPara();247 const items = [];248 while (i < lines.length && lines[i].trim().startsWith("- ")) {249 items.push(lines[i].trim().slice(2).trim());250 i++;251 }252 renderList(items, container);253 continue;254 }255 para.push(trimmed);256 i++;257 }258 flushPara();259 }260 261 function renderCell(meta, body, container, artifacts) {262 const cell = document.createElement("section");263 cell.className = `cell ${meta.type || "markdown"}`;264 if (meta.id) cell.dataset.cellId = meta.id;265 if (isPinned(meta)) cell.classList.add("pinned-source");266 267 const head = document.createElement("div");268 head.className = "cell-head";269 const rawTitle = (meta.title || "").trim();270 const title = rawTitle && rawTitle.toLowerCase() !== "untitled" ? esc(rawTitle) : "";271 const when = meta.created_at ? `<span>${esc(formatTime(meta.created_at))}</span>` : "";272 head.innerHTML =273 (title ? `<div class="cell-title">${title}</div>` : "") +274 `<div class="cell-meta">${when}</div>`;275 if (!title) head.classList.add("no-title");276 cell.appendChild(head);277 278 const bodyEl = document.createElement("div");279 bodyEl.className = "cell-body";280 if (meta.type === "code") {281 renderCodeCell(body, bodyEl, artifacts);282 } else if (meta.type === "figure") {283 cell.dataset.resUrl = `trackio-figure://${(meta.title || "Figure").trim()}`;284 renderFigureCell(body, bodyEl, head);285 } else if (meta.type === "artifact") {286 renderMarkdownPlain(body, bodyEl);287 const chip = bodyEl.querySelector(".artifact-chip");288 const uri = body.match(289 /(trackio-artifact:\/\/\S+|trackio-local-path:\/\/\S+|https:\/\/huggingface\.co\/buckets\/[^\s<)]+#\S+)/290 );291 if (chip && uri) chip.dataset.resUrl = uri[1];292 if (chip && meta.path) {293 const ico = chip.querySelector(".art-ico");294 if (ico) ico.outerHTML = FILE_ICON;295 }296 } else if (meta.type === "dashboard") {297 const sp = body.match(/https:\/\/huggingface\.co\/spaces\/[^\s<>)"'`]+/);298 cell.dataset.resUrl = sp299 ? sp[0]300 : `trackio-local-dashboard://${(meta.dashboard_project || "").trim()}`;301 renderDashboardCell(meta, body, bodyEl, head);302 } else {303 const cleaned = stripDuplicateTitle(body, meta.title);304 renderMarkdownPlain(cleaned, bodyEl);305 renderDetectedEmbeds(cleaned, bodyEl);306 }307 cell.appendChild(bodyEl);308 container.appendChild(cell);309 return cell;310 }311 312 function isPinned(meta) {313 return Boolean(meta && (meta.pinned === true || meta.pinned === "true"));314 }315 316 function stripDuplicateTitle(body, title) {317 if (!title) return body;318 const m = body.match(/^\s*#{1,6}\s+([^\n]+)\n?/);319 if (!m) return body;320 const norm = (s) =>321 s322 .toLowerCase()323 .replace(/[*_`#]/g, "")324 .replace(/\s+/g, " ")325 .trim();326 return norm(m[1]) === norm(title) ? body.slice(m[0].length) : body;327 }328 329 function formatTime(iso) {330 const d = new Date(iso);331 if (Number.isNaN(d.getTime())) return iso;332 return d.toLocaleString(undefined, {333 month: "short",334 day: "numeric",335 hour: "2-digit",336 minute: "2-digit",337 });338 }339 340 function parseFences(text) {341 const fenceRe = /(`{3,4}|~{3,4})([^\n]*)\n([\s\S]*?)\n\1/g;342 const parts = [];343 let pos = 0;344 let match;345 while ((match = fenceRe.exec(text))) {346 if (match.index > pos) {347 parts.push({ kind: "text", text: text.slice(pos, match.index) });348 }349 const info = match[2].trim();350 const lang = (info.split(/\s+/)[0] || "").toLowerCase();351 const titleMatch = info.match(/title=(\S+)/);352 parts.push({353 kind: lang === "result" || lang === "output" ? "output" : "code",354 lang,355 title: titleMatch ? titleMatch[1] : null,356 text: match[3],357 });358 pos = match.index + match[0].length;359 }360 if (pos < text.length) parts.push({ kind: "text", text: text.slice(pos) });361 return parts;362 }363 364 function fitFigureFrame(frame, wrap) {365 let doc;366 try {367 doc = frame.contentDocument;368 } catch (e) {369 return;370 }371 if (!doc || !doc.body) return;372 frame.style.transform = "none";373 frame.style.width = "100%";374 frame.style.height = "auto";375 frame.style.position = "";376 frame.style.left = "";377 frame.style.top = "";378 const avail = wrap.clientWidth;379 const isFullscreen =380 document.fullscreenElement === wrap ||381 document.webkitFullscreenElement === wrap;382 const availHeight = isFullscreen ? wrap.clientHeight : Infinity;383 const cw = Math.max(doc.body.scrollWidth, doc.documentElement.scrollWidth, 1);384 const ch = Math.max(doc.body.scrollHeight, doc.documentElement.scrollHeight, 1);385 const scale = Math.min(avail / cw, availHeight / ch);386 if (avail && scale < 1 - 1e-3) {387 frame.style.width = `${cw}px`;388 frame.style.height = `${ch}px`;389 frame.style.transformOrigin = "top left";390 frame.style.transform = `scale(${scale})`;391 if (isFullscreen) {392 frame.style.position = "absolute";393 frame.style.left = `${Math.max(0, (avail - cw * scale) / 2)}px`;394 frame.style.top = `${Math.max(0, (availHeight - ch * scale) / 2)}px`;395 wrap.style.height = "100%";396 } else {397 wrap.style.height = `${Math.ceil(ch * scale)}px`;398 }399 } else {400 frame.style.width = "100%";401 frame.style.height = `${ch}px`;402 wrap.style.height = isFullscreen ? "100%" : `${ch}px`;403 }404 }405 406 function attachFigureFit(frame, wrap) {407 const refit = () => fitFigureFrame(frame, wrap);408 frame.addEventListener("load", refit);409 if (window.ResizeObserver) {410 const ro = new ResizeObserver(() => refit());411 ro.observe(wrap);412 }413 }414 415 function renderFigureCell(text, container, head) {416 const parts = parseFences(text);417 const htmlPart = parts.find((part) => part.lang === "html");418 const rawPart = parts.find((part) => part.lang === "raw");419 if (!htmlPart || !htmlPart.text.trim()) {420 const empty = document.createElement("p");421 empty.className = "muted";422 empty.textContent = "No figure HTML.";423 container.appendChild(empty);424 return;425 }426 const frame = document.createElement("iframe");427 frame.className = "figure-frame";428 frame.sandbox = "allow-scripts allow-same-origin";429 frame.loading = "lazy";430 frame.srcdoc = htmlPart.text;431 registerFigureNavigation(frame);432 const figWrap = document.createElement("div");433 figWrap.className = "figure-fit";434 figWrap.appendChild(frame);435 attachFigureFit(frame, figWrap);436 if (head) {437 const metaEl = head.querySelector(".cell-meta");438 if (metaEl)439 metaEl.insertBefore(buildFullscreenControl(figWrap, frame), metaEl.firstChild);440 }441 if (!rawPart || !rawPart.text.trim()) {442 container.appendChild(figWrap);443 return;444 }445 const sw = document.createElement("div");446 sw.className = "fig-switch";447 const thumb = document.createElement("span");448 thumb.className = "fig-switch-thumb";449 const figBtn = document.createElement("button");450 figBtn.type = "button";451 figBtn.className = "active";452 figBtn.textContent = "Figure";453 const rawBtn = document.createElement("button");454 rawBtn.type = "button";455 rawBtn.textContent = "Raw";456 sw.appendChild(thumb);457 sw.appendChild(figBtn);458 sw.appendChild(rawBtn);459 const rawView = document.createElement("div");460 rawView.className = "figure-raw";461 rawView.hidden = true;462 const pre = document.createElement("pre");463 const code = document.createElement("code");464 code.textContent = rawPart.text;465 pre.appendChild(code);466 rawView.appendChild(pre);467 rawView.appendChild(copySnippetBtn(rawPart.text));468 const select = (showRaw) => {469 sw.classList.toggle("raw", showRaw);470 figBtn.classList.toggle("active", !showRaw);471 rawBtn.classList.toggle("active", showRaw);472 figWrap.hidden = showRaw;473 rawView.hidden = !showRaw;474 };475 figBtn.addEventListener("click", () => select(false));476 rawBtn.addEventListener("click", () => select(true));477 if (head) {478 head.insertBefore(sw, head.querySelector(".cell-meta"));479 } else {480 container.appendChild(sw);481 }482 container.appendChild(figWrap);483 container.appendChild(rawView);484 }485 486 // Poster embeds can send `{ type: "trackio-logbook:navigate", target: "..." }`487 // from their iframe. Only accept messages from figure frames we created, and488 // only route to pages that are present in this logbook's manifest.489 function registerFigureNavigation(frame) {490 const registerFrameWindow = () => {491 if (frame.contentWindow) FIGURE_FRAME_WINDOWS.add(frame.contentWindow);492 };493 // `srcdoc` replaces the initial about:blank document. Register after that494 // navigation as well, so messages come from the live figure document.495 frame.addEventListener("load", registerFrameWindow);496 registerFrameWindow();497 if (FIGURE_NAVIGATION_READY) return;498 FIGURE_NAVIGATION_READY = true;499 window.addEventListener("message", (event) => {500 if (!FIGURE_FRAME_WINDOWS.has(event.source)) return;501 const message = event.data;502 if (!message || message.type !== "trackio-logbook:navigate") return;503 const target = String(message.target || "").replace(/^#?\//, "");504 if (!target || !MANIFEST || !findNode(MANIFEST.root, target)) return;505 const hash = "#/view/code/" + target;506 if (location.hash === hash) scrollToHash();507 else location.hash = hash;508 });509 }510 511 const FULLSCREEN_ICON =512 '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" ' +513 'stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">' +514 '<path d="M8 3H3v5M16 3h5v5M21 16v5h-5M3 16v5h5"/>' +515 '<path d="M3 8 8 3M16 3l5 5M21 16l-5 5M8 21l-5-5"/></svg>';516 517 const PIN_ICON =518 '<svg class="pin-ico" viewBox="0 0 24 24" aria-hidden="true">' +519 '<path d="M16 9V4h1c.55 0 1-.45 1-1s-.45-1-1-1H7c-.55 0-1 .45-1 1s.45 1 1 1h1v5c0 ' +520 '1.66-1.34 3-3 3v2h5.97v7l1 1 1-1v-7H19v-2c-1.66 0-3-1.34-3-3z"/></svg>';521 522 const FILE_ICON =523 '<svg class="art-file-ico" viewBox="0 0 24 24" aria-hidden="true">' +524 '<path d="M6 3.5h8l4 4V20H6zM14 3.5V8h4"/></svg>';525 526 // Figures are rendered in same-origin iframes, so fullscreen the fitted527 // wrapper rather than the iframe document. This uses the browser's native528 // fullscreen UI and preserves the figure's existing responsive sizing.529 function buildFullscreenControl(figWrap, frame) {530 const wrap = document.createElement("span");531 wrap.className = "cell-fullscreen";532 const btn = document.createElement("button");533 btn.type = "button";534 btn.className = "cell-fullscreen-btn";535 btn.setAttribute("aria-label", "Open figure in fullscreen");536 btn.title = "Open figure in fullscreen";537 btn.innerHTML = FULLSCREEN_ICON;538 wrap.appendChild(btn);539 540 btn.addEventListener("click", async () => {541 const request = figWrap.requestFullscreen || figWrap.webkitRequestFullscreen;542 if (!request) return;543 try {544 await request.call(figWrap);545 } catch (_) {546 // Fullscreen can be disabled by the embedding browser or policy.547 }548 });549 document.addEventListener("fullscreenchange", () => {550 if (document.fullscreenElement === figWrap) fitFigureFrame(frame, figWrap);551 });552 return wrap;553 }554 555 function extractUrls(text) {556 const seen = new Set();557 const urls = [];558 let match;559 while ((match = DETECTED_URL.exec(text))) {560 const url = match[1].replace(/[.,;:!?'"`]+$/, "");561 if (!seen.has(url)) {562 seen.add(url);563 urls.push(url);564 }565 }566 DETECTED_URL.lastIndex = 0;567 return urls;568 }569 570 const IMG_URL = /(\.(png|jpe?g|gif|svg|webp)(\?|$)|\/artifact_blob\/)/i;571 572 function renderDetectedEmbeds(text, container) {573 extractUrls(text).forEach((url) => {574 if (url.startsWith("trackio-local-dashboard://")) {575 const div = document.createElement("div");576 div.className = "artifact-chip";577 div.dataset.resUrl = url;578 div.innerHTML =579 "๐ฏ <strong>Local Trackio dashboard</strong> โ publish the logbook to share it";580 container.appendChild(div);581 } else if (IMG_URL.test(url)) {582 container.appendChild(renderImage(url));583 } else if (/huggingface\.co\/spaces\//.test(url)) {584 maybeEmbedTrackioSpace(url, container);585 }586 });587 }588 589 function renderStandaloneUrl(url) {590 if (IMG_URL.test(url) || IMG_PATH.test(url)) return renderImage(url);591 const item = classifyResource(url);592 if (item) {593 const marker = document.createElement("span");594 marker.className = "resource-anchor";595 marker.dataset.resUrl = item.url;596 marker.setAttribute("aria-hidden", "true");597 return marker;598 }599 const p = document.createElement("p");600 p.innerHTML = inline(url);601 return p;602 }603 604 function renderImage(url) {605 const a = document.createElement("a");606 a.className = "unfurl image";607 a.href = url;608 a.target = "_blank";609 a.rel = "noopener";610 const img = document.createElement("img");611 img.loading = "lazy";612 img.src = url;613 img.alt = "artifact image";614 a.appendChild(img);615 return a;616 }617 618 function maybeEmbedTrackioSpace(url, container) {619 const id = url.split("/spaces/")[1].split(/[?#]/)[0].replace(/\/$/, "");620 const holder = document.createElement("div");621 container.appendChild(holder);622 getJSON(`https://huggingface.co/api/spaces/${id}`).then((d) => {623 const tags = (d && d.tags) || [];624 if (tags.some((t) => String(t).toLowerCase() === "trackio")) {625 renderTrackioSpaceEmbed(holder, url, id);626 } else {627 holder.remove();628 }629 });630 }631 632 function jpGutter(label) {633 const g = document.createElement("div");634 g.className = "jp-gutter";635 g.textContent = label;636 return g;637 }638 639 function renderOutArtifact(info) {640 const remote = !info.local && !!info.url;641 const el = document.createElement(remote ? "a" : "div");642 el.className = "out-artifact";643 if (remote) {644 el.href = info.url;645 el.target = "_blank";646 el.rel = "noopener";647 }648 el.dataset.resUrl = info.resUrl;649 const parts = [info.type, info.size].filter(Boolean).map(esc);650 const state = remote651 ? `<span class="out-artifact-state open">Open โ</span>`652 : `<span class="out-artifact-state">publish to share</span>`;653 const meta = parts.length ? `${parts.join(" ยท ")} ยท ${state}` : state;654 const icon = info.isPathRef ? FILE_ICON : ARTIFACT_ICON_IMG;655 el.innerHTML =656 `<span class="out-artifact-ico">${icon}</span>` +657 `<span class="out-artifact-name">${esc(info.name)}</span>` +658 `<span class="out-artifact-meta">${meta}</span>`;659 return el;660 }661 662 function isShellCommand(part) {663 return (664 part.kind === "code" &&665 part.lang === "bash" &&666 !part.title &&667 /^\s*\$\s/.test(part.text)668 );669 }670 671 function renderCommandLine(text) {672 const command = text.trim().replace(/^\$\s*/, "");673 const el = document.createElement("div");674 el.className = "jp-cmd";675 const prompt = document.createElement("span");676 prompt.className = "jp-cmd-prompt";677 prompt.textContent = "$";678 const code = document.createElement("code");679 code.textContent = command;680 el.appendChild(prompt);681 el.appendChild(code);682 el.appendChild(copySnippetBtn(command));683 return el;684 }685 686 function renderCodeCell(body, container, artifacts) {687 const parts = parseFences(body);688 const block = document.createElement("div");689 block.className = "jp";690 const input = document.createElement("div");691 input.className = "jp-in";692 const inputBody = document.createElement("div");693 inputBody.className = "jp-in-body";694 input.appendChild(jpGutter("In"));695 input.appendChild(inputBody);696 let metaEl = null;697 let outputEl = null;698 let outBody = null;699 const ensureOut = () => {700 if (outputEl) return;701 outputEl = document.createElement("div");702 outputEl.className = "jp-out";703 outputEl.appendChild(jpGutter("Out"));704 outBody = document.createElement("div");705 outBody.className = "jp-out-body";706 outputEl.appendChild(outBody);707 };708 const embedTexts = [];709 parts.forEach((part) => {710 if (part.kind === "text") {711 const text = part.text.trim();712 if (!text) return;713 if (/^exit\s+\S+(\s|ยท)/.test(text)) {714 metaEl = document.createElement("div");715 metaEl.className = "jp-meta";716 metaEl.textContent = text.replace(717 /\s*ยท\s*[A-Z][a-z]{2} \d{1,2}, \d{4}.*$/,718 ""719 );720 } else {721 renderMarkdownPlain(text, container);722 embedTexts.push(text);723 }724 return;725 }726 if (part.kind === "output") {727 ensureOut();728 const pre = document.createElement("pre");729 pre.className = "jp-out-pre";730 const c = document.createElement("code");731 c.textContent = part.text;732 pre.appendChild(c);733 outBody.appendChild(pre);734 outputEl.appendChild(copySnippetBtn(part.text));735 embedTexts.push(part.text);736 return;737 }738 if (isShellCommand(part)) {739 inputBody.appendChild(renderCommandLine(part.text));740 } else {741 inputBody.appendChild(742 renderCode(part.text, part.lang, part.title, Boolean(part.title))743 );744 }745 });746 if (artifacts && artifacts.length) {747 ensureOut();748 const artWrap = document.createElement("div");749 artWrap.className = "jp-artifacts";750 artifacts.forEach((a) => {751 artWrap.appendChild(752 renderOutArtifact(artifactInfoFromCell(a.meta, a.body))753 );754 });755 outBody.appendChild(artWrap);756 }757 if (inputBody.childNodes.length > 0) block.appendChild(input);758 if (metaEl) block.appendChild(metaEl);759 if (outputEl) block.appendChild(outputEl);760 if (block.childNodes.length) container.appendChild(block);761 embedTexts.forEach((text) => renderDetectedEmbeds(text, container));762 }763 764 function parseRow(line) {765 let s = line.trim();766 if (s.startsWith("|")) s = s.slice(1);767 if (s.endsWith("|")) s = s.slice(0, -1);768 return s.split(/(?<!\\)\|/).map((c) => c.replace(/\\\|/g, "|").trim());769 }770 771 const TRUTHY = ["x", "โ", "โ", "yes", "done", "true", "[x]"];772 const CHIP_COLORS = [773 ["#e7f0ff", "#2158d0"],774 ["#fde8ec", "#c62a4b"],775 ["#e6f7ee", "#1a8a55"],776 ["#fdf0e0", "#b26a12"],777 ["#efe9ff", "#5b3bd6"],778 ["#e6f6f8", "#127b88"],779 ];780 781 function chipColor(name) {782 let h = 0;783 for (let i = 0; i < name.length; i++) h = (h * 31 + name.charCodeAt(i)) >>> 0;784 return CHIP_COLORS[h % CHIP_COLORS.length];785 }786 787 const STATUS_MAP = {788 "": ["Planned", "gray"],789 planned: ["Planned", "gray"],790 todo: ["Planned", "gray"],791 "to do": ["Planned", "gray"],792 backlog: ["Planned", "gray"],793 "in progress": ["In progress", "amber"],794 "in-progress": ["In progress", "amber"],795 wip: ["In progress", "amber"],796 running: ["In progress", "amber"],797 active: ["In progress", "amber"],798 done: ["Done", "green"],799 complete: ["Done", "green"],800 completed: ["Done", "green"],801 blocked: ["Blocked", "red"],802 failed: ["Failed", "red"],803 abandoned: ["Abandoned", "gray"],804 };805 806 function statusBadge(val) {807 const [label, tone] = STATUS_MAP[val.toLowerCase()] || [val || "โ", "gray"];808 return `<span class="badge ${tone}">${esc(label)}</span>`;809 }810 811 function renderTable(rows, container) {812 if (rows.length < 2) return;813 const header = rows[0];814 const body = rows.slice(2);815 const roles = header.map((h) => {816 const t = h.toLowerCase();817 if (t.includes("status") || t.includes("state")) return "status";818 if (t.includes("progress") || t.includes("complete") || t.includes("done"))819 return "check";820 if (t === "who" || t.includes("assign") || t.includes("owner")) return "who";821 return "text";822 });823 const table = document.createElement("table");824 table.className = "board";825 const thead = document.createElement("thead");826 const htr = document.createElement("tr");827 header.forEach((h, c) => {828 const th = document.createElement("th");829 th.textContent = h;830 if (roles[c] === "check") th.className = "col-check";831 htr.appendChild(th);832 });833 thead.appendChild(htr);834 table.appendChild(thead);835 const tbody = document.createElement("tbody");836 body.forEach((cells) => {837 const nonEmpty = cells.filter((x) => x !== "").length;838 if (header.length > 1 && nonEmpty === 1 && cells[0]) {839 const tr = document.createElement("tr");840 tr.className = "section-row";841 const td = document.createElement("td");842 td.colSpan = header.length;843 td.innerHTML = inline(cells[0]);844 tr.appendChild(td);845 tbody.appendChild(tr);846 return;847 }848 const tr = document.createElement("tr");849 header.forEach((_, c) => {850 const td = document.createElement("td");851 const val = (cells[c] || "").trim();852 if (roles[c] === "status") {853 td.className = "col-status";854 td.innerHTML = statusBadge(val);855 } else if (roles[c] === "check") {856 td.className = "col-check";857 const on = TRUTHY.indexOf(val.toLowerCase()) !== -1;858 td.innerHTML = `<span class="box ${on ? "on" : ""}">${on ? "โ" : ""}</span>`;859 } else if (roles[c] === "who") {860 if (!val || /^to assign$/i.test(val)) {861 td.innerHTML = `<span class="who-chip muted">${esc(val || "โ")}</span>`;862 } else {863 const [bg, fg] = chipColor(val);864 td.innerHTML = `<span class="who-chip" style="background:${bg};color:${fg}">${esc(val)}</span>`;865 }866 } else {867 td.innerHTML = inline(val);868 }869 tr.appendChild(td);870 });871 const link = tr.querySelector('a[href^="#/"]');872 if (link) {873 tr.classList.add("linked-row");874 tr.addEventListener("click", (e) => {875 if (e.target.tagName !== "A") location.hash = link.getAttribute("href");876 });877 }878 tbody.appendChild(tr);879 });880 table.appendChild(tbody);881 const wrap = document.createElement("div");882 wrap.className = "board-wrap";883 wrap.appendChild(table);884 container.appendChild(wrap);885 }886 887 const HL_RULES = {888 python: [889 ["comment", /#[^\n]*/],890 ["string", /'''[\s\S]*?'''|"""[\s\S]*?"""|'(?:\\.|[^'\\])*'|"(?:\\.|[^"\\])*"/],891 [892 "keyword",893 /\b(?:def|class|return|if|elif|else|for|while|import|from|as|with|try|except|finally|raise|in|not|and|or|is|None|True|False|lambda|yield|global|nonlocal|assert|pass|break|continue|async|await|print)\b/,894 ],895 ["number", /\b\d[\d_.eE+-]*\b/],896 ],897 bash: [898 ["comment", /#[^\n]*/],899 ["string", /'(?:\\.|[^'\\])*'|"(?:\\.|[^"\\])*"/],900 ["keyword", /\b(?:if|then|else|fi|for|in|do|done|while|case|esac|function|export|source|echo|cd|return|local)\b/],901 ["number", /(?<=\s)-{1,2}[a-zA-Z][\w-]*/],902 ],903 json: [904 ["string", /"(?:\\.|[^"\\])*"/],905 ["keyword", /\b(?:true|false|null)\b/],906 ["number", /-?\b\d[\d.eE+-]*\b/],907 ],908 yaml: [909 ["comment", /#[^\n]*/],910 ["string", /'(?:\\.|[^'\\])*'|"(?:\\.|[^"\\])*"/],911 ["keyword", /\b(?:true|false|null|yes|no)\b/],912 ["number", /-?\b\d[\d.eE+-]*\b/],913 ],914 };915 HL_RULES.javascript = HL_RULES.python;916 HL_RULES.typescript = HL_RULES.python;917 HL_RULES.sql = [918 ["comment", /--[^\n]*/],919 ["string", /'(?:\\.|[^'\\])*'/],920 [921 "keyword",922 /\b(?:SELECT|FROM|WHERE|JOIN|LEFT|RIGHT|INNER|OUTER|ON|GROUP|BY|ORDER|LIMIT|INSERT|INTO|VALUES|UPDATE|SET|DELETE|CREATE|TABLE|AS|AND|OR|NOT|NULL|COUNT|DISTINCT|IN)\b/i,923 ],924 ["number", /\b\d[\d.]*\b/],925 ];926 927 function highlightCode(code, lang) {928 const rules = HL_RULES[lang];929 if (!rules) return esc(code);930 const combined = new RegExp(rules.map((r) => "(" + r[1].source + ")").join("|"), "g");931 let out = "";932 let last = 0;933 let m;934 while ((m = combined.exec(code))) {935 if (m[0] === "") {936 combined.lastIndex++;937 continue;938 }939 out += esc(code.slice(last, m.index));940 let gi = 1;941 while (gi < m.length && m[gi] === undefined) gi++;942 out += `<span class="tok-${rules[gi - 1][0]}">${esc(m[0])}</span>`;943 last = m.index + m[0].length;944 }945 out += esc(code.slice(last));946 return out;947 }948 949 function copySnippetBtn(text) {950 const btn = document.createElement("button");951 btn.type = "button";952 btn.className = "copy-snippet";953 btn.title = "Copy";954 btn.textContent = "โง";955 btn.addEventListener("click", (e) => {956 e.preventDefault();957 e.stopPropagation();958 copyText(text, btn, "โง");959 });960 return btn;961 }962 963 function renderCode(code, lang, title, open) {964 const pre = document.createElement("pre");965 pre.className = "hl";966 const c = document.createElement("code");967 c.innerHTML = highlightCode(code, lang);968 pre.appendChild(c);969 if (!title || open) {970 const wrap = document.createElement("div");971 wrap.className = "snippet";972 wrap.appendChild(pre);973 wrap.appendChild(copySnippetBtn(code));974 return wrap;975 }976 const det = document.createElement("details");977 det.className = "code-accordion";978 det.dataset.resUrl = `trackio-script://${title}`;979 const sum = document.createElement("summary");980 sum.innerHTML =981 `<span class="code-ico"></></span>` +982 `<span class="code-name">${esc(title)}</span>`;983 sum984 .querySelector(".code-name")985 .addEventListener("click", (e) => e.preventDefault());986 det.appendChild(sum);987 const wrap = document.createElement("div");988 wrap.className = "snippet";989 wrap.appendChild(pre);990 wrap.appendChild(copySnippetBtn(code));991 det.appendChild(wrap);992 return det;993 }994 995 const IMG_PATH = /^[^\s]+\.(png|jpe?g|gif|svg|webp)$/i;996 997 function renderList(items, container) {998 let ul = null;999 items.forEach((item) => {1000 if (URL_ONLY.test(item) || IMG_PATH.test(item)) {1001 const el = renderStandaloneUrl(item);1002 if (el) {1003 ul = null;1004 container.appendChild(el);1005 }1006 } else if (item.indexOf("๐ฆ Artifact") !== -1) {1007 ul = null;1008 const div = document.createElement("div");1009 div.className = "artifact-chip";1010 div.innerHTML = inline(item.replace("๐ฆ", "๐ชฃ"));1011 container.appendChild(div);1012 } else if (item.indexOf("trackio-local-dashboard://") !== -1) {1013 ul = null;1014 const uri = item.match(/trackio-local-dashboard:\/\/\S+/)?.[0] || "";1015 const div = document.createElement("div");1016 div.className = "artifact-chip";1017 if (uri) div.dataset.resUrl = uri;1018 div.innerHTML =1019 "๐ฏ <strong>Local dashboard</strong> โ publish the logbook to share it";1020 container.appendChild(div);1021 } else {1022 if (!ul) {1023 ul = document.createElement("ul");1024 container.appendChild(ul);1025 }1026 const li = document.createElement("li");1027 li.innerHTML = inline(item);1028 ul.appendChild(li);1029 }1030 });1031 }1032 1033 /* -------------------- resource classification -------------------- */1034 1035 function fmt(n) {1036 if (n == null) return null;1037 if (n >= 1e6) return (n / 1e6).toFixed(1) + "M";1038 if (n >= 1e3) return (n / 1e3).toFixed(1) + "k";1039 return String(n);1040 }1041 1042 const RESOURCE_SECTIONS = [1043 ["dashboard", "Dashboards", "๐ฏ"],1044 ["model", "Models", "๐ค"],1045 ["dataset", "Datasets", "๐"],1046 ["space", "Spaces", "๐"],1047 ["artifact", "Artifacts", "๐ชฃ"],1048 ["paper", "Papers", "๐"],1049 ["repo", "Code", "๐"],1050 ["job", "Jobs", "โ๏ธ"],1051 ["bucket", "Buckets", "๐ชฃ"],1052 ];1053 1054 const RESOURCE_ICONS = Object.fromEntries(1055 RESOURCE_SECTIONS.map(([kind, , icon]) => [kind, icon])1056 );1057 1058 const ARTIFACT_ICON_IMG = `<img class="art-ico" src="./bucket-icon.svg" alt="" />`;1059 const DASHBOARD_ICON_IMG = `<img class="art-ico" src="./trackio-logo-light.png" alt="" />`;1060 1061 const HF_NON_MODEL_PREFIX =1062 /^(datasets|spaces|jobs|buckets|papers|blog|docs|api|posts|collections|organizations|settings|new|join|login|pricing|tasks|learn|chat|models)(\/|$)/;1063 1064 function hfId(url, marker) {1065 return url.split(marker)[1].split(/[?#]/)[0].replace(/\/$/, "");1066 }1067 1068 function validHfSegment(value) {1069 return Boolean(1070 value &&1071 value.length <= 96 &&1072 /^[A-Za-z0-9_.-]+$/.test(value) &&1073 !/^[.-]|[.-]$|--|\.\./.test(value)1074 );1075 }1076 1077 function validHfRepoId(parts) {1078 return (1079 parts.length === 2 &&1080 parts.join("/").length <= 96 &&1081 parts.every(validHfSegment)1082 );1083 }1084 1085 function classifyResource(url) {1086 if (IMG_URL.test(url)) {1087 return null;1088 }1089 let m;1090 if (url.startsWith("trackio-local-dashboard://")) {1091 return {1092 kind: "dashboard",1093 id: url.slice("trackio-local-dashboard://".length),1094 url,1095 local: true,1096 };1097 }1098 if (url.startsWith("trackio-artifact://")) {1099 return {1100 kind: "artifact",1101 id: url.slice("trackio-artifact://".length),1102 url,1103 local: true,1104 };1105 }1106 if (url.startsWith("trackio-local-path://")) {1107 return {1108 kind: "artifact",1109 id: url.slice("trackio-local-path://".length),1110 url,1111 local: true,1112 };1113 }1114 if ((m = url.match(/huggingface\.co\/buckets\/([^/#\s]+\/[^/#\s]+)#(.+)/))) {1115 if (!validHfRepoId(m[1].split("/"))) return null;1116 return { kind: "artifact", id: decodeURIComponent(m[2]), url };1117 }1118 if (/huggingface\.co\/datasets\//.test(url)) {1119 const parts = hfId(url, "/datasets/").split("/").slice(0, 2);1120 if (!validHfRepoId(parts)) return null;1121 return { kind: "dataset", id: parts.join("/"), url };1122 }1123 if (/huggingface\.co\/spaces\//.test(url)) {1124 const parts = hfId(url, "/spaces/").split("/").slice(0, 2);1125 if (!validHfRepoId(parts)) return null;1126 return { kind: "space", id: parts.join("/"), url };1127 }1128 if (/huggingface\.co\/jobs\//.test(url)) {1129 const parts = hfId(url, "/jobs/").split("/").slice(0, 2);1130 if (!validHfRepoId(parts)) return null;1131 const jid = parts[1];1132 return {1133 kind: "job",1134 id: parts[0] + ` ยท ${jid.slice(0, 12)}${jid.length > 12 ? "โฆ" : ""}`,1135 url,1136 };1137 }1138 if (/huggingface\.co\/buckets\//.test(url)) {1139 const parts = hfId(url, "/buckets/").split("/").slice(0, 2);1140 if (!validHfRepoId(parts)) return null;1141 return { kind: "bucket", id: parts.join("/"), url };1142 }1143 if (/huggingface\.co\/papers\//.test(url)) {1144 const id = hfId(url, "/papers/").split("/")[0];1145 if (!validHfSegment(id)) return null;1146 return { kind: "paper", id: `Paper ${id}`, url };1147 }1148 if ((m = url.match(/arxiv\.org\/(?:abs|pdf)\/([^?#\s]+)/))) {1149 return { kind: "paper", id: `arXiv:${m[1].replace(/\.pdf$/, "")}`, url };1150 }1151 if ((m = url.match(/github\.com\/([^/?#]+\/[^/?#]+)/))) {1152 return { kind: "repo", id: m[1], url };1153 }1154 if ((m = url.match(/huggingface\.co\/([^?#]+)/))) {1155 const rest = m[1].replace(/\/$/, "");1156 if (validHfRepoId(rest.split("/")) && !HF_NON_MODEL_PREFIX.test(rest)) {1157 return { kind: "model", id: rest, url };1158 }1159 }1160 return null;1161 }1162 1163 function dashboardSubdomainFromUrl(url) {1164 return spaceIdFromUrl(url).toLowerCase().replace(/[^a-z0-9-]/g, "-");1165 }1166 1167 function dashboardOpenLink(head, url) {1168 if (!head || !url) return;1169 const meta = head.querySelector(".cell-meta");1170 if (!meta) return;1171 let link = meta.querySelector(".cell-open");1172 if (!link) {1173 link = document.createElement("a");1174 link.className = "cell-open";1175 link.target = "_blank";1176 link.rel = "noopener";1177 meta.insertBefore(link, meta.firstChild);1178 }1179 link.href = url;1180 link.textContent = "Open โ";1181 }1182 1183 function dashboardFrame(src) {1184 const iframe = document.createElement("iframe");1185 iframe.className = "dashboard-frame";1186 iframe.src = src;1187 iframe.loading = "lazy";1188 iframe.allow = "clipboard-read; clipboard-write; fullscreen";1189 return iframe;1190 }1191 1192 function renderDashboardCell(meta, body, container, head) {1193 const project = meta.dashboard_project || "";1194 const holder = document.createElement("div");1195 holder.className = "dashboard-shell";1196 container.appendChild(holder);1197 const space = body.match(/https:\/\/huggingface\.co\/spaces\/[^\s<>)"'`]+/);1198 if (space) {1199 const url = space[0];1200 dashboardOpenLink(head, url);