Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

v1 state

Back to all declarations

glyph

func(c uint8) string

glyph returns the stroke encoding for one character, or "" for anything unknown — an unknown character draws nothing rather than a box, because this markup lands inside a token that other people's software renders and a missing letter is better than a wrong one.

Open
OID
058c22…fb3a:3
glyph details

Inspect func

glyphW

untyped bigint

// grid width of one glyph

Value

(10 <untyped> bigint)

glyphH

untyped bigint

// grid height, top to bottom

Value

(14 <untyped> bigint)

glyphAd

untyped bigint

// advance: glyph width plus the gap to the next one

Value

(12 <untyped> bigint)

hexish

func(c uint8) int

hexish decodes one coordinate character. Digits are themselves; a..d carry 10..13, which is the only reason y can exceed nine in two characters.

Open
OID
058c22…fb3a:5
hexish details

Inspect func

MarkerText

func(s string, x int, y int, size int, colour string, weight int) string

MarkerText draws a line of text as stroked paths. \`size\` is the CAP HEIGHT in user units, not an em size: it is the height of a capital letter, which is the measurement anybody positioning this by eye is actually thinking in. \`x\` is the left edge and \`y\` is the TOP of the capitals, matching how the rest of this file positions things and unlike SVG's own text baseline, which is a trap when mixing the two. The jitter is what makes it read as a pen rather than a plotter. It is derived from the character and its position, so it is stable: the same string renders identically on every read, which matters because these cards are regenerated constantly and a letter that wobbled between reads would look like a rendering fault.

Open
OID
058c22…fb3a:6
MarkerText details

Inspect func

strokes

func(enc string, ox int, oy int, size int, idx int) string

strokes turns one glyph's encoding into path elements at a position.

Open
OID
058c22…fb3a:7
strokes details

Inspect func

wobble

func(seed int) int

wobble is a tiny deterministic offset in the range -1..1. Not random: the cards are regenerated on every read, and anything genuinely random would make the lettering shimmer.

Open
OID
058c22…fb3a:8
wobble details

Inspect func

MarkerWidth

func(s string, size int) int

MarkerWidth is what MarkerText will occupy, so a caller can centre it. Counts every character including the ones that draw nothing, because a space still advances.

Open
OID
058c22…fb3a:9
MarkerWidth details

Inspect func

MarkerCentred

func(s string, cx int, y int, size int, colour string, weight int) string

MarkerCentred draws text centred on cx, which is what almost every caller here wants and what the SVG text-anchor attribute would have done for them if a font had been available.

Open
OID
058c22…fb3a:10
MarkerCentred details

Inspect func

selfPath

string

selfPath is this realm's path without the chain domain, for links to its own gnoweb pages. Set at init, because inside a renderer call the realm context belongs to whoever asked, not to this realm.

Value

"/r/nym-mnsrehearsal001/nsview/v1"

ledgerArt

type

Value

v1.ledgerArt

RegisterWithLedger

func()

RegisterWithLedger hands the ledger this realm's renderer. Anyone may call it: it only ever registers THIS realm's own drawing, and the ledger refuses unless this realm is the one it has approved.

Open
OID
058c22…fb3a:14
RegisterWithLedger details

Inspect func

tokenMetadata

func(tid string) string

tokenMetadata is the camelCase JSON Adena reads: name, description, externalUrl, attributes of {traitType, value}. Everything in it is read from the registry at the moment of asking, like the card, so a renewal or a sale shows up without anybody writing anything.

Open
OID
058c22…fb3a:15
tokenMetadata details

Inspect func

attr

func(k string, v string) string
Open
OID
058c22…fb3a:16
attr details

Inspect func

escapeJSON

func(s string) string
Open
OID
058c22…fb3a:17
escapeJSON details

Inspect func

plateW

untyped bigint

The card is 400x400 and the name may use all but a margin either side.

Value

(400 <untyped> bigint)

plateMargin

untyped bigint

The card is 400x400 and the name may use all but a margin either side.

Value

(30 <untyped> bigint)

plateAvail

untyped bigint

// 340

Value

(340 <untyped> bigint)

plateMaxSize

untyped bigint

// any larger and a two-letter name dominates the art

Value

(56 <untyped> bigint)

plateMinSize

untyped bigint

The card is 400x400 and the name may use all but a margin either side.

Value

(4 <untyped> bigint)

plateOrder

untyped string

GLYPH WIDTHS, per generic family, in thousandths of the type size. This replaced a single average-width ratio per family, and the reason is worth keeping, because the average was not merely imprecise — it put names visibly off centre, by an amount that depended on which letters somebody had picked. A serif "l" is 278 and a serif "m" is 833. One number cannot stand in for both. The old ratio was 560 against a true average of 488, so a name made of narrow letters — tessellation, say — came out forty per cent too wide, and because the asterisk is placed using that figure, the whole name slid sideways by half the error. That is exactly what showed up on the proof sheet: tessellation pushed right, cosmos slightly left, say\*gm slightly right. Monospace was never off, because there one number IS the answer and 600 was within two thousandths of it. Only the three generic families are offered. Every renderer that shows these puts the SVG in a sandbox with no network, so a web font never loads — it silently substitutes, and the card becomes whatever that viewer happens to default to. serif, sans-serif and monospace are the only families that resolve everywhere. These are the metrics of the bold faces they resolve to almost everywhere; textLength covers the rest. Three digits per character, in the order of plateOrder. Names are \[a-z0-9-] — lowercase is enforced at registration — so that is the whole alphabet this has to cover.

Value

"abcdefghijklmnopqrstuvwxyz0123456789-"

plateWSerif

untyped string

Value

"500556444556444333500556278333556278833556500556556444389333556500722500500444500500500500500500500500500500333"

plateWSans

untyped string

Value

"556611556611556333611611278278556278889611611611611389556333611556778556556500556556556556556556556556556556333"

plateWMono

untyped string

Value

"602602602602602602602602602602602602602602602602602602602602602602602602602602602602602602602602602602602602602"

plateWidths

func(face string) (tbl string, fallback int)
Open
OID
058c22…fb3a:18
plateWidths details

Inspect func

plateFamily

func(face string) string
Open
OID
058c22…fb3a:20
plateFamily details

Inspect func

plateAdvance

func(s string, face string) int

plateAdvance sums a string's width in thousandths of the type size. A character outside the alphabet falls back to the family's average rather than to zero: a name that somehow escapes the pattern should lay out slightly wrong, not collapse into the asterisk.

Open
OID
058c22…fb3a:21
plateAdvance details

Inspect func

plateSize

func(adv int, face string) int

plateSize solves for the largest type size whose width fits. The asterisk occupies a column of its own, 0.86 of the type size wide, which is why it is in the denominator rather than added afterwards: the letters and the asterisk have to shrink together or the proportions drift as a name gets longer. That is the whole reason this is one calculation instead of two. \`adv\` is the summed advance of both halves, in thousandths.

Open
OID
058c22…fb3a:22
plateSize details

Inspect func

plateGeom

func(size int) (capH int, xH int, starR int, starArm int, outline int)

GEOMETRY, all derived from the type size so every proportion holds at every length. capH 0.70 * size the height of an uppercase letter xH 0.52 * size the height of a lowercase e — no ascender starR 0.26 * size half the x-height, so the asterisk is exactly as tall as an "e" and not as tall as a "b". Matching the cap height made it the tallest thing on the line; names are lowercase, so the x-height is what the eye reads as "letter height" and anything above it reads as a mark starArm 0.104 * size the asterisk's own stroke. This is the weight a MONOSPACED face sets an asterisk at — lighter than the letters around it, because every glyph there has to fit one fixed width — and it is the one that read best of the three that were tried, so it is now the weight in every face outline 0.05 * size the border, on the letters AND the asterisk, the same on both because a border that differs between them looks like a mistake rather than a choice. Thin enough to be a contrast device and not a second typeface: a heavy outline thickens every stem and the name stops looking like the face it was set in

Open
OID
058c22…fb3a:23
plateGeom details

Inspect func

starRays

[6][2]int

THE SIX RAYS, as unit vectors in thousandths. An asterisk is six rays at sixty degrees. In SVG's coordinate system y grows downward, so "up" is negative. cos30 is 866 and cos60 is 500. Listed in CLOCKWISE SCREEN ORDER starting from straight up, which starPoly depends on: it walks them in sequence to trace the outline, and any other order produces a self-intersecting polygon.

Open
OID
058c22…fb3a:25
starRays details

Inspect array

starPoints

func(cx int, cy int, r int, arm int) [18][2]int

starPoints returns the asterisk's outline, IN HUNDREDTHS OF A PIXEL. WHY IT IS AN OUTLINE AND NOT THREE CROSSING LINES. The border has to be the same thickness the whole way round, exactly as it is on the letters, and drawing the shape twice at two stroke widths cannot give that. A wider stroke offsets a line sideways, but where two arms MEET the two wide strokes overlap and fill the valley between them in, so the border is fat at the hub. At the tips it only extends by its own half-width, so it is thin there. That is not a rounding error, it is the wrong tool. Widening a stroke is not the same operation as offsetting a boundary, and they only agree on a shape with no concave corners. An asterisk is nothing but concave corners. The letters do not have this problem because a renderer strokes a glyph's OUTLINE, which is a true offset — every point of the border ends up the same distance from the edge. So the asterisk gets an outline too, and then exactly the same two passes the text gets. WHY HUNDREDTHS, AND NOT WHOLE PIXELS. Because whole pixels made the six arms different widths, which is worse than the problem above and was plainly visible. The arm half-width is arm/2, and at the sizes this actually renders arm is 5, so the half-width is 2.5 — a number a pixel grid cannot hold. Worse, each direction lost a DIFFERENT amount to truncation: the vertical arm computed 1000\*5/2000 = 2 exactly, while a diagonal computed (500\*5/2000, 866\*5/2000) = (1,2), whose length is 2.236. So four arms came out twelve per cent fatter than the other two, and every arm was a fifth thinner than intended. SVG coordinates are not integers, so the fix is simply to stop rounding to them. Everything below is computed in hundredths of a pixel and printed with two decimals, which brings the six half-widths to 2.500 and 2.496 — a spread of 0.16% instead of 12%. THE GEOMETRY. Each ray is a rectangle of half-width arm/2 out to radius r, cut square at the tip. Where two adjacent rays meet, their inner edges cross on the bisector — and for rays sixty degrees apart that crossing sits at radius exactly arm, which falls out of the algebra rather than being tuned. Eighteen points: two tip corners and one valley per ray, walked in the ray order above.

Open
OID
058c22…fb3a:32
starPoints details

Inspect func

hundredths

func(v int) string

hundredths formats a coordinate held in hundredths of a pixel. Two things it must not do, both found the hard way. The sign is peeled off first, because integer division truncates toward zero on BOTH halves and -250 would otherwise print as "-2.-50". And the fraction is assembled a digit at a time rather than with "%02d", because ufmt does not implement the zero-padding flag — it silently printed 68.0 where two digits were asked for, which the mirror diff caught as drift.

Open
OID
058c22…fb3a:33
hundredths details

Inspect func

starPoly

func(cx int, cy int, r int, arm int) string
Open
OID
058c22…fb3a:34
starPoly details

Inspect func

starSVG

func(cx int, cy int, r int, arm int, outline int, ink string, edge string) string

starSVG draws the asterisk in the two passes the lettering uses: border first at twice the width, ink over it. No face argument — one asterisk in every face, see the note at the top of the file.

Open
OID
058c22…fb3a:35
starSVG details

Inspect func

NameplateSVG

func(label string, domain string, face string, pos string, light bool, expires int64) string

NameplateSVG composites the name, the asterisk and the expiry over whatever is already on the card. face "mono" | "serif" | "sans" pos "top" | "middle" | "bottom" light true = white letters with a black border false = black letters with a white border Only two ink pairs exist, and that is not a limitation waiting to be lifted. Both read on every background there is; a free colour choice does not, and mid-grey lettering on a mid-grey drawing is exactly what somebody will pick. \`now\` is deliberately absent from the signature. Nothing here counts down, so nothing here needs the clock — see the note on the expiry.

Open
OID
058c22…fb3a:36
NameplateSVG details

Inspect func

keyFX

untyped string

Seasonal decoration, driven by DATA rather than by code. The card is generated on every read, so anything it draws can change after names have been sold. That makes a holiday overlay possible — snow in December, falling leaves in October — across every token at once. The temptation is to write a drawSnow() into this realm and a drawPumpkins() next year, which would make every new decoration a redeploy of the view. So it is parameterised instead. This realm knows how to draw drifting particles; WHICH particles, what colour, how many and until when live in a global that any admin call can rewrite. Christmas is then one transaction, not a deployment, and so is turning it off. Format, read from the global key \`cardfx\`: dir:fall;n:22;c:#ffffff;c2:#dbeafe;s:3;d:9;until:1767225600 dir fall | rise | burst drift down, drift up, or fireworks n 1..40 how many c #rrggbb colour (c2, c3 optional, cycled) s 1..6 pixel size d 2..30 seconds for one traverse (lower = faster) sv 0..3 size jitter, so they are not all identical k 4..16 sparks per shell, when dir is burst sh sq | leaf | petal particle shape; leaf and petal are angled until unix seconds, 0 = no expiry \`until\` matters more than it looks: an overlay that expires on its own cannot be forgotten in January. Everything is parsed defensively and a malformed value yields NO overlay, for the same reason the sprite parser does — this markup lands inside a token that other people's software renders.

Value

"cardfx"

overlaySVG

func(now int64) string
Open
OID
058c22…fb3a:37
overlaySVG details

Inspect func

pickRule

func(spec string, now int64) string

A SCHEDULE, so December snows without anybody remembering to make it. This is free in a way the treasury swap was not. That needed somebody to send a transaction, because a realm cannot act on its own. This needs nobody, because the card is generated on every read and can simply look at the clock — the decoration is a rendering decision, not an action. Rules are separated by "|" and the FIRST one whose window contains today wins, so put the specific ones first: from:12-01;to:01-06;dir:fall;n:26;c:#ffffff|from:10-24;to:11-02;dir:rise;n:22;c:#f97316 from/to are MM-DD and RECUR every year, which is the point — set it once and every December snows. A window whose start is after its end wraps the new year, so 12-01 to 01-06 is what you would expect rather than an empty range. A rule with no window is always eligible, so a bare spec still behaves as it did.

Open
OID
058c22…fb3a:39
pickRule details

Inspect func

ruleField

func(rule string, key string) string
Open
OID
058c22…fb3a:40
ruleField details

Inspect func

mmdd

func(s string) (int, bool)

mmdd reads "12-01" into 1201. Rejects anything that is not a real calendar date, so a typo cannot silently make a rule match all year.

Open
OID
058c22…fb3a:41
mmdd details

Inspect func

buildOverlay

func(spec string, now int64) string
Open
OID
058c22…fb3a:42
buildOverlay details

Inspect func

hash

func(i int) int

A small deterministic spread. Not random: the same index must always give the same particle, or a cached render and a fresh one disagree.

Open
OID
058c22…fb3a:43
hash details

Inspect func

atoiClamp

func(s string, lo int, hi int) int
Open
OID
058c22…fb3a:44
atoiClamp details

Inspect func

fireworks

func(shells int, sparks int, size int, dur int, cols []string) string

Fireworks: a shell climbs, vanishes, and throws sparks outward. The cost question is worth answering plainly, because it is the first decoration that is not one rect per particle. A shell is 1 rect for the climb plus k rects for the burst, so \`n:5;k:10\` is 55 rects — the same order as the 34 the rain already draws, and a fifth of the 128 the domain sprite draws on every card anyway. None of it is stored: the card is built during a read, so this costs no gas and no storage, only the browser's time. That is the real ceiling, so the totals are capped below rather than left to whoever writes the spec. Two phases in one loop, driven by keyTimes on a single animation each, because a \<set> chain or nested \<g> would double the element count for the same picture.

Open
OID
058c22…fb3a:45
fireworks details

Inspect func

dirCos

[16]int

Sixteen directions on a circle, as hundredths. A table rather than math.Sin: the same integers must come out on every node, and this is the whole of the trigonometry the card needs.

Open
OID
058c22…fb3a:47
dirCos details

Inspect array

dirSin

[16]int

Sixteen directions on a circle, as hundredths. A table rather than math.Sin: the same integers must come out on every node, and this is the whole of the trigonometry the card needs.

Open
OID
058c22…fb3a:49
dirSin details

Inspect array

shapeAt

func(kind string, x int, y int, px int, ang int, col string) string

shapeAt draws one non-square particle at a position, turned to its own angle. Leaves and petals are two curves each rather than a polygon: a leaf is pointed at both ends, a petal is round at one, and that single difference is the whole of what distinguishes October from April. The numbers are derived from the particle size so \`s\` still means what it means everywhere else, and both shapes stay legible at the size a card is actually looked at.

Open
OID
058c22…fb3a:50
shapeAt details

Inspect func

weekdayMatch

func(spec string, t time.Time) bool

weekdayMatch reads "fri" or "fri-13": a weekday, optionally pinned to a day of the month. Anything it does not understand matches nothing, so a typo disables its own rule rather than firing every day.

Open
OID
058c22…fb3a:51
weekdayMatch details

Inspect func

keyDisplayName

untyped string

Profile keys inside a name's extension slot. Conventions owned by this realm and the logic realm, not by the vault — the vault stores strings and has no opinion about what they mean.

Value

"displayName"

keyBio

untyped string

Profile keys inside a name's extension slot. Conventions owned by this realm and the logic realm, not by the vault — the vault stores strings and has no opinion about what they mean.

Value

"bio"

keyWebsite

untyped string

Profile keys inside a name's extension slot. Conventions owned by this realm and the logic realm, not by the vault — the vault stores strings and has no opinion about what they mean.

Value

"website"

renderDomain

func(domainLabel string, after string) string
Open
OID
058c22…fb3a:55
renderDomain details

Inspect func

namePage

untyped bigint

namePage is how many names one domain page shows. Small enough that the work is bounded whatever the registry does, large enough that an ordinary domain is one page.

Value

(100 <untyped> bigint)

renderDomainNames

func(domainLabel string, after string) string
Open
OID
058c22…fb3a:56
renderDomainNames details

Inspect func

renderSkin

func(tid string) string

renderSkin draws a skin DEFINITION's own card, matted and labelled, from a token id of the form "\<definition>#\<serial>". Deliberately not the name card: a skin for sale and a name for sale must not look alike, which is what skincard.gno's frame is for.

Open
OID
058c22…fb3a:57
renderSkin details

Inspect func

renderName

func(label string, domainLabel string) string
Open
OID
058c22…fb3a:58
renderName details

Inspect func

splitCSV

func(s string) []string
Open
OID
058c22…fb3a:59
splitCSV details

Inspect func

splitTokenID

func(tid string) (label string, domain string)

splitTokenID splits \`label\*domain\`; a leading "\*" yields an empty label, which is how a domain page is addressed.

Open
OID
058c22…fb3a:60
splitTokenID details

Inspect func

escapeMarkdown

func(s string) string

escapeMarkdown neutralises user-authored text so it renders as the literal characters typed rather than as markup. Backslash-escapes the CommonMark ASCII punctuation set and folds newlines, which stops headings, lists, tables, images, links, and raw HTML alike.

Open
OID
058c22…fb3a:61
escapeMarkdown details

Inspect func

isSafeURL

func(u string) bool

isSafeURL only admits plain http/https. Everything else — javascript:, data:, anything unrecognised — is refused a live link. Checked on read rather than on write so tightening the rule later also applies to profiles that already exist.

Open
OID
058c22…fb3a:62
isSafeURL details

Inspect func

skinTop

untyped bigint

// the band the word SKIN sits in

Value

(74 <untyped> bigint)

skinFoot

untyped bigint

// the band the skin's own name sits in

Value

(62 <untyped> bigint)

skinBox

untyped bigint

// 264

Value

(264 <untyped> bigint)

skinPad

untyped bigint

// 68

Value

(68 <untyped> bigint)

skinArtSVG

func(enc string, ox int, oy int, box int) string

skinArtSVG renders a sprite to fill a box, INFERRING THE GRID from the data rather than assuming twelve. spriteSVG hardcodes twelve in four places, which is right for the domain artwork it was written for and wrong here: SKINS.md §2a offers 12, 16, 24 and 32, and the whole point of inferring is that one format then covers every size and every sprite already on chain keeps working. Validation is spriteSVG's, unchanged and unrelaxed, because it is not merely a parser — it is the thing standing between community-authored data and markup inside somebody else's wallet. Any violation rejects the WHOLE sprite rather than skipping the bad part: a partial picture hides the fault.

Open
OID
058c22…fb3a:63
skinArtSVG details

Inspect func

SkinCardSVG

func(name string, art string, lock string, light bool) string

SkinCardSVG draws a skin token's own listing card. name the skin's name, as the shop shows it art the sprite string lock the extension it is restricted to, or "" for one that goes on any name light true = pale lettering on a dark matte false = dark lettering on a pale matte The return is a whole document rather than a fragment, because unlike the nameplate this composites over nothing — it IS the card.

Open
OID
058c22…fb3a:65
SkinCardSVG details

Inspect func

inkCrossover

untyped bigint

THE CROSSOVER IS AT 46, NOT 128, and getting that wrong is what made the hand-picked values worse than this rule. Contrast against white is 1.05/(L+0.05); against black it is (L+0.05)/0.05. Setting them equal gives (L+0.05)^2 = 0.0525, so L = 0.179 — about 46 out of 255. Contrast is NOT symmetric about mid-grey: black lettering on a mid-grey ground is far more readable than white on the same ground, and a threshold at 128 hands eleven cards to the wrong ink.

Value

(46 <untyped> bigint)

lumOf

func(hex string) int

lumOf is relative luminance, 0..255, with a gamma of two. The real curve is sRGB's 2.4-with-a-linear-toe, which needs a pow(). Squaring is within a couple of points of it across the whole range and is exact in integers — and this feeds a THRESHOLD, where being two points out only matters for a colour already sitting on the boundary, on which no ink is much better than the other anyway.

Open
OID
058c22…fb3a:66
lumOf details

Inspect func

hexPair

func(a uint8, b uint8) int
Open
OID
058c22…fb3a:68
hexPair details

Inspect func

bandMedian

func(art string, num int, den int) int

bandMedian is the luminance of what the lettering actually sits on. THE MEDIAN, NOT THE MEAN, and the difference is not academic. A mean of black and hot pink is a mid-grey that exists nowhere on the card, and it sends the ink the wrong way on exactly the high-contrast patterns that most need the right answer. A median is what most of the band is. Three rows, because a line of type is taller than one cell at every grid size offered. The middle seventy per cent of the width, because the name is centred and the margins are not under it.

Open
OID
058c22…fb3a:70
bandMedian details

Inspect func

inkForArt

func(art string) bool

inkForArt returns true for white lettering. The name's own band decides it alone: measured across the launch collection the date band never changed an outcome for the better, and letting it vote was what put white letters on a pale card.

Open
OID
058c22…fb3a:71
inkForArt details

Inspect func

faceForArt

func(art string) string

faceForArt picks one of the three generic families from the art itself. Nothing about a background implies a typeface, so this is arbitrary — but it must be arbitrary in the SAME WAY on the chain and in the shop, or the preview shows a card that does not mint. Derived from the art rather than stored for the same reason as the ink: it costs nothing and cannot drift.

Open
OID
058c22…fb3a:72
faceForArt details

Inspect func

skinnedCardSVG

func(art string, label string, domain string, expires int64) string

skinnedCardSVG is the whole card: the art edge to edge, the name over it. FULL BLEED, unlike the skin's own listing card, which is matted. That contrast is deliberate and load-bearing — it is what stops somebody mistaking a skin for sale for a name for sale. See skincard.gno. The ground behind the art matters because a sprite may have transparent cells, and without it they would show whatever the viewer's page is, which is not a colour we chose.

Open
OID
058c22…fb3a:73
skinnedCardSVG details

Inspect func

wornArt

func(label string, domain string) string

skinFor a NAME, as opposed to skinFor the calendar. Separate because they answer different questions and only one of them involves money.

Open
OID
058c22…fb3a:74
wornArt details

Inspect func

skinFor

func(now int64) string

skinFor returns the skin named by whichever calendar rule is active today, or "" for the ordinary card. Reusing pickRule means a skin obeys the same window rules, the same first-match-wins ordering and the same year wrapping as every other season.

Open
OID
058c22…fb3a:75
skinFor details

Inspect func

skinFromSpec

func(spec string, now int64) string

Split out so the calendar logic can be tested against a spec directly, without standing up a vault to hold one.

Open
OID
058c22…fb3a:77
skinFromSpec details

Inspect func

hasSkin

func(name string) bool

hasSkin reports whether a name is renderable as this skin. Unknown names render nothing rather than a broken card — the same defensive stance the overlay parser takes, and for the same reason: this markup lands inside a token that other people's software renders.

Open
OID
058c22…fb3a:78
hasSkin details

Inspect func

seedOf

func(tid string) int

seedOf turns a token id into a small number, so that a card can differ from the one beside it without any randomness — which a deterministic machine does not have. Every node computes the same answer for the same name, which is the requirement; looking arbitrary is merely the effect.

Open
OID
058c22…fb3a:79
seedOf details

Inspect func

skinSVG

func(name string, tid string, now int64) string

skinSVG renders a complete 400x400 card. Same frame as the ordinary one, so nothing downstream has to know which it received.

Open
OID
058c22…fb3a:80
skinSVG details

Inspect func

skinPizza

func(label string, size int, seed int) string

\---------------- 22 May: the pizza ---------------- \* \* Eight wedges with a gap between them, so it reads as CUT rather than \* merely divided, and each wedge carries its own toppings inside its own \* group — that is what makes a slice leave with its pepperoni still on \* it instead of leaving them floating over the board. \* \* EVERY NAME EATS IN ITS OWN ORDER. The seed decides which slice goes \* first and how long each one waits, so a marketplace full of these is a \* room full of pizzas being eaten from different sides at different \* rates rather than one animation repeated. It is derived from the token \* id, so it is the same on every node and different for every name.

Open
OID
058c22…fb3a:83
skinPizza details

Inspect func

wedge

func(cx int, cy int, r float64, a0 float64, a1 float64, fill string) string
Open
OID
058c22…fb3a:84
wedge details

Inspect func

polar

func(cx int, cy int, r float64, deg float64) (int, int)

Degrees clockwise from twelve o'clock, which is how a pizza is cut. Integer maths throughout: a realm has no floating point worth trusting across nodes, and a pizza does not need sub-pixel accuracy.

Open
OID
058c22…fb3a:85
polar details

Inspect func

sinApprox

func(x float64) float64
Open
OID
058c22…fb3a:86
sinApprox details

Inspect func

cosApprox

func(x float64) float64
Open
OID
058c22…fb3a:87
cosApprox details

Inspect func

skinPaper

func(label string, size int, now int64) string

\---------------- 3 Jan: the front page ----------------

Open
OID
058c22…fb3a:88
skinPaper details

Inspect func

skinCal

func(label string, size int) string

\---------------- 29 Feb: the calendar page ----------------

Open
OID
058c22…fb3a:89
skinCal details

Inspect func

skinFog

func(label string, size int) string

\---------------- 20 Apr: the fog ----------------

Open
OID
058c22…fb3a:90
skinFog details

Inspect func

skinSlash

func(label string, size int) string

\---------------- Friday 13th: the poster ----------------

Open
OID
058c22…fb3a:91
skinSlash details

Inspect func

skinPi

func(label string, size int) string

\---------------- 14 Mar: pi ----------------

Open
OID
058c22…fb3a:92
skinPi details

Inspect func

skinHeart

func(label string, size int) string

\---------------- 14 Feb: the heart ---------------- \* \* A real double thump, not one pulse: squeeze, small recoil, second \* smaller squeeze, then a long rest. The rest is most of what makes it \* read as a heartbeat rather than a throb.

Open
OID
058c22…fb3a:93
skinHeart details

Inspect func

esc

func(s string) string

Markup safety, same as everywhere else that puts a name into SVG: a label is validated on registration, but this is the last gate before it lands inside somebody else's renderer.

Open
OID
058c22…fb3a:94
esc details

Inspect func

TokenURI

func(tid string) string

TokenURI returns the full data: URI for a token, generated on every read so the image always reflects current state (never baked at mint).

Open
OID
058c22…fb3a:95
TokenURI details

Inspect func

BuildSVG

func(tid string) string

BuildSVG renders a token. Everything on the card derives from four stored values — owner, registered, expires, and the domain's drawing — so a renewal moves \`expires\` and the bar, the time remaining and the years held all follow from it. Nothing is baked at mint: the card is generated on every read, which is what lets a domain's artwork be changed after its names have been sold.

Open
OID
058c22…fb3a:97
BuildSVG details

Inspect func

cardSVG

func(tid string, art string, registered int64, expires int64, streak int64, frozen bool, now int64, overlay string) string

cardSVG is the card itself, with every stored value already resolved. Split out from BuildSVG so the markup can be rendered — and asserted against — without a vault under it. TestStaticFrameShowsTheDate is the reason: what a marketplace shows as a still is a property of this string and of nothing else, and it deserves to be checked rather than assumed.

Open
OID
058c22…fb3a:98
cardSVG details

Inspect func

graceHeartbeat

func(body string, statusWash string) string

graceHeartbeat re-wraps three pieces of an already-built grace card in the failing-heartbeat flicker, leaving the status band and the date line between them untouched. See the "GRACE AND LAPSED, LAYERED ON TOP" comment in cardSVG for why this operates on the finished string rather than building a second template. Every anchor here is fixed template text, not a dynamic value, so it does not drift when a colour, a date or a name changes -- only when the template itself does, and TestGraceHeartbeatLeavesBandAndDateAlone would catch that (the -1 guards below make a missed anchor degrade to the plain card rather than a corrupted one).

Open
OID
058c22…fb3a:99
graceHeartbeat details

Inspect func

fitSize

func(s string) int

fitSize solves for a size rather than stepping through a ladder. Monospace glyphs are ~0.6em, so a name up to the full 32-character limit sets on one line without overflowing 336px.

Open
OID
058c22…fb3a:100
fitSize details

Inspect func

domainAccent

func(domainLabel string) string

domainAccent reads the accent out of the domain's stored drawing, so the card wears the domain's own colour without this realm carrying a palette of its own. Falls back to the house colour.

Open
OID
058c22…fb3a:101
domainAccent details

Inspect func

accentOf

func(enc string) string
Open
OID
058c22…fb3a:102
accentOf details

Inspect func

remaining

func(expires int64, now int64) string
Open
OID
058c22…fb3a:103
remaining details

Inspect func

keyArt

untyped string

keyArt is the per-domain extension key holding the drawing. The value is "A#facc15,B#7c2d12|............|....AAAA....|..." — the palette, then twelve rows of twelve characters where '.' is transparent. PARSED DEFENSIVELY AND NEVER TRUSTED. It is written by whichever logic realm is current, so a future one could store something malformed; anything unexpected yields no sprite rather than broken markup inside a token that a marketplace will render.

Value

"art"

spriteSVG

func(enc string, px int, ox int, oy int, opacity string) string
Open
OID
058c22…fb3a:104
spriteSVG details

Inspect func

isHexColour

func(s string) bool
Open
OID
058c22…fb3a:105
isHexColour details

Inspect func

placeholderSVG

func(msg string) string
Open
OID
058c22…fb3a:106
placeholderSVG details

Inspect func

daySeconds

int64

statusFields formats a lifecycle state for display. Reads the grace period from nsdata rather than hardcoding it, so retuning the lifecycle is a config change and this stays correct. All lifecycle times are unix seconds, so this is integer arithmetic over a day constant rather than duration division.

Value

86400

metal

type

\---- THE METAL LADDER ---- \* \* From the "Name States" study, 2026-08-23, where it was designed and \* then not built for a fortnight. One rung per year held, carried by the \* frame: 1 bronze, 2 silver, 3 gold, 4 platinum, 5+ diamond. \* \* THE LADDER IS PICKED FOR SEPARATION, not for what the metals are \* worth. Brown, then cool grey, then yellow, then warm white, then \* something that is not a metal at all. The obvious ladder — silver, \* platinum, rhodium — is three whitish metals in a row, and nobody can \* tell year two from year five across a grid of thumbnails. Platinum is \* pulled deliberately WARM to keep it off the gold below it. \* \* The highlight travels faster at the higher rungs, so a longer-held \* name reads as brighter as well as merely different. \* \* DIAMOND IS SATURATED AND KEEPS ITS WHITE. Fire in a real stone is \* spectral colour separated BY white; take the white bands out and it \* stops reading as a gem and starts reading as an oil slick. \* \* IT ADDS NO WORDS. The ribbon has said DIAMOND HANDS since year one and \* at year five the card finally makes good on it. The domain's own \* colour still runs through the type and the term bar, so a name reads \* as its domain first and its tenure second. \* \* YEAR ZERO GETS NO METAL, which is the whole point of a ladder: if a \* new name looked decorated, the rungs a name EARNS would mean nothing. \* \* Mirrored in the site's nft.js. These two move together or a preview \* stops matching what the chain draws.

Value

v1.metal

metalFor

func(streak int64) (v1.metal, bool)
Open
OID
058c22…fb3a:107
metalFor details

Inspect func

metalFrame

func(tid string, status string, edge string, streak int64) (defs string, stroke string, width string)

metalFrame returns the \<defs>, the stroke and the stroke width for a card, or the plain versions when no metal is earned. THE METAL ONLY APPLIES TO A LIVE NAME. A gilded frame around a lapsed card would celebrate a name that is about to belong to somebody else, and it would fight the red wash that exists to say so. Grace and lapsed lose the metal, which is itself information: the frame going plain is the tenure visibly at risk. THE GRADIENT ID CARRIES THE TOKEN. A Render() page draws many of these into one document and SVG resolves url(#id) document-wide, so a fixed id would make every card after the first wear the first card's metal. The token id is unique by construction; it is sanitised because "\*" and "-" are not valid in an id.

Open
OID
058c22…fb3a:108
metalFrame details

Inspect func

idSafe

func(tid string) string

An XML id may not contain "\*", and a name may not contain anything else that would need escaping — the registry's own label rules see to that — so one substitution is enough.

Open
OID
058c22…fb3a:109
idSafe details

Inspect func

smallRibbon

func(status string, edge string, ribbon string, band string) string

The foot of the card: a quiet ribbon while the name is alive, the loud band once it is not. One function so the two cannot both be drawn.

Open
OID
058c22…fb3a:110
smallRibbon details

Inspect func

graceValues

untyped string

\---- FAILING HEARTBEAT (grace period) ---- \* \* From the "Name States" study, 2026-08-23 -- the "Failing heartbeat" \* treatment, built around pulses()/BURSTS/track() there. Bursts of two, \* one, three and one flash at 0.02/0.30/0.55/0.80 of a 7.5s cycle read \* as an unpredictable fault rather than an even, designed blink, so the \* rhythm carries over unchanged. graceValues and graceKeyTimes below are \* that generator's output for base=1, dip=0.25 -- computed once, not \* rebuilt on every read, since a fixed rhythm shared by every grace card \* on the chain has nothing left to vary. \* \* INVERTED FROM THE STUDY, and deliberately. There the track sits DARK \* and briefly flashes LIT -- fine for something animating live in a \* browser tab, useless for a marketplace that renders one still frame: \* the base opacity in the markup and the first keyframe are BOTH the \* dark value there, so a still render of that track is nearly \* invisible. Here the rest state is fully lit -- opacity 1, exactly the \* live card -- and the bursts are brief DIPS toward .25 instead, so \* whichever still a renderer takes (the base attribute for one that \* ignores SMIL, the first keyframe for one that honours it) lands on \* the fully-lit card. graceValues therefore reads "1;1;0.25;..." and \* graceKeyTimes starts "0.0000;...": both a "1" at index zero, on \* purpose. TestGraceHeartbeatLeavesBandAndDateAlone checks exactly that. \* \* Mirrored in the site's nft.js (pulseTrack/heartbeat there, same two \* numbers). If this changes, that changes, or a preview stops matching \* what the chain draws.

Value

"1;1;0.25;0.25;1;1;0.25;0.25;1;1;0.25;0.25;1;1;0.25;0.25;1;1;0.25;0.25;1;1;0.25;0.25;1;1;0.25;0.25;1;1"

graceKeyTimes

untyped string

Value

"0.0000;0.0200;0.0240;0.0350;0.0390;0.0570;0.0610;0.0720;0.0760;0.3000;0.3040;0.3150;0.3190;0.5500;0.5540;0.5650;0.5690;0.5870;0.5910;0.6020;0.6060;0.6240;0.6280;0.6390;0.6430;0.8000;0.8040;0.8150;0.8190;1.0000"

heartbeat

func(inner string) string

heartbeat wraps one piece of a grace card in the failing-heartbeat flicker. Called three separate times in graceHeartbeat rather than once around the whole card, so the status band and the date line can sit between the wrapped pieces untouched. Every call shares the same values/keyTimes/dur; SMIL times every \<animate> from document load, so three separate \<g>s stay in lockstep without needing to share one.

Open
OID
058c22…fb3a:111
heartbeat details

Inspect func

crackOverlay

untyped string

\---- CRACKED (lapsed) ---- \* \* From the same study, under LAPSED. Static, no animation: a fracture \* across the glass with two short branches, drawn last so it sits over \* everything else on the card; the art behind it is untouched and \* undimmed. \* \* THE STUDY'S PATH IS NOT USED AS-IS. Its middle segment runs through \* x=140-176 at y=168-214 -- dead centre, right through where the name \* sits on the study's fixed-width demo cards. That is not fine here: \* the name is centred on x=200 with text-anchor="middle" and can run up \* to 32 characters (see fitSize), so its box can span nearly the full \* card width -- as far out as roughly x=30 to x=370 -- for a long one. \* No amount of routing the crack sideways dodges that band, because a \* long enough name is somewhere underneath any vertical line drawn \* across it. \* \* So the crack is drawn as two pieces rather than one continuous line: \* an upper fracture that stays above y=158 and a lower one that stays \* below y=224, leaving the name's row (166-206) and the date line under \* it (214-228) untouched regardless of how long the name is. It reads \* as the fracture running into the nameplate and continuing on the far \* side, rather than through it -- arguably truer to how a crack behaves \* against a raised, painted surface anyway. Other type on the card (the \* term bar, the held count) is still legitimately crossed, same as in \* the study; only the name and the date get the gap. \* \* Mirrored byte-for-byte in the site's nft.js (CRACK\_OVERLAY there).

Value

"<g stroke=\"#ffffff\" fill=\"none\" opacity=\"0.5\" stroke-width=\"2\"><path d=\"M92 24 L150 72 L112 118 L162 152\"/><path d=\"M112 118 L54 138\"/><path d=\"M158 224 L206 270 L172 318 L228 388\"/><path d=\"M172 318 L268 300\"/></g><g stroke=\"#000000\" fill=\"none\" opacity=\""...

statusFields

func(expires int64, frozen bool) (status string, edge string)
Open
OID
058c22…fb3a:112
statusFields details

Inspect func

escapeXML

func(s string) string
Open
OID
058c22…fb3a:113
escapeXML details

Inspect func
glyph : func(c uint8) string Inspect
glyphW : untyped bigint =(10 <untyped> bigint)
glyphH : untyped bigint =(14 <untyped> bigint)
glyphAd : untyped bigint =(12 <untyped> bigint)
hexish : func(c uint8) int Inspect
MarkerText : func(s string, x int, y int, size int, colour string, weight int) string Inspect
strokes : func(enc string, ox int, oy int, size int, idx int) string Inspect
wobble : func(seed int) int Inspect
MarkerWidth : func(s string, size int) int Inspect
MarkerCentred : func(s string, cx int, y int, size int, colour string, weight int) string Inspect
selfPath : string ="/r/nym-mnsrehearsal001/nsview/v1"
ledgerArt : type =v1.ledgerArt
init.12 : func() Inspect
RegisterWithLedger : func() Inspect
tokenMetadata : func(tid string) string Inspect
attr : func(k string, v string) string Inspect
escapeJSON : func(s string) string Inspect
plateW : untyped bigint =(400 <untyped> bigint)
plateMargin : untyped bigint =(30 <untyped> bigint)
plateAvail : untyped bigint =(340 <untyped> bigint)
plateMaxSize : untyped bigint =(56 <untyped> bigint)
plateMinSize : untyped bigint =(4 <untyped> bigint)
plateOrder : untyped string ="abcdefghijklmnopqrstuvwxyz0123456789-"
plateWSerif : untyped string ="500556444556444333500556278333556278833556500556556444389333556500722500500444500500500500500500500500500500333"
plateWSans : untyped string ="556611556611556333611611278278556278889611611611611389556333611556778556556500556556556556556556556556556556333"
plateWMono : untyped string ="602602602602602602602602602602602602602602602602602602602602602602602602602602602602602602602602602602602602602"
plateWidths : func(face string) (tbl string, fallback int) Inspect
plateFamily : func(face string) string Inspect
plateAdvance : func(s string, face string) int Inspect
plateSize : func(adv int, face string) int Inspect
plateGeom : func(size int) (capH int, xH int, starR int, starArm int, outline int) Inspect
starRays : [6][2]int Inspect
starPoints : func(cx int, cy int, r int, arm int) [18][2]int Inspect
hundredths : func(v int) string Inspect
starPoly : func(cx int, cy int, r int, arm int) string Inspect
starSVG : func(cx int, cy int, r int, arm int, outline int, ink string, edge string) string Inspect
NameplateSVG : func(label string, domain string, face string, pos string, light bool, expires int64) string Inspect
keyFX : untyped string ="cardfx"
overlaySVG : func(now int64) string Inspect
pickRule : func(spec string, now int64) string Inspect
ruleField : func(rule string, key string) string Inspect
mmdd : func(s string) (int, bool) Inspect
buildOverlay : func(spec string, now int64) string Inspect
hash : func(i int) int Inspect
atoiClamp : func(s string, lo int, hi int) int Inspect
fireworks : func(shells int, sparks int, size int, dur int, cols []string) string Inspect
dirCos : [16]int Inspect
dirSin : [16]int Inspect
shapeAt : func(kind string, x int, y int, px int, ang int, col string) string Inspect
weekdayMatch : func(spec string, t time.Time) bool Inspect
keyDisplayName : untyped string ="displayName"
keyBio : untyped string ="bio"
keyWebsite : untyped string ="website"
Render : func(path string) string Inspect
renderHome : func() string Inspect
renderDomain : func(domainLabel string, after string) string Inspect
namePage : untyped bigint =(100 <untyped> bigint)
renderDomainNames : func(domainLabel string, after string) string Inspect
renderSkin : func(tid string) string Inspect
renderName : func(label string, domainLabel string) string Inspect
splitCSV : func(s string) []string Inspect
splitTokenID : func(tid string) (label string, domain string) Inspect
escapeMarkdown : func(s string) string Inspect
isSafeURL : func(u string) bool Inspect
skinTop : untyped bigint =(74 <untyped> bigint)
skinFoot : untyped bigint =(62 <untyped> bigint)
skinBox : untyped bigint =(264 <untyped> bigint)
skinPad : untyped bigint =(68 <untyped> bigint)
skinArtSVG : func(enc string, ox int, oy int, box int) string Inspect
SkinCardSVG : func(name string, art string, lock string, light bool) string Inspect
inkCrossover : untyped bigint =(46 <untyped> bigint)
lumOf : func(hex string) int Inspect
hexPair : func(a uint8, b uint8) int Inspect
hexDigit : func(c uint8) int Inspect
bandMedian : func(art string, num int, den int) int Inspect
inkForArt : func(art string) bool Inspect
faceForArt : func(art string) string Inspect
skinnedCardSVG : func(art string, label string, domain string, expires int64) string Inspect
wornArt : func(label string, domain string) string Inspect
skinFor : func(now int64) string Inspect
skinFromSpec : func(spec string, now int64) string Inspect
hasSkin : func(name string) bool Inspect
seedOf : func(tid string) int Inspect
skinSVG : func(name string, tid string, now int64) string Inspect
head : func(bg string) string Inspect
foot : func() string Inspect
skinPizza : func(label string, size int, seed int) string Inspect
wedge : func(cx int, cy int, r float64, a0 float64, a1 float64, fill string) string Inspect
polar : func(cx int, cy int, r float64, deg float64) (int, int) Inspect
sinApprox : func(x float64) float64 Inspect
cosApprox : func(x float64) float64 Inspect
skinPaper : func(label string, size int, now int64) string Inspect
skinCal : func(label string, size int) string Inspect
skinFog : func(label string, size int) string Inspect
skinSlash : func(label string, size int) string Inspect
skinPi : func(label string, size int) string Inspect
skinHeart : func(label string, size int) string Inspect
esc : func(s string) string Inspect
TokenURI : func(tid string) string Inspect
BuildSVG : func(tid string) string Inspect
cardSVG : func(tid string, art string, registered int64, expires int64, streak int64, frozen bool, now int64, overlay string) string Inspect
graceHeartbeat : func(body string, statusWash string) string Inspect
fitSize : func(s string) int Inspect
domainAccent : func(domainLabel string) string Inspect
accentOf : func(enc string) string Inspect
remaining : func(expires int64, now int64) string Inspect
keyArt : untyped string ="art"
spriteSVG : func(enc string, px int, ox int, oy int, opacity string) string Inspect
isHexColour : func(s string) bool Inspect
placeholderSVG : func(msg string) string Inspect
daySeconds : int64 =86400
metal : type =v1.metal
metalFor : func(streak int64) (v1.metal, bool) Inspect
metalFrame : func(tid string, status string, edge string, streak int64) (defs string, stroke string, width string) Inspect
idSafe : func(tid string) string Inspect
smallRibbon : func(status string, edge string, ribbon string, band string) string Inspect
graceValues : untyped string ="1;1;0.25;0.25;1;1;0.25;0.25;1;1;0.25;0.25;1;1;0.25;0.25;1;1;0.25;0.25;1;1;0.25;0.25;1;1;0.25;0.25;1;1"
graceKeyTimes : untyped string ="0.0000;0.0200;0.0240;0.0350;0.0390;0.0570;0.0610;0.0720;0.0760;0.3000;0.3040;0.3150;0.3190;0.5500;0.5540;0.5650;0.5690;0.5870;0.5910;0.6020;0.6060;0.6240;0.6280;0.6390;0.6430;0.8000;0.8040;0.8150;0.8190;1.0000"
heartbeat : func(inner string) string Inspect
crackOverlay : untyped string ="<g stroke=\"#ffffff\" fill=\"none\" opacity=\"0.5\" stroke-width=\"2\"><path d=\"M92 24 L150 72 L112 118 L162 152\"/><path d=\"M112 118 L54 138\"/><path d=\"M158 224 L206 270 L172 318 L228 388\"/><path d=\"M172 318 L268 300\"/></g><g stroke=\"#000000\" fill=\"none\" opacity=\""...
statusFields : func(expires int64, frozen bool) (status string, edge string) Inspect
escapeXML : func(s string) string Inspect