/** * WHERE A SCHEDULE'S BLOCKS LAND ON ITS AXIS, AND WHAT IS LEFT OVER — the * arithmetic a resource schedule is, kept out of the component that draws it. * * A gap is the product the operation has left to sell, so it is derived once, * here, and both the ghost the lane draws and the destinations a block's move * menu offers read the same list. * * EVERYTHING IS MINUTES FROM AN ORIGIN, never a timestamp: the origin is local * midnight on the day the board opens, so a day boundary is a whole multiple of * a day away from it whatever offset the reader stands in, and the kit's own * `dayDiff` carries the day count across a daylight-saving step. */ /** Minutes in each unit the axis can be ruled in. */ declare const UNIT_MINUTES: { readonly hour: 60; readonly day: number; }; /** * WHAT THE AXIS IS RULED IN — hours where the work is placed at a TIME of day, * days where it is placed on a date. * * Read off the values rather than stated: asked of the plan it would be a clause * an author could answer wrongly, and a board ruled in the wrong unit draws a * two-hour drop as two days of work. IT ALSO DECIDES WHAT A DURATION COUNTS IN. */ export type ScheduleScale = keyof typeof UNIT_MINUTES; /** A stretch of the axis, in minutes from the board's origin. */ export interface ScheduleSpan { from: number; to: number; } /** The ruled axis — its ends, and the marks the reader reads positions off. */ export interface ScheduleAxis { scale: ScheduleScale; from: number; to: number; /** Local midnight on the first day the board covers — what a minute count is FROM. */ origin: Date; /** Each mark's minute and its share of the axis, left to right. */ ticks: readonly { at: number; share: number; }[]; } /** A block's box on the axis, as shares of it — so a lane is drawn at any width. */ export interface ScheduleBox { left: number; width: number; } export declare function scheduleScale(starts: Iterable): ScheduleScale; /** The minute a value stands at, counted from the origin. */ export declare function minuteOf(origin: Date, value: string | null | undefined): number | null; /** * WHERE ONE BLOCK LIES — its start, and its length in the axis's own unit. * * A LENGTH NOBODY STATED IS ONE UNIT, not nothing: the block is placed, so the * lane is occupied at that moment, and a zero-width bar is a block the reader * cannot see or press. */ export declare function blockSpan(origin: Date, scale: ScheduleScale, start: string | null | undefined, length: number | null | undefined): ScheduleSpan | null; /** * THE AXIS THE BOARD IS RULED ON — from the first block to the last, snapped out * to whole units so the marks land on the hour and the day. `null` where nothing * is placed: an axis over no spans has no ends. */ export declare function scheduleAxis(spans: readonly ScheduleSpan[], scale: ScheduleScale, origin: Date): ScheduleAxis | null; /** A span's box on the axis — clipped to it, because a block is drawn where the reader can see it. */ export declare function spanBox(span: ScheduleSpan, axis: ScheduleAxis): ScheduleBox; /** * WHAT IS STILL OPEN ON ONE LANE — every stretch of the axis nothing covers, * left to right. * * The walk carries the FURTHEST end reached rather than the last span's, which * is what makes an overlap harmless: a lane booked nine-to-eleven and * ten-to-twelve is covered to twelve. */ export declare function laneGaps(spans: readonly ScheduleSpan[], axis: ScheduleAxis): ScheduleSpan[]; /** * HOW FULL A LANE IS — the readings its blocks state, added up, against the * ceiling they are read against. * * THE CEILING IS THE LANE'S, so it is the first one any block on it states. * Blocks that disagree about it are a model error the board cannot arbitrate. * * `null` where no block states a level, which is not the same claim as a lane * loaded to nothing. */ export declare function laneReading(entries: Iterable<{ level: number | null | undefined; limit: number | null | undefined; }>): { level: number; limit: number | null; } | null; /** The instant a minute count stands at — what the axis's marks and a gap are NAMED by. */ export declare function instantAt(axis: ScheduleAxis, minute: number): Date; /** * THE VALUE A WRITE PUTS IN THE START FIELD for a moment on this axis — at the * axis's own grain, and naive, the way every date the platform stores is. A day * board writes a DAY, or the next read back would rule the whole board in hours. */ export declare function isoAt(axis: ScheduleAxis, minute: number): string; /** Local midnight on the earliest day anything is placed on — the board's origin. */ export declare function scheduleOrigin(starts: Iterable, now: Date): Date; /** How long a stretch runs, in the axis's own unit — what a gap says of itself. */ export declare function spanUnits(span: ScheduleSpan, scale: ScheduleScale): number; export {};