Spaces:
Running
Demo polish: SEO/AI-agent discoverability + new hexagonal logo + §1 helix per-letter fade + sandbox empty-state
Browse files- Discoverability surface: robots.txt, sitemap.xml, llms.txt, JSON-LD/OG/Twitter
metadata in demo.html; app.py templates demo + social-banner with {{SITE_URL}}
resolved per-request from X-Forwarded-*; Dockerfile COPYs the new files.
- New hexagonal Carbon mark (img/logo.svg) plus black square/rectangle lockups
used by the social-banner contact sheet.
- social-banner: noindex, doubles as a brand contact sheet under the stage with
native-size square and rectangle lockups for one-shot screenshots.
- §1 intro helix: per-letter depth-aware fade — front-strand letter at each
crossing stays readable while its back-strand sibling recedes, instead of both
going equally ghosted.
- Sandbox empty-state: centered, white-on-white, lighter contrast so the
placeholder reads as a hint rather than a block.
- New §X efficiency section script wired into demo.html.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Dockerfile +5 -0
- app.py +87 -7
- assets/js/sections/efficiency.js +151 -0
- assets/js/sections/intro.js +35 -7
- assets/styles/sandbox.css +10 -1
- demo.html +124 -6
- img/Group 2.eps +971 -0
- img/Group 2.pdf +0 -0
- img/Group 2.png +3 -0
- img/Group 2.svg +19 -0
- img/logo-black-rectangle.svg +20 -0
- img/logo-black-square.svg +17 -0
- img/logo.svg +12 -15
- llms.txt +38 -0
- robots.txt +74 -0
- sitemap.xml +15 -0
- social-banner.html +244 -11
|
@@ -6,6 +6,11 @@ COPY requirements.txt .
|
|
| 6 |
RUN pip install --no-cache-dir -r requirements.txt
|
| 7 |
|
| 8 |
COPY app.py index.html demo.html social-banner.html ./
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
COPY data/ ./data/
|
| 10 |
COPY img/ ./img/
|
| 11 |
COPY annotations/ ./annotations/
|
|
|
|
| 6 |
RUN pip install --no-cache-dir -r requirements.txt
|
| 7 |
|
| 8 |
COPY app.py index.html demo.html social-banner.html ./
|
| 9 |
+
# Discoverability surface (SEO + AI agents + social previews). These are
|
| 10 |
+
# read once at startup by app.py, with {{SITE_URL}} substituted in at
|
| 11 |
+
# request time. Without this COPY the production image 404s on every
|
| 12 |
+
# crawler / answer-engine probe.
|
| 13 |
+
COPY robots.txt llms.txt sitemap.xml ./
|
| 14 |
COPY data/ ./data/
|
| 15 |
COPY img/ ./img/
|
| 16 |
COPY annotations/ ./annotations/
|
|
@@ -6,7 +6,7 @@ import os
|
|
| 6 |
import httpx
|
| 7 |
from fastapi import FastAPI, Request
|
| 8 |
from fastapi.middleware.gzip import GZipMiddleware
|
| 9 |
-
from fastapi.responses import FileResponse, StreamingResponse
|
| 10 |
from fastapi.staticfiles import StaticFiles
|
| 11 |
from openai import OpenAI
|
| 12 |
|
|
@@ -44,6 +44,50 @@ _FOLD_CACHE_MAX = 256
|
|
| 44 |
|
| 45 |
HERE = os.path.dirname(os.path.abspath(__file__))
|
| 46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
|
| 48 |
def get_api_key():
|
| 49 |
key = os.environ.get("HF_TOKEN")
|
|
@@ -132,13 +176,13 @@ async def no_cache_dev_assets(request: Request, call_next):
|
|
| 132 |
|
| 133 |
|
| 134 |
@app.get("/")
|
| 135 |
-
def root():
|
| 136 |
-
return
|
| 137 |
|
| 138 |
|
| 139 |
@app.get("/demo")
|
| 140 |
-
def demo():
|
| 141 |
-
return
|
| 142 |
|
| 143 |
|
| 144 |
@app.get("/sandbox-only")
|
|
@@ -148,12 +192,48 @@ def sandbox_only():
|
|
| 148 |
|
| 149 |
|
| 150 |
@app.get("/social-banner")
|
| 151 |
-
def social_banner():
|
| 152 |
# Standalone hero — wordmark + subtitle + specs + animated DNA helix,
|
| 153 |
# sized to fit common social-media canvases (Twitter / OG / LinkedIn /
|
| 154 |
# HF). Used to grab cover-art screenshots without firing up the full
|
| 155 |
# demo page.
|
| 156 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 157 |
|
| 158 |
|
| 159 |
@app.get("/config")
|
|
|
|
| 6 |
import httpx
|
| 7 |
from fastapi import FastAPI, Request
|
| 8 |
from fastapi.middleware.gzip import GZipMiddleware
|
| 9 |
+
from fastapi.responses import FileResponse, HTMLResponse, PlainTextResponse, RedirectResponse, Response, StreamingResponse
|
| 10 |
from fastapi.staticfiles import StaticFiles
|
| 11 |
from openai import OpenAI
|
| 12 |
|
|
|
|
| 44 |
|
| 45 |
HERE = os.path.dirname(os.path.abspath(__file__))
|
| 46 |
|
| 47 |
+
# Absolute base URL used to fill {{SITE_URL}} placeholders in demo.html,
|
| 48 |
+
# sitemap.xml and robots.txt (og:image, canonical, sitemap reference…).
|
| 49 |
+
# If unset, we derive it per-request from the X-Forwarded-* headers (HF
|
| 50 |
+
# Spaces sits behind a proxy that sets them) so og:image, canonical and
|
| 51 |
+
# the sitemap stay correct on whatever host the page is served from.
|
| 52 |
+
SITE_URL_ENV = os.environ.get("SITE_URL", "").rstrip("/")
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
def site_url_for(request: Request) -> str:
|
| 56 |
+
"""Return the absolute origin (scheme://host, no trailing slash)."""
|
| 57 |
+
if SITE_URL_ENV:
|
| 58 |
+
return SITE_URL_ENV
|
| 59 |
+
scheme = request.headers.get("x-forwarded-proto") or request.url.scheme or "http"
|
| 60 |
+
# X-Forwarded-Host may carry a comma-separated chain when multiple
|
| 61 |
+
# proxies are involved; the original client-visible host is the
|
| 62 |
+
# first entry. Host header is the fallback.
|
| 63 |
+
fwd_host = request.headers.get("x-forwarded-host")
|
| 64 |
+
if fwd_host:
|
| 65 |
+
host = fwd_host.split(",")[0].strip()
|
| 66 |
+
else:
|
| 67 |
+
host = request.headers.get("host") or request.url.netloc
|
| 68 |
+
return f"{scheme}://{host}"
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
def _load_text(path: str) -> str:
|
| 72 |
+
with open(path, encoding="utf-8") as f:
|
| 73 |
+
return f.read()
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
# Templates loaded once at startup. demo.html and social-banner.html are
|
| 77 |
+
# large; reading them on every request would add ~100 us of syscall +
|
| 78 |
+
# parse overhead each time, which adds up under load. The substitution
|
| 79 |
+
# itself (a single str.replace) is cheap. Reloading on edit happens via
|
| 80 |
+
# uvicorn --reload in dev, which restarts the worker.
|
| 81 |
+
_DEMO_HTML = _load_text(os.path.join(HERE, "demo.html"))
|
| 82 |
+
_SOCIAL_BANNER_HTML = _load_text(os.path.join(HERE, "social-banner.html"))
|
| 83 |
+
_ROBOTS_TXT = _load_text(os.path.join(HERE, "robots.txt"))
|
| 84 |
+
_SITEMAP_XML = _load_text(os.path.join(HERE, "sitemap.xml"))
|
| 85 |
+
_LLMS_TXT = _load_text(os.path.join(HERE, "llms.txt"))
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
def render(template: str, site_url: str) -> str:
|
| 89 |
+
return template.replace("{{SITE_URL}}", site_url)
|
| 90 |
+
|
| 91 |
|
| 92 |
def get_api_key():
|
| 93 |
key = os.environ.get("HF_TOKEN")
|
|
|
|
| 176 |
|
| 177 |
|
| 178 |
@app.get("/")
|
| 179 |
+
def root(request: Request):
|
| 180 |
+
return HTMLResponse(render(_DEMO_HTML, site_url_for(request)))
|
| 181 |
|
| 182 |
|
| 183 |
@app.get("/demo")
|
| 184 |
+
def demo(request: Request):
|
| 185 |
+
return HTMLResponse(render(_DEMO_HTML, site_url_for(request)))
|
| 186 |
|
| 187 |
|
| 188 |
@app.get("/sandbox-only")
|
|
|
|
| 192 |
|
| 193 |
|
| 194 |
@app.get("/social-banner")
|
| 195 |
+
def social_banner(request: Request):
|
| 196 |
# Standalone hero — wordmark + subtitle + specs + animated DNA helix,
|
| 197 |
# sized to fit common social-media canvases (Twitter / OG / LinkedIn /
|
| 198 |
# HF). Used to grab cover-art screenshots without firing up the full
|
| 199 |
# demo page.
|
| 200 |
+
return HTMLResponse(render(_SOCIAL_BANNER_HTML, site_url_for(request)))
|
| 201 |
+
|
| 202 |
+
|
| 203 |
+
# ---------------------------------------------------------------------
|
| 204 |
+
# Discoverability surface: robots.txt, sitemap.xml, llms.txt, favicon.
|
| 205 |
+
# These are tiny files but they are what indexers, AI answer engines
|
| 206 |
+
# (Perplexity, ChatGPT browsing…) and social previews look for first.
|
| 207 |
+
# ---------------------------------------------------------------------
|
| 208 |
+
|
| 209 |
+
|
| 210 |
+
@app.get("/robots.txt", response_class=PlainTextResponse)
|
| 211 |
+
def robots_txt(request: Request):
|
| 212 |
+
return PlainTextResponse(render(_ROBOTS_TXT, site_url_for(request)))
|
| 213 |
+
|
| 214 |
+
|
| 215 |
+
@app.get("/sitemap.xml")
|
| 216 |
+
def sitemap_xml(request: Request):
|
| 217 |
+
return Response(
|
| 218 |
+
content=render(_SITEMAP_XML, site_url_for(request)),
|
| 219 |
+
media_type="application/xml",
|
| 220 |
+
)
|
| 221 |
+
|
| 222 |
+
|
| 223 |
+
@app.get("/llms.txt", response_class=PlainTextResponse)
|
| 224 |
+
def llms_txt():
|
| 225 |
+
# llms.txt (https://llmstxt.org/) — Markdown index aimed at LLM-based
|
| 226 |
+
# agents that need a compact map of the site without scraping the
|
| 227 |
+
# whole editorial page. No {{SITE_URL}} substitution: links are
|
| 228 |
+
# either site-relative or absolute to canonical external URLs.
|
| 229 |
+
return PlainTextResponse(_LLMS_TXT, media_type="text/markdown; charset=utf-8")
|
| 230 |
+
|
| 231 |
+
|
| 232 |
+
@app.get("/favicon.ico")
|
| 233 |
+
def favicon():
|
| 234 |
+
# Browsers ask for /favicon.ico whether or not the page declared one.
|
| 235 |
+
# Redirect to the SVG logo so we don't ship a 404 on every cold load.
|
| 236 |
+
return RedirectResponse(url="/img/logo.svg", status_code=301)
|
| 237 |
|
| 238 |
|
| 239 |
@app.get("/config")
|
|
@@ -0,0 +1,151 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// =========================================================================
|
| 2 |
+
// §13, Efficiency: inference throughput vs number of prompts
|
| 3 |
+
// =========================================================================
|
| 4 |
+
// Numbers come from the public release dataset:
|
| 5 |
+
// HuggingFaceBio/carbon-inference-evals (data/train-00000-of-00001.parquet),
|
| 6 |
+
// filtered to non-remote prompt-scan runs through 512 prompts. Carbon and
|
| 7 |
+
// GENERator runs use vLLM dynamic batching (so batch ≡ num_prompts).
|
| 8 |
+
// Evo2 caps batch size to fit a single H100: Evo2 1B caps at 34 prompts,
|
| 9 |
+
// 7B at 13, 20B and 40B at 4. Past those caps the throughput curve flattens
|
| 10 |
+
// because additional prompts spill into a second sequential mini-batch
|
| 11 |
+
// instead of widening the live one.
|
| 12 |
+
//
|
| 13 |
+
// Two-family palette: cool greens for the Carbon checkpoints (light → dark
|
| 14 |
+
// = small → large), warm browns for the Evo2 baselines. Echoes the rest of
|
| 15 |
+
// the demo so "Carbon vs Evo2" reads at a glance even when several lines
|
| 16 |
+
// stack inside the lower decade of the log axis.
|
| 17 |
+
(function initDemo13() {
|
| 18 |
+
const host = document.getElementById("d13-throughput");
|
| 19 |
+
if (!host) return;
|
| 20 |
+
|
| 21 |
+
const PROMPTS = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512];
|
| 22 |
+
|
| 23 |
+
// throughput in output bp/s, indexed positionally against PROMPTS above.
|
| 24 |
+
// Source: carbon-inference-evals · output_bp_per_second column.
|
| 25 |
+
const SERIES = [
|
| 26 |
+
{ name: "Carbon-500M", color: "#A8DCB4", weight: 2.8,
|
| 27 |
+
throughput: [3416.78, 5395.16, 11071.54, 21723.72, 43443.40, 74971.36, 110803.57, 161581.87, 146471.03, 152044.37] },
|
| 28 |
+
{ name: "Carbon-3B", color: "#6DBF7E", weight: 3.0,
|
| 29 |
+
throughput: [1489.33, 2916.85, 5561.60, 11309.62, 20109.93, 40027.81, 65218.26, 100126.89, 125130.82, 122840.91] },
|
| 30 |
+
{ name: "Carbon-8B", color: "#1A7A40", weight: 3.2,
|
| 31 |
+
throughput: [ 811.71, 1737.51, 3274.83, 6576.03, 12675.68, 22560.89, 39248.04, 46435.76, 76582.70, 85084.69] },
|
| 32 |
+
{ name: "Evo2 1B", color: "#C9A06A", weight: 2.6, capLabel: "min(n, 34)",
|
| 33 |
+
throughput: [ 42.32, 86.48, 176.82, 351.63, 705.34, 1409.67, 1436.89, 1435.27, 1342.48, 1400.36] },
|
| 34 |
+
{ name: "Evo2 7B", color: "#8C7355", weight: 2.6, capLabel: "min(n, 13)",
|
| 35 |
+
throughput: [ 33.28, 68.78, 132.86, 269.00, 267.13, 360.91, 441.94, 432.32, 453.76, 444.48] },
|
| 36 |
+
{ name: "Evo2 20B", color: "#5A4A38", weight: 2.6, capLabel: "min(n, 4)",
|
| 37 |
+
throughput: [ 43.97, 86.04, 169.45, 175.90, 176.45, 177.16, 177.88, 180.47, 177.46, 177.17] },
|
| 38 |
+
{ name: "Evo2 40B", color: "#2A211A", weight: 2.6, capLabel: "min(n, 4)",
|
| 39 |
+
throughput: [ 21.75, 43.01, 85.12, 85.74, 84.94, 87.20, 87.93, 85.63, 87.07, 86.78] },
|
| 40 |
+
];
|
| 41 |
+
|
| 42 |
+
// ----- Layout ----------------------------------------------------------
|
| 43 |
+
// Right gutter is wider than longcontext.js's NIAH chart because we have
|
| 44 |
+
// 7 lines to label end-on (instead of 3) and Evo2 capLabels add a second
|
| 45 |
+
// line under each model name. Font sizes are bumped one notch above the
|
| 46 |
+
// §6 NIAH chart because this figure renders inside the same ~828 px
|
| 47 |
+
// section column as a 1000 px viewBox, so the type optically lands at
|
| 48 |
+
// ~10–11 px on screen — too small for a 7-series log–log plot. Sticking
|
| 49 |
+
// with the 1000×460 viewBox keeps the section grid intact and just
|
| 50 |
+
// restyles the contents.
|
| 51 |
+
const W = 1000, H = 460;
|
| 52 |
+
const padL = 86, padR = 178, padT = 30, padB = 64;
|
| 53 |
+
const innerW = W - padL - padR;
|
| 54 |
+
const innerH = H - padT - padB;
|
| 55 |
+
|
| 56 |
+
const xLo = Math.log2(1), xHi = Math.log2(512);
|
| 57 |
+
const yLo = Math.log10(10), yHi = Math.log10(300000);
|
| 58 |
+
const xFor = n => padL + ((Math.log2(n) - xLo) / (xHi - xLo)) * innerW;
|
| 59 |
+
const yFor = v => padT + ((yHi - Math.log10(v)) / (yHi - yLo)) * innerH;
|
| 60 |
+
|
| 61 |
+
// ----- Render ----------------------------------------------------------
|
| 62 |
+
function render() {
|
| 63 |
+
let svg = "";
|
| 64 |
+
|
| 65 |
+
// y-axis gridlines + labels (1-3-1-3 log decades, matches the source ref)
|
| 66 |
+
const Y_TICKS = [10, 30, 100, 300, 1000, 3000, 10000, 30000, 100000, 300000];
|
| 67 |
+
Y_TICKS.forEach(v => {
|
| 68 |
+
const y = yFor(v);
|
| 69 |
+
const isMajor = v === 10 || v === 100 || v === 1000 || v === 10000 || v === 100000;
|
| 70 |
+
svg += `<line x1="${padL}" y1="${y.toFixed(1)}" x2="${(W - padR).toFixed(1)}" y2="${y.toFixed(1)}" stroke="${isMajor ? "#e5e5e5" : "#f4f4f1"}" stroke-width="1"/>`;
|
| 71 |
+
svg += `<text x="${padL - 10}" y="${(y + 4).toFixed(1)}" font-family="JetBrains Mono" font-size="13" fill="${isMajor ? "#666" : "#b5b5b5"}" text-anchor="end">${formatY(v)}</text>`;
|
| 72 |
+
});
|
| 73 |
+
// Axis title (rotated, left side)
|
| 74 |
+
svg += `<text x="22" y="${(padT + innerH / 2).toFixed(1)}" font-family="JetBrains Mono" font-size="12" fill="#666" text-anchor="middle" transform="rotate(-90 22 ${(padT + innerH / 2).toFixed(1)})" letter-spacing="1.2">THROUGHPUT · BP/S · LOG</text>`;
|
| 75 |
+
|
| 76 |
+
// x-axis ticks + labels
|
| 77 |
+
PROMPTS.forEach(n => {
|
| 78 |
+
const x = xFor(n);
|
| 79 |
+
svg += `<line x1="${x.toFixed(1)}" y1="${(padT + innerH).toFixed(1)}" x2="${x.toFixed(1)}" y2="${(padT + innerH + 5).toFixed(1)}" stroke="#666" stroke-width="1"/>`;
|
| 80 |
+
svg += `<text x="${x.toFixed(1)}" y="${(padT + innerH + 22).toFixed(1)}" font-family="JetBrains Mono" font-size="13" fill="#1f1f1d" text-anchor="middle">${n}</text>`;
|
| 81 |
+
});
|
| 82 |
+
// x-axis title
|
| 83 |
+
svg += `<text x="${(padL + innerW / 2).toFixed(1)}" y="${(padT + innerH + 50).toFixed(1)}" font-family="JetBrains Mono" font-size="12" fill="#666" text-anchor="middle" letter-spacing="1.2">NUMBER OF PROMPTS · LOG</text>`;
|
| 84 |
+
|
| 85 |
+
// baseline at the bottom of the plot zone
|
| 86 |
+
svg += `<line x1="${padL}" y1="${(padT + innerH).toFixed(1)}" x2="${(W - padR).toFixed(1)}" y2="${(padT + innerH).toFixed(1)}" stroke="#1f1f1d" stroke-width="1.2"/>`;
|
| 87 |
+
|
| 88 |
+
// lines (drawn lightest → darkest so the dark Carbon-8B sits on top of
|
| 89 |
+
// its lighter Carbon siblings where the curves cross at low n)
|
| 90 |
+
const drawOrder = [
|
| 91 |
+
"Carbon-500M", "Evo2 1B", "Evo2 20B", "Evo2 40B", "Evo2 7B",
|
| 92 |
+
"Carbon-3B", "Carbon-8B"
|
| 93 |
+
];
|
| 94 |
+
drawOrder.forEach(name => {
|
| 95 |
+
const s = SERIES.find(s => s.name === name);
|
| 96 |
+
let d = "";
|
| 97 |
+
s.throughput.forEach((v, i) => {
|
| 98 |
+
const x = xFor(PROMPTS[i]);
|
| 99 |
+
const y = yFor(v);
|
| 100 |
+
d += (i === 0 ? "M" : "L") + x.toFixed(1) + " " + y.toFixed(1);
|
| 101 |
+
});
|
| 102 |
+
svg += `<path d="${d}" fill="none" stroke="${s.color}" stroke-width="${s.weight}" stroke-linejoin="round" stroke-linecap="round"/>`;
|
| 103 |
+
s.throughput.forEach((v, i) => {
|
| 104 |
+
const x = xFor(PROMPTS[i]);
|
| 105 |
+
const y = yFor(v);
|
| 106 |
+
svg += `<circle cx="${x.toFixed(1)}" cy="${y.toFixed(1)}" r="3.6" fill="${s.color}" stroke="#fff" stroke-width="1.2"/>`;
|
| 107 |
+
});
|
| 108 |
+
});
|
| 109 |
+
|
| 110 |
+
// End-of-line labels in the right gutter. Each label sits at the y of
|
| 111 |
+
// the n=512 data point; we then nudge overlapping labels apart so the
|
| 112 |
+
// 7-line stack stays legible (Carbon-500M / Carbon-3B are within 0.09
|
| 113 |
+
// log-decades of each other).
|
| 114 |
+
const xEnd = xFor(512) + 14;
|
| 115 |
+
const labels = SERIES.map(s => {
|
| 116 |
+
const last = s.throughput[s.throughput.length - 1];
|
| 117 |
+
return { name: s.name, color: s.color, capLabel: s.capLabel, value: last, y: yFor(last) };
|
| 118 |
+
}).sort((a, b) => a.y - b.y);
|
| 119 |
+
|
| 120 |
+
const minGap = 36; // px, room for two text lines per label
|
| 121 |
+
for (let i = 1; i < labels.length; i++) {
|
| 122 |
+
if (labels[i].y - labels[i - 1].y < minGap) {
|
| 123 |
+
labels[i].y = labels[i - 1].y + minGap;
|
| 124 |
+
}
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
labels.forEach(l => {
|
| 128 |
+
svg += `<text x="${xEnd.toFixed(1)}" y="${l.y.toFixed(1)}" font-family="JetBrains Mono" font-size="14" fill="${l.color}" font-weight="600">${l.name}</text>`;
|
| 129 |
+
const sub = l.capLabel
|
| 130 |
+
? `<tspan fill="#aaa">batch </tspan>${l.capLabel}`
|
| 131 |
+
: `<tspan fill="#aaa">${formatBp(l.value)} bp/s</tspan>`;
|
| 132 |
+
svg += `<text x="${xEnd.toFixed(1)}" y="${(l.y + 16).toFixed(1)}" font-family="JetBrains Mono" font-size="11" fill="#888">${sub}</text>`;
|
| 133 |
+
});
|
| 134 |
+
|
| 135 |
+
host.setAttribute("viewBox", `0 0 ${W} ${H}`);
|
| 136 |
+
host.innerHTML = svg;
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
// 10 → "10", 1000 → "1k", 30000 → "30k", 100000 → "100k"
|
| 140 |
+
function formatY(v) {
|
| 141 |
+
if (v >= 1000) return (v / 1000) + "k";
|
| 142 |
+
return String(v);
|
| 143 |
+
}
|
| 144 |
+
function formatBp(v) {
|
| 145 |
+
if (v >= 10000) return Math.round(v / 1000) + "k";
|
| 146 |
+
if (v >= 1000) return (v / 1000).toFixed(1) + "k";
|
| 147 |
+
return Math.round(v).toLocaleString();
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
render();
|
| 151 |
+
})();
|
|
@@ -192,6 +192,11 @@
|
|
| 192 |
sep: Math.abs(yA - yB),
|
| 193 |
top: topSeq[seqIdx],
|
| 194 |
bot: comp[topSeq[seqIdx]],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 195 |
});
|
| 196 |
seqIdx++;
|
| 197 |
}
|
|
@@ -357,15 +362,38 @@
|
|
| 357 |
}
|
| 358 |
|
| 359 |
// 4. Letter glyphs themselves (no haloes, since the rung is already
|
| 360 |
-
// interrupted around each letter).
|
| 361 |
-
//
|
| 362 |
-
//
|
| 363 |
-
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 364 |
for (const r of rungs) {
|
| 365 |
-
const fade = fadeForSep(r.sep);
|
| 366 |
const [yA, yB] = rungLetterYs(r);
|
| 367 |
-
|
| 368 |
-
|
|
|
|
|
|
|
| 369 |
}
|
| 370 |
|
| 371 |
// 5′ / 3′ end tags. Each label is placed *outside* the higher/lower
|
|
|
|
| 192 |
sep: Math.abs(yA - yB),
|
| 193 |
top: topSeq[seqIdx],
|
| 194 |
bot: comp[topSeq[seqIdx]],
|
| 195 |
+
// Which strand currently sits visually higher? Used by letterFade
|
| 196 |
+
// to map each glyph to its attaching strand's depth. The flag flips
|
| 197 |
+
// every time the strands cross, which is what drives the alternating
|
| 198 |
+
// bright/dim pattern of adjacent rungs around the helix waist.
|
| 199 |
+
topOnA: yA <= yB,
|
| 200 |
});
|
| 201 |
seqIdx++;
|
| 202 |
}
|
|
|
|
| 362 |
}
|
| 363 |
|
| 364 |
// 4. Letter glyphs themselves (no haloes, since the rung is already
|
| 365 |
+
// interrupted around each letter). Each glyph fades independently
|
| 366 |
+
// of its rung-mate via letterFade: the rung-wide sep fade still
|
| 367 |
+
// sets the baseline, but each letter is then biased by the depth
|
| 368 |
+
// (z) of the strand it attaches to. Net result: instead of two
|
| 369 |
+
// equally-ghosted letters stacked on top of each other at the
|
| 370 |
+
// crossings, the front-strand letter holds clearly readable while
|
| 371 |
+
// the back-strand letter recedes to a barely-there ghost. And
|
| 372 |
+
// because the "front" strand flips at every half-period, the
|
| 373 |
+
// bright letter alternates between the upper and lower rung
|
| 374 |
+
// position from one rung to the next around the helix waist —
|
| 375 |
+
// echoes the strand back-arc gradients painted in step 1.
|
| 376 |
+
function letterFade(r, isTop) {
|
| 377 |
+
const onA = isTop ? r.topOnA : !r.topOnA;
|
| 378 |
+
const z = zAt(r.x, onA ? phaseA : phaseB); // -1 (back) … +1 (front)
|
| 379 |
+
const lo = 12, hi = 28;
|
| 380 |
+
const t = Math.max(0, Math.min(1, (r.sep - lo) / (hi - lo)));
|
| 381 |
+
const ease = t * t * (3 - 2 * t);
|
| 382 |
+
const sepFade = 0.18 + 0.82 * ease;
|
| 383 |
+
// Bias only kicks in around the crossings; wide rungs (where the
|
| 384 |
+
// strands sit symmetric and z ≈ 0 anyway) keep both letters at
|
| 385 |
+
// full opacity. Amplitude 0.37 lands the front letter near 0.55
|
| 386 |
+
// and the back letter at the 0.08 floor when |z| = 1.
|
| 387 |
+
const bias = z * (1 - ease) * 0.37;
|
| 388 |
+
return Math.max(0.08, Math.min(1, sepFade + bias));
|
| 389 |
+
}
|
| 390 |
+
|
| 391 |
for (const r of rungs) {
|
|
|
|
| 392 |
const [yA, yB] = rungLetterYs(r);
|
| 393 |
+
const topFade = letterFade(r, true);
|
| 394 |
+
const botFade = letterFade(r, false);
|
| 395 |
+
text(svg, r.x, yA, r.top, { mono: true, size: 10, weight: 600, fill: GREEN, opacity: topFade });
|
| 396 |
+
text(svg, r.x, yB, r.bot, { mono: true, size: 10, weight: 600, fill: GREEN, opacity: botFade });
|
| 397 |
}
|
| 398 |
|
| 399 |
// 5′ / 3′ end tags. Each label is placed *outside* the higher/lower
|
|
@@ -230,7 +230,16 @@
|
|
| 230 |
min-height: 80px;
|
| 231 |
flex: 1 0 auto;
|
| 232 |
}
|
| 233 |
-
#panel-sandbox .sb-seq-block.empty {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 234 |
#panel-sandbox .sb-seq-line { white-space: pre; }
|
| 235 |
#panel-sandbox .sb-pos { color: #bbb; user-select: none; font-weight: 300; }
|
| 236 |
#panel-sandbox .sb-seq-line.tail::after {
|
|
|
|
| 230 |
min-height: 80px;
|
| 231 |
flex: 1 0 auto;
|
| 232 |
}
|
| 233 |
+
#panel-sandbox .sb-seq-block.empty {
|
| 234 |
+
color: #cfcfcf;
|
| 235 |
+
font-weight: 300;
|
| 236 |
+
letter-spacing: normal;
|
| 237 |
+
background: #fff;
|
| 238 |
+
text-align: center;
|
| 239 |
+
display: flex;
|
| 240 |
+
align-items: center;
|
| 241 |
+
justify-content: center;
|
| 242 |
+
}
|
| 243 |
#panel-sandbox .sb-seq-line { white-space: pre; }
|
| 244 |
#panel-sandbox .sb-pos { color: #bbb; user-select: none; font-weight: 300; }
|
| 245 |
#panel-sandbox .sb-seq-line.tail::after {
|
|
@@ -3,7 +3,92 @@
|
|
| 3 |
<head>
|
| 4 |
<meta charset="utf-8">
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
-
<title>Carbon ·
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 8 |
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 9 |
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;600;700;800&family=Inter:wght@300;400;500;600&display=swap">
|
|
@@ -1871,11 +1956,43 @@ print(f"log P(alt) - log P(ref) at pos 20: {delta:+.3f}")</code></pre></div>
|
|
| 1871 |
|
| 1872 |
<div class="section-body">
|
| 1873 |
<div class="demo" id="demo13">
|
| 1874 |
-
<!--
|
| 1875 |
-
|
| 1876 |
-
|
| 1877 |
-
|
| 1878 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1879 |
</div>
|
| 1880 |
</div>
|
| 1881 |
|
|
@@ -2045,6 +2162,7 @@ print(f"log P(alt) - log P(ref) at pos 20: {delta:+.3f}")</code></pre></div>
|
|
| 2045 |
<script src="/assets/js/sections/architecture.js"></script>
|
| 2046 |
<script src="/assets/js/sections/longcontext.js"></script>
|
| 2047 |
<script src="/assets/js/sections/results.js"></script>
|
|
|
|
| 2048 |
<script src="/assets/js/sections/sandbox.js"></script>
|
| 2049 |
<script src="/assets/js/sections/umap.js"></script>
|
| 2050 |
<script src="/assets/js/sections/tree.js"></script>
|
|
|
|
| 3 |
<head>
|
| 4 |
<meta charset="utf-8">
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>Carbon · an open-source autoregressive genomic foundation model</title>
|
| 7 |
+
|
| 8 |
+
<!-- ============================================================ -->
|
| 9 |
+
<!-- Discoverability: SEO + social previews + AI-agent metadata. -->
|
| 10 |
+
<!-- {{SITE_URL}} is substituted at request time by app.py with -->
|
| 11 |
+
<!-- the absolute base URL (scheme + host) the page was served -->
|
| 12 |
+
<!-- under, so og:image / og:url stay correct whether we're on -->
|
| 13 |
+
<!-- the HF Space, a preview deploy, or localhost. -->
|
| 14 |
+
<!-- ============================================================ -->
|
| 15 |
+
<meta name="description" content="Carbon is Hugging Face's open-source family of autoregressive genomic foundation models for DNA. Explore an interactive demo of what the 3B checkpoint learned: streaming continuation, variant effect prediction, ESMFold structure prediction, a UMAP of half a million gene embeddings, and the full training recipe.">
|
| 16 |
+
<meta name="keywords" content="Carbon, DNA, genomics, foundation model, Hugging Face, autoregressive, language model, bioinformatics, variant effect prediction, ESMFold, UMAP, gene embeddings, open source">
|
| 17 |
+
<meta name="author" content="Hugging Face Bio">
|
| 18 |
+
<meta name="theme-color" content="#f7f5ee">
|
| 19 |
+
<meta name="color-scheme" content="light">
|
| 20 |
+
<link rel="canonical" href="{{SITE_URL}}/">
|
| 21 |
+
|
| 22 |
+
<!-- Favicon. Modern browsers honour SVG; we keep the PNG as a -->
|
| 23 |
+
<!-- raster fallback for the few that don't (Safari < 14 etc.). -->
|
| 24 |
+
<link rel="icon" type="image/svg+xml" href="/img/logo.svg">
|
| 25 |
+
<link rel="icon" type="image/png" href="/img/logo.png">
|
| 26 |
+
<link rel="apple-touch-icon" href="/img/logo.png">
|
| 27 |
+
|
| 28 |
+
<!-- Open Graph (Facebook, LinkedIn, Slack, Discord, iMessage…). -->
|
| 29 |
+
<!-- og:image points at /img/logo.png, which is the wide Carbon -->
|
| 30 |
+
<!-- wordmark+helix lockup (1153x634, ~OG-shaped). Swap with a -->
|
| 31 |
+
<!-- proper 1200x630 screenshot of /social-banner once exported. -->
|
| 32 |
+
<meta property="og:type" content="website">
|
| 33 |
+
<meta property="og:site_name" content="Carbon">
|
| 34 |
+
<meta property="og:title" content="Carbon · an open-source autoregressive genomic foundation model">
|
| 35 |
+
<meta property="og:description" content="An interactive editorial demo of Carbon, Hugging Face's open-source DNA foundation model. Streaming continuation, variant scoring, protein folding, gene-embedding UMAP, and the full training recipe.">
|
| 36 |
+
<meta property="og:url" content="{{SITE_URL}}/">
|
| 37 |
+
<meta property="og:image" content="{{SITE_URL}}/img/logo.png">
|
| 38 |
+
<meta property="og:image:width" content="1153">
|
| 39 |
+
<meta property="og:image:height" content="634">
|
| 40 |
+
<meta property="og:image:alt" content="Carbon — the wordmark wrapped in a four-strand DNA helix.">
|
| 41 |
+
<meta property="og:locale" content="en_US">
|
| 42 |
+
|
| 43 |
+
<!-- Twitter / X card. summary_large_image renders the OG image -->
|
| 44 |
+
<!-- as a full-bleed preview tile. -->
|
| 45 |
+
<meta name="twitter:card" content="summary_large_image">
|
| 46 |
+
<meta name="twitter:site" content="@huggingface">
|
| 47 |
+
<meta name="twitter:creator" content="@huggingface">
|
| 48 |
+
<meta name="twitter:title" content="Carbon · an open-source autoregressive genomic foundation model">
|
| 49 |
+
<meta name="twitter:description" content="An interactive editorial demo of Carbon, Hugging Face's open-source DNA foundation model. Streaming continuation, variant scoring, protein folding, gene-embedding UMAP, and the full training recipe.">
|
| 50 |
+
<meta name="twitter:image" content="{{SITE_URL}}/img/logo.png">
|
| 51 |
+
<meta name="twitter:image:alt" content="Carbon — the wordmark wrapped in a four-strand DNA helix.">
|
| 52 |
+
|
| 53 |
+
<!-- JSON-LD structured data. Helps search engines and LLM- -->
|
| 54 |
+
<!-- powered answer engines (Perplexity, ChatGPT browsing, etc.) -->
|
| 55 |
+
<!-- understand what this page is: a tech article about an open- -->
|
| 56 |
+
<!-- source software model, with links back to its model card, -->
|
| 57 |
+
<!-- code, and dataset. -->
|
| 58 |
+
<script type="application/ld+json">
|
| 59 |
+
{
|
| 60 |
+
"@context": "https://schema.org",
|
| 61 |
+
"@graph": [
|
| 62 |
+
{
|
| 63 |
+
"@type": "TechArticle",
|
| 64 |
+
"@id": "{{SITE_URL}}/#article",
|
| 65 |
+
"headline": "Carbon · an open-source autoregressive genomic foundation model",
|
| 66 |
+
"description": "An interactive editorial walkthrough of Carbon, Hugging Face's open-source DNA foundation model: streaming continuation, variant effect prediction, ESMFold-based protein structure prediction, a UMAP of ~500k gene embeddings, and the full training recipe (tokenizer, loss, dataset, results).",
|
| 67 |
+
"url": "{{SITE_URL}}/",
|
| 68 |
+
"image": "{{SITE_URL}}/img/logo.png",
|
| 69 |
+
"inLanguage": "en",
|
| 70 |
+
"author": { "@type": "Organization", "name": "Hugging Face Bio", "url": "https://huggingface.co/HuggingFaceBio" },
|
| 71 |
+
"publisher": { "@type": "Organization", "name": "Hugging Face", "url": "https://huggingface.co" },
|
| 72 |
+
"about": {
|
| 73 |
+
"@type": "SoftwareApplication",
|
| 74 |
+
"name": "Carbon-3B",
|
| 75 |
+
"applicationCategory": "ScienceApplication",
|
| 76 |
+
"operatingSystem": "Any",
|
| 77 |
+
"url": "https://huggingface.co/HuggingFaceBio/Carbon-3B",
|
| 78 |
+
"description": "Autoregressive genomic foundation model. 3B parameters, 393,216 bp context, 6-mer tokenizer, trained on 1T tokens of DNA across the tree of life.",
|
| 79 |
+
"license": "https://huggingface.co/HuggingFaceBio/Carbon-3B",
|
| 80 |
+
"isAccessibleForFree": true
|
| 81 |
+
},
|
| 82 |
+
"isPartOf": {
|
| 83 |
+
"@type": "WebSite",
|
| 84 |
+
"name": "Carbon",
|
| 85 |
+
"url": "{{SITE_URL}}/"
|
| 86 |
+
}
|
| 87 |
+
}
|
| 88 |
+
]
|
| 89 |
+
}
|
| 90 |
+
</script>
|
| 91 |
+
|
| 92 |
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 93 |
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 94 |
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;600;700;800&family=Inter:wght@300;400;500;600&display=swap">
|
|
|
|
| 1956 |
|
| 1957 |
<div class="section-body">
|
| 1958 |
<div class="demo" id="demo13">
|
| 1959 |
+
<!-- Caption stack:
|
| 1960 |
+
- eyebrow (mono, green) : "what is this chart"
|
| 1961 |
+
- rule line : a thin neutral hairline that separates
|
| 1962 |
+
eyebrow from secondary meta, lifting
|
| 1963 |
+
the title above an undifferentiated
|
| 1964 |
+
string of bullet-separated notes
|
| 1965 |
+
- meta line (mono, grey) : units, hardware, axes
|
| 1966 |
+
The implementation detail (vLLM / Evo2 native runner) was previously
|
| 1967 |
+
crammed into the same line as the title; it now lives next to the
|
| 1968 |
+
legend at the bottom where the reader actually looks for "how was
|
| 1969 |
+
this measured" once they've parsed the curves. -->
|
| 1970 |
+
<div class="fig-caption" style="display:flex;align-items:baseline;gap:14px;flex-wrap:nowrap;margin-top:0;margin-bottom:6px;font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:1.2px;text-transform:uppercase;white-space:nowrap">
|
| 1971 |
+
<span style="color:#317f3f;font-weight:600">Fig · Inference throughput</span>
|
| 1972 |
+
<span aria-hidden="true" style="flex:1;min-width:24px;height:1px;background:#e5e5e5;align-self:center"></span>
|
| 1973 |
+
<span style="color:#1f1f1d">Output bp/s</span>
|
| 1974 |
+
<span style="color:#aaa">·</span>
|
| 1975 |
+
<span style="color:#888">Single H100</span>
|
| 1976 |
+
</div>
|
| 1977 |
+
<svg id="d13-throughput" preserveAspectRatio="xMinYMin meet" style="display:block;width:100%;background:#fff;border:1px solid #eee"></svg>
|
| 1978 |
+
<!-- Bigger sentence-case legend (.chart-legend variant from sequence.css)
|
| 1979 |
+
to make the 7-model key feel like a proper colour reference rather
|
| 1980 |
+
than a caption strip. The "Legend" prefix uses the same mono-uppercase
|
| 1981 |
+
editorial-label register as .seq-label / .sb-examples-label so it
|
| 1982 |
+
reads as a section gutter rather than as another item in the row. -->
|
| 1983 |
+
<div class="track-axis-label chart-legend" style="justify-content:flex-start">
|
| 1984 |
+
<span style="font-family:'JetBrains Mono',monospace;font-size:10px;color:#888;text-transform:uppercase;letter-spacing:1.5px;font-weight:500">Legend</span>
|
| 1985 |
+
<span class="chart-legend__item"><span class="legend-swatch" style="background:#1A7A40"></span>Carbon-8B</span>
|
| 1986 |
+
<span class="chart-legend__item"><span class="legend-swatch" style="background:#6DBF7E"></span>Carbon-3B</span>
|
| 1987 |
+
<span class="chart-legend__item"><span class="legend-swatch" style="background:#A8DCB4"></span>Carbon-500M</span>
|
| 1988 |
+
<span class="chart-legend__item"><span class="legend-swatch" style="background:#C9A06A"></span>Evo2 1B</span>
|
| 1989 |
+
<span class="chart-legend__item"><span class="legend-swatch" style="background:#8C7355"></span>Evo2 7B</span>
|
| 1990 |
+
<span class="chart-legend__item"><span class="legend-swatch" style="background:#5A4A38"></span>Evo2 20B</span>
|
| 1991 |
+
<span class="chart-legend__item"><span class="legend-swatch" style="background:#2A211A"></span>Evo2 40B</span>
|
| 1992 |
+
</div>
|
| 1993 |
+
<div style="margin-top:14px;padding-top:10px;border-top:1px solid #eee;font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:1px;text-transform:uppercase;color:#888;display:flex;justify-content:space-between;flex-wrap:wrap;gap:14px">
|
| 1994 |
+
<span>Source · <a href="https://huggingface.co/datasets/HuggingFaceBio/carbon-inference-evals" style="color:#1f1f1d;text-decoration:underline">carbon-inference-evals</a></span>
|
| 1995 |
+
<span style="color:#aaa">vLLM for Carbon · Evo2 native runner</span>
|
| 1996 |
</div>
|
| 1997 |
</div>
|
| 1998 |
|
|
|
|
| 2162 |
<script src="/assets/js/sections/architecture.js"></script>
|
| 2163 |
<script src="/assets/js/sections/longcontext.js"></script>
|
| 2164 |
<script src="/assets/js/sections/results.js"></script>
|
| 2165 |
+
<script src="/assets/js/sections/efficiency.js"></script>
|
| 2166 |
<script src="/assets/js/sections/sandbox.js"></script>
|
| 2167 |
<script src="/assets/js/sections/umap.js"></script>
|
| 2168 |
<script src="/assets/js/sections/tree.js"></script>
|
|
@@ -0,0 +1,971 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
%!PS-Adobe-3.0 EPSF-3.0
|
| 2 |
+
%APL_DSC_Encoding: UTF8
|
| 3 |
+
%APLProducer: (Version 26.2 (Build 25C56) Quartz PS Context)
|
| 4 |
+
%%Title: (Unknown)
|
| 5 |
+
%%Creator: (Unknown)
|
| 6 |
+
%%CreationDate: (Unknown)
|
| 7 |
+
%%For: (Unknown)
|
| 8 |
+
%%DocumentData: Clean7Bit
|
| 9 |
+
%%LanguageLevel: 2
|
| 10 |
+
%%Pages: 1
|
| 11 |
+
%%BoundingBox: 0 0 145 144
|
| 12 |
+
%%EndComments
|
| 13 |
+
%%BeginProlog
|
| 14 |
+
%%BeginFile: cg-pdf.ps
|
| 15 |
+
%%Copyright: Copyright 2000-2004 Apple Computer Incorporated.
|
| 16 |
+
%%Copyright: All Rights Reserved.
|
| 17 |
+
currentpacking true setpacking
|
| 18 |
+
/cg_md 141 dict def
|
| 19 |
+
cg_md begin
|
| 20 |
+
/L3? languagelevel 3 ge def
|
| 21 |
+
/bd{bind def}bind def
|
| 22 |
+
/ld{load def}bd
|
| 23 |
+
/xs{exch store}bd
|
| 24 |
+
/xd{exch def}bd
|
| 25 |
+
/cmmtx matrix def
|
| 26 |
+
mark
|
| 27 |
+
/sc/setcolor
|
| 28 |
+
/scs/setcolorspace
|
| 29 |
+
/dr/defineresource
|
| 30 |
+
/fr/findresource
|
| 31 |
+
/T/true
|
| 32 |
+
/F/false
|
| 33 |
+
/d/setdash
|
| 34 |
+
/w/setlinewidth
|
| 35 |
+
/J/setlinecap
|
| 36 |
+
/j/setlinejoin
|
| 37 |
+
/M/setmiterlimit
|
| 38 |
+
/i/setflat
|
| 39 |
+
/rc/rectclip
|
| 40 |
+
/rf/rectfill
|
| 41 |
+
/rs/rectstroke
|
| 42 |
+
/f/fill
|
| 43 |
+
/f*/eofill
|
| 44 |
+
/sf/selectfont
|
| 45 |
+
/s/show
|
| 46 |
+
%/as/ashow
|
| 47 |
+
/xS/xshow
|
| 48 |
+
/yS/yshow
|
| 49 |
+
/xyS/xyshow
|
| 50 |
+
/S/stroke
|
| 51 |
+
/m/moveto
|
| 52 |
+
/l/lineto
|
| 53 |
+
/c/curveto
|
| 54 |
+
/h/closepath
|
| 55 |
+
/n/newpath
|
| 56 |
+
/q/gsave
|
| 57 |
+
/Q/grestore
|
| 58 |
+
counttomark 2 idiv
|
| 59 |
+
%dup (number of ld's = )print == flush % *** how many
|
| 60 |
+
{ld}repeat pop
|
| 61 |
+
/SC{ % CSname
|
| 62 |
+
/ColorSpace fr scs
|
| 63 |
+
}bd
|
| 64 |
+
/sopr /setoverprint where{pop/setoverprint}{/pop}ifelse ld
|
| 65 |
+
/soprm /setoverprintmode where{pop/setoverprintmode}{/pop}ifelse ld
|
| 66 |
+
/cgmtx matrix def
|
| 67 |
+
/sdmtx{cgmtx currentmatrix pop}bd
|
| 68 |
+
/CM {cgmtx setmatrix}bd % pop the ctm: our gstate ctm on host is now identity
|
| 69 |
+
/cm {cmmtx astore CM concat}bd % reset the matrix and then concat
|
| 70 |
+
/W{clip newpath}bd
|
| 71 |
+
/W*{eoclip newpath}bd
|
| 72 |
+
|
| 73 |
+
statusdict begin product end dup (HP) anchorsearch{
|
| 74 |
+
pop pop pop % pop off the search results
|
| 75 |
+
true
|
| 76 |
+
}{
|
| 77 |
+
pop % previous search result
|
| 78 |
+
(hp) anchorsearch{
|
| 79 |
+
pop pop true
|
| 80 |
+
}{
|
| 81 |
+
pop false
|
| 82 |
+
}ifelse
|
| 83 |
+
}ifelse
|
| 84 |
+
|
| 85 |
+
{ % HP is the product: we use this method of stroking because of a bug in their clone printers with certain T3 fonts
|
| 86 |
+
{
|
| 87 |
+
{ % charCode Wx Wy
|
| 88 |
+
pop pop % charCode
|
| 89 |
+
(0)dup 0 4 -1 roll put
|
| 90 |
+
F charpath
|
| 91 |
+
}cshow
|
| 92 |
+
}
|
| 93 |
+
}{
|
| 94 |
+
{F charpath}
|
| 95 |
+
}ifelse
|
| 96 |
+
/cply exch bd
|
| 97 |
+
/cps {cply stroke}bd
|
| 98 |
+
/pgsave 0 def
|
| 99 |
+
/bp{/pgsave save store}bd
|
| 100 |
+
/ep{pgsave restore showpage}def % dont' bind
|
| 101 |
+
/re{4 2 roll m 1 index 0 rlineto 0 exch rlineto neg 0 rlineto h}bd
|
| 102 |
+
|
| 103 |
+
/scrdict 10 dict def
|
| 104 |
+
/scrmtx matrix def
|
| 105 |
+
/patarray 0 def
|
| 106 |
+
/createpat{patarray 3 1 roll put}bd
|
| 107 |
+
/makepat{
|
| 108 |
+
scrmtx astore pop
|
| 109 |
+
gsave
|
| 110 |
+
initgraphics
|
| 111 |
+
CM
|
| 112 |
+
patarray exch get
|
| 113 |
+
scrmtx
|
| 114 |
+
makepattern
|
| 115 |
+
grestore
|
| 116 |
+
setpattern
|
| 117 |
+
}bd
|
| 118 |
+
|
| 119 |
+
/cg_BeginEPSF{
|
| 120 |
+
userdict save/cg_b4_Inc_state exch put
|
| 121 |
+
userdict/cg_endepsf/cg_EndEPSF load put
|
| 122 |
+
count userdict/cg_op_count 3 -1 roll put
|
| 123 |
+
countdictstack dup array dictstack userdict/cg_dict_array 3 -1 roll put
|
| 124 |
+
3 sub{end}repeat
|
| 125 |
+
/showpage {} def
|
| 126 |
+
0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin
|
| 127 |
+
10 setmiterlimit [] 0 setdash newpath
|
| 128 |
+
false setstrokeadjust false setoverprint % don't use F
|
| 129 |
+
}bd
|
| 130 |
+
/cg_EndEPSF{
|
| 131 |
+
countdictstack 3 sub { end } repeat
|
| 132 |
+
cg_dict_array 3 1 index length 3 sub getinterval
|
| 133 |
+
{begin}forall
|
| 134 |
+
count userdict/cg_op_count get sub{pop}repeat
|
| 135 |
+
userdict/cg_b4_Inc_state get restore
|
| 136 |
+
F setpacking
|
| 137 |
+
}bd
|
| 138 |
+
|
| 139 |
+
/cg_biproc{currentfile/RunLengthDecode filter}bd
|
| 140 |
+
/cg_aiproc{currentfile/ASCII85Decode filter/RunLengthDecode filter}bd
|
| 141 |
+
/ImageDataSource 0 def
|
| 142 |
+
L3?{
|
| 143 |
+
/cg_mibiproc{pop pop/ImageDataSource{cg_biproc}def}bd
|
| 144 |
+
/cg_miaiproc{pop pop/ImageDataSource{cg_aiproc}def}bd
|
| 145 |
+
}{
|
| 146 |
+
/ImageBandMask 0 def
|
| 147 |
+
/ImageBandData 0 def
|
| 148 |
+
/cg_mibiproc{
|
| 149 |
+
string/ImageBandMask xs
|
| 150 |
+
string/ImageBandData xs
|
| 151 |
+
/ImageDataSource{[currentfile/RunLengthDecode filter dup ImageBandMask/readstring cvx
|
| 152 |
+
/pop cvx dup ImageBandData/readstring cvx/pop cvx]cvx bind}bd
|
| 153 |
+
}bd
|
| 154 |
+
/cg_miaiproc{
|
| 155 |
+
string/ImageBandMask xs
|
| 156 |
+
string/ImageBandData xs
|
| 157 |
+
/ImageDataSource{[currentfile/ASCII85Decode filter/RunLengthDecode filter
|
| 158 |
+
dup ImageBandMask/readstring cvx
|
| 159 |
+
/pop cvx dup ImageBandData/readstring cvx/pop cvx]cvx bind}bd
|
| 160 |
+
}bd
|
| 161 |
+
}ifelse
|
| 162 |
+
/imsave 0 def
|
| 163 |
+
/BI{save/imsave xd mark}bd
|
| 164 |
+
/EI{imsave restore}bd
|
| 165 |
+
/ID{
|
| 166 |
+
counttomark 2 idiv
|
| 167 |
+
dup 2 add % leave room for imagetype and imagematrix
|
| 168 |
+
dict begin
|
| 169 |
+
{def} repeat
|
| 170 |
+
pop % remove mark
|
| 171 |
+
/ImageType 1 def
|
| 172 |
+
/ImageMatrix[Width 0 0 Height neg 0 Height]def
|
| 173 |
+
currentdict dup/ImageMask known{ImageMask}{F}ifelse exch
|
| 174 |
+
% currentdict on stack
|
| 175 |
+
L3?{
|
| 176 |
+
dup/MaskedImage known
|
| 177 |
+
{
|
| 178 |
+
pop
|
| 179 |
+
<<
|
| 180 |
+
/ImageType 3
|
| 181 |
+
/InterleaveType 2
|
| 182 |
+
/DataDict currentdict
|
| 183 |
+
/MaskDict
|
| 184 |
+
<< /ImageType 1
|
| 185 |
+
/Width Width
|
| 186 |
+
/Height Height
|
| 187 |
+
/ImageMatrix ImageMatrix
|
| 188 |
+
/BitsPerComponent 1
|
| 189 |
+
/Decode [0 1]
|
| 190 |
+
currentdict/Interpolate known
|
| 191 |
+
{/Interpolate Interpolate}if
|
| 192 |
+
>>
|
| 193 |
+
>>
|
| 194 |
+
}if
|
| 195 |
+
}if
|
| 196 |
+
exch
|
| 197 |
+
{imagemask}{image}ifelse
|
| 198 |
+
end % pop imagedict from dict stack
|
| 199 |
+
}bd
|
| 200 |
+
|
| 201 |
+
/cguidfix{statusdict begin mark version end
|
| 202 |
+
{cvr}stopped{cleartomark 0}{exch pop}ifelse
|
| 203 |
+
2012 lt{dup findfont dup length dict begin
|
| 204 |
+
{1 index/FID ne 2 index/UniqueID ne and
|
| 205 |
+
{def} {pop pop} ifelse}forall
|
| 206 |
+
currentdict end definefont pop
|
| 207 |
+
}{pop}ifelse
|
| 208 |
+
}bd
|
| 209 |
+
/t_array 0 def
|
| 210 |
+
/t_i 0 def
|
| 211 |
+
/t_c 1 string def
|
| 212 |
+
/x_proc{ % x y
|
| 213 |
+
exch t_array t_i get add exch moveto
|
| 214 |
+
/t_i t_i 1 add store
|
| 215 |
+
}bd
|
| 216 |
+
/y_proc{ % x y
|
| 217 |
+
t_array t_i get add moveto
|
| 218 |
+
/t_i t_i 1 add store
|
| 219 |
+
}bd
|
| 220 |
+
/xy_proc{
|
| 221 |
+
% x y
|
| 222 |
+
t_array t_i 2 copy 1 add get 3 1 roll get
|
| 223 |
+
4 -1 roll add 3 1 roll add moveto
|
| 224 |
+
/t_i t_i 2 add store
|
| 225 |
+
}bd
|
| 226 |
+
/sop 0 def % don't bind sop
|
| 227 |
+
/cp_proc/x_proc ld % default moveto proc is for xwidths only
|
| 228 |
+
/base_charpath % string array
|
| 229 |
+
{
|
| 230 |
+
/t_array xs
|
| 231 |
+
/t_i 0 def
|
| 232 |
+
{ % char
|
| 233 |
+
t_c 0 3 -1 roll put
|
| 234 |
+
currentpoint
|
| 235 |
+
t_c cply sop
|
| 236 |
+
cp_proc
|
| 237 |
+
}forall
|
| 238 |
+
/t_array 0 def
|
| 239 |
+
}bd
|
| 240 |
+
/sop/stroke ld % default sop is stroke. Done here so we don't bind in /base_charpath
|
| 241 |
+
|
| 242 |
+
% default sop is stroke
|
| 243 |
+
/nop{}def
|
| 244 |
+
/xsp/base_charpath ld
|
| 245 |
+
/ysp{/cp_proc/y_proc ld base_charpath/cp_proc/x_proc ld}bd
|
| 246 |
+
/xysp{/cp_proc/xy_proc ld base_charpath/cp_proc/x_proc ld}bd
|
| 247 |
+
/xmp{/sop/nop ld /cp_proc/x_proc ld base_charpath/sop/stroke ld}bd
|
| 248 |
+
/ymp{/sop/nop ld /cp_proc/y_proc ld base_charpath/sop/stroke ld}bd
|
| 249 |
+
/xymp{/sop/nop ld /cp_proc/xy_proc ld base_charpath/sop/stroke ld}bd
|
| 250 |
+
/refnt{ % newname encoding fontname
|
| 251 |
+
findfont dup length dict copy dup
|
| 252 |
+
/Encoding 4 -1 roll put
|
| 253 |
+
definefont pop
|
| 254 |
+
}bd
|
| 255 |
+
/renmfont{ % newname fontname
|
| 256 |
+
findfont dup length dict copy definefont pop
|
| 257 |
+
}bd
|
| 258 |
+
|
| 259 |
+
L3? dup dup{save exch}if
|
| 260 |
+
|
| 261 |
+
% languagelevel2 ONLY code goes here
|
| 262 |
+
|
| 263 |
+
/Range 0 def
|
| 264 |
+
/DataSource 0 def
|
| 265 |
+
/val 0 def
|
| 266 |
+
/nRange 0 def
|
| 267 |
+
/mulRange 0 def
|
| 268 |
+
/d0 0 def
|
| 269 |
+
/r0 0 def
|
| 270 |
+
/di 0 def
|
| 271 |
+
/ri 0 def
|
| 272 |
+
/a0 0 def
|
| 273 |
+
/a1 0 def
|
| 274 |
+
/r1 0 def
|
| 275 |
+
/r2 0 def
|
| 276 |
+
/dx 0 def
|
| 277 |
+
/Nsteps 0 def
|
| 278 |
+
/sh3tp 0 def
|
| 279 |
+
/ymax 0 def
|
| 280 |
+
/ymin 0 def
|
| 281 |
+
/xmax 0 def
|
| 282 |
+
/xmin 0 def
|
| 283 |
+
|
| 284 |
+
/setupFunEval % funDict -- % this calculates and sets up a function dict for evaulation.
|
| 285 |
+
{
|
| 286 |
+
begin
|
| 287 |
+
/nRange Range length 2 idiv store
|
| 288 |
+
/mulRange % precompute the range data needed to map a sample value from the table to a range value
|
| 289 |
+
% this data looks like [ range0mul range0min range1mul range1min ... rangeN-1mul rangeN-1min ]
|
| 290 |
+
[
|
| 291 |
+
0 1 nRange 1 sub
|
| 292 |
+
{ % index
|
| 293 |
+
2 mul/nDim2 xd % 2*dimension# we are dealing with
|
| 294 |
+
Range nDim2 get % ymin
|
| 295 |
+
Range nDim2 1 add get % ymin ymax
|
| 296 |
+
1 index sub % ymin (ymax-ymin)
|
| 297 |
+
% xmin = 0, xmax = 255 (2^bitspersample - 1)
|
| 298 |
+
255 div % ymin (ymax-ymin)/(xmax - xmin)
|
| 299 |
+
exch % (ymax-ymin)/(xmax - xmin) ymin
|
| 300 |
+
}for
|
| 301 |
+
]store
|
| 302 |
+
end
|
| 303 |
+
}bd
|
| 304 |
+
|
| 305 |
+
/FunEval % val1 fundict -> comp1 comp2 ... compN
|
| 306 |
+
{
|
| 307 |
+
begin
|
| 308 |
+
% the value passed in is the base index into the table
|
| 309 |
+
nRange mul /val xd % compute the actual index to the table
|
| 310 |
+
% since there are nRange entries per base index
|
| 311 |
+
0 1 nRange 1 sub
|
| 312 |
+
{
|
| 313 |
+
dup 2 mul/nDim2 xd % dim
|
| 314 |
+
val % base value to use to do our lookup
|
| 315 |
+
add DataSource exch get % lookedupval
|
| 316 |
+
mulRange nDim2 get mul % lookedupval*(ymax-ymin)/(xmax-xmin)
|
| 317 |
+
mulRange nDim2 1 add get % lookedupval*(ymax-ymin)/(xmax-xmin) ymin
|
| 318 |
+
add % interpolated result
|
| 319 |
+
}for % comp1 comp2 ... compN
|
| 320 |
+
end
|
| 321 |
+
}bd
|
| 322 |
+
|
| 323 |
+
/max % a b -> max(a, b)
|
| 324 |
+
{
|
| 325 |
+
2 copy lt
|
| 326 |
+
{exch pop}{pop}ifelse
|
| 327 |
+
}bd
|
| 328 |
+
|
| 329 |
+
/sh2
|
| 330 |
+
{ % emulation of shading type 2. Assumes shading dictionary is top dictionary on the dict stack
|
| 331 |
+
/Coords load aload pop % x0 y0 x1 y1
|
| 332 |
+
3 index 3 index translate % origin is now at beginning point of shading
|
| 333 |
+
% x0 y0 x1 y1
|
| 334 |
+
3 -1 roll sub % x0 x1 y1-y0
|
| 335 |
+
3 1 roll exch % y1-y0 x1 x0
|
| 336 |
+
sub % y1-y0 x1-x0
|
| 337 |
+
2 copy
|
| 338 |
+
dup mul exch dup mul add sqrt % length of segment between two points
|
| 339 |
+
dup
|
| 340 |
+
scale
|
| 341 |
+
atan % atan (dy/dx)
|
| 342 |
+
%dup (rotation angle = )print ==
|
| 343 |
+
rotate % now line between 0,0 and 1,0 is the line perpendicular to which the axial lines are drawn
|
| 344 |
+
|
| 345 |
+
/Function load setupFunEval % may need to setup function dictionary by calling setupFunEval
|
| 346 |
+
|
| 347 |
+
% this is now specific to axial shadings. Compute the maximum bounds to fill
|
| 348 |
+
clippath {pathbbox}stopped {0 0 0 0}if newpath % x0 y0 x1 y1
|
| 349 |
+
/ymax xs
|
| 350 |
+
/xmax xs
|
| 351 |
+
/ymin xs
|
| 352 |
+
/xmin xs
|
| 353 |
+
currentdict/Extend known
|
| 354 |
+
{
|
| 355 |
+
/Extend load 0 get
|
| 356 |
+
{
|
| 357 |
+
0/Function load FunEval sc % evaluate the function to get a color and set it
|
| 358 |
+
xmin ymin xmin abs ymax ymin sub rectfill
|
| 359 |
+
}if
|
| 360 |
+
}if
|
| 361 |
+
% paint the rects. The sampling frequency is that of our table
|
| 362 |
+
/Nsteps/Function load/Size get 0 get 1 sub store
|
| 363 |
+
/dx 1 Nsteps div store
|
| 364 |
+
gsave
|
| 365 |
+
/di ymax ymin sub store
|
| 366 |
+
/Function load
|
| 367 |
+
% loop Nsteps + 1 times, incrementing the index by 1 each time
|
| 368 |
+
0 1 Nsteps
|
| 369 |
+
{
|
| 370 |
+
1 index FunEval sc
|
| 371 |
+
0 ymin dx di rectfill
|
| 372 |
+
dx 0 translate
|
| 373 |
+
}for
|
| 374 |
+
pop % pop our function
|
| 375 |
+
grestore % origin is back to start point
|
| 376 |
+
currentdict/Extend known
|
| 377 |
+
{
|
| 378 |
+
/Extend load 1 get
|
| 379 |
+
{
|
| 380 |
+
Nsteps/Function load FunEval sc % last element
|
| 381 |
+
1 ymin xmax 1 sub abs ymax ymin sub rectfill
|
| 382 |
+
}if
|
| 383 |
+
}if
|
| 384 |
+
}bd
|
| 385 |
+
|
| 386 |
+
/shp % this paints our shape for shading type 3
|
| 387 |
+
{ % x1 r1 x0 r0 -
|
| 388 |
+
4 copy
|
| 389 |
+
|
| 390 |
+
% fill interior arc
|
| 391 |
+
dup 0 gt{
|
| 392 |
+
0 exch a1 a0 arc
|
| 393 |
+
}{
|
| 394 |
+
pop 0 moveto
|
| 395 |
+
}ifelse
|
| 396 |
+
|
| 397 |
+
dup 0 gt{
|
| 398 |
+
0 exch a0 a1 arcn
|
| 399 |
+
}{
|
| 400 |
+
pop 0 lineto
|
| 401 |
+
}ifelse
|
| 402 |
+
|
| 403 |
+
fill
|
| 404 |
+
|
| 405 |
+
% fill exterior arc
|
| 406 |
+
dup 0 gt{
|
| 407 |
+
0 exch a0 a1 arc
|
| 408 |
+
}{
|
| 409 |
+
pop 0 moveto
|
| 410 |
+
}ifelse
|
| 411 |
+
|
| 412 |
+
dup 0 gt{
|
| 413 |
+
0 exch a1 a0 arcn
|
| 414 |
+
}{
|
| 415 |
+
pop 0 lineto
|
| 416 |
+
}ifelse
|
| 417 |
+
|
| 418 |
+
fill
|
| 419 |
+
}bd
|
| 420 |
+
|
| 421 |
+
/calcmaxs
|
| 422 |
+
{ % calculate maximum distance vector from origin to corner points
|
| 423 |
+
% of bbox
|
| 424 |
+
xmin dup mul ymin dup mul add sqrt % (xmin2 + ymin2)
|
| 425 |
+
xmax dup mul ymin dup mul add sqrt % (xmax2 + ymin2)
|
| 426 |
+
xmin dup mul ymax dup mul add sqrt % (xmin2 + ymax2)
|
| 427 |
+
xmax dup mul ymax dup mul add sqrt % (xmax2 + ymax2)
|
| 428 |
+
max max max % maximum value
|
| 429 |
+
}bd
|
| 430 |
+
|
| 431 |
+
/sh3
|
| 432 |
+
{ % emulation of shading type 3. Assumes shading dictionary is top dictionary on the dict stack
|
| 433 |
+
/Coords load aload pop % x0 y0 r1 x1 y1 r2
|
| 434 |
+
5 index 5 index translate % origin is now at first circle origin
|
| 435 |
+
3 -1 roll 6 -1 roll sub % y0 r1 y1 r2 dx
|
| 436 |
+
3 -1 roll 5 -1 roll sub % r1 r2 dx dy
|
| 437 |
+
2 copy dup mul exch dup mul add sqrt
|
| 438 |
+
/dx xs % r1 r2 dx dy
|
| 439 |
+
2 copy 0 ne exch 0 ne or
|
| 440 |
+
{
|
| 441 |
+
% r1 r2 dx dy
|
| 442 |
+
exch atan rotate % we are now rotated so dy is zero and positive values of dx move us as expected
|
| 443 |
+
}{
|
| 444 |
+
pop pop
|
| 445 |
+
}ifelse
|
| 446 |
+
% r1 r2
|
| 447 |
+
/r2 xs
|
| 448 |
+
/r1 xs
|
| 449 |
+
/Function load
|
| 450 |
+
dup/Size get 0 get 1 sub % this is the size of our table minus 1
|
| 451 |
+
/Nsteps xs % at some point we should optimize this better so NSteps is based on needed steps for the device
|
| 452 |
+
setupFunEval % may need to setup function dictionary by calling setupFunEval
|
| 453 |
+
% determine the case:
|
| 454 |
+
% case 0: circle1 inside circle2
|
| 455 |
+
% case 1: circle 2 inside circle 1
|
| 456 |
+
% case 2: r1 = r2
|
| 457 |
+
% case 3: r1 != r2
|
| 458 |
+
dx r2 add r1 lt{
|
| 459 |
+
% circle 2 inside of circle 1
|
| 460 |
+
0
|
| 461 |
+
}{
|
| 462 |
+
dx r1 add r2 le
|
| 463 |
+
{ % circle 1 inside of circle 2
|
| 464 |
+
1
|
| 465 |
+
}{ % circles don't contain each other
|
| 466 |
+
r1 r2 eq
|
| 467 |
+
{ % equal
|
| 468 |
+
2
|
| 469 |
+
}{ % r1 != r2
|
| 470 |
+
3
|
| 471 |
+
}ifelse
|
| 472 |
+
}ifelse
|
| 473 |
+
}ifelse
|
| 474 |
+
/sh3tp xs % sh3tp has the number of our different cases
|
| 475 |
+
clippath {pathbbox}stopped {0 0 0 0}if
|
| 476 |
+
newpath % x0 y0 x1 y1
|
| 477 |
+
/ymax xs
|
| 478 |
+
/xmax xs
|
| 479 |
+
/ymin xs
|
| 480 |
+
/xmin xs
|
| 481 |
+
|
| 482 |
+
% Arc angle atan( sqrt((dx*dx + dy*dy) - dr*dr), dr)
|
| 483 |
+
dx dup mul r2 r1 sub dup mul sub dup 0 gt
|
| 484 |
+
{
|
| 485 |
+
sqrt r2 r1 sub atan
|
| 486 |
+
/a0 exch 180 exch sub store
|
| 487 |
+
/a1 a0 neg store
|
| 488 |
+
}{
|
| 489 |
+
pop
|
| 490 |
+
/a0 0 store
|
| 491 |
+
/a1 360 store
|
| 492 |
+
}ifelse
|
| 493 |
+
|
| 494 |
+
currentdict/Extend known
|
| 495 |
+
{
|
| 496 |
+
/Extend load 0 get r1 0 gt and % no need to extend if the radius of the first end is 0
|
| 497 |
+
{
|
| 498 |
+
0/Function load FunEval sc % evaluate the function to get a color and set it
|
| 499 |
+
% case 0: circle1 inside circle2
|
| 500 |
+
% case 1: circle 2 inside circle 1
|
| 501 |
+
% case 2: circles don't contain each other and r1 == r2
|
| 502 |
+
% case 3: circles don't contain each other and r1 != r2
|
| 503 |
+
{
|
| 504 |
+
{ % case 0
|
| 505 |
+
dx 0 r1 360 0 arcn
|
| 506 |
+
xmin ymin moveto
|
| 507 |
+
xmax ymin lineto
|
| 508 |
+
xmax ymax lineto
|
| 509 |
+
xmin ymax lineto
|
| 510 |
+
xmin ymin lineto
|
| 511 |
+
eofill % for the bigger radius we fill everything except our circle
|
| 512 |
+
}
|
| 513 |
+
{ % case 1
|
| 514 |
+
r1 0 gt{0 0 r1 0 360 arc fill}if
|
| 515 |
+
}
|
| 516 |
+
{ % case 2
|
| 517 |
+
% r1 == r2, extend 0
|
| 518 |
+
% r3 = r, x3 = -(abs(minx) + r), x1 = 0
|
| 519 |
+
|
| 520 |
+
% x(i+1) r(i+1) x(i) r(i) shp
|
| 521 |
+
0 r1 xmin abs r1 add neg r1 shp
|
| 522 |
+
}
|
| 523 |
+
{ % case 3
|
| 524 |
+
% no containment, r1 != r2
|
| 525 |
+
|
| 526 |
+
r2 r1 gt{ % the endpoint we are drawing is that with a circle of zero radius
|
| 527 |
+
% x(i+1) r(i+1) x(i) r(i) shp
|
| 528 |
+
0 r1
|
| 529 |
+
r1 neg r2 r1 sub div dx mul % this is point of beginning circle
|
| 530 |
+
0 % point of ending circle
|
| 531 |
+
shp % takes x(i+1) r(i+1) x(i) r(i)
|
| 532 |
+
}{ % the first circle is the bigger of the two
|
| 533 |
+
% we find a circle on our line which is outside the bbox in the
|
| 534 |
+
% negative direction
|
| 535 |
+
% x(i+1) r(i+1) x(i) r(i) shp
|
| 536 |
+
0 r1 calcmaxs % 0 r1 maxs
|
| 537 |
+
dup
|
| 538 |
+
% calculating xs: (-(maxs+r2)*x2)/(x2-(r1-r2))
|
| 539 |
+
r2 add dx mul dx r1 r2 sub sub div
|
| 540 |
+
neg % maxs xs'
|
| 541 |
+
exch 1 index % xs' maxs xs'
|
| 542 |
+
abs exch sub
|
| 543 |
+
shp
|
| 544 |
+
}ifelse
|
| 545 |
+
}
|
| 546 |
+
}sh3tp get exec % execute the extend at beginning proc for our shading type
|
| 547 |
+
}if
|
| 548 |
+
}if
|
| 549 |
+
|
| 550 |
+
% now do the shading
|
| 551 |
+
/d0 0 store
|
| 552 |
+
/r0 r1 store
|
| 553 |
+
/di dx Nsteps div store
|
| 554 |
+
/ri r2 r1 sub Nsteps div store
|
| 555 |
+
/Function load
|
| 556 |
+
0 1 Nsteps
|
| 557 |
+
{ % function t(i)
|
| 558 |
+
1 index FunEval sc
|
| 559 |
+
d0 di add r0 ri add d0 r0 shp
|
| 560 |
+
{
|
| 561 |
+
% fill interior arc
|
| 562 |
+
d0 0 r0 a1 a0 arc
|
| 563 |
+
d0 di add 0 r0 ri add a0 a1 arcn
|
| 564 |
+
fill
|
| 565 |
+
|
| 566 |
+
% fill exterior arc
|
| 567 |
+
d0 0 r0 a0 a1 arc
|
| 568 |
+
d0 di add 0 r0 ri add a1 a0 arcn
|
| 569 |
+
fill
|
| 570 |
+
}pop
|
| 571 |
+
|
| 572 |
+
% advance to next
|
| 573 |
+
/d0 d0 di add store
|
| 574 |
+
/r0 r0 ri add store
|
| 575 |
+
}for
|
| 576 |
+
pop % pop our function dict
|
| 577 |
+
|
| 578 |
+
% handle Extend
|
| 579 |
+
currentdict/Extend known
|
| 580 |
+
{
|
| 581 |
+
/Extend load 1 get r2 0 gt and % no need to extend if the radius of the last end is 0
|
| 582 |
+
{
|
| 583 |
+
Nsteps/Function load FunEval sc % last element
|
| 584 |
+
% case 0: circle1 inside circle2
|
| 585 |
+
% case 1: circle 2 inside circle 1
|
| 586 |
+
% case 2: circles don't contain each other and r1 == r2
|
| 587 |
+
% case 3: circles don't contain each other and r1 != r2
|
| 588 |
+
{
|
| 589 |
+
{
|
| 590 |
+
dx 0 r2 0 360 arc fill
|
| 591 |
+
}
|
| 592 |
+
{
|
| 593 |
+
dx 0 r2 360 0 arcn
|
| 594 |
+
xmin ymin moveto
|
| 595 |
+
xmax ymin lineto
|
| 596 |
+
xmax ymax lineto
|
| 597 |
+
xmin ymax lineto
|
| 598 |
+
xmin ymin lineto
|
| 599 |
+
eofill % for the bigger radius we fill everything except our circle
|
| 600 |
+
}
|
| 601 |
+
{ % r1 == r2, extend 1
|
| 602 |
+
% r3 = r, x3 = (abs(xmax) + r), x1 = dx
|
| 603 |
+
% x(i+1) r(i+1) x(i) r(i) shp
|
| 604 |
+
xmax abs r1 add r1 dx r1 shp
|
| 605 |
+
}
|
| 606 |
+
{ % no containment, r1 != r2
|
| 607 |
+
|
| 608 |
+
r2 r1 gt{
|
| 609 |
+
% we find a circle on our line which is outside the bbox in the
|
| 610 |
+
% positive direction
|
| 611 |
+
% x(i+1) r(i+1) x(i) r(i) shp
|
| 612 |
+
calcmaxs dup % maxs maxs
|
| 613 |
+
% calculating xs: ((maxs+r1)*x2)/(x2-(r2-r1))
|
| 614 |
+
r1 add dx mul dx r2 r1 sub sub div % maxs xs
|
| 615 |
+
exch 1 index % xs maxs xs
|
| 616 |
+
exch sub
|
| 617 |
+
dx r2
|
| 618 |
+
shp
|
| 619 |
+
}{ % the endpoint we are drawing is that with a circle of zero radius
|
| 620 |
+
% x(i+1) r(i+1) x(i) r(i) shp
|
| 621 |
+
r1 neg r2 r1 sub div dx mul % this is point of ending circle
|
| 622 |
+
0 % radius of ending circle
|
| 623 |
+
dx % point of starting circle
|
| 624 |
+
r2 % radius of starting circle
|
| 625 |
+
shp
|
| 626 |
+
}ifelse
|
| 627 |
+
}
|
| 628 |
+
}
|
| 629 |
+
sh3tp get exec % execute the extend at end proc for our shading type
|
| 630 |
+
}if
|
| 631 |
+
}if
|
| 632 |
+
}bd
|
| 633 |
+
/sh % emulation of shfill operator for type 2 and type 3 shadings based on type 0 functions
|
| 634 |
+
{ % shadingDict --
|
| 635 |
+
begin
|
| 636 |
+
/ShadingType load dup dup 2 eq exch 3 eq or
|
| 637 |
+
{ % shadingtype
|
| 638 |
+
gsave
|
| 639 |
+
newpath
|
| 640 |
+
/ColorSpace load scs
|
| 641 |
+
currentdict/BBox known
|
| 642 |
+
{
|
| 643 |
+
/BBox load aload pop % llx lly urx ury
|
| 644 |
+
2 index sub % llx lly urx ury-lly
|
| 645 |
+
3 index % llx lly urx ury-lly llx
|
| 646 |
+
3 -1 roll exch sub
|
| 647 |
+
exch rectclip
|
| 648 |
+
}if
|
| 649 |
+
2 eq
|
| 650 |
+
{sh2}{sh3}ifelse
|
| 651 |
+
grestore
|
| 652 |
+
}{
|
| 653 |
+
% shadingtype
|
| 654 |
+
pop
|
| 655 |
+
(DEBUG: shading type unimplemented\n)print flush
|
| 656 |
+
}ifelse
|
| 657 |
+
end
|
| 658 |
+
}bd
|
| 659 |
+
|
| 660 |
+
% end of language level 2 ONLY code
|
| 661 |
+
|
| 662 |
+
{restore}if not dup{save exch}if
|
| 663 |
+
% languagelevel3 ONLY code goes here
|
| 664 |
+
L3?{ % we do these loads conditionally or else they will fail on a level 2 printer
|
| 665 |
+
/sh/shfill ld
|
| 666 |
+
/csq/clipsave ld
|
| 667 |
+
/csQ/cliprestore ld
|
| 668 |
+
}if
|
| 669 |
+
{restore}if
|
| 670 |
+
|
| 671 |
+
%currentdict dup maxlength exch length sub (number of extra slots in md = )print == flush % *** how many entries are free
|
| 672 |
+
end
|
| 673 |
+
setpacking
|
| 674 |
+
% count 0 ne { pstack(***extras on stack during prolog execution***\n)print flush}if % *** BARK if anything is left on stack
|
| 675 |
+
%%EndFile
|
| 676 |
+
%%EndProlog
|
| 677 |
+
%%BeginSetup
|
| 678 |
+
%%EndSetup
|
| 679 |
+
%%Page: 1 1
|
| 680 |
+
%%PageBoundingBox: 0 0 145 144
|
| 681 |
+
%%BeginPageSetup
|
| 682 |
+
cg_md begin
|
| 683 |
+
bp
|
| 684 |
+
sdmtx
|
| 685 |
+
[ /CIEBasedABC 4 dict dup begin
|
| 686 |
+
/WhitePoint [ 0.9505 1.0000 1.0891 ] def
|
| 687 |
+
/DecodeABC [
|
| 688 |
+
{ 1.0 0.0 3 -1 roll 1 index 1 index le { exch pop} { pop } ifelse
|
| 689 |
+
1 index 1 index ge { exch pop } { pop } ifelse <
|
| 690 |
+
0000000000000000000000000000000000000000000000000000000000000000
|
| 691 |
+
0000000000000000000000000000000000000001010101010101010101010101
|
| 692 |
+
0101010101010101010101010101010101010101010101020202020202020202
|
| 693 |
+
0202020202020202020202020202020202030303030303030303030303030303
|
| 694 |
+
0303030303030304040404040404040404040404040404040404050505050505
|
| 695 |
+
0505050505050505050506060606060606060606060606060607070707070707
|
| 696 |
+
0707070707070708080808080808080808080808090909090909090909090909
|
| 697 |
+
0a0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0c0c0c0c0c0c0c0c0c0c
|
| 698 |
+
0d0d0d0d0d0d0d0d0d0d0e0e0e0e0e0e0e0e0e0f0f0f0f0f0f0f0f0f10101010
|
| 699 |
+
1010101010111111111111111112121212121212121313131313131313141414
|
| 700 |
+
1414141414151515151515151616161616161616171717171717171818181818
|
| 701 |
+
18181919191919191a1a1a1a1a1a1a1b1b1b1b1b1b1c1c1c1c1c1c1c1d1d1d1d
|
| 702 |
+
1d1d1e1e1e1e1e1e1f1f1f1f1f1f202020202020212121212121222222222223
|
| 703 |
+
2323232323242424242425252525252526262626262727272727282828282829
|
| 704 |
+
292929292a2a2a2a2a2b2b2b2b2b2c2c2c2c2c2d2d2d2d2d2e2e2e2e2e2f2f2f
|
| 705 |
+
2f2f303030303131313131323232323333333333343434343535353535363636
|
| 706 |
+
36373737373838383839393939393a3a3a3a3b3b3b3b3c3c3c3c3d3d3d3d3e3e
|
| 707 |
+
3e3e3f3f3f3f4040404041414141424242424343434444444445454545464646
|
| 708 |
+
4647474748484848494949494a4a4a4b4b4b4b4c4c4c4d4d4d4d4e4e4e4f4f4f
|
| 709 |
+
4f50505051515151525252535353535454545555555656565657575758585859
|
| 710 |
+
59595a5a5a5a5b5b5b5c5c5c5d5d5d5e5e5e5f5f5f6060606061616162626263
|
| 711 |
+
63636464646565656666666767676868686969696a6a6a6b6b6b6c6c6d6d6d6e
|
| 712 |
+
6e6e6f6f6f707070717171727273737374747475757576767677777878787979
|
| 713 |
+
797a7a7b7b7b7c7c7c7d7d7e7e7e7f7f7f808081818182828283838484848585
|
| 714 |
+
86868687878888888989898a8a8b8b8b8c8c8d8d8d8e8e8f8f90909091919292
|
| 715 |
+
9293939494949595969697979798989999999a9a9b9b9c9c9c9d9d9e9e9f9f9f
|
| 716 |
+
a0a0a1a1a2a2a3a3a3a4a4a5a5a6a6a6a7a7a8a8a9a9aaaaabababacacadadae
|
| 717 |
+
aeafafb0b0b0b1b1b2b2b3b3b4b4b5b5b6b6b6b7b7b8b8b9b9bababbbbbcbcbd
|
| 718 |
+
bdbebebebfbfc0c0c1c1c2c2c3c3c4c4c5c5c6c6c7c7c8c8c9c9cacacbcbcccc
|
| 719 |
+
cdcdcececfcfd0d0d1d1d2d2d3d3d4d4d5d5d6d6d7d7d8d8d9d9dadadbdcdcdd
|
| 720 |
+
dddededfdfe0e0e1e1e2e2e3e3e4e4e5e6e6e7e7e8e8e9e9eaeaebebecededee
|
| 721 |
+
eeefeff0f0f1f1f2f3f3f4f4f5f5f6f6f7f8f8f9f9fafafbfcfcfdfdfefeffff
|
| 722 |
+
> dup length 1 sub 3 -1 roll mul dup dup floor cvi exch ceiling
|
| 723 |
+
cvi 3 index exch get 4 -1 roll 3 -1 roll get
|
| 724 |
+
dup 3 1 roll sub 3 -1 roll dup floor cvi sub mul add 255 div } bind
|
| 725 |
+
|
| 726 |
+
{ 1.0 0.0 3 -1 roll 1 index 1 index le { exch pop} { pop } ifelse
|
| 727 |
+
1 index 1 index ge { exch pop } { pop } ifelse <
|
| 728 |
+
0000000000000000000000000000000000000000000000000000000000000000
|
| 729 |
+
0000000000000000000000000000000000000001010101010101010101010101
|
| 730 |
+
0101010101010101010101010101010101010101010101020202020202020202
|
| 731 |
+
0202020202020202020202020202020202030303030303030303030303030303
|
| 732 |
+
0303030303030304040404040404040404040404040404040404050505050505
|
| 733 |
+
0505050505050505050506060606060606060606060606060607070707070707
|
| 734 |
+
0707070707070708080808080808080808080808090909090909090909090909
|
| 735 |
+
0a0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0c0c0c0c0c0c0c0c0c0c
|
| 736 |
+
0d0d0d0d0d0d0d0d0d0d0e0e0e0e0e0e0e0e0e0f0f0f0f0f0f0f0f0f10101010
|
| 737 |
+
1010101010111111111111111112121212121212121313131313131313141414
|
| 738 |
+
1414141414151515151515151616161616161616171717171717171818181818
|
| 739 |
+
18181919191919191a1a1a1a1a1a1a1b1b1b1b1b1b1c1c1c1c1c1c1c1d1d1d1d
|
| 740 |
+
1d1d1e1e1e1e1e1e1f1f1f1f1f1f202020202020212121212121222222222223
|
| 741 |
+
2323232323242424242425252525252526262626262727272727282828282829
|
| 742 |
+
292929292a2a2a2a2a2b2b2b2b2b2c2c2c2c2c2d2d2d2d2d2e2e2e2e2e2f2f2f
|
| 743 |
+
2f2f303030303131313131323232323333333333343434343535353535363636
|
| 744 |
+
36373737373838383839393939393a3a3a3a3b3b3b3b3c3c3c3c3d3d3d3d3e3e
|
| 745 |
+
3e3e3f3f3f3f4040404041414141424242424343434444444445454545464646
|
| 746 |
+
4647474748484848494949494a4a4a4b4b4b4b4c4c4c4d4d4d4d4e4e4e4f4f4f
|
| 747 |
+
4f50505051515151525252535353535454545555555656565657575758585859
|
| 748 |
+
59595a5a5a5a5b5b5b5c5c5c5d5d5d5e5e5e5f5f5f6060606061616162626263
|
| 749 |
+
63636464646565656666666767676868686969696a6a6a6b6b6b6c6c6d6d6d6e
|
| 750 |
+
6e6e6f6f6f707070717171727273737374747475757576767677777878787979
|
| 751 |
+
797a7a7b7b7b7c7c7c7d7d7e7e7e7f7f7f808081818182828283838484848585
|
| 752 |
+
86868687878888888989898a8a8b8b8b8c8c8d8d8d8e8e8f8f90909091919292
|
| 753 |
+
9293939494949595969697979798989999999a9a9b9b9c9c9c9d9d9e9e9f9f9f
|
| 754 |
+
a0a0a1a1a2a2a3a3a3a4a4a5a5a6a6a6a7a7a8a8a9a9aaaaabababacacadadae
|
| 755 |
+
aeafafb0b0b0b1b1b2b2b3b3b4b4b5b5b6b6b6b7b7b8b8b9b9bababbbbbcbcbd
|
| 756 |
+
bdbebebebfbfc0c0c1c1c2c2c3c3c4c4c5c5c6c6c7c7c8c8c9c9cacacbcbcccc
|
| 757 |
+
cdcdcececfcfd0d0d1d1d2d2d3d3d4d4d5d5d6d6d7d7d8d8d9d9dadadbdcdcdd
|
| 758 |
+
dddededfdfe0e0e1e1e2e2e3e3e4e4e5e6e6e7e7e8e8e9e9eaeaebebecededee
|
| 759 |
+
eeefeff0f0f1f1f2f3f3f4f4f5f5f6f6f7f8f8f9f9fafafbfcfcfdfdfefeffff
|
| 760 |
+
> dup length 1 sub 3 -1 roll mul dup dup floor cvi exch ceiling
|
| 761 |
+
cvi 3 index exch get 4 -1 roll 3 -1 roll get
|
| 762 |
+
dup 3 1 roll sub 3 -1 roll dup floor cvi sub mul add 255 div } bind
|
| 763 |
+
|
| 764 |
+
{ 1.0 0.0 3 -1 roll 1 index 1 index le { exch pop} { pop } ifelse
|
| 765 |
+
1 index 1 index ge { exch pop } { pop } ifelse <
|
| 766 |
+
0000000000000000000000000000000000000000000000000000000000000000
|
| 767 |
+
0000000000000000000000000000000000000001010101010101010101010101
|
| 768 |
+
0101010101010101010101010101010101010101010101020202020202020202
|
| 769 |
+
0202020202020202020202020202020202030303030303030303030303030303
|
| 770 |
+
0303030303030304040404040404040404040404040404040404050505050505
|
| 771 |
+
0505050505050505050506060606060606060606060606060607070707070707
|
| 772 |
+
0707070707070708080808080808080808080808090909090909090909090909
|
| 773 |
+
0a0a0a0a0a0a0a0a0a0a0a0b0b0b0b0b0b0b0b0b0b0b0c0c0c0c0c0c0c0c0c0c
|
| 774 |
+
0d0d0d0d0d0d0d0d0d0d0e0e0e0e0e0e0e0e0e0f0f0f0f0f0f0f0f0f10101010
|
| 775 |
+
1010101010111111111111111112121212121212121313131313131313141414
|
| 776 |
+
1414141414151515151515151616161616161616171717171717171818181818
|
| 777 |
+
18181919191919191a1a1a1a1a1a1a1b1b1b1b1b1b1c1c1c1c1c1c1c1d1d1d1d
|
| 778 |
+
1d1d1e1e1e1e1e1e1f1f1f1f1f1f202020202020212121212121222222222223
|
| 779 |
+
2323232323242424242425252525252526262626262727272727282828282829
|
| 780 |
+
292929292a2a2a2a2a2b2b2b2b2b2c2c2c2c2c2d2d2d2d2d2e2e2e2e2e2f2f2f
|
| 781 |
+
2f2f303030303131313131323232323333333333343434343535353535363636
|
| 782 |
+
36373737373838383839393939393a3a3a3a3b3b3b3b3c3c3c3c3d3d3d3d3e3e
|
| 783 |
+
3e3e3f3f3f3f4040404041414141424242424343434444444445454545464646
|
| 784 |
+
4647474748484848494949494a4a4a4b4b4b4b4c4c4c4d4d4d4d4e4e4e4f4f4f
|
| 785 |
+
4f50505051515151525252535353535454545555555656565657575758585859
|
| 786 |
+
59595a5a5a5a5b5b5b5c5c5c5d5d5d5e5e5e5f5f5f6060606061616162626263
|
| 787 |
+
63636464646565656666666767676868686969696a6a6a6b6b6b6c6c6d6d6d6e
|
| 788 |
+
6e6e6f6f6f707070717171727273737374747475757576767677777878787979
|
| 789 |
+
797a7a7b7b7b7c7c7c7d7d7e7e7e7f7f7f808081818182828283838484848585
|
| 790 |
+
86868687878888888989898a8a8b8b8b8c8c8d8d8d8e8e8f8f90909091919292
|
| 791 |
+
9293939494949595969697979798989999999a9a9b9b9c9c9c9d9d9e9e9f9f9f
|
| 792 |
+
a0a0a1a1a2a2a3a3a3a4a4a5a5a6a6a6a7a7a8a8a9a9aaaaabababacacadadae
|
| 793 |
+
aeafafb0b0b0b1b1b2b2b3b3b4b4b5b5b6b6b6b7b7b8b8b9b9bababbbbbcbcbd
|
| 794 |
+
bdbebebebfbfc0c0c1c1c2c2c3c3c4c4c5c5c6c6c7c7c8c8c9c9cacacbcbcccc
|
| 795 |
+
cdcdcececfcfd0d0d1d1d2d2d3d3d4d4d5d5d6d6d7d7d8d8d9d9dadadbdcdcdd
|
| 796 |
+
dddededfdfe0e0e1e1e2e2e3e3e4e4e5e6e6e7e7e8e8e9e9eaeaebebecededee
|
| 797 |
+
eeefeff0f0f1f1f2f3f3f4f4f5f5f6f6f7f8f8f9f9fafafbfcfcfdfdfefeffff
|
| 798 |
+
> dup length 1 sub 3 -1 roll mul dup dup floor cvi exch ceiling
|
| 799 |
+
cvi 3 index exch get 4 -1 roll 3 -1 roll get
|
| 800 |
+
dup 3 1 roll sub 3 -1 roll dup floor cvi sub mul add 255 div } bind
|
| 801 |
+
] def
|
| 802 |
+
/MatrixABC [ 0.4124 0.2126 0.0193 0.3576 0.7151 0.1192 0.1805 0.0722 0.9508 ] def
|
| 803 |
+
/RangeLMN [ 0.0 0.9505 0.0 1.0000 0.0 1.0891 ] def
|
| 804 |
+
end ] /Cs1 exch/ColorSpace dr pop
|
| 805 |
+
%%EndPageSetup
|
| 806 |
+
0.60000002 i
|
| 807 |
+
/Cs1 SC
|
| 808 |
+
0.19215687 0.50196081 0.24705882 sc
|
| 809 |
+
q
|
| 810 |
+
107.81159 97.479164 m
|
| 811 |
+
107.70937 97.318977 107.6055 97.16069 107.49998 97.004311 c
|
| 812 |
+
105.73492 94.38842 102.64958 90.816887 99.963394 89.267845 c
|
| 813 |
+
94.390419 86.056587 88.16684 85.510155 82.133011 85.425964 c
|
| 814 |
+
80.360062 85.399292 78.461891 85.222542 76.881088 85.076981 c
|
| 815 |
+
74.223763 84.832245 71.583275 84.33358 68.959625 83.580986 c
|
| 816 |
+
68.066261 83.325096 67.04287 82.908684 65.889458 82.331726 c
|
| 817 |
+
64.58416 81.678329 63.463833 80.832115 62.528469 79.793068 c
|
| 818 |
+
62.503223 79.764771 62.49094 79.726929 62.495075 79.690193 c
|
| 819 |
+
62.499214 79.65345 62.519321 79.62178 62.549747 79.60408 c
|
| 820 |
+
84.089394 67.168159 l
|
| 821 |
+
84.118233 67.151718 84.15358 67.150269 84.185539 67.164215 c
|
| 822 |
+
84.217499 67.178162 84.24263 67.206009 84.253891 67.23996 c
|
| 823 |
+
84.800957 68.883072 84.952927 70.5756 84.709808 72.317543 c
|
| 824 |
+
84.701675 72.380081 84.667191 72.433487 84.615746 72.463181 c
|
| 825 |
+
79.435493 75.455322 70.91024 80.378036 70.142578 80.821251 c
|
| 826 |
+
74.395477 81.717239 l
|
| 827 |
+
78.583549 79.292633 83.475731 76.463501 83.87587 76.229836 c
|
| 828 |
+
83.894463 76.218201 83.918961 76.220802 83.936653 76.236275 c
|
| 829 |
+
83.954346 76.251755 83.961258 76.276634 83.953796 76.298012 c
|
| 830 |
+
83.269753 78.37262 82.458595 80.492157 81.52034 82.656616 c
|
| 831 |
+
81.508797 82.682777 81.511681 82.714195 81.527977 82.739838 c
|
| 832 |
+
81.544273 82.76548 81.571701 82.781769 81.600647 82.782982 c
|
| 833 |
+
87.057648 82.97187 l
|
| 834 |
+
87.083649 82.972557 87.106491 82.957031 87.115677 82.932411 c
|
| 835 |
+
88.154175 80.357338 88.956558 78.015862 89.559402 75.191978 c
|
| 836 |
+
90.097984 72.663963 90.122963 70.157173 89.634338 67.671593 c
|
| 837 |
+
89.305534 65.995125 88.631523 64.334641 87.612282 62.690151 c
|
| 838 |
+
85.797989 59.760822 82.732033 57.478695 79.625153 56.312176 c
|
| 839 |
+
76.374931 55.091423 73.000679 54.354588 69.502396 54.101673 c
|
| 840 |
+
67.25396 53.93853 63.718658 54.002148 60.815487 53.859646 c
|
| 841 |
+
55.699306 53.60899 50.585567 53.009476 46.171291 49.772522 c
|
| 842 |
+
46.141224 49.749836 46.123119 49.713654 46.123283 49.676563 c
|
| 843 |
+
46.123444 49.639473 46.141846 49.606606 46.172085 49.589401 c
|
| 844 |
+
66.34536 37.94236 l
|
| 845 |
+
66.366119 37.930351 66.39344 37.938282 66.407135 37.960297 c
|
| 846 |
+
66.439926 38.012844 66.45974 38.071552 66.466583 38.136429 c
|
| 847 |
+
66.616646 39.562687 66.584175 41.035431 66.369186 42.554649 c
|
| 848 |
+
66.354828 42.651142 66.300346 42.733353 66.220001 42.779762 c
|
| 849 |
+
65.341606 43.283207 61.58448 45.45034 59.110184 46.878483 c
|
| 850 |
+
57.155937 48.006458 55.080814 49.20525 53.480167 50.131138 c
|
| 851 |
+
57.70182 50.979649 l
|
| 852 |
+
58.31049 50.663971 61.808525 48.64835 65.242722 46.637821 c
|
| 853 |
+
65.256119 46.63026 65.272957 46.631359 65.28643 46.640671 c
|
| 854 |
+
65.299904 46.649982 65.307793 46.66597 65.306892 46.682171 c
|
| 855 |
+
65.285988 46.915287 65.235031 47.131336 65.154022 47.330322 c
|
| 856 |
+
64.360596 49.264248 63.895523 50.372593 63.758812 50.655357 c
|
| 857 |
+
63.689651 50.798531 63.578194 50.973404 63.424431 51.179981 c
|
| 858 |
+
63.407581 51.202202 63.405197 51.233398 63.418304 51.26017 c
|
| 859 |
+
63.431408 51.286942 63.457664 51.304527 63.485802 51.305367 c
|
| 860 |
+
69.062767 51.498455 l
|
| 861 |
+
69.095558 51.498917 69.124481 51.479904 69.137321 51.449455 c
|
| 862 |
+
70.08194 49.211174 70.769211 47.108231 71.199158 45.140621 c
|
| 863 |
+
72.139458 40.838387 71.897247 35.775063 69.736961 31.646093 c
|
| 864 |
+
69.65992 31.498837 67.861 28.374626 67.779045 28.229824 c
|
| 865 |
+
63.466091 30.715939 l
|
| 866 |
+
65.724426 34.866062 l
|
| 867 |
+
65.747192 34.913773 65.73143 34.96954 65.68821 34.994186 c
|
| 868 |
+
43.896503 47.57563 l
|
| 869 |
+
43.849712 47.602848 43.788166 47.586426 43.75539 47.537979 c
|
| 870 |
+
41.296982 43.515282 l
|
| 871 |
+
37.014671 45.987675 l
|
| 872 |
+
37.087574 46.118549 38.888317 49.232536 38.978039 49.373341 c
|
| 873 |
+
39.177372 49.686165 39.418217 50.023487 39.700573 50.385311 c
|
| 874 |
+
43.244904 54.930614 48.118938 57.211201 53.350811 58.298428 c
|
| 875 |
+
55.762325 58.80024 58.08091 59.087009 60.306557 59.158741 c
|
| 876 |
+
61.328564 59.192108 63.216022 59.234741 65.968933 59.286633 c
|
| 877 |
+
67.805626 59.320854 69.851242 59.482624 72.105797 59.77195 c
|
| 878 |
+
73.521057 59.954178 74.675316 60.175255 75.568558 60.435181 c
|
| 879 |
+
78.122505 61.178383 80.95903 62.280609 82.667351 64.536514 c
|
| 880 |
+
82.683975 64.558952 82.691216 64.586975 82.687256 64.613533 c
|
| 881 |
+
82.683296 64.640099 82.66851 64.662659 82.646614 64.675552 c
|
| 882 |
+
61.09182 77.120224 l
|
| 883 |
+
61.072231 77.131241 61.048443 77.132599 61.02655 77.123932 c
|
| 884 |
+
61.004662 77.115273 60.986801 77.097435 60.977558 77.075005 c
|
| 885 |
+
60.333374 75.51709 60.208103 73.68737 60.376854 72.071091 c
|
| 886 |
+
60.38942 71.948601 60.456219 71.843254 60.557571 71.786079 c
|
| 887 |
+
62.952961 70.415016 70.361839 66.143448 74.123955 63.971394 c
|
| 888 |
+
70.150085 62.926216 l
|
| 889 |
+
66.804855 64.868179 62.681252 67.246956 61.243378 68.062553 c
|
| 890 |
+
61.227962 68.072044 61.20771 68.069565 61.193394 68.056442 c
|
| 891 |
+
61.179081 68.043312 61.17403 68.022583 61.180935 68.005287 c
|
| 892 |
+
61.978542 65.792313 62.828018 63.77309 63.729362 61.947613 c
|
| 893 |
+
63.740822 61.924011 63.738827 61.89497 63.724125 61.871479 c
|
| 894 |
+
63.709427 61.847988 63.684269 61.833633 63.658173 61.833851 c
|
| 895 |
+
61.785522 61.877308 59.955116 61.792473 58.166954 61.579342 c
|
| 896 |
+
58.061222 61.566261 57.963032 61.623745 57.921261 61.723179 c
|
| 897 |
+
57.349731 63.082924 56.801182 64.594856 56.275604 66.25898 c
|
| 898 |
+
55.780033 67.82769 55.475639 69.46669 55.283581 70.90583 c
|
| 899 |
+
54.659359 75.572617 56.044724 80.310135 59.354027 83.821716 c
|
| 900 |
+
61.780403 86.395676 65.323822 88.060646 68.675797 88.932777 c
|
| 901 |
+
70.46209 89.397148 71.866837 89.713844 72.890022 89.882866 c
|
| 902 |
+
75.994705 90.393478 79.956833 90.665154 83.582916 90.771492 c
|
| 903 |
+
84.893387 90.810387 86.144226 90.876427 87.335449 90.969612 c
|
| 904 |
+
91.598228 91.303978 96.271645 92.578621 99.77639 95.344009 c
|
| 905 |
+
99.788483 95.353035 99.795479 95.367683 99.794945 95.382866 c
|
| 906 |
+
99.794418 95.398041 99.78643 95.411667 99.773766 95.418991 c
|
| 907 |
+
79.223083 107.28393 l
|
| 908 |
+
79.20314 107.29511 79.178452 107.29479 79.157288 107.28307 c
|
| 909 |
+
79.136131 107.27135 79.121307 107.24979 79.117783 107.2256 c
|
| 910 |
+
78.896484 105.77561 78.880066 104.30727 79.068535 102.82057 c
|
| 911 |
+
79.086639 102.68067 79.164726 102.5612 79.28112 102.49532 c
|
| 912 |
+
79.560493 102.33667 87.516136 97.750099 92.755722 94.735611 c
|
| 913 |
+
88.659622 93.784828 l
|
| 914 |
+
88.63942 93.796494 84.163239 96.384789 79.87014 98.871353 c
|
| 915 |
+
79.856552 98.879875 79.838844 98.877953 79.825706 98.866531 c
|
| 916 |
+
79.812576 98.85511 79.806763 98.836586 79.811134 98.820045 c
|
| 917 |
+
79.970955 98.248619 80.193474 97.606583 80.478683 96.893944 c
|
| 918 |
+
81.025894 95.521759 81.513702 94.38176 81.942108 93.47393 c
|
| 919 |
+
81.96048 93.435539 81.957031 93.388542 81.933044 93.350243 c
|
| 920 |
+
81.90905 93.311951 81.868057 93.288033 81.82518 93.287308 c
|
| 921 |
+
80.025665 93.258095 78.262054 93.142632 76.534355 92.940926 c
|
| 922 |
+
76.414925 92.927559 76.30468 92.991997 76.256981 93.10305 c
|
| 923 |
+
74.592598 96.992493 73.533508 101.53908 73.830086 105.94624 c
|
| 924 |
+
73.999916 108.48585 74.681496 110.94965 75.874825 113.33765 c
|
| 925 |
+
75.951622 113.49133 76.890251 115.13376 76.971291 115.28681 c
|
| 926 |
+
81.304047 112.78728 l
|
| 927 |
+
80.60321 111.52448 80.220871 110.82555 80.157028 110.69051 c
|
| 928 |
+
80.113869 110.59922 80.049133 110.46229 79.962822 110.27972 c
|
| 929 |
+
79.941872 110.23676 79.955956 110.18616 79.995079 110.16381 c
|
| 930 |
+
101.84601 97.548172 l
|
| 931 |
+
101.889 97.523132 101.94555 97.53801 101.97594 97.582352 c
|
| 932 |
+
102.13994 97.82048 102.26295 97.999077 102.34495 98.118134 c
|
| 933 |
+
102.40427 98.204262 102.77982 98.829819 103.4716 99.994789 c
|
| 934 |
+
107.81159 97.479164 l
|
| 935 |
+
h
|
| 936 |
+
W
|
| 937 |
+
17 17 110 110 rc
|
| 938 |
+
54.347878 147.30881 m
|
| 939 |
+
146.8744 93.888588 l
|
| 940 |
+
90.478394 -3.7921684 l
|
| 941 |
+
-2.0481343 49.628044 l
|
| 942 |
+
h
|
| 943 |
+
f
|
| 944 |
+
Q
|
| 945 |
+
12 w
|
| 946 |
+
0 0 0 sc
|
| 947 |
+
q
|
| 948 |
+
117.96633 45.75 m
|
| 949 |
+
72.5 19.5 l
|
| 950 |
+
27.033667 45.75 l
|
| 951 |
+
27.033667 98.25 l
|
| 952 |
+
72.5 124.5 l
|
| 953 |
+
117.96633 98.25 l
|
| 954 |
+
117.96633 45.75 l
|
| 955 |
+
h
|
| 956 |
+
W*
|
| 957 |
+
17 17 110 110 rc
|
| 958 |
+
-0.5 -0.86602539 -0.86602539 0.5 144.21634 91.216331 cm
|
| 959 |
+
52.5 0 m
|
| 960 |
+
97.966331 26.25 l
|
| 961 |
+
97.966331 78.75 l
|
| 962 |
+
52.5 105 l
|
| 963 |
+
7.0336661 78.75 l
|
| 964 |
+
7.0336661 26.25 l
|
| 965 |
+
52.5 0 l
|
| 966 |
+
h
|
| 967 |
+
S
|
| 968 |
+
ep
|
| 969 |
+
end
|
| 970 |
+
%%Trailer
|
| 971 |
+
%%EOF
|
|
Binary file (7.01 kB). View file
|
|
|
|
Git LFS Details
|
|
|
|
|
|
|
|
|
|
|
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Carbon
|
| 2 |
+
|
| 3 |
+
> Carbon is Hugging Face's open-source family of autoregressive genomic foundation models for DNA. Three sizes (500M, 3B, and 8B parameters), a 393,216 bp context window, a 6-mer BPE tokenizer, and 1 trillion training tokens spanning the tree of life. Model weights, training code, and the data pipeline are all open source on the Hugging Face Hub.
|
| 4 |
+
|
| 5 |
+
This site is the interactive editorial walkthrough of what the 3B checkpoint learned. It is organised into four tabs:
|
| 6 |
+
|
| 7 |
+
- **Intro** — a short primer on what the model reads (the four bases of DNA, helices, genes, splicing, translation) and a guided tour of the rest of the page.
|
| 8 |
+
- **DNA Lab** — five live sections that hit the deployed 3B model: streaming continuation of an arbitrary DNA prefix, per-token likelihood scoring, in-silico variant effect prediction (VEP), ESMFold-based protein folding over Carbon-decoded ORFs, and a UMAP scatter of ~500,000 gene embeddings.
|
| 9 |
+
- **Carbon Recipe** — the training story: tokenizer design, the hybrid loss, the dataset mixture, the species tree learned from per-species mean embeddings, the long-context training schedule, and the headline results.
|
| 10 |
+
- **Sandbox** — a minimal prompt-and-stream UI for running Carbon on arbitrary DNA sequences without leaving the page.
|
| 11 |
+
|
| 12 |
+
## Demo
|
| 13 |
+
|
| 14 |
+
- [Live interactive demo (this site)](/): Editorial scrollytell across Intro / DNA Lab / Carbon Recipe / Sandbox.
|
| 15 |
+
- [Standalone sandbox](/sandbox-only): The DNA continuation UI without the surrounding editorial.
|
| 16 |
+
|
| 17 |
+
## Models
|
| 18 |
+
|
| 19 |
+
- [HuggingFaceBio/Carbon-3B](https://huggingface.co/HuggingFaceBio/Carbon-3B): The default 3B checkpoint used by every live interaction on this page.
|
| 20 |
+
- [HuggingFaceBio organisation page](https://huggingface.co/HuggingFaceBio): Full list of Carbon model sizes (500M, 3B, 8B) and related artefacts.
|
| 21 |
+
|
| 22 |
+
## Code
|
| 23 |
+
|
| 24 |
+
- [github.com/huggingface/carbon](https://github.com/huggingface/carbon): Training and inference code.
|
| 25 |
+
|
| 26 |
+
## Data
|
| 27 |
+
|
| 28 |
+
- [HuggingFaceBio/carbon-inference-evals](https://huggingface.co/datasets/HuggingFaceBio/carbon-inference-evals): The evaluation dataset behind the headline numbers shown in the Results section.
|
| 29 |
+
|
| 30 |
+
## API
|
| 31 |
+
|
| 32 |
+
The demo's FastAPI backend exposes a small set of JSON endpoints that crawlers and agents may find useful. They are designed for the frontend but are not gated:
|
| 33 |
+
|
| 34 |
+
- `POST /generate` — streaming DNA continuation. Body: `{"prompt": "ACGT...", "max_tokens": 128, "temperature": 0.5, "top_p": 0.9}`. Returns Server-Sent Events.
|
| 35 |
+
- `POST /score` — per-token log-probabilities over a forced sequence. Body: `{"sequence": "ACGT...", "max_window": 24000}`.
|
| 36 |
+
- `POST /fold` — ESMFold-based protein structure prediction. Body: `{"sequence": "<AMINO_ACIDS>"}`. Returns PDB plus mean pLDDT.
|
| 37 |
+
- `GET /config` — the model identifier currently served.
|
| 38 |
+
- `GET /umap`, `GET /umap_labels`, `GET /umap_names`, `GET /highlights`, `GET /species_tree`, `GET /genes`, `GET /variants`, `GET /species` — static data payloads powering the visualisations.
|
|
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# robots.txt for the Carbon demo.
|
| 2 |
+
#
|
| 3 |
+
# Policy: explicitly welcome every crawler — including LLM-training and
|
| 4 |
+
# answer-engine bots — to read the page. The whole point of the demo is
|
| 5 |
+
# to make the model's behaviour and the surrounding write-up easy to
|
| 6 |
+
# discover and to cite. The only path we keep out of the index is the
|
| 7 |
+
# /social-banner utility page, which is a screenshot rig, not content.
|
| 8 |
+
#
|
| 9 |
+
# The Sitemap line below is rewritten with an absolute URL at request
|
| 10 |
+
# time by app.py (it has to be absolute per the sitemaps protocol).
|
| 11 |
+
|
| 12 |
+
User-agent: *
|
| 13 |
+
Allow: /
|
| 14 |
+
Disallow: /social-banner
|
| 15 |
+
|
| 16 |
+
# AI / LLM crawlers, called out by name so it's unambiguous that this
|
| 17 |
+
# site opts IN to training and to live answer-engine retrieval.
|
| 18 |
+
User-agent: GPTBot
|
| 19 |
+
Allow: /
|
| 20 |
+
Disallow: /social-banner
|
| 21 |
+
|
| 22 |
+
User-agent: ChatGPT-User
|
| 23 |
+
Allow: /
|
| 24 |
+
Disallow: /social-banner
|
| 25 |
+
|
| 26 |
+
User-agent: OAI-SearchBot
|
| 27 |
+
Allow: /
|
| 28 |
+
Disallow: /social-banner
|
| 29 |
+
|
| 30 |
+
User-agent: ClaudeBot
|
| 31 |
+
Allow: /
|
| 32 |
+
Disallow: /social-banner
|
| 33 |
+
|
| 34 |
+
User-agent: Claude-Web
|
| 35 |
+
Allow: /
|
| 36 |
+
Disallow: /social-banner
|
| 37 |
+
|
| 38 |
+
User-agent: anthropic-ai
|
| 39 |
+
Allow: /
|
| 40 |
+
Disallow: /social-banner
|
| 41 |
+
|
| 42 |
+
User-agent: PerplexityBot
|
| 43 |
+
Allow: /
|
| 44 |
+
Disallow: /social-banner
|
| 45 |
+
|
| 46 |
+
User-agent: Perplexity-User
|
| 47 |
+
Allow: /
|
| 48 |
+
Disallow: /social-banner
|
| 49 |
+
|
| 50 |
+
User-agent: Google-Extended
|
| 51 |
+
Allow: /
|
| 52 |
+
Disallow: /social-banner
|
| 53 |
+
|
| 54 |
+
User-agent: Applebot-Extended
|
| 55 |
+
Allow: /
|
| 56 |
+
Disallow: /social-banner
|
| 57 |
+
|
| 58 |
+
User-agent: CCBot
|
| 59 |
+
Allow: /
|
| 60 |
+
Disallow: /social-banner
|
| 61 |
+
|
| 62 |
+
User-agent: Bytespider
|
| 63 |
+
Allow: /
|
| 64 |
+
Disallow: /social-banner
|
| 65 |
+
|
| 66 |
+
User-agent: cohere-ai
|
| 67 |
+
Allow: /
|
| 68 |
+
Disallow: /social-banner
|
| 69 |
+
|
| 70 |
+
User-agent: Meta-ExternalAgent
|
| 71 |
+
Allow: /
|
| 72 |
+
Disallow: /social-banner
|
| 73 |
+
|
| 74 |
+
Sitemap: {{SITE_URL}}/sitemap.xml
|
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 2 |
+
<!-- {{SITE_URL}} is substituted with the absolute base URL at request -->
|
| 3 |
+
<!-- time by app.py so the sitemap stays valid wherever it's served. -->
|
| 4 |
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
| 5 |
+
<url>
|
| 6 |
+
<loc>{{SITE_URL}}/</loc>
|
| 7 |
+
<changefreq>weekly</changefreq>
|
| 8 |
+
<priority>1.0</priority>
|
| 9 |
+
</url>
|
| 10 |
+
<url>
|
| 11 |
+
<loc>{{SITE_URL}}/sandbox-only</loc>
|
| 12 |
+
<changefreq>monthly</changefreq>
|
| 13 |
+
<priority>0.4</priority>
|
| 14 |
+
</url>
|
| 15 |
+
</urlset>
|
|
@@ -4,6 +4,11 @@
|
|
| 4 |
<meta charset="utf-8">
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
<title>Carbon · social banner</title>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 8 |
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 9 |
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;600;700;800&family=Inter:wght@300;400;500;600&display=swap">
|
|
@@ -22,16 +27,21 @@
|
|
| 22 |
/* edges of the social-media canvas read clearly — handy when you're */
|
| 23 |
/* about to crop a screenshot. */
|
| 24 |
/* ------------------------------------------------------------------ */
|
| 25 |
-
html, body { height: 100%; }
|
| 26 |
body {
|
| 27 |
background: #e8e5d6;
|
| 28 |
display: flex;
|
| 29 |
flex-direction: column;
|
| 30 |
align-items: center;
|
| 31 |
-
justify-content:
|
| 32 |
gap: 28px;
|
| 33 |
-
padding
|
| 34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
}
|
| 36 |
|
| 37 |
/* The social-banner-stage IS the social-media canvas: a fixed width
|
|
@@ -165,6 +175,147 @@
|
|
| 165 |
body { background: white; padding: 0; }
|
| 166 |
.sb-switcher { display: none; }
|
| 167 |
.social-banner-stage { transform: none !important; box-shadow: none; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 168 |
}
|
| 169 |
</style>
|
| 170 |
</head>
|
|
@@ -179,10 +330,14 @@
|
|
| 179 |
<div class="banner-inner">
|
| 180 |
<div class="banner-left">
|
| 181 |
|
| 182 |
-
<!-- Identity strip —
|
| 183 |
-
|
| 184 |
-
|
|
|
|
| 185 |
<div class="banner-identity">
|
|
|
|
|
|
|
|
|
|
| 186 |
<div class="banner-breadcrumb">
|
| 187 |
<div class="banner-title">CARBON</div>
|
| 188 |
<div class="banner-path">huggingfacebio/carbon-3b</div>
|
|
@@ -223,6 +378,42 @@
|
|
| 223 |
<span class="sb-switcher__dim" id="sb-scale-readout">100%</span>
|
| 224 |
</div>
|
| 225 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 226 |
<!-- Helix animation. Same script as the main demo — it queries
|
| 227 |
.carbon-banner + .cb-helix-canvas, both of which exist here. -->
|
| 228 |
<script src="/assets/js/banner.js"></script>
|
|
@@ -243,12 +434,16 @@
|
|
| 243 |
const stage = document.getElementById("sb-stage");
|
| 244 |
const readout = document.getElementById("sb-scale-readout");
|
| 245 |
const buttons = document.querySelectorAll(".sb-switcher__btn");
|
|
|
|
| 246 |
|
| 247 |
-
//
|
| 248 |
-
// (height of the row + body padding + gap). Kept conservative so
|
| 249 |
-
// the banner always has clear margin around it.
|
| 250 |
-
const CHROME_V = 160;
|
| 251 |
const CHROME_H = 80;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 252 |
|
| 253 |
function fitStage() {
|
| 254 |
const w = parseFloat(getComputedStyle(stage).getPropertyValue("--sb-w"));
|
|
@@ -258,6 +453,21 @@
|
|
| 258 |
const scale = Math.min(1, availW / w, availH / h);
|
| 259 |
stage.style.setProperty("--sb-scale", scale.toFixed(4));
|
| 260 |
readout.textContent = Math.round(scale * 100) + "%";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 261 |
}
|
| 262 |
|
| 263 |
function setFormat(btn) {
|
|
@@ -292,6 +502,29 @@
|
|
| 292 |
|
| 293 |
fitStage();
|
| 294 |
window.addEventListener("resize", fitStage);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 295 |
})();
|
| 296 |
</script>
|
| 297 |
|
|
|
|
| 4 |
<meta charset="utf-8">
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
<title>Carbon · social banner</title>
|
| 7 |
+
<!-- Internal screenshot tool — keep it out of search results and AI -->
|
| 8 |
+
<!-- training crawls. The canonical page is demo.html (served at /). -->
|
| 9 |
+
<meta name="robots" content="noindex, nofollow">
|
| 10 |
+
<link rel="icon" type="image/svg+xml" href="/img/logo.svg">
|
| 11 |
+
<link rel="icon" type="image/png" href="/img/logo.png">
|
| 12 |
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 13 |
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 14 |
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;600;700;800&family=Inter:wght@300;400;500;600&display=swap">
|
|
|
|
| 27 |
/* edges of the social-media canvas read clearly — handy when you're */
|
| 28 |
/* about to crop a screenshot. */
|
| 29 |
/* ------------------------------------------------------------------ */
|
| 30 |
+
html, body { min-height: 100%; }
|
| 31 |
body {
|
| 32 |
background: #e8e5d6;
|
| 33 |
display: flex;
|
| 34 |
flex-direction: column;
|
| 35 |
align-items: center;
|
| 36 |
+
justify-content: flex-start;
|
| 37 |
gap: 28px;
|
| 38 |
+
/* Top padding sized so the banner stage sits roughly where it used
|
| 39 |
+
to (centred-ish in a 1080p window) while leaving room for the
|
| 40 |
+
logo contact-sheet below without forcing a scrollbar on common
|
| 41 |
+
screens. Falls back to scroll when there's genuinely more
|
| 42 |
+
content than fits. */
|
| 43 |
+
padding: clamp(28px, 6vh, 80px) 24px 80px;
|
| 44 |
+
overflow-x: hidden;
|
| 45 |
}
|
| 46 |
|
| 47 |
/* The social-banner-stage IS the social-media canvas: a fixed width
|
|
|
|
| 175 |
body { background: white; padding: 0; }
|
| 176 |
.sb-switcher { display: none; }
|
| 177 |
.social-banner-stage { transform: none !important; box-shadow: none; }
|
| 178 |
+
.sb-logos { page-break-before: always; }
|
| 179 |
+
}
|
| 180 |
+
|
| 181 |
+
/* ------------------------------------------------------------------ */
|
| 182 |
+
/* Logo showcase. */
|
| 183 |
+
/* Sits below the banner stage so the same page doubles as a brand */
|
| 184 |
+
/* contact-sheet: the square mark, the square lockup with wordmark, */
|
| 185 |
+
/* and the wide rectangular lockup, each painted at its native pixel */
|
| 186 |
+
/* size on a paper card. Screenshot one tile and you have the asset */
|
| 187 |
+
/* at the exact dimensions of the source SVG, ready to drop into a */
|
| 188 |
+
/* deck or a README without any re-export step. */
|
| 189 |
+
/* ------------------------------------------------------------------ */
|
| 190 |
+
.sb-section-label {
|
| 191 |
+
font-family: "JetBrains Mono", ui-monospace, monospace;
|
| 192 |
+
font-size: 11px;
|
| 193 |
+
letter-spacing: 0.18em;
|
| 194 |
+
text-transform: uppercase;
|
| 195 |
+
color: #6f6d65;
|
| 196 |
+
margin-top: 24px;
|
| 197 |
+
/* Hairline tick under the label, matching the section dividers used
|
| 198 |
+
on demo.html so the chrome reads as part of the same family. */
|
| 199 |
+
border-bottom: 1px solid #d6d3c4;
|
| 200 |
+
padding-bottom: 6px;
|
| 201 |
+
width: 100%;
|
| 202 |
+
max-width: 1100px;
|
| 203 |
+
display: flex;
|
| 204 |
+
justify-content: space-between;
|
| 205 |
+
align-items: baseline;
|
| 206 |
+
}
|
| 207 |
+
.sb-section-label__hint {
|
| 208 |
+
color: #b0ada0;
|
| 209 |
+
text-transform: none;
|
| 210 |
+
letter-spacing: 0.06em;
|
| 211 |
+
font-size: 10px;
|
| 212 |
+
}
|
| 213 |
+
|
| 214 |
+
.sb-logos {
|
| 215 |
+
display: flex;
|
| 216 |
+
flex-wrap: wrap;
|
| 217 |
+
align-items: flex-end;
|
| 218 |
+
justify-content: center;
|
| 219 |
+
gap: 24px;
|
| 220 |
+
/* Auto-scale row when the viewport is too narrow for both stages
|
| 221 |
+
side-by-side, mirroring the auto-fit behaviour the banner stage
|
| 222 |
+
already does for itself (see fitStage in the script below). The
|
| 223 |
+
JS sets --sb-logo-scale on this wrapper. */
|
| 224 |
+
transform: scale(var(--sb-logo-scale, 1));
|
| 225 |
+
transform-origin: center top;
|
| 226 |
+
}
|
| 227 |
+
.sb-logo-card {
|
| 228 |
+
background: #f7f5ee;
|
| 229 |
+
box-shadow:
|
| 230 |
+
0 1px 0 #cfcdbf inset,
|
| 231 |
+
0 14px 28px -18px rgba(31, 31, 29, 0.22),
|
| 232 |
+
0 6px 14px -10px rgba(31, 31, 29, 0.14);
|
| 233 |
+
display: flex;
|
| 234 |
+
flex-direction: column;
|
| 235 |
+
flex-shrink: 0;
|
| 236 |
+
}
|
| 237 |
+
/* The .sb-logo-stage IS the export canvas: width × height pinned to the
|
| 238 |
+
SVG's native viewBox in pixels so a screenshot of the stage matches
|
| 239 |
+
the source 1:1. The inner <img> fills the stage. */
|
| 240 |
+
.sb-logo-stage {
|
| 241 |
+
--w: 230px;
|
| 242 |
+
--h: 230px;
|
| 243 |
+
width: var(--w);
|
| 244 |
+
height: var(--h);
|
| 245 |
+
box-shadow: inset 0 0 0 1px #cfcdbf;
|
| 246 |
+
display: flex;
|
| 247 |
+
align-items: center;
|
| 248 |
+
justify-content: center;
|
| 249 |
+
background: #f7f5ee;
|
| 250 |
+
}
|
| 251 |
+
.sb-logo-stage img {
|
| 252 |
+
width: 100%;
|
| 253 |
+
height: 100%;
|
| 254 |
+
display: block;
|
| 255 |
+
object-fit: contain;
|
| 256 |
+
}
|
| 257 |
+
/* Per-variant sizes, sourced from each SVG's viewBox so the stage
|
| 258 |
+
matches the asset 1:1 on screen. */
|
| 259 |
+
.sb-logo-stage--square { --w: 230px; --h: 230px; }
|
| 260 |
+
.sb-logo-stage--rectangle { --w: 487px; --h: 230px; }
|
| 261 |
+
|
| 262 |
+
.sb-logo-meta {
|
| 263 |
+
font-family: "JetBrains Mono", ui-monospace, monospace;
|
| 264 |
+
font-size: 10px;
|
| 265 |
+
letter-spacing: 0.12em;
|
| 266 |
+
text-transform: uppercase;
|
| 267 |
+
color: #6f6d65;
|
| 268 |
+
padding: 10px 12px 12px;
|
| 269 |
+
display: flex;
|
| 270 |
+
justify-content: space-between;
|
| 271 |
+
align-items: baseline;
|
| 272 |
+
gap: 12px;
|
| 273 |
+
border-top: 1px solid #cfcdbf;
|
| 274 |
+
background: #fbf9f2;
|
| 275 |
+
/* Constrain the row to the stage width so the long filename has
|
| 276 |
+
to truncate (with --name min-width:0) instead of pushing the
|
| 277 |
+
dim+copy chips off the right edge of the card. */
|
| 278 |
+
min-width: 0;
|
| 279 |
+
}
|
| 280 |
+
.sb-logo-meta__name {
|
| 281 |
+
color: #1f1f1d;
|
| 282 |
+
font-weight: 500;
|
| 283 |
+
/* Flex item with min-width:0 so the JetBrains Mono filename can
|
| 284 |
+
shrink and ellipsize instead of forcing the meta row wider than
|
| 285 |
+
its stage (most visible on the square tile, whose 230px width
|
| 286 |
+
is barely enough for the full "logo-black-square.svg"). */
|
| 287 |
+
min-width: 0;
|
| 288 |
+
flex: 1 1 auto;
|
| 289 |
+
overflow: hidden;
|
| 290 |
+
text-overflow: ellipsis;
|
| 291 |
+
white-space: nowrap;
|
| 292 |
+
}
|
| 293 |
+
/* Discreet "copy path" affordance so the SVG file name can be grabbed
|
| 294 |
+
without leaving the page. The button replaces itself with a "copied"
|
| 295 |
+
pill for ~1s on success. */
|
| 296 |
+
.sb-logo-meta__copy {
|
| 297 |
+
appearance: none;
|
| 298 |
+
border: 1px solid #cfcdbf;
|
| 299 |
+
background: #fff;
|
| 300 |
+
color: #6f6d65;
|
| 301 |
+
font-family: inherit;
|
| 302 |
+
font-size: 9px;
|
| 303 |
+
letter-spacing: 0.16em;
|
| 304 |
+
text-transform: uppercase;
|
| 305 |
+
padding: 3px 7px;
|
| 306 |
+
cursor: pointer;
|
| 307 |
+
transition: background 0.15s, border-color 0.15s, color 0.15s;
|
| 308 |
+
flex-shrink: 0;
|
| 309 |
+
}
|
| 310 |
+
.sb-logo-meta__copy:hover {
|
| 311 |
+
background: #1f1f1d;
|
| 312 |
+
border-color: #1f1f1d;
|
| 313 |
+
color: #f7f5ee;
|
| 314 |
+
}
|
| 315 |
+
.sb-logo-meta__copy.is-copied {
|
| 316 |
+
background: #317f3f;
|
| 317 |
+
border-color: #317f3f;
|
| 318 |
+
color: #f7f5ee;
|
| 319 |
}
|
| 320 |
</style>
|
| 321 |
</head>
|
|
|
|
| 330 |
<div class="banner-inner">
|
| 331 |
<div class="banner-left">
|
| 332 |
|
| 333 |
+
<!-- Identity strip — square brand mark (img/logo.svg, the latest
|
| 334 |
+
black-hex stamp) sitting flush with the model-card breadcrumb,
|
| 335 |
+
same composition as the hero on demo.html. The SVG ships with
|
| 336 |
+
its own black frame so .logo-card stays chrome-free here too. -->
|
| 337 |
<div class="banner-identity">
|
| 338 |
+
<a class="logo-card" href="#" aria-label="Carbon, go to top">
|
| 339 |
+
<img class="logo-img" src="/img/logo.svg" alt="" width="44" height="44">
|
| 340 |
+
</a>
|
| 341 |
<div class="banner-breadcrumb">
|
| 342 |
<div class="banner-title">CARBON</div>
|
| 343 |
<div class="banner-path">huggingfacebio/carbon-3b</div>
|
|
|
|
| 378 |
<span class="sb-switcher__dim" id="sb-scale-readout">100%</span>
|
| 379 |
</div>
|
| 380 |
|
| 381 |
+
<!-- ------------------------------------------------------------------ -->
|
| 382 |
+
<!-- Logo contact-sheet. -->
|
| 383 |
+
<!-- Two tiles, each a 1:1 export stage for one of the SVG lockups -->
|
| 384 |
+
<!-- shipped in img/. Sized to match the source viewBox so screenshots -->
|
| 385 |
+
<!-- come out at exactly the right pixel dimensions. Order: square -->
|
| 386 |
+
<!-- lockup → wide rectangular lockup. -->
|
| 387 |
+
<!-- ------------------------------------------------------------------ -->
|
| 388 |
+
<div class="sb-section-label">
|
| 389 |
+
<span>logo · brand marks</span>
|
| 390 |
+
<span class="sb-section-label__hint">img/logo-black-*.svg · screenshot at 100% for 1:1 export</span>
|
| 391 |
+
</div>
|
| 392 |
+
|
| 393 |
+
<div class="sb-logos" id="sb-logos">
|
| 394 |
+
|
| 395 |
+
<figure class="sb-logo-card">
|
| 396 |
+
<div class="sb-logo-stage sb-logo-stage--square">
|
| 397 |
+
<img src="/img/logo-black-square.svg" alt="Carbon square lockup, symbol over wordmark">
|
| 398 |
+
</div>
|
| 399 |
+
<figcaption class="sb-logo-meta">
|
| 400 |
+
<span class="sb-logo-meta__name" title="logo-black-square.svg">logo-black-square.svg</span>
|
| 401 |
+
<button type="button" class="sb-logo-meta__copy" data-copy="/img/logo-black-square.svg">copy</button>
|
| 402 |
+
</figcaption>
|
| 403 |
+
</figure>
|
| 404 |
+
|
| 405 |
+
<figure class="sb-logo-card">
|
| 406 |
+
<div class="sb-logo-stage sb-logo-stage--rectangle">
|
| 407 |
+
<img src="/img/logo-black-rectangle.svg" alt="Carbon horizontal lockup, symbol next to wordmark">
|
| 408 |
+
</div>
|
| 409 |
+
<figcaption class="sb-logo-meta">
|
| 410 |
+
<span class="sb-logo-meta__name" title="logo-black-rectangle.svg">logo-black-rectangle.svg</span>
|
| 411 |
+
<button type="button" class="sb-logo-meta__copy" data-copy="/img/logo-black-rectangle.svg">copy</button>
|
| 412 |
+
</figcaption>
|
| 413 |
+
</figure>
|
| 414 |
+
|
| 415 |
+
</div>
|
| 416 |
+
|
| 417 |
<!-- Helix animation. Same script as the main demo — it queries
|
| 418 |
.carbon-banner + .cb-helix-canvas, both of which exist here. -->
|
| 419 |
<script src="/assets/js/banner.js"></script>
|
|
|
|
| 434 |
const stage = document.getElementById("sb-stage");
|
| 435 |
const readout = document.getElementById("sb-scale-readout");
|
| 436 |
const buttons = document.querySelectorAll(".sb-switcher__btn");
|
| 437 |
+
const logos = document.getElementById("sb-logos");
|
| 438 |
|
| 439 |
+
// Horizontal breathing room (body padding both sides).
|
|
|
|
|
|
|
|
|
|
| 440 |
const CHROME_H = 80;
|
| 441 |
+
// Vertical breathing room reserved for the format switcher row +
|
| 442 |
+
// body padding + the section label above the logo contact-sheet.
|
| 443 |
+
// The fit-to-viewport cap aims at making the banner sit comfortably
|
| 444 |
+
// above the logos without forcing a scrollbar on a 1080p screen,
|
| 445 |
+
// while still letting tall windows render at native 100%.
|
| 446 |
+
const CHROME_V = 160;
|
| 447 |
|
| 448 |
function fitStage() {
|
| 449 |
const w = parseFloat(getComputedStyle(stage).getPropertyValue("--sb-w"));
|
|
|
|
| 453 |
const scale = Math.min(1, availW / w, availH / h);
|
| 454 |
stage.style.setProperty("--sb-scale", scale.toFixed(4));
|
| 455 |
readout.textContent = Math.round(scale * 100) + "%";
|
| 456 |
+
fitLogos();
|
| 457 |
+
}
|
| 458 |
+
|
| 459 |
+
// Scale the logo contact-sheet down when the viewport is narrower
|
| 460 |
+
// than the row at 100%. The three tiles together are roughly
|
| 461 |
+
// 230 + 230 + 487 + (gaps) ≈ 1015px wide; on a 1024-ish window we
|
| 462 |
+
// want them to shrink to fit so they sit centred under the banner
|
| 463 |
+
// instead of overflowing the page horizontally.
|
| 464 |
+
function fitLogos() {
|
| 465 |
+
if (!logos) return;
|
| 466 |
+
logos.style.setProperty("--sb-logo-scale", "1");
|
| 467 |
+
const natural = logos.scrollWidth;
|
| 468 |
+
const avail = Math.max(200, window.innerWidth - CHROME_H);
|
| 469 |
+
const s = Math.min(1, avail / natural);
|
| 470 |
+
logos.style.setProperty("--sb-logo-scale", s.toFixed(4));
|
| 471 |
}
|
| 472 |
|
| 473 |
function setFormat(btn) {
|
|
|
|
| 502 |
|
| 503 |
fitStage();
|
| 504 |
window.addEventListener("resize", fitStage);
|
| 505 |
+
|
| 506 |
+
// Wire up the discreet "copy" buttons under each logo tile so the
|
| 507 |
+
// asset path can be grabbed in one click. Falls back gracefully on
|
| 508 |
+
// browsers / contexts where the async clipboard API is unavailable
|
| 509 |
+
// (e.g. http:// origins) by showing a "failed" pill briefly.
|
| 510 |
+
document.querySelectorAll(".sb-logo-meta__copy").forEach(btn => {
|
| 511 |
+
btn.addEventListener("click", async () => {
|
| 512 |
+
const value = btn.dataset.copy || "";
|
| 513 |
+
if (!value) return;
|
| 514 |
+
const original = btn.textContent;
|
| 515 |
+
try {
|
| 516 |
+
await navigator.clipboard.writeText(value);
|
| 517 |
+
btn.textContent = "copied";
|
| 518 |
+
btn.classList.add("is-copied");
|
| 519 |
+
} catch {
|
| 520 |
+
btn.textContent = "failed";
|
| 521 |
+
}
|
| 522 |
+
setTimeout(() => {
|
| 523 |
+
btn.textContent = original;
|
| 524 |
+
btn.classList.remove("is-copied");
|
| 525 |
+
}, 1100);
|
| 526 |
+
});
|
| 527 |
+
});
|
| 528 |
})();
|
| 529 |
</script>
|
| 530 |
|