Catalog npm
Back to packageRELEASE DETAILS

0.7.3

npm

8bit-nes

NES 8-bit retro-modern design system. Design tokens + class-based CSS components + light-DOM web components. Cross-framework: HTML, Vue 3, Nuxt, React.

8bitcssdark-themedesign-systemdesign-tokensnesnuxtreactretrovueweb-components
Published28 Jul 2026
Direct dependencies2
Transitive dependenciesNot calculated

README

Current package documentation

8-BIT NES — component system

NES arcade CRT, dark-only, modern-crisp. Cross-framework by design.

Install

Reusable across every project in the studio — install it into any repo, no build step.

# from npm — always the current release
pnpm add 8bit-nes

# or straight from GitHub (a tag is a valid spec too)
pnpm add github:TuTranMVP/8bit-components#v0.16.0
// once, at app entry:
import "8bit-nes/all.css";   // tokens + base + components
import "8bit-nes";           // registers <nes-*> web components

Or granular: 8bit-nes/tokens.css, 8bit-nes/base.css, 8bit-nes/components.css, 8bit-nes/elements.js. The exports map keeps every entry addressable; sideEffects is declared so bundlers keep the CSS and the custom-element registration.

Zero build, zero runtime deps. It ships plain CSS + one ES module, so it drops into a Vite/Nuxt/Next app, a plain HTML page, or another design-system package all the same.

CDN / no build

No bundler? Link the minified, single-file build — the three @imports are inlined, so it's one request instead of four. This is the whole recommended <head>, tuned for a cold visit (copy it verbatim — every line earns its place):

<!-- 1. one origin for every byte → one DNS + TLS handshake, warmed early -->
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin>

<!-- 2. fonts, at the exact URLs all.min.css resolves url() to → fetched once, in parallel
        with the stylesheet instead of after it -->
<link rel="preload" as="font" type="font/woff2" crossorigin
  href="https://cdn.jsdelivr.net/npm/8bit-nes@0.16.0/fonts/nes-sans-var.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin
  href="https://cdn.jsdelivr.net/npm/8bit-nes@0.16.0/fonts/nes-mono-400.woff2">

<!-- 3. the system: pinned version + byte-pinned integrity -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/8bit-nes@0.16.0/all.min.css"
  integrity="sha384-bnFVHVR0cb4DTlgB65iWy3avLsXlwZAz9CzgSZW8/U/+XnBxbko+ZgIiSs2kkSdi"
  crossorigin="anonymous">
<script type="module" src="https://cdn.jsdelivr.net/npm/8bit-nes@0.16.0/elements.min.js"
  integrity="sha384-SfWC08i1nvFLoCQd9rUoNGTjMCXhZ97Cl7Hfx4EDrqj3Mkieuf/+q0Qwi6jeVItg"
  crossorigin="anonymous"></script>

Why it's shaped like that:

  • Pin the version. A pinned @x.y.z URL is immutable — jsDelivr serves it max-age=31536000, immutable, so a repeat visit costs zero requests. A bare /npm/8bit-nes/all.min.css is a mutable alias: it revalidates every 7 days and costs a redirect hop on the first hit. Bump the number to upgrade; nothing silently changes underneath a shipped page. A @0.7 range is the middle ground (patches auto-adopt, still cached a week).

  • Preload only the two fonts above the fold. nes-sans-var.woff2 (body) and nes-mono-400.woff2 (chrome/labels). The 700-weight mono is left to font-display: swap. The preload href must match the CSS-resolved URL character for character — same version, same path — or the browser downloads each font twice.

  • integrity + crossorigin. A pinned URL trusts the CDN not to swap the file; a hash doesn't have to. Digests for every shipped asset (both minified entries, the granular CSS, the fonts, the RAG artifacts) live in sri.json, generated from the build by scripts/gen-sri.mjs and published at /sri.json — read it, don't retype it:

    const sri = await (await fetch("https://tutranmvp.github.io/8bit-components/sri.json")).json();
    sri.files["all.min.css"]; // "sha384-…"  · sri.cdn is the matching pinned base URL
    

    The hashes above belong to the version pinned above. They change with every release — regenerate (pnpm gen:sri) or re-fetch sri.json when you bump, or the browser will (correctly) refuse the file.

  • Fonts don't need a separate request budget. The whole system is 4 files: 75 kB CSS + 79 kB ESM + 2 woff2 (both subset with unicode-range), all Brotli'd by the CDN.

