import type { CrowdShape, Side, Sport, SurfaceOptions } from "./types.ts"; export type Pt = [number, number]; export type Box = { x: number; y: number; w: number; h: number; }; /** The outline of a part of the stands, in feet in the surface's wide frame: a rectangle with rounded corners, an ellipse, or a polygon. */ export type Outline = { kind: "rrect"; x0: number; y0: number; x1: number; y1: number; r: number; } | { kind: "ellipse"; cx: number; cy: number; rx: number; ry: number; } | { kind: "poly"; points: Pt[]; }; /** A tier of the stands: a band of seats between two outlines. */ export interface StandRing { /** `lower`, `upper`, `courtside`, `grandstand` or `bleachers`, with the tier's number where a ring has parts. */ id: string; tier: "courtside" | "gallery" | "lower" | "upper" | "grandstand" | "bleachers" | "wall"; /** The band is `region` less `hole` (nothing for a polygon that is the band itself). */ region: Outline; /** Further pieces of the band that are apart from `region` (a ballpark's bleachers either side of the batter's eye). */ more?: Outline[]; hole: Outline | null; /** How far the band's inner and outer edges are from the edge of the playing surface, in feet, at the sides (the ends' distances are the same plus the venue's end gap less its side gap). */ from: number; to: number; /** The height of the first and of the last row above the playing surface, in feet; `rake` is the slope between them in degrees. For a view that raises the stands. */ height: [number, number]; rake: number; /** The share of its seats that are taken, relative to the stands' (the upper tier is emptier). */ fill: number; /** A hall's gallery: the rows of seats the band holds. */ rows?: number; /** The seats the band holds, at a seat's 2 by 2.3 feet. */ seats: number; /** The aisles and vomitories across the band, each from a point on its inner edge to its outer: across the sides, fanning round the corners. */ aisles: [Pt, Pt][]; } /** A block of the stands that is not the home fans': the visitors', or a card display. A polygon in the wide frame. */ export interface StandSector { ring: string; kind: "away" | "tifo-home" | "tifo-away"; points: Pt[]; } /** A place left open or built on: a tunnel through the lower stands, a bench, the camera platform of the media side. A box in the wide frame. */ export interface StandGap { kind: "tunnel" | "bench" | "media" | "camera"; box: [x0: number, y0: number, x1: number, y1: number]; } /** The stands round a surface as data. */ export interface CrowdStands { sport: Sport; shape: CrowdShape; /** The stadium a soccer pitch stands in: `purpose` (its own), `nfl` or `cfl` (a gridiron's), or nothing for another sport. */ stadium?: "purpose" | "nfl" | "cfl"; /** The playing surface, in the wide frame. */ box: Box; rings: StandRing[]; /** Boxes where the stands are left out (the open end of a horseshoe, the ends of two sides). */ covers: [x0: number, y0: number, x1: number, y1: number][]; sectors: StandSector[]; gaps: StandGap[]; /** The walks between the tiers: a band between one tier's outer edge and the next one's inner. */ concourses: { region: Outline; hole: Outline | null; }[]; /** A gridiron stadium's field under a soccer pitch: its outline and its two end zones, in the wide frame, so that the gap is seen. */ footprint?: { field: Box; endZones: [Box, Box]; }; /** The ground the stands need beyond the surface on each side, in feet. */ reach: { left: number; right: number; top: number; bottom: number; }; /** The seats of all the stands, from the model: what a density is a share of when no capacity is given. */ seats: number; /** The stands are a hall's gallery (a dojo's balcony): a thin band close to the walls, plain seats, a few neutral people and no sides. */ gallery?: boolean; } /** The crowd options read: every part has its value. */ export interface Crowd { shape: CrowdShape | undefined; open: "left" | "right"; stadium: "auto" | "purpose" | "nfl" | "cfl"; density: number | undefined; attendance: number | undefined; capacity: number | undefined; seed: number; home: string | undefined; away: string | undefined; awayEnd: "auto" | "left" | "right" | "corner" | "none"; tifo: "home" | "away" | "both" | undefined; tifoDesign: "stripes" | "checks"; gaps: boolean; roof: boolean; wallSeats: boolean | undefined; detail: "auto" | "fine" | "plain"; } /** The crowd the options ask for, or `undefined` for none. */ export declare function resolveCrowd(value: SurfaceOptions["crowd"]): Crowd | undefined; /** How full the stands are: a density, else attendance over capacity (the ground's, else the model's seats), else 0.85. */ export declare function densityOf(crowd: Crowd, seats: number, groundCapacity: number | undefined): number; /** A small, fast generator (mulberry32): the same seed gives the same numbers on every machine. */ export declare function generator(seed: number): () => number; /** The grounds of the package that are the home of an NFL or a CFL club, where a soccer pitch stands inside a gridiron's stands. From each ground's article. */ export declare const GRIDIRON_GROUNDS: Readonly>; /** The walls the package knows have seats on top of them, by park and the wall's label: Fenway Park's Green Monster (the Monster seats, 2003). */ export declare const WALL_SEATS: Readonly>; /** The point of an outline hit by a ray from `(cx, cy)` at angle `a` (screen angle, y down). */ export declare function rayAt(o: Outline, cx: number, cy: number, a: number): Pt; /** An outline as a path, drawn clockwise, or counter-clockwise when `reverse` (a hole in a band that is filled with the non-zero rule). */ export declare function outlinePath(o: Outline, reverse?: boolean): string; /** An outline as points, for a view that raises the stands: arcs are cut into steps of about 7.5 degrees. */ export declare function outlinePoints(o: Outline): Pt[]; /** The seats of a band of the stands: its area at a seat's 2 by 2.3 feet. */ export declare const seatsIn: (region: Outline, hole: Outline | null) => number; /** A point of a rounded rectangle and the outward normal there, by its parameter `u` (any real number, taken modulo 8): the four straight sides are the even whole numbers (the top from left to right, the right from top to bottom and so on round) and the four corners the odd ones. Concentric outlines (the same corners' centres) have the same parameter at the points an aisle joins. */ export declare function rrectAt(o: Extract, u: number): { p: Pt; n: Pt; }; /** What the layout needs of the options and the surface. */ export interface LayoutInput { sport: Sport; /** The playing surface in the wide frame. */ box: Box; crowd: Crowd; /** The side the visitors sit towards (the opposite of the home team's). */ awaySide: Side; /** A ground's key, for the stadium a soccer pitch stands in. */ ground?: string; /** The surface lies on an arena floor that fills most of the hall: the sport's closer stands, where it has them. */ arena?: boolean; /** A hall's gallery instead of the sport's stands (a dojo's balcony, from `dojoRoom`): the distance of its first row from the surface, its depth and the heights of its first and last rows, in feet. */ gallery?: { offset: number; depth: number; height: [number, number]; rows?: number; aisles?: readonly number[]; }; /** The ballpark's fence as points on the field, for a ballpark (see `parkLayout`). */ fence?: readonly Pt[]; /** The foul lines' length at the poles and the backstop's distance, for a ballpark. */ backstop?: number; } /** The layout of a sport's stands round its surface: rings, covers, sectors and gaps. For a ballpark see `parkLayout`. */ export declare function layoutOf(input: LayoutInput): CrowdStands;