/** one directory entry — extra keys (the cloud may add email) ride through */ export interface PersonEntry { handle: string; name?: string; [extra: string]: unknown; } /** the payload's directory declaration, carried VERBATIM as D.people: * inline = baked entries; url = a live endpoint the client fetches once per * page-life, `entries` as its offline snapshot. Absent = no directory, and * every person surface degrades to plain text — fail closed. */ export interface PeopleDecl { mode: 'inline' | 'url'; url?: string; entries?: PersonEntry[]; } export type PersonLookup = (handle: string) => PersonEntry | null; /** The handles a person cell holds: one, or a comma/space-separated list. * A leading `@` is the mention spelling of the same handle — tolerated and * stripped for resolution; rendering shows names, not handles (Linear). */ export declare function personHandles(raw: string): string[]; /** A lookup over a directory's entries. Case-folded: the handle is vocabulary, * and vocabulary is case-insensitive everywhere else in the engine (the enum * check, laneOf, facetMatch) — `@Felipe` in prose must find `felipe` in the * directory. First declaration wins on a fold collision, like buildTones. * Map-backed, so an entry named "constructor" is an entry, never * Object.prototype's (the own() discipline without the import). */ export declare function personLookupOf(entries: PersonEntry[] | undefined | null): PersonLookup; /** * One handle as a chip. Resolved: the initial of the display name + the name. * Unresolved (no entry, or an entry that carries no name to show): the * initial of the handle + the handle, muted — readable, never an error. * `data-handle` carries the PORTABLE identity the document actually stores, * which is what lets the client re-resolve a baked cell when a live * directory lands without ever guessing a handle back out of a name. */ export declare function personChipHtml(handle: string, lookup: PersonLookup): string; /** * THE FACEPILE — several people, one glance: overlapping initial circles * where a surface holds MORE THAN ONE handle. The glance shows who-many; the * hover says exactly who — every face carries its resolved display name as * its title, and the pile's aria-label reads the whole roster (initials are * decoration, so the faces themselves are aria-hidden). Past `max` faces the * pile stops drawing and says the honest arithmetic (+N), the hidden names * living in the +N title. * * `data-handles` on the pile root carries EVERY handle, space-joined — the * same recovery contract as the chip's data-handle, and the only complete * one here: overflow handles have no face to ride, so the client repaint * (peoplesource) reads the pile's roster from the root, never from faces. * Unresolved faces are muted (`unres`), a state, not an error — the chip's * doctrine exactly. Same escaper, same both-sides purity: one builder for * the server cell ladder and the client repaint. */ export declare function facepileHtml(handles: string[], lookup: PersonLookup, max?: number): string; /** A whole cell: ONE handle keeps the chip it always rendered — the exact * bytes, byte-stability's floor — and SEVERAL handles stack into a facepile * (the ≥2 spelling). The cell ladder has already swallowed empty markers * before this runs; a cell that splits to no handles at all (stray * separators) renders as nothing rather than as an invented chip. */ export declare function personCellHtml(raw: string, lookup: PersonLookup): string;