<script type="module"> is deferred by definition, so it never blocks the parser — the custom elements register on their own and upgrade whatever <nes-*> markup is already in the DOM. Nothing to call, no wrapper.

Copy-paste starter, already wired exactly like the above: examples/cdn-starter.html — also live on the docs site at /examples/cdn-starter.html.

unpkg instead? Same paths (https://unpkg.com/8bit-nes@0.16.0/all.min.css) and the same SRI digests — it's the identical npm tarball. Pick one origin per page, though: two CDNs means two handshakes for no benefit.

For AI agents (RAG-ready)

This library is built to be consumed by AI coding agents in other repos — so they can retrieve the official API and generate correct 8-BIT NES markup. Canonical, machine-readable docs follow the llms.txt convention and are generated from the docs source (never drift):

ArtifactURLUse
llms.txthttps://tutranmvp.github.io/8bit-components/llms.txtdiscovery index (title, install, every component + deep link)
llms-full.txt.../llms-full.txtcomplete flat-text reference to ingest/chunk for RAG (contract, rules, verified examples, all components)
components.json.../components.jsonstructured manifest — exact { id, name, category, selector, kind, description, docs } per component

They're also shipped inside the npm package, so an agent working in a consuming repo can read them straight from node_modules:

import manifest from "8bit-nes/components.json" with { type: "json" };
// or read node_modules/8bit-nes/llms-full.txt

pnpm gen:llms regenerates all three from docs.js; CI fails if the committed copies are stale.

Size & performance

Filerawgzipnotes
all.min.css~33 kB~7 kBtokens + base + components, bundled & minified
elements.min.js~9 kB~4 kBall six <nes-*> + helpers, minified ESM
  • No-build / CDN → the .min files above (fewest bytes, one request each).
  • Bundler (Vite/Nuxt/Next) → import the sources (8bit-nes, 8bit-nes/all.css); your pipeline minifies, and JS tree-shakes the named helpers you don't use (toast, grantXP, highlightCode, …). The <nes-*> registration is a deliberate side effect (sideEffects set), so importing the module always wires the components.
  • CSS is one layer set; drop what you don't need at the file level via the granular imports.
  • pnpm build (esbuild) regenerates the .min files; CI fails if the committed ones are stale.

Two checks need a browser, so they sit outside pnpm check (which stays hermetic for CI):

  • pnpm check:viewport — both ends of the breakpoint ladder on real viewports over CDP: a 390×844 phone with touch (every control hit-tested off centre, the 24px floor, the iOS 16px entry floor) and a large desktop (the type step, the widened container, prose still measured, the rail still beside the text).
  • pnpm check:ui — every fixture page in a real browser: the stateful components (ui-check), the scales (scale-check), and the upstream spec items (spec-check). It fails if a page reports a FAIL, throws, or never reports at all.

CHROME=/path/to/chrome points them at your binary.

Release flow (maintainer)

  1. Bump version in package.json → commit.
  2. git tag vX.Y.Z && git push --follow-tags.
  3. GitHub Action release.yml gates on pnpm check, verifies tag == version, publishes to npm with provenance.

Files (ROI order — stop anywhere, still useful)

FileLayerContainsDepends on
tokens.csssource of truth:root vars, 3 @font-face, @layer order—
base.cssreset + primitivesreset, focus→gold, reduced-motion, .pixel-box (notch), elevation, accent mapper, motiontokens
components.cssstateless recipesElement/Form/Feedback/Nav/Overlay/Data recipes (see catalog below)tokens, base
elements.jsstatefulapp: <nes-quiz> <nes-hud> <nes-collapsible> <nes-sound> <nes-tabs> <nes-code>; form: <nes-form> <nes-number> <nes-rating> <nes-tags> <nes-pin> <nes-file> <nes-listbox> <nes-input-menu> <nes-select-menu>; data: <nes-tree>; chat: <nes-chat-prompt> <nes-chat-messages>; editor: <nes-editor>; typography: <nes-code-tree>; visualize: <nes-mermaid> <nes-walkthrough> <nes-zoom> <nes-annotate> <nes-compare> + store/bleep/grantXP/toast/enableMermaidtokens, components
icons.jspixel iconstree-shakeable <svg>-string exports + icon() helper; <nes-icon> renders by name—
demo.htmlgallery + testevery component wired togetherall
docs.html + docs.jsdocumentation siteNuxt-UI-style sidebar + per-component pages (Usage / preview / API / a11y)all

80% of the value is CSS. elements.js is only for things that hold state.

Component catalog

CategoryComponents
ElementButton · Badge · Chip · Card · Avatar · Kbd · Separator · Icon (<nes-icon> / 8bit-nes/icons) · Toolbar (.toolbar — a row of actions that scrolls on a phone instead of reflowing under your thumb) · Split view (<nes-split> — two panes, one divider you can drag, arrow or double-click; role="separator", 44px hit area on touch)
FormInput · Textarea · Select · Checkbox · CheckboxGroup · Radio · RadioGroup · Switch · Field · Form (<nes-form>) · Slider (.range) · Segmented control · Switcher (<nes-switcher> — ◀/▶ option cycler) · InputNumber (<nes-number>) · InputRating (<nes-rating>) · InputTags (<nes-tags>) · PinInput (<nes-pin>) · ColorPicker · InputDate · InputTime · FileUpload (<nes-file>) · Listbox (<nes-listbox>) · InputMenu (<nes-input-menu>) · SelectMenu (<nes-select-menu>)
FeedbackAlert (.callout) · Progress (.pbar) · Skeleton · Toast (toast() — text-safe by default, pauses while you read it, swipe-to-dismiss, UNDO action, crit interrupts) · Spinner · Meter · Empty state · Banner
NavigationTabs (<nes-tabs>) · Breadcrumb · Pagination · Steps · Nav list · Map of Content (<nes-toc> — the live "on this page" index: builds itself from your headings, scroll-spy, mobile-first collapsible bar naming the current section → sticky rail when there's room; renders as the .outline recipe)
OverlayModal (<dialog>) · Dropdown (<details>) · Tooltip ([data-tip]) · Drawer (<dialog>) · Popover (<nes-popover> — an anchored panel in the top layer, so no ancestor's overflow can clip it; native popover API for Esc + light dismiss) · Confirm (confirmDialog() → Promise<boolean> — destructive confirm on <dialog>.showModal(), focus starts on Cancel)
DataTable · Code block · Accordion (<nes-collapsible>) · Stat · Rating · Description list · Timeline · Prose · Tree (<nes-tree>)
Chat (AI)Chat (.chat) · ChatMessages (<nes-chat-messages>) · ChatMessage (.msg) · ChatPrompt (<nes-chat-prompt>) · ChatPromptSubmit (.chat-submit) · Composer (.composer + .attach — ChatGPT/Claude-Code-style prompt box: attachments, toolbar, model picker, send) · Suggestions (.suggest — starters / follow-ups) · Citations (.cite + .sources — grounded answers) · ChatReasoning · ChatTool · ChatShimmer · ChatPalette
Agents (AI)Agent (.agent) · Context usage (.usage) · Trace (.trace) · Feedback bar (.feedback) — AI-First WebUI primitives: a multi-agent status roster, a context/token-budget bar, an orchestration/reasoning trace (zero-JS <details>), and the human-in-the-loop feedback footer. Pure CSS recipes an agent can emit straight as HTML; one shared data-state vocabulary (queued/thinking/running/done/error)
Editor (AI)Editor (<nes-editor>) · EditorToolbar · EditorSuggestionMenu (/ — incl. AI commands translate/improve/continue/fix/summarize) · EditorMentionMenu (@) · EditorEmojiMenu (:) · EditorDragHandle — VSCode-style Tab ghost + bilingual mode (lang/target-lang: write one language, Tab out the other) + word-count (stats) + AI hook, contenteditable, zero-dep
Typography (MDC)CodePreview (.code-preview) · CodeGroup (<nes-tabs class="code-group">) · CodeCollapse (<details class="code-collapse">) · CodeTree (<nes-code-tree>) · CardGroup (.card-group) · FieldGroup (.field-group) · Prompt (.prompt) · Terminal (.terminal) · Diff (.diff) · Tasklist (.tasklist) · code filename header (<nes-code file>) — render an AI agent's streamed Markdown/MDC output as on-brand HTML (the render target, not a parser)
VisualizeMermaid (<nes-mermaid>) · Walkthrough (<nes-walkthrough>, autoplay) · Lens (<nes-tabs class="lens">) · Zoom (<nes-zoom>) · Annotate (<nes-annotate>) · Compare (<nes-compare>) · Legend (.legend) — render an AI agent's Mermaid diagrams on-brand + teach a concept step-by-step, then explore (pan/zoom), point at parts (hotspots), and compare A/B. Mermaid never bundled (BYO / lazy via enableMermaid); everything else is zero-dep pointer + CSS
Second BrainGraph (<nes-graph> — knowledge graph: force-laid-out nodes + edges, click a node to light its neighbourhood; wrap in <nes-zoom> to pan/zoom) · Note card (.note) · Backlinks (.backlinks) · Wiki-link (.wikilink, .new = unresolved) · Tag (.tag) · Properties (.props) · Outline (.outline) · Activity heatmap (.heatmap) · Board (.board — Kanban) · Command palette (.palette) · Search result (.result) · Note embed (.embed — transclusion) · Maturity (.maturity — 🌱🌿🌳) · Tag cloud (.tag-cloud) · Concept card (.concept) · Note stats (.note-stats) — Obsidian-style note/knowledge UI: vault cards, [[links]], #tags, backlinks, frontmatter, kanban, quick-switcher, transclusion, digital-garden maturity, and a deterministic 0-dep knowledge graph. All stateless recipes bar the graph — an agent can emit them as HTML
OpenCode (vibe coding)Workbench (.workbench — 3-pane cloud-IDE shell: rail / main / side, stacks on mobile) · Repo bar (.repobar) · File tabs (.filetabs) · Status line (.statusline) · Sandbox (.sandbox — cloud dev container) · Plan (.plan — the agent's todo with live per-step state) · Permission (.perm — allow-once / always / deny gate, command shown verbatim) · Diff stat (.diffstat) · File change (.filechange — A/M/D/R) · Hunk (.hunk — reviewable slice, zero-JS <details>) · DiffView (<nes-diff> — unified diff → on-brand markup + nes:diff totals) · Checks (.checks) · Run bar (.runbar) · Logs (<nes-logs> — tail-following, ring-buffered, level-filtered stream) · App preview (<nes-preview> — framed iframe, URL bar, 375/768/full) · Stack trace (.stacktrace — your frames lit, vendor dimmed) · Checkpoints (.ckpt — rewind timeline) · Deploy (.deploy) — the WebUI shell around an agent that writes code, for Vibe-Coding tools on web/cloud. Each recipe owns one responsibility and composes with .diff / .terminal / .tree / .trace / .btn / .input / .segment instead of re-implementing them; three pieces hold state, the rest is HTML an agent can emit

Run the docs site locally with pnpm demo, then open /docs.html.

The contract

Everything reads from :root. Change the look in tokens.css, never in a component. One component = one accent: set data-accent="blue|gold|cyan|purple|good|warn|crit" on the component and its fill, dots, bars and borders follow via --accent / --accent-d. It applies to the element you put it on — a recipe declares its own --accent, so it keeps that rather than inheriting a wrapper's. Accent a row of components by setting the attribute on each.

The grid law. Space lands on 4px steps (a --sp-* rung; --sp-hair 2px is the one sub-grid exception), size lands on 2px steps, every type rung is an integer px (9 · 11 · 12 · 14 · 16 · 17 · 26), weight is one of exactly three (--fw-regular 400 · --fw-medium 450 · --fw-bold 700 — the only stops the bundled faces ship), z-index comes from one --z-* ladder, and exactly three widths switch a layout, always mobile-first (min-width only — the base block is the phone) — --bp-sm 36rem, --bp-lg 56rem, --bp-xl 74rem. pnpm check fails the build on a value that drifts off either grid, on a breakpoint outside the ladder, and on max-width (which overlaps min-width at exactly the same width). Box padding has three roles you can override to retune density in one line — --pad-tight 4/8, --pad-snug 8/12, --pad-box 12/16 — and the app frame has --gutter, --chrome-h, --nav-w, --rail-w. Full table: Layout & rhythm.

Signature

The button is the one bold element — but by hard shadow (box-shadow: Npx Npx 0, zero blur) + press-in on :active, not a corner trick. Every surface, buttons included, is a square 90° corner (never a radius, never a chamfer), hard border, hard shadow. Full rationale in DESIGN.md.

Fonts (bundled, self-hosted)

  • fonts/nes-mono-400.woff2 / -700.woff2 — NES Mono: chrome, labels, numbers, code.
  • fonts/nes-sans-var.woff2 — NES Sans variable (wght 300–700): body, đọc tiếng Việt có dấu.

Weights & styles. NES Sans is variable so any weight 300–700 is real (regular 400, medium 500, bold 700 all interpolate). NES Mono ships 400 + 700 (crisp static faces — it's chrome/code, so no separate medium by design). Italic works for both: neither ships an italic face, so the browser synthesizes oblique — font-synthesis: style keeps the real weights crisp (no faux-bold) while allowing the slant, which costs 0 bytes vs a ~100 KB italic set. <b>/<strong> → 700, <i>/<em> → oblique.

Latin + Vietnamese subset (~171KB tổng), full diacritic coverage verified. License: fonts/LICENSE-FONTS.txt (SIL OFL 1.1). Zero-FOUT: preload 2 file critical — snippet trong comment đầu tokens.css.

Wire it up

Plain HTML

<link rel="stylesheet" href="tokens.css">
<link rel="stylesheet" href="base.css">
<link rel="stylesheet" href="components.css">
<script type="module" src="elements.js"></script>

Vue 3.3+ / 3.5 (Vite) — verified

1. Install: pnpm add 8bit-nes

2. Tell the Vue compiler that <nes-*> are custom elements (required, or Vue errors "failed to resolve component"):

// vite.config.ts
import vue from '@vitejs/plugin-vue'
export default {
  plugins: [vue({ template: { compilerOptions: { isCustomElement: (t) => t.startsWith('nes-') } } })],
}

3. Import the CSS + register the elements once at the app entry:

// src/main.ts
import '8bit-nes/all.css'   // tokens + base + components
import '8bit-nes'           // registers every <nes-*> (side-effect)

Vite auto-bundles the three woff2 fonts (the CSS references them with relative url()) — no font config.

4. Use classes + <nes-*> in any .vue. Custom events bubble as CustomEvent — read event.detail:

<template>
  <div data-size="lg" style="display:flex;gap:.5rem;align-items:center">
    <button class="btn" data-accent="cyan">Save</button>
    <input class="input" />
    <button class="btn icon" aria-label="Go"><nes-icon name="rocket" /></button>
  </div>
  <nes-form @nes:submit="e => console.log(e.detail)">    <!-- {data, form} -->
    <label class="field"><span class="label">Name</span><input class="input" name="name" required /></label>
    <button class="btn" type="submit">Submit</button>
  </nes-form>
</template>

No two-way v-model on <nes-*>; bind via @nes:change="v = $event.detail.value". Inside <nes-form> the controls keep a hidden <input name> and submit with zero wiring.

Nuxt 3 — customElements needs the browser, so register in a client plugin:

// nuxt.config.ts
export default defineNuxtConfig({
  css: ['8bit-nes/all.css'],
  vue: { compilerOptions: { isCustomElement: (t) => t.startsWith('nes-') } },
})
// plugins/8bit.client.ts
import '8bit-nes'

React 19

No wrapper needed — React 19 passes props and listens to custom-element events natively.

import './tokens.css'; import './base.css'; import './components.css'; import './elements.js';
<nes-hud ns="quest" per-level="150" max-xp="600" />
<nes-quiz xp={50} onnes:answer={e => console.log(e.detail.correct)} />

(React < 19: use a small ref wrapper for the nes:answer event.)

Web components API

<nes-sound></nes-sound>                     <!-- mute toggle, persists to localStorage -->

<nes-collapsible open accent="gold">
  <span slot="head">STAGE 1 · title</span>
  ...body...
</nes-collapsible>

<nes-hud ns="quest" per-level="400" max-xp="1600"></nes-hud>  <!-- listens on nes:xp bus -->

<nes-quiz xp="50">
  <script type="application/json">
  { "q":"...", "options":["A","B"], "answer":1, "explain":"..." }
  </script>
</nes-quiz>                                  <!-- correct → +XP flies into the HUD -->
<nes-tabs>                                  <!-- roving-focus tabs, arrow keys -->
  <section data-label="Install" selected>…</section>
  <section data-label="Usage">…</section>
</nes-tabs>

Form module

Native where it can be (Checkbox/Radio groups are a .control-group fieldset; ColorPicker is <input type="color" class="swatch">; Date/Time are themed native inputs). Stateful controls are <nes-*> that each keep a hidden <input name>, so they submit inside any form with zero wiring:

<nes-form>                                  <!-- native validation → inline errors → nes:submit -->
  <label class="field"><span class="label">Email <span class="req">*</span></span>
    <input class="input" type="email" name="email" required></label>
  <nes-tags name="labels" value="agent,retro"></nes-tags>       <!-- chip input -->
  <nes-pin length="6" name="otp" numeric></nes-pin>             <!-- OTP → nes:complete -->
  <nes-select-menu name="model" placeholder="Choose model…">    <!-- searchable single-select -->
    <script type="application/json">[{"value":"opus","label":"Opus 4.8"}]</script>
  </nes-select-menu>
  <button class="btn" type="submit">CREATE</button>
</nes-form>
<script type="module">
  document.querySelector("nes-form")
    .addEventListener("nes:submit", (e) => console.log(e.detail.data));  // {email, labels, otp, model}
</script>

Also: <nes-number> (stepper), <nes-rating> (star input), <nes-file> (drop zone), <nes-listbox>, <nes-input-menu> (free-text combobox). Custom events bubble: nes:change, nes:submit, nes:invalid, nes:complete.

JS helpers (named exports): store, bleep(seq), SFX, setMute/isMuted, grantXP(n, el), floatXP(el, text), toast(msg, { accent, timeout }).

Extend

New component → add a recipe in components.css, add a token in tokens.css if needed. Keep the Do/Don't: square 90° surfaces everywhere, buttons included (never a radius or chamfer), hard shadow not blur, smooth --ease easing (transform/opacity), one accent per block, dark text on solid accents, everything via token. Full guidance in DESIGN.md.

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Declared dependencies 2

Native requirements
2 direct targetsNot calculated transitive count
Package / targetRequirementRelationship
esbuild
Environment
{
  "local_name": "esbuild",
  "alias": false,
  "peer_metadata": null
}
0.28.1development
@biomejs/biome
Environment
{
  "local_name": "@biomejs/biome",
  "alias": false,
  "peer_metadata": null
}
^2.0.0development

Distribution files

1 collected
Distribution 1

Source distribution

Source file
Checksums from source
{
  "shasum": "cc9ca0e61fb30231ef827bc62da85d57d6f15663",
  "tarball": "https://registry.npmjs.org/8bit-nes/-/8bit-nes-0.7.3.tgz",
  "fileCount": 23,
  "integrity": "sha512-7++IQOFsXDyO+ef2ixqBL+pFtwqH55s62g0/+PxaEMqSM0NS5N23m+ulI3CBoYtY/t4OrI6/l9Xit9hU3ARBOw==",
  "signatures": [
    {
      "sig": "MEQCIDb0zJYw2ZBeTMNwjslV3O/wNEyYMCV74dNpXn6m32y4AiAaIP5G5gWq2NAgKMKe6OkML9KSx1+UyPi5uJ49J91RHg==",
      "keyid": "SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"
    }
  ],
  "attestations": {
    "url": "https://registry.npmjs.org/-/npm/v1/attestations/8bit-nes@0.7.3",
    "provenance": {
      "predicateType": "https://slsa.dev/provenance/v1"
    }
  },
  "unpackedSize": 888425
}

Repository

PENDING
tutranmvp/8bit-components

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 21:21 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package_version:a360ff9da245fa242bc8a2b93bc873d1f16ce8bdc6ed8216ef23b0fd3fbbd313

Other collected versions

0.16.031 Jul0.15.030 Jul0.14.029 Jul0.13.029 Jul0.12.029 Jul0.8.028 JulView all collected versions →