@vueye-table/core 3.0.0-alpha.1 → 3.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +138 -60
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +512 -96
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["isRecord"],"sources":["../src/humanize.ts","../src/path.ts","../src/column.ts","../src/delimited.ts","../src/grid.ts","../src/undo-stack.ts","../src/infer.ts","../src/pipeline.ts","../src/state.ts","../src/issues.ts","../src/row.ts","../src/table.ts"],"sourcesContent":["/**\n * Turn a column id into a readable header: `\"name.first_name\"` becomes `\"Name first name\"` and\n * `\"createdAt\"` becomes `\"Created at\"`.\n */\nexport function humanize(id: string): string {\n const words = id\n .replace(/([a-z0-9])([A-Z])/gu, \"$1 $2\")\n .split(/[\\s._-]+/u)\n .filter((word) => word.length > 0)\n .map((word) => word.toLowerCase());\n const sentence = words.join(\" \");\n return sentence.charAt(0).toUpperCase() + sentence.slice(1);\n}\n","/**\n * Dotted property paths.\n *\n * A column addresses nested data with a path such as `\"address.city\"`. The types below give every\n * such path its value type, and the functions read and write through a path without mutating.\n */\n\ntype Leaf =\n | string\n | number\n | boolean\n | bigint\n | symbol\n | null\n | undefined\n | Date\n | readonly unknown[]\n | ((...args: never[]) => unknown);\n\ntype Depth = [never, 0, 1, 2, 3];\n\n/** Every dotted path into `T`, four levels deep. Arrays, dates, and functions are leaves. */\nexport type DeepKeys<T, TDepth extends number = 4> = [TDepth] extends [never]\n ? never\n : T extends Leaf\n ? never\n : {\n [K in keyof T & string]:\n | K\n | (NonNullable<T[K]> extends Leaf\n ? never\n : `${K}.${DeepKeys<NonNullable<T[K]>, Depth[TDepth]>}`);\n }[keyof T & string];\n\n/** The value found at `TPath` in `T`. A nullable step makes the result possibly `undefined`. */\nexport type PathValue<T, TPath extends string> = TPath extends `${infer THead}.${infer TRest}`\n ? THead extends keyof T\n ? PathValue<NonNullable<T[THead]>, TRest> | (undefined extends T[THead] ? undefined : never)\n : undefined\n : TPath extends keyof T\n ? T[TPath]\n : undefined;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\n/** Read the value at a dotted path, or `undefined` when a step is missing. */\nexport function getPath(source: unknown, path: string): unknown {\n let current: unknown = source;\n for (const segment of path.split(\".\")) {\n if (!isRecord(current)) {\n return undefined;\n }\n current = current[segment];\n }\n return current;\n}\n\n/**\n * Return a copy of `source` with `value` at `path`. Only the objects along the path are copied;\n * everything else is shared. Missing steps are created as plain objects.\n */\nexport function setPath<T>(source: T, path: string, value: unknown): T {\n const [head, ...rest] = path.split(\".\");\n const base: Record<string, unknown> = isRecord(source) ? { ...source } : {};\n if (head === undefined) {\n return source;\n }\n base[head] = rest.length === 0 ? value : setPath(base[head], rest.join(\".\"), value);\n return base as T;\n}\n","import { humanize } from \"./humanize\";\nimport { getPath, setPath, type DeepKeys, type PathValue } from \"./path\";\n\nexport type ColumnAlign = \"start\" | \"center\" | \"end\";\n\n/** How typed or pasted text becomes a value when a column has no `parse`. */\nexport type ColumnType = \"text\" | \"number\" | \"boolean\" | \"date\";\n\n/** A range filter value, inclusive at both ends. Either end may be left open. */\nexport interface RangeFilter {\n readonly min?: number | string | Date | undefined;\n readonly max?: number | string | Date | undefined;\n}\n\n/** Options shared by path columns and computed columns. */\nexport interface ColumnOptions<TRow, TValue> {\n /** Header text. Defaults to the id made readable: `\"createdAt\"` becomes `\"Created at\"`. */\n readonly header?: string | undefined;\n readonly align?: ColumnAlign | undefined;\n /** Width in pixels. */\n readonly width?: number | undefined;\n readonly minWidth?: number | undefined;\n /** Whether a user may sort by this column. Defaults to `true`. */\n readonly sortable?: boolean | undefined;\n /** Whether the free-text search looks at this column. Defaults to `true`. */\n readonly searchable?: boolean | undefined;\n /** Hidden until a user shows it. */\n readonly hidden?: boolean | undefined;\n /**\n * How text becomes a value. Defaults to the type of the cell's current value, or of another\n * row's value when the cell is empty.\n */\n readonly type?: ColumnType | undefined;\n /** Whether cells of this column accept edits. A function decides per row. */\n readonly editable?: boolean | ((row: TRow) => boolean) | undefined;\n /** Order two values; the engine flips the sign for descending sorts. */\n readonly compare?: ((left: TValue, right: TValue) => number) | undefined;\n /** Decide whether a row passes this column's filter value. */\n readonly filter?: ((value: TValue, filterValue: unknown, row: TRow) => boolean) | undefined;\n /** Turn a value into the text a cell shows, searches, copies, and exports. */\n readonly format?: ((value: TValue, row: TRow) => string) | undefined;\n /**\n * Turn typed or pasted text into a value. Throw to reject the input. Defaults to reading the\n * column's `type`.\n */\n readonly parse?: ((input: string, row: TRow) => TValue) | undefined;\n /** Free-form data for renderers. The engine never reads it. */\n readonly meta?: Readonly<Record<string, unknown>> | undefined;\n}\n\n/** A column that reads `row[id]`, following dots into nested objects. */\nexport interface PathColumnDef<TRow, TPath extends string> extends ColumnOptions<\n TRow,\n PathValue<TRow, TPath>\n> {\n readonly id: TPath;\n readonly accessor?: undefined;\n readonly setValue?: undefined;\n}\n\n/** A column whose value is computed from the row. It is editable only with `setValue`. */\nexport interface ComputedColumnDef<TRow, TValue = unknown> extends ColumnOptions<TRow, TValue> {\n readonly id: string;\n readonly accessor: (row: TRow) => TValue;\n /** Return a copy of `row` carrying `value`. Without it the column is read-only. */\n readonly setValue?: ((row: TRow, value: TValue) => TRow) | undefined;\n}\n\n/**\n * One column definition. A path column is discriminated by its literal id, so `format`,\n * `compare`, and `parse` receive the value type found at that path.\n */\nexport type ColumnDef<TRow> =\n | {\n [TPath in DeepKeys<TRow>]: PathColumnDef<TRow, TPath>;\n }[DeepKeys<TRow>]\n | ComputedColumnDef<TRow, any>;\n\n/**\n * A column definition for any row type, for props and containers that accept every table.\n */\nexport type AnyColumnDef = ColumnDef<any>;\n\n/** Declare columns for a row type with full inference, outside a table. */\nexport function defineColumns<TRow>(\n columns: readonly ColumnDef<TRow>[],\n): readonly ColumnDef<TRow>[] {\n return Object.freeze([...columns]);\n}\n\n/**\n * A column resolved against its defaults. Renderers read these; they never read definitions.\n */\nexport interface TableColumn<TRow> {\n readonly id: string;\n readonly header: string;\n readonly align: ColumnAlign;\n readonly width: number | undefined;\n readonly minWidth: number | undefined;\n readonly sortable: boolean;\n readonly searchable: boolean;\n readonly initiallyHidden: boolean;\n readonly meta: Readonly<Record<string, unknown>>;\n readonly definition: ColumnDef<TRow>;\n getValue(row: TRow): unknown;\n format(value: unknown, row: TRow): string;\n compare(left: unknown, right: unknown): number;\n matches(value: unknown, filterValue: unknown, row: TRow): boolean;\n isEditable(row: TRow): boolean;\n /**\n * Parse text into a value, or report why it could not be read. `sample` is a value from another\n * row, used to tell the column's type when this cell is empty.\n */\n parse(input: string, row: TRow, sample?: unknown): ParseResult;\n /** Return a copy of `row` carrying `value`, or `undefined` for a read-only column. */\n setValue(row: TRow, value: unknown): TRow | undefined;\n}\n\n/** The outcome of reading text into a cell value. */\nexport type ParseResult =\n | { readonly ok: true; readonly value: unknown }\n | { readonly ok: false; readonly message: string };\n\nconst collator = new Intl.Collator(undefined, { numeric: true, sensitivity: \"base\" });\n\nfunction isEmpty(value: unknown): boolean {\n return value === null || value === undefined || value === \"\";\n}\n\n/** Order any two values: empty last, then numbers, dates, booleans, and text naturally. */\nexport function compareValues(left: unknown, right: unknown): number {\n const leftEmpty = isEmpty(left);\n const rightEmpty = isEmpty(right);\n if (leftEmpty || rightEmpty) {\n return leftEmpty === rightEmpty ? 0 : leftEmpty ? 1 : -1;\n }\n if (typeof left === \"number\" && typeof right === \"number\") {\n return left - right;\n }\n if (typeof left === \"bigint\" && typeof right === \"bigint\") {\n return left < right ? -1 : left > right ? 1 : 0;\n }\n if (left instanceof Date && right instanceof Date) {\n return left.getTime() - right.getTime();\n }\n if (typeof left === \"boolean\" && typeof right === \"boolean\") {\n return Number(left) - Number(right);\n }\n return collator.compare(formatValue(left), formatValue(right));\n}\n\n/**\n * Text for a value: empty for `null` and `undefined`, ISO for dates, comma-joined for arrays, and\n * JSON for other objects. The result never depends on the runtime's locale, so server and client\n * render the same text.\n */\nexport function formatValue(value: unknown): string {\n if (value === null || value === undefined) {\n return \"\";\n }\n if (value instanceof Date) {\n return Number.isNaN(value.getTime()) ? \"\" : value.toISOString();\n }\n if (Array.isArray(value)) {\n return value.map(formatValue).join(\", \");\n }\n if (typeof value === \"object\") {\n return JSON.stringify(value);\n }\n switch (typeof value) {\n case \"string\":\n return value;\n case \"number\":\n case \"bigint\":\n case \"boolean\":\n return String(value);\n case \"symbol\":\n return value.toString();\n default:\n return \"\";\n }\n}\n\nfunction toComparable(value: unknown): number | string | undefined {\n if (value instanceof Date) {\n const time = value.getTime();\n return Number.isNaN(time) ? undefined : time;\n }\n if (typeof value === \"number\") {\n return Number.isNaN(value) ? undefined : value;\n }\n return typeof value === \"string\" ? value : undefined;\n}\n\n/**\n * Read a range bound in the kind of the value it is compared with, so a bound typed into a text\n * box (`\"10\"`, `\"2024-01-31\"`) compares with numbers as a number and with dates as a time. An\n * empty or unreadable bound leaves that end of the range open.\n */\nfunction toBound(bound: unknown, value: unknown): number | string | undefined {\n if (isEmpty(bound)) {\n return undefined;\n }\n if (typeof bound === \"string\" && typeof value === \"number\") {\n const number = Number(bound.trim());\n return bound.trim() === \"\" || Number.isNaN(number) ? undefined : number;\n }\n if (typeof bound === \"string\" && value instanceof Date) {\n return toComparable(new Date(bound));\n }\n if (bound instanceof Date && typeof value === \"string\") {\n // Compare text dates at their own precision: \"2024-01-31\" against the bound's day.\n return Number.isNaN(bound.getTime()) ? undefined : bound.toISOString().slice(0, value.length);\n }\n return toComparable(bound);\n}\n\nfunction isRangeFilter(value: unknown): value is RangeFilter {\n return (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n !(value instanceof Date) &&\n (\"min\" in value || \"max\" in value)\n );\n}\n\n/**\n * The default column filter:\n *\n * - an empty filter value (`undefined`, `null`, `\"\"`, `[]`) lets every row through;\n * - an array keeps rows whose value is one of its items;\n * - `{ min, max }` keeps values inside the inclusive range; a bound given as text is read as a\n * number or a date when the value is one, and an empty bound leaves that end open;\n * - text keeps rows whose shown text contains it, ignoring case;\n * - anything else keeps rows whose value is identical.\n */\nexport function matchesFilter(value: unknown, filterValue: unknown, display: string): boolean {\n if (isEmpty(filterValue) || (Array.isArray(filterValue) && filterValue.length === 0)) {\n return true;\n }\n if (Array.isArray(filterValue)) {\n return filterValue.some((item) => Object.is(item, value) || compareValues(item, value) === 0);\n }\n if (isRangeFilter(filterValue)) {\n const min = toBound(filterValue.min, value);\n const max = toBound(filterValue.max, value);\n if (min === undefined && max === undefined) {\n return true;\n }\n const comparable = toComparable(value);\n if (comparable === undefined) {\n return false;\n }\n return (min === undefined || comparable >= min) && (max === undefined || comparable <= max);\n }\n if (typeof filterValue === \"string\") {\n return display.toLowerCase().includes(filterValue.toLowerCase());\n }\n return Object.is(value, filterValue);\n}\n\nconst TRUE_WORDS = new Set([\"true\", \"1\", \"yes\", \"y\", \"on\"]);\nconst FALSE_WORDS = new Set([\"false\", \"0\", \"no\", \"n\", \"off\"]);\n\n/** The column type a value suggests, or `undefined` for an empty value. */\nexport function typeOf(value: unknown): ColumnType | undefined {\n if (value === null || value === undefined) {\n return undefined;\n }\n if (typeof value === \"number\") {\n return \"number\";\n }\n if (typeof value === \"boolean\") {\n return \"boolean\";\n }\n return value instanceof Date ? \"date\" : \"text\";\n}\n\n/** Read text as a column type. Empty text is `null` for every type but text. */\nexport function parseAs(input: string, type: ColumnType): ParseResult {\n const text = input.trim();\n if (type === \"text\") {\n return { ok: true, value: input };\n }\n if (text === \"\") {\n return { ok: true, value: null };\n }\n if (type === \"number\") {\n const value = Number(text);\n return Number.isFinite(value)\n ? { ok: true, value }\n : { ok: false, message: `\"${input}\" is not a number` };\n }\n if (type === \"boolean\") {\n const word = text.toLowerCase();\n if (TRUE_WORDS.has(word)) {\n return { ok: true, value: true };\n }\n if (FALSE_WORDS.has(word)) {\n return { ok: true, value: false };\n }\n return { ok: false, message: `\"${input}\" is not a yes or no value` };\n }\n const value = new Date(text);\n return Number.isNaN(value.getTime())\n ? { ok: false, message: `\"${input}\" is not a date` }\n : { ok: true, value };\n}\n\n/** Resolve a definition against its defaults. */\nexport function resolveColumn<TRow>(definition: ColumnDef<TRow>): TableColumn<TRow> {\n // Both branches of the union share these members; the value type is erased at runtime.\n const def = definition as ComputedColumnDef<TRow> | PathColumnDef<TRow, string>;\n const { accessor } = def;\n const getValue: (row: TRow) => unknown = accessor ?? ((row) => getPath(row, def.id));\n const format = def.format ?? ((value: unknown) => formatValue(value));\n const compare = def.compare ?? compareValues;\n const customFilter = def.filter;\n const customParse = def.parse;\n const editable = def.editable ?? false;\n const customSetValue = def.setValue;\n const canWrite = accessor === undefined || customSetValue !== undefined;\n\n return Object.freeze({\n id: def.id,\n header: def.header ?? humanize(def.id),\n align: def.align ?? \"start\",\n width: def.width,\n minWidth: def.minWidth,\n sortable: def.sortable ?? true,\n searchable: def.searchable ?? true,\n initiallyHidden: def.hidden ?? false,\n meta: Object.freeze({ ...def.meta }),\n definition,\n getValue,\n format: (value: unknown, row: TRow): string => format(value as never, row),\n compare: (left: unknown, right: unknown): number => compare(left as never, right as never),\n matches(value: unknown, filterValue: unknown, row: TRow): boolean {\n return customFilter\n ? customFilter(value as never, filterValue, row)\n : matchesFilter(value, filterValue, format(value as never, row));\n },\n isEditable(row: TRow): boolean {\n if (!canWrite) {\n return false;\n }\n return typeof editable === \"function\" ? editable(row) : editable;\n },\n parse(input: string, row: TRow, sample?: unknown): ParseResult {\n if (customParse) {\n try {\n return { ok: true, value: customParse(input, row) };\n } catch (error) {\n return { ok: false, message: error instanceof Error ? error.message : String(error) };\n }\n }\n return parseAs(input, def.type ?? typeOf(getValue(row)) ?? typeOf(sample) ?? \"text\");\n },\n setValue(row: TRow, value: unknown): TRow | undefined {\n if (customSetValue) {\n return customSetValue(row, value);\n }\n return accessor === undefined ? setPath(row, def.id, value) : undefined;\n },\n });\n}\n","/**\n * Delimited text: tab-separated for the clipboard, comma-separated for export.\n *\n * A field is quoted when it holds the delimiter, a quote, or a line break, and quotes inside it\n * are doubled. This is what spreadsheet applications write and read.\n */\n\nfunction quote(field: string, delimiter: string): string {\n return field.includes(delimiter) ||\n field.includes('\"') ||\n field.includes(\"\\n\") ||\n field.includes(\"\\r\")\n ? `\"${field.replaceAll('\"', '\"\"')}\"`\n : field;\n}\n\n/** Write a matrix of text as delimited lines joined with `\\n`. */\nexport function toDelimited(matrix: readonly (readonly string[])[], delimiter = \"\\t\"): string {\n return matrix\n .map((line) => line.map((field) => quote(field, delimiter)).join(delimiter))\n .join(\"\\n\");\n}\n\n/**\n * Read delimited text into a matrix. Accepts `\\n` and `\\r\\n`, quoted fields with doubled quotes\n * and embedded line breaks, and ignores one trailing line break.\n */\nexport function parseDelimited(text: string, delimiter = \"\\t\"): string[][] {\n const rows: string[][] = [];\n let row: string[] = [];\n let field = \"\";\n let quoted = false;\n let index = 0;\n\n const endField = (): void => {\n row.push(field);\n field = \"\";\n };\n const endRow = (): void => {\n endField();\n rows.push(row);\n row = [];\n };\n\n while (index < text.length) {\n const char = text.charAt(index);\n if (quoted) {\n if (char === '\"') {\n if (text.charAt(index + 1) === '\"') {\n field += '\"';\n index += 1;\n } else {\n quoted = false;\n }\n } else {\n field += char;\n }\n } else if (char === '\"' && field === \"\") {\n quoted = true;\n } else if (char === delimiter) {\n endField();\n } else if (char === \"\\n\" || char === \"\\r\") {\n if (char === \"\\r\" && text.charAt(index + 1) === \"\\n\") {\n index += 1;\n }\n endRow();\n } else {\n field += char;\n }\n index += 1;\n }\n\n if (field !== \"\" || row.length > 0) {\n endRow();\n }\n return rows;\n}\n","/**\n * Spreadsheet addressing and selection.\n *\n * A cell is addressed by its position in what is shown: the row index on the current page and the\n * column index among visible columns. A selection is an anchor, where it started, and a focus,\n * where it is now; the rectangle between them is the selected range.\n */\n\nexport interface CellPosition {\n readonly row: number;\n readonly column: number;\n}\n\nexport interface CellRange {\n readonly top: number;\n readonly left: number;\n readonly bottom: number;\n readonly right: number;\n}\n\nexport interface GridSelection {\n readonly anchor: CellPosition;\n readonly focus: CellPosition;\n}\n\n/** The size of the addressable grid. */\nexport interface GridBounds {\n readonly rows: number;\n readonly columns: number;\n}\n\nexport type GridDirection = \"up\" | \"down\" | \"left\" | \"right\";\n\nexport interface MoveOptions {\n /** Keep the anchor and move only the focus, growing or shrinking the range. */\n readonly extend?: boolean | undefined;\n /** Jump to the edge of the grid in that direction. */\n readonly toEdge?: boolean | undefined;\n}\n\nfunction clamp(value: number, max: number): number {\n return Math.min(Math.max(0, value), Math.max(0, max - 1));\n}\n\nexport function clampPosition(position: CellPosition, bounds: GridBounds): CellPosition {\n return { row: clamp(position.row, bounds.rows), column: clamp(position.column, bounds.columns) };\n}\n\n/** A selection of one cell. */\nexport function selectCell(position: CellPosition): GridSelection {\n return { anchor: position, focus: position };\n}\n\n/** Move the focus one step, or to the edge, staying inside the bounds. */\nexport function moveSelection(\n selection: GridSelection,\n direction: GridDirection,\n bounds: GridBounds,\n options: MoveOptions = {},\n): GridSelection {\n const { row, column } = selection.focus;\n const far = options.toEdge === true;\n const next: CellPosition = clampPosition(\n {\n row:\n direction === \"up\"\n ? far\n ? 0\n : row - 1\n : direction === \"down\"\n ? far\n ? bounds.rows - 1\n : row + 1\n : row,\n column:\n direction === \"left\"\n ? far\n ? 0\n : column - 1\n : direction === \"right\"\n ? far\n ? bounds.columns - 1\n : column + 1\n : column,\n },\n bounds,\n );\n return options.extend === true\n ? { anchor: selection.anchor, focus: next }\n : { anchor: next, focus: next };\n}\n\n/** The rectangle a selection covers. */\nexport function selectionRange(selection: GridSelection): CellRange {\n return {\n top: Math.min(selection.anchor.row, selection.focus.row),\n left: Math.min(selection.anchor.column, selection.focus.column),\n bottom: Math.max(selection.anchor.row, selection.focus.row),\n right: Math.max(selection.anchor.column, selection.focus.column),\n };\n}\n\nexport function rangeContains(range: CellRange, position: CellPosition): boolean {\n return (\n position.row >= range.top &&\n position.row <= range.bottom &&\n position.column >= range.left &&\n position.column <= range.right\n );\n}\n\n/** `0` is `\"A\"`, `25` is `\"Z\"`, `26` is `\"AA\"`. */\nexport function columnLabel(index: number): string {\n let label = \"\";\n let rest = index + 1;\n while (rest > 0) {\n const remainder = (rest - 1) % 26;\n label = String.fromCharCode(65 + remainder) + label;\n rest = Math.floor((rest - 1) / 26);\n }\n return label;\n}\n\n/** `{ row: 2, column: 1 }` is `\"B3\"`. */\nexport function toA1(position: CellPosition): string {\n return `${columnLabel(position.column)}${position.row + 1}`;\n}\n\n/** `\"B3\"` is `{ row: 2, column: 1 }`. Returns `undefined` for anything else. */\nexport function fromA1(reference: string): CellPosition | undefined {\n const match = /^([A-Z]+)([1-9]\\d*)$/u.exec(reference.trim().toUpperCase());\n if (!match?.[1] || !match[2]) {\n return undefined;\n }\n let column = 0;\n for (const char of match[1]) {\n column = column * 26 + (char.charCodeAt(0) - 64);\n }\n return { row: Number(match[2]) - 1, column: column - 1 };\n}\n\n/** The keys of a keyboard event that grid navigation reads. */\nexport interface GridKey {\n readonly key: string;\n readonly shiftKey?: boolean | undefined;\n readonly ctrlKey?: boolean | undefined;\n readonly metaKey?: boolean | undefined;\n readonly altKey?: boolean | undefined;\n}\n\n/** What a key press asks a grid to do while no cell is being edited. */\nexport type GridCommand =\n | { readonly type: \"move\"; readonly direction: GridDirection; readonly options: MoveOptions }\n | { readonly type: \"edit\"; readonly initial?: string | undefined }\n | { readonly type: \"clear\" }\n | { readonly type: \"selectAll\" }\n | { readonly type: \"undo\" }\n | { readonly type: \"redo\" }\n | { readonly type: \"cancel\" };\n\nconst ARROWS: Readonly<Record<string, GridDirection>> = {\n ArrowUp: \"up\",\n ArrowDown: \"down\",\n ArrowLeft: \"left\",\n ArrowRight: \"right\",\n};\n\n/**\n * Map a key press to a grid command, spreadsheet style: arrows move (Shift extends, Ctrl or Cmd\n * jumps to the edge), Tab moves across, Home and End reach the row's ends, Enter or F2 edit,\n * a printable character starts editing with that character, Delete and Backspace clear, Escape\n * collapses the selection, and Ctrl or Cmd with A, Z, Y select all, undo, and redo.\n */\nexport function gridCommand(event: GridKey): GridCommand | undefined {\n const mod = event.ctrlKey === true || event.metaKey === true;\n const shift = event.shiftKey === true;\n const direction = ARROWS[event.key];\n if (direction) {\n return { type: \"move\", direction, options: { extend: shift, toEdge: mod } };\n }\n switch (event.key) {\n case \"Tab\":\n return { type: \"move\", direction: shift ? \"left\" : \"right\", options: {} };\n case \"Home\":\n case \"End\":\n return {\n type: \"move\",\n direction: event.key === \"Home\" ? \"left\" : \"right\",\n options: { extend: shift, toEdge: true },\n };\n case \"Enter\":\n case \"F2\":\n return { type: \"edit\" };\n case \"Delete\":\n case \"Backspace\":\n return { type: \"clear\" };\n case \"Escape\":\n return { type: \"cancel\" };\n default:\n break;\n }\n if (mod) {\n const key = event.key.toLowerCase();\n if (key === \"a\") {\n return { type: \"selectAll\" };\n }\n if (key === \"z\") {\n return shift ? { type: \"redo\" } : { type: \"undo\" };\n }\n if (key === \"y\") {\n return { type: \"redo\" };\n }\n return undefined;\n }\n if (event.key.length === 1 && event.altKey !== true) {\n return { type: \"edit\", initial: event.key };\n }\n return undefined;\n}\n","/**\n * An undo stack of batches. Recording a batch clears whatever could be redone, and the stack\n * keeps at most `limit` batches, dropping the oldest.\n */\nexport interface UndoStack<TEntry> {\n readonly canUndo: boolean;\n readonly canRedo: boolean;\n record(entry: TEntry): void;\n /** Take the most recent batch to undo, if any. */\n undo(): TEntry | undefined;\n /** Take the most recently undone batch to redo, if any. */\n redo(): TEntry | undefined;\n clear(): void;\n}\n\nexport function createUndoStack<TEntry>(limit = 100): UndoStack<TEntry> {\n const past: TEntry[] = [];\n const future: TEntry[] = [];\n return {\n get canUndo(): boolean {\n return past.length > 0;\n },\n get canRedo(): boolean {\n return future.length > 0;\n },\n record(entry: TEntry): void {\n past.push(entry);\n if (past.length > limit) {\n past.shift();\n }\n future.length = 0;\n },\n undo(): TEntry | undefined {\n const entry = past.pop();\n if (entry !== undefined) {\n future.push(entry);\n }\n return entry;\n },\n redo(): TEntry | undefined {\n const entry = future.pop();\n if (entry !== undefined) {\n past.push(entry);\n }\n return entry;\n },\n clear(): void {\n past.length = 0;\n future.length = 0;\n },\n };\n}\n","import type { ColumnDef } from \"./column\";\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return false;\n }\n const prototype: unknown = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction collect(value: unknown, prefix: string, depth: number, into: Set<string>): void {\n if (!isPlainObject(value)) {\n return;\n }\n for (const [key, child] of Object.entries(value)) {\n const path = prefix === \"\" ? key : `${prefix}.${key}`;\n if (isPlainObject(child) && depth < 4) {\n collect(child, path, depth + 1, into);\n } else {\n into.add(path);\n }\n }\n}\n\n/**\n * Columns for data that has none declared: one path column per leaf of the first `sample` rows,\n * nested objects flattened into dotted paths, in first-seen order.\n */\nexport function inferColumns<TRow>(rows: readonly TRow[], sample = 20): readonly ColumnDef<TRow>[] {\n const paths = new Set<string>();\n for (const row of rows.slice(0, sample)) {\n collect(row, \"\", 1, paths);\n }\n return Object.freeze([...paths].map((id) => ({ id }) as ColumnDef<TRow>));\n}\n","import type { TableColumn } from \"./column\";\nimport type { TableRow } from \"./row\";\nimport type { PaginationState, SortRule } from \"./state\";\n\n/**\n * The row pipeline: filter, then sort, then paginate. Each stage is a pure function, so a table\n * recomputes only the stages whose inputs changed, and a server can run the same stages.\n */\n\n/** Split free text into lowercase terms. */\nfunction searchTerms(search: string): readonly string[] {\n return search\n .toLowerCase()\n .split(/\\s+/u)\n .filter((term) => term.length > 0);\n}\n\n/**\n * Keep rows that pass every column filter and contain every search term in at least one\n * searchable column.\n */\nexport function filterRows<TRow>(\n rows: readonly TableRow<TRow>[],\n columns: readonly TableColumn<TRow>[],\n search: string,\n filters: Readonly<Record<string, unknown>>,\n): readonly TableRow<TRow>[] {\n const terms = searchTerms(search);\n const byId = new Map(columns.map((column) => [column.id, column]));\n const activeFilters = Object.entries(filters).flatMap(([id, value]) => {\n const column = byId.get(id);\n return column && value !== undefined ? [{ column, value }] : [];\n });\n const searchable = columns.filter((column) => column.searchable);\n\n if (terms.length === 0 && activeFilters.length === 0) {\n return rows;\n }\n\n return rows.filter((row) => {\n for (const { column, value } of activeFilters) {\n if (!column.matches(row.getValue(column.id), value, row.original)) {\n return false;\n }\n }\n if (terms.length === 0) {\n return true;\n }\n const haystack = searchable.map((column) => row.getDisplay(column.id).toLowerCase());\n return terms.every((term) => haystack.some((text) => text.includes(term)));\n });\n}\n\n/** Sort rows by each rule in turn. The sort is stable: ties keep their incoming order. */\nexport function sortRows<TRow>(\n rows: readonly TableRow<TRow>[],\n columns: readonly TableColumn<TRow>[],\n sorting: readonly SortRule[],\n): readonly TableRow<TRow>[] {\n const byId = new Map(columns.map((column) => [column.id, column]));\n const rules = sorting.flatMap((rule) => {\n const column = byId.get(rule.column);\n return column ? [{ column, sign: rule.direction === \"desc\" ? -1 : 1 }] : [];\n });\n if (rules.length === 0) {\n return rows;\n }\n return rows.toSorted((left, right) => {\n for (const { column, sign } of rules) {\n const leftValue = left.getValue(column.id);\n const rightValue = right.getValue(column.id);\n const leftEmpty = leftValue === null || leftValue === undefined || leftValue === \"\";\n const rightEmpty = rightValue === null || rightValue === undefined || rightValue === \"\";\n // Empty values stay last in both directions.\n if (leftEmpty !== rightEmpty) {\n return leftEmpty ? 1 : -1;\n }\n const order = column.compare(leftValue, rightValue) * sign;\n if (order !== 0) {\n return order;\n }\n }\n return 0;\n });\n}\n\n/** The number of pages for a row count. An empty table still has one page. */\nexport function countPages(rowCount: number, pageSize: number): number {\n return Math.max(1, Math.ceil(rowCount / pageSize));\n}\n\n/** Clamp a page into `1..pageCount`. */\nexport function clampPage(page: number, pageCount: number): number {\n return Math.min(Math.max(1, Math.trunc(page) || 1), pageCount);\n}\n\n/** The rows on one page. `pagination.page` must already be clamped. */\nexport function paginateRows<TRow>(\n rows: readonly TableRow<TRow>[],\n pagination: PaginationState,\n): readonly TableRow<TRow>[] {\n const start = (pagination.page - 1) * pagination.pageSize;\n return rows.slice(start, start + pagination.pageSize);\n}\n\n/** A page number, or a gap between page numbers. */\nexport type PageItem =\n | { readonly type: \"page\"; readonly page: number; readonly current: boolean }\n | { readonly type: \"gap\"; readonly key: string };\n\n/**\n * The page buttons to show: always the first and last page, `siblings` pages on each side of the\n * current one, and a gap wherever pages are skipped. A gap never hides a single page.\n */\nexport function paginationItems(\n page: number,\n pageCount: number,\n siblings = 1,\n): readonly PageItem[] {\n const pages = new Set<number>([1, pageCount]);\n for (let offset = -siblings; offset <= siblings; offset += 1) {\n const candidate = page + offset;\n if (candidate >= 1 && candidate <= pageCount) {\n pages.add(candidate);\n }\n }\n const sorted = [...pages].toSorted((left, right) => left - right);\n const items: PageItem[] = [];\n let previous = 0;\n for (const value of sorted) {\n if (value - previous === 2) {\n items.push({ type: \"page\", page: value - 1, current: value - 1 === page });\n } else if (value - previous > 2) {\n items.push({ type: \"gap\", key: `gap-${previous}-${value}` });\n }\n items.push({ type: \"page\", page: value, current: value === page });\n previous = value;\n }\n return items;\n}\n","/** A stable identity for a row, read from the row itself or produced by a function. */\nexport type RowKey = string | number;\n\nexport type SortDirection = \"asc\" | \"desc\";\n\n/** One level of a sort. Several rules sort by the first, then break ties with the next. */\nexport interface SortRule {\n readonly column: string;\n readonly direction: SortDirection;\n}\n\n/** Pages are counted from 1. */\nexport interface PaginationState {\n readonly page: number;\n readonly pageSize: number;\n}\n\n/**\n * Everything a user can change about a table, as plain serializable data.\n *\n * Being plain data, the state can be stored, restored, sent to a server that sorts and pages, or\n * written to the URL with a library such as QueryWeave.\n */\nexport interface TableState {\n readonly sorting: readonly SortRule[];\n /** Free text matched against every searchable column. */\n readonly search: string;\n /** Filter value per column id, interpreted by that column's `filter`. */\n readonly filters: Readonly<Record<string, unknown>>;\n readonly pagination: PaginationState;\n readonly selection: readonly RowKey[];\n readonly hiddenColumns: readonly string[];\n /** Column ids in display order. Columns missing from the list keep their definition order. */\n readonly columnOrder: readonly string[];\n}\n\n/** A partial state, as accepted by `setState` and `initialState`. */\nexport type TableStatePatch = {\n readonly [K in keyof TableState]?: TableState[K] | undefined;\n};\n\nexport const DEFAULT_PAGE_SIZE = 10;\n\nexport function createInitialState(patch: TableStatePatch = {}): TableState {\n return freezeState({\n sorting: patch.sorting ?? [],\n search: patch.search ?? \"\",\n filters: patch.filters ?? {},\n pagination: patch.pagination ?? { page: 1, pageSize: DEFAULT_PAGE_SIZE },\n selection: patch.selection ?? [],\n hiddenColumns: patch.hiddenColumns ?? [],\n columnOrder: patch.columnOrder ?? [],\n });\n}\n\nexport function mergeState(state: TableState, patch: TableStatePatch): TableState {\n let changed = false;\n const next: Record<string, unknown> = { ...state };\n for (const [key, value] of Object.entries(patch)) {\n if (value === undefined || Object.is(next[key], value)) {\n continue;\n }\n if (\n key === \"pagination\" &&\n samePagination(next[key] as PaginationState, value as PaginationState)\n ) {\n continue;\n }\n next[key] = value;\n changed = true;\n }\n return changed ? freezeState(next as unknown as TableState) : state;\n}\n\nfunction samePagination(left: PaginationState, right: PaginationState): boolean {\n return left.page === right.page && left.pageSize === right.pageSize;\n}\n\nfunction freezeState(state: TableState): TableState {\n return Object.freeze({\n sorting: Object.freeze(state.sorting.map((rule) => Object.freeze({ ...rule }))),\n search: state.search,\n filters: Object.freeze({ ...state.filters }),\n pagination: Object.freeze({ ...state.pagination }),\n selection: Object.freeze([...state.selection]),\n hiddenColumns: Object.freeze([...state.hiddenColumns]),\n columnOrder: Object.freeze([...state.columnOrder]),\n });\n}\n","import type { RowKey } from \"./state\";\n\n/** Every problem the engine can report. The union grows in minor versions. */\nexport type TableIssueCode =\n | \"duplicate_row_key\"\n | \"unknown_column\"\n | \"invalid_page_size\"\n | \"unknown_row\"\n | \"read_only_cell\"\n | \"invalid_value\";\n\n/**\n * A problem the engine recovered from. Invalid input is never dropped silently: the engine falls\n * back to something safe and reports what it did here.\n */\nexport interface TableIssue {\n readonly code: TableIssueCode;\n readonly message: string;\n readonly column?: string | undefined;\n readonly rowKey?: RowKey | undefined;\n}\n\nexport function issue(\n code: TableIssueCode,\n message: string,\n details: { readonly column?: string | undefined; readonly rowKey?: RowKey | undefined } = {},\n): TableIssue {\n return Object.freeze({ code, message, ...details });\n}\n","import type { TableColumn } from \"./column\";\nimport type { RowKey } from \"./state\";\n\n/**\n * One row of data as the engine sees it: its key, its position in the source data, and cached\n * access to each column's value and text.\n */\nexport interface TableRow<TRow> {\n readonly key: RowKey;\n /** Position in the data the table was given. */\n readonly index: number;\n readonly original: TRow;\n getValue(columnId: string): unknown;\n /** The formatted text of a cell, as shown, searched, copied, and exported. */\n getDisplay(columnId: string): string;\n}\n\nexport function createRow<TRow>(\n original: TRow,\n key: RowKey,\n index: number,\n columns: ReadonlyMap<string, TableColumn<TRow>>,\n): TableRow<TRow> {\n const values = new Map<string, unknown>();\n const displays = new Map<string, string>();\n\n const getValue = (columnId: string): unknown => {\n if (values.has(columnId)) {\n return values.get(columnId);\n }\n const value = columns.get(columnId)?.getValue(original);\n values.set(columnId, value);\n return value;\n };\n\n return Object.freeze({\n key,\n index,\n original,\n getValue,\n getDisplay(columnId: string): string {\n const cached = displays.get(columnId);\n if (cached !== undefined) {\n return cached;\n }\n const column = columns.get(columnId);\n const display = column ? column.format(getValue(columnId), original) : \"\";\n displays.set(columnId, display);\n return display;\n },\n });\n}\n","import { resolveColumn, type ColumnDef, type TableColumn } from \"./column\";\nimport { parseDelimited, toDelimited } from \"./delimited\";\nimport { rangeContains, type CellPosition, type CellRange } from \"./grid\";\nimport { issue, type TableIssue } from \"./issues\";\nimport type { DeepKeys } from \"./path\";\nimport { getPath } from \"./path\";\nimport {\n clampPage,\n countPages,\n filterRows,\n paginateRows,\n sortRows,\n type PageItem,\n paginationItems,\n} from \"./pipeline\";\nimport { createRow, type TableRow } from \"./row\";\nimport {\n DEFAULT_PAGE_SIZE,\n createInitialState,\n mergeState,\n type RowKey,\n type SortDirection,\n type TableState,\n type TableStatePatch,\n} from \"./state\";\nimport { createUndoStack } from \"./undo-stack\";\n\nexport type SelectionMode = \"none\" | \"single\" | \"multiple\";\n\n/** Which rows \"select all\" covers: the current page, or every row that passes the filters. */\nexport type SelectScope = \"page\" | \"all\";\n\nexport interface TableOptions<TRow> {\n readonly data: readonly TRow[];\n readonly columns: readonly ColumnDef<TRow>[];\n /**\n * How to identify a row: a path into it, or a function. Defaults to `id` when rows have one and\n * to the row's position otherwise.\n */\n readonly rowKey?: DeepKeys<TRow> | ((row: TRow, index: number) => RowKey) | undefined;\n readonly initialState?: TableStatePatch | undefined;\n /** Defaults to `\"multiple\"`. */\n readonly selectionMode?: SelectionMode | undefined;\n /** Defaults to `\"all\"`. */\n readonly selectScope?: SelectScope | undefined;\n /**\n * The data is one page that a server has already searched, filtered, sorted, and paginated\n * with the current state. The table only presents it; `rowCount` gives the total.\n */\n readonly manual?: boolean | undefined;\n /** The total number of rows across all pages, for `manual` tables. */\n readonly rowCount?: number | undefined;\n /** Called after every state change a table operation makes, not after `setState`. */\n readonly onStateChange?: ((state: TableState, previous: TableState) => void) | undefined;\n /** Called with the new data after an edit, a paste, an undo, or a redo. */\n readonly onDataChange?:\n | ((data: readonly TRow[], changes: readonly CellChange<TRow>[]) => void)\n | undefined;\n /** Called with the reasons whenever an edit, a paste, or a clear refuses some cells. */\n readonly onEditIssues?: ((issues: readonly TableIssue[]) => void) | undefined;\n /** The most edit batches `undo` can reach. Defaults to 100. */\n readonly historyLimit?: number | undefined;\n}\n\nexport type SelectionCoverage = \"none\" | \"some\" | \"all\";\n\nexport interface SortInfo {\n readonly direction: SortDirection;\n /** 0 for the first rule, 1 for the next, and so on. */\n readonly priority: number;\n}\n\n/**\n * Everything a renderer needs, computed from the data, the columns, and the state. A snapshot is\n * frozen and replaced on each change, so comparing snapshots by identity detects a change.\n */\nexport interface TableSnapshot<TRow> {\n readonly state: TableState;\n /** Visible columns in display order. */\n readonly columns: readonly TableColumn<TRow>[];\n /** Every column in display order, hidden ones included. */\n readonly allColumns: readonly TableColumn<TRow>[];\n /** Rows on the current page. */\n readonly rows: readonly TableRow<TRow>[];\n /** Rows on every page, filtered and sorted. For `manual` tables this is the current page. */\n readonly processedRows: readonly TableRow<TRow>[];\n /** The current page, clamped into range. */\n readonly page: number;\n readonly pageSize: number;\n readonly pageCount: number;\n /** Rows that pass the search and filters. */\n readonly rowCount: number;\n /** Rows before searching and filtering. */\n readonly totalRowCount: number;\n /** The 1-based position of the first row on this page, or 0 when there are no rows. */\n readonly pageStart: number;\n /** The 1-based position of the last row on this page, or 0 when there are no rows. */\n readonly pageEnd: number;\n readonly pageItems: readonly PageItem[];\n readonly canPreviousPage: boolean;\n readonly canNextPage: boolean;\n readonly selectionMode: SelectionMode;\n readonly selectedCount: number;\n /** How much of the current page is selected. */\n readonly pageSelection: SelectionCoverage;\n /** How much of the select-all scope is selected. */\n readonly allSelection: SelectionCoverage;\n readonly canUndo: boolean;\n readonly canRedo: boolean;\n readonly issues: readonly TableIssue[];\n isSelected(key: RowKey): boolean;\n getSort(columnId: string): SortInfo | undefined;\n getColumn(columnId: string): TableColumn<TRow> | undefined;\n getRow(key: RowKey): TableRow<TRow> | undefined;\n}\n\n/** An edit given as a value of the column's type. */\nexport interface CellValueEdit {\n readonly rowKey: RowKey;\n readonly column: string;\n readonly value: unknown;\n}\n\n/** An edit given as text, read by the column's `parse`, as typed or pasted. */\nexport interface CellInputEdit {\n readonly rowKey: RowKey;\n readonly column: string;\n readonly input: string;\n}\n\nexport type CellEdit = CellValueEdit | CellInputEdit;\n\nexport interface CellChange<TRow> {\n readonly rowKey: RowKey;\n readonly column: string;\n readonly previous: unknown;\n readonly value: unknown;\n /** The row after the change. */\n readonly row: TRow;\n}\n\nexport type EditStatus = \"applied\" | \"partial\" | \"rejected\" | \"unchanged\";\n\n/**\n * The outcome of a batch of edits. `partial` means some edits applied and others were refused;\n * each refusal is in `issues`.\n */\nexport interface EditResult<TRow> {\n readonly status: EditStatus;\n readonly changes: readonly CellChange<TRow>[];\n readonly issues: readonly TableIssue[];\n}\n\nexport interface ExportOptions {\n /** Defaults to `\"csv\"`. */\n readonly format?: \"csv\" | \"tsv\" | undefined;\n /** Column ids to export. Defaults to the visible columns. */\n readonly columns?: readonly string[] | undefined;\n /** Export only the current page. Defaults to every filtered row. */\n readonly pageOnly?: boolean | undefined;\n /** Defaults to `true`. */\n readonly headers?: boolean | undefined;\n}\n\n/**\n * A data table: data, columns, and state, with named operations to change them. It knows nothing\n * about rendering; a framework binding subscribes to it and draws each snapshot.\n */\nexport interface DataTable<TRow> {\n getSnapshot(): TableSnapshot<TRow>;\n getState(): TableState;\n /** Called after every change with the new snapshot. Returns the unsubscribe function. */\n subscribe(listener: (snapshot: TableSnapshot<TRow>) => void): () => void;\n\n /** Replace part of the state from outside, without calling `onStateChange`. */\n setState(patch: TableStatePatch): void;\n /** Replace the data. The undo stack is cleared unless the data is the table's own. */\n setData(data: readonly TRow[]): void;\n setColumns(columns: readonly ColumnDef<TRow>[]): void;\n /** Update the total row count of a `manual` table. */\n setRowCount(rowCount: number): void;\n\n /** Cycle a column through ascending, descending, and unsorted. */\n toggleSort(columnId: string, options?: { readonly multi?: boolean | undefined }): void;\n /** Sort by one column, or clear it with `undefined`. */\n sort(\n columnId: string,\n direction: SortDirection | undefined,\n options?: { readonly multi?: boolean | undefined },\n ): void;\n clearSorting(): void;\n search(text: string): void;\n /** Set a column's filter value; an empty value removes the filter. */\n filter(columnId: string, value: unknown): void;\n clearFilters(): void;\n\n goToPage(page: number): void;\n nextPage(): void;\n previousPage(): void;\n /** Change the page size, keeping the first row of the current page in view. */\n setPageSize(pageSize: number): void;\n\n select(keys: readonly RowKey[]): void;\n deselect(keys: readonly RowKey[]): void;\n toggleRow(key: RowKey, selected?: boolean): void;\n /** Select every row in the scope, or clear them when all are already selected. */\n toggleAll(scope?: SelectScope): void;\n clearSelection(): void;\n /** The selected rows that are present in the data. */\n getSelectedRows(): readonly TableRow<TRow>[];\n\n toggleColumn(columnId: string, visible?: boolean): void;\n moveColumn(columnId: string, toIndex: number): void;\n\n edit(edits: CellEdit | readonly CellEdit[]): EditResult<TRow>;\n undo(): boolean;\n redo(): boolean;\n /** The text of a range of shown cells, tab-separated like a spreadsheet clipboard. */\n copy(range: CellRange): string;\n /** Paste tab-separated text with its top-left cell at `origin`, clipped to the grid. */\n paste(origin: CellPosition, text: string): EditResult<TRow>;\n /** Empty every editable cell in a range. */\n clear(range: CellRange): EditResult<TRow>;\n exportRows(options?: ExportOptions): string;\n\n /** Return to the initial state. */\n reset(): void;\n /** Drop every listener. */\n destroy(): void;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction memo<TDeps extends readonly unknown[], TResult>(\n compute: (...deps: TDeps) => TResult,\n): (...deps: TDeps) => TResult {\n let last: { readonly deps: TDeps; readonly result: TResult } | undefined;\n return (...deps: TDeps): TResult => {\n if (\n last &&\n last.deps.length === deps.length &&\n last.deps.every((d, i) => Object.is(d, deps[i]))\n ) {\n return last.result;\n }\n const result = compute(...deps);\n last = { deps, result };\n return result;\n };\n}\n\nfunction isInputEdit(edit: CellEdit): edit is CellInputEdit {\n return \"input\" in edit;\n}\n\nfunction coverage(selected: number, total: number): SelectionCoverage {\n if (selected === 0 || total === 0) {\n return \"none\";\n }\n return selected === total ? \"all\" : \"some\";\n}\n\ninterface IndexedRows<TRow> {\n readonly rows: readonly TableRow<TRow>[];\n readonly byKey: ReadonlyMap<RowKey, TableRow<TRow>>;\n readonly issues: readonly TableIssue[];\n}\n\n/** Create a data table. */\nexport function createTable<TRow>(options: TableOptions<TRow>): DataTable<TRow> {\n const selectionMode = options.selectionMode ?? \"multiple\";\n const selectScope = options.selectScope ?? \"all\";\n const manual = options.manual ?? false;\n const undoStack = createUndoStack<readonly CellChange<TRow>[]>(options.historyLimit);\n const listeners = new Set<(snapshot: TableSnapshot<TRow>) => void>();\n\n let data = options.data;\n let definitions = options.columns;\n let rowCount = options.rowCount;\n const initialState = createInitialState({\n ...options.initialState,\n hiddenColumns:\n options.initialState?.hiddenColumns ??\n options.columns.filter((column) => column.hidden === true).map((column) => column.id),\n });\n let state = initialState;\n let snapshot: TableSnapshot<TRow> | undefined;\n\n const readKey = (row: TRow, index: number): RowKey => {\n const { rowKey } = options;\n if (typeof rowKey === \"function\") {\n return rowKey(row, index);\n }\n const path = rowKey ?? \"id\";\n const value = getPath(row, path);\n if (typeof value === \"string\" || typeof value === \"number\") {\n return value;\n }\n return rowKey === undefined || !isRecord(row) ? index : String(value);\n };\n\n const resolveColumns = memo((defs: readonly ColumnDef<TRow>[]) => {\n const columns = defs.map((definition) => resolveColumn(definition));\n return { columns, byId: new Map(columns.map((column) => [column.id, column])) };\n });\n\n const indexRows = memo(\n (rows: readonly TRow[], byId: ReadonlyMap<string, TableColumn<TRow>>): IndexedRows<TRow> => {\n const byKey = new Map<RowKey, TableRow<TRow>>();\n const issues: TableIssue[] = [];\n const indexed = rows.map((original, index) => {\n let key = readKey(original, index);\n if (byKey.has(key)) {\n issues.push(\n issue(\n \"duplicate_row_key\",\n `Row ${index} repeats the key \"${String(key)}\"; it is keyed \"${String(key)}#${index}\" instead.`,\n { rowKey: key },\n ),\n );\n key = `${String(key)}#${index}`;\n }\n const row = createRow(original, key, index, byId);\n byKey.set(key, row);\n return row;\n });\n return { rows: indexed, byKey, issues };\n },\n );\n\n const orderColumns = memo(\n (\n columns: readonly TableColumn<TRow>[],\n columnOrder: readonly string[],\n hiddenColumns: readonly string[],\n ) => {\n const position = new Map(columnOrder.map((id, index) => [id, index]));\n const ordered = columns\n .map((column, index) => ({ column, index }))\n .toSorted((left, right) => {\n const leftPosition = position.get(left.column.id) ?? columnOrder.length + left.index;\n const rightPosition = position.get(right.column.id) ?? columnOrder.length + right.index;\n return leftPosition - rightPosition;\n })\n .map(({ column }) => column);\n const hidden = new Set(hiddenColumns);\n return { all: ordered, visible: ordered.filter((column) => !hidden.has(column.id)) };\n },\n );\n\n const filterStage = memo(filterRows<TRow>);\n const sortStage = memo(sortRows<TRow>);\n const selectedSet = memo((selection: readonly RowKey[]) => new Set(selection));\n\n function stateIssues(byId: ReadonlyMap<string, TableColumn<TRow>>): TableIssue[] {\n const issues: TableIssue[] = [];\n const referenced = new Set([\n ...state.sorting.map((rule) => rule.column),\n ...Object.keys(state.filters),\n ...state.hiddenColumns,\n ...state.columnOrder,\n ]);\n for (const id of referenced) {\n if (!byId.has(id)) {\n issues.push(\n issue(\"unknown_column\", `The state refers to a column \"${id}\" that is not defined.`, {\n column: id,\n }),\n );\n }\n }\n const { pageSize } = state.pagination;\n if (!Number.isInteger(pageSize) || pageSize < 1) {\n issues.push(\n issue(\n \"invalid_page_size\",\n `Page size ${String(pageSize)} is not a positive whole number; ${DEFAULT_PAGE_SIZE} is used.`,\n ),\n );\n }\n return issues;\n }\n\n function computeSnapshot(): TableSnapshot<TRow> {\n const { columns, byId } = resolveColumns(definitions);\n const indexed = indexRows(data, byId);\n const ordered = orderColumns(columns, state.columnOrder, state.hiddenColumns);\n const issues = [...indexed.issues, ...stateIssues(byId)];\n const requestedSize = state.pagination.pageSize;\n const pageSize =\n Number.isInteger(requestedSize) && requestedSize >= 1 ? requestedSize : DEFAULT_PAGE_SIZE;\n\n let processedRows: readonly TableRow<TRow>[];\n let rows: readonly TableRow<TRow>[];\n let filteredCount: number;\n let page: number;\n let pageCount: number;\n if (manual) {\n processedRows = indexed.rows;\n rows = indexed.rows;\n filteredCount = rowCount ?? indexed.rows.length;\n pageCount = countPages(filteredCount, pageSize);\n page = clampPage(state.pagination.page, pageCount);\n } else {\n const filtered = filterStage(indexed.rows, columns, state.search, state.filters);\n processedRows = sortStage(filtered, columns, state.sorting);\n filteredCount = processedRows.length;\n pageCount = countPages(filteredCount, pageSize);\n page = clampPage(state.pagination.page, pageCount);\n rows = paginateRows(processedRows, { page, pageSize });\n }\n\n const selected = selectedSet(state.selection);\n const pageSelected = rows.filter((row) => selected.has(row.key)).length;\n const scopeRows = selectScope === \"page\" || manual ? rows : processedRows;\n const scopeSelected =\n scopeRows === rows ? pageSelected : scopeRows.filter((row) => selected.has(row.key)).length;\n const pageStart = rows.length === 0 ? 0 : (page - 1) * pageSize + 1;\n const sortIndex = new Map(\n state.sorting.map((rule, priority) => [rule.column, { direction: rule.direction, priority }]),\n );\n\n return Object.freeze({\n state,\n columns: ordered.visible,\n allColumns: ordered.all,\n rows,\n processedRows,\n page,\n pageSize,\n pageCount,\n rowCount: filteredCount,\n totalRowCount: manual ? filteredCount : indexed.rows.length,\n pageStart,\n pageEnd: rows.length === 0 ? 0 : pageStart + rows.length - 1,\n pageItems: paginationItems(page, pageCount),\n canPreviousPage: page > 1,\n canNextPage: page < pageCount,\n selectionMode,\n selectedCount: state.selection.length,\n pageSelection: coverage(pageSelected, rows.length),\n allSelection: coverage(scopeSelected, scopeRows.length),\n canUndo: undoStack.canUndo,\n canRedo: undoStack.canRedo,\n issues: Object.freeze(issues),\n isSelected: (key: RowKey): boolean => selected.has(key),\n getSort: (columnId: string): SortInfo | undefined => sortIndex.get(columnId),\n getColumn: (columnId: string): TableColumn<TRow> | undefined => byId.get(columnId),\n getRow: (key: RowKey): TableRow<TRow> | undefined => indexed.byKey.get(key),\n });\n }\n\n function getSnapshot(): TableSnapshot<TRow> {\n snapshot ??= computeSnapshot();\n return snapshot;\n }\n\n function notify(): void {\n snapshot = undefined;\n if (listeners.size === 0) {\n return;\n }\n const next = getSnapshot();\n for (const listener of listeners) {\n listener(next);\n }\n }\n\n /** Apply a change made by a table operation. */\n function commit(patch: TableStatePatch): void {\n const previous = state;\n const next = mergeState(state, patch);\n if (next === previous) {\n return;\n }\n state = next;\n options.onStateChange?.(state, previous);\n notify();\n }\n\n const firstPage = (): { readonly page: number; readonly pageSize: number } => ({\n page: 1,\n pageSize: state.pagination.pageSize,\n });\n\n function setSort(columnId: string, direction: SortDirection | undefined, multi: boolean): void {\n const column = getSnapshot().getColumn(columnId);\n if (!column?.sortable) {\n return;\n }\n const others = multi ? state.sorting.filter((rule) => rule.column !== columnId) : [];\n const existing = state.sorting.findIndex((rule) => rule.column === columnId);\n let sorting = others;\n if (direction) {\n const rule = { column: columnId, direction };\n sorting =\n multi && existing !== -1\n ? state.sorting.map((current) => (current.column === columnId ? rule : current))\n : [...others, rule];\n }\n commit({ sorting, pagination: firstPage() });\n }\n\n function applySelection(next: readonly RowKey[]): void {\n if (selectionMode === \"none\") {\n return;\n }\n const unique = [...new Set(next)];\n const selection = selectionMode === \"single\" ? unique.slice(-1) : unique;\n const current = state.selection;\n if (selection.length === current.length && selection.every((key, i) => key === current[i])) {\n return;\n }\n commit({ selection });\n }\n\n function applyChanges(edits: readonly CellEdit[], record: boolean): EditResult<TRow> {\n const current = getSnapshot();\n const working = [...data];\n const issues: TableIssue[] = [];\n const changes: CellChange<TRow>[] = [];\n // A value from another row tells a column's type when the edited cell is empty. It is looked\n // up once per column, not once per edit, so pasting a large range stays linear.\n const samples = new Map<string, unknown>();\n const sampleOf = (columnId: string): unknown => {\n if (!samples.has(columnId)) {\n const other = current.processedRows.find((candidate) => {\n const value = candidate.getValue(columnId);\n return value !== null && value !== undefined;\n });\n samples.set(columnId, other?.getValue(columnId));\n }\n return samples.get(columnId);\n };\n for (const edit of edits) {\n const row = current.getRow(edit.rowKey);\n const column = current.getColumn(edit.column);\n if (!row) {\n issues.push(\n issue(\"unknown_row\", `No row has the key \"${String(edit.rowKey)}\".`, {\n rowKey: edit.rowKey,\n column: edit.column,\n }),\n );\n continue;\n }\n if (!column) {\n issues.push(\n issue(\"unknown_column\", `No column has the id \"${edit.column}\".`, {\n rowKey: edit.rowKey,\n column: edit.column,\n }),\n );\n continue;\n }\n const original = working[row.index] as TRow;\n if (record && !column.isEditable(original)) {\n issues.push(\n issue(\n \"read_only_cell\",\n `The \"${column.id}\" cell of row \"${String(row.key)}\" is read-only.`,\n {\n rowKey: row.key,\n column: column.id,\n },\n ),\n );\n continue;\n }\n let value: unknown;\n if (isInputEdit(edit)) {\n const parsed = column.parse(edit.input, original, sampleOf(column.id));\n if (!parsed.ok) {\n issues.push(\n issue(\"invalid_value\", parsed.message, { rowKey: row.key, column: column.id }),\n );\n continue;\n }\n value = parsed.value;\n } else {\n value = edit.value;\n }\n const previous = column.getValue(original);\n if (Object.is(previous, value)) {\n continue;\n }\n const updated = column.setValue(original, value);\n if (updated === undefined) {\n issues.push(\n issue(\"read_only_cell\", `The \"${column.id}\" column has no way to write a value.`, {\n rowKey: row.key,\n column: column.id,\n }),\n );\n continue;\n }\n working[row.index] = updated;\n changes.push({ rowKey: row.key, column: column.id, previous, value, row: updated });\n }\n\n let status: EditStatus;\n if (changes.length === 0) {\n status = issues.length > 0 ? \"rejected\" : \"unchanged\";\n } else {\n status = issues.length > 0 ? \"partial\" : \"applied\";\n data = working;\n if (record) {\n undoStack.record(changes);\n }\n options.onDataChange?.(data, changes);\n notify();\n }\n if (issues.length > 0) {\n options.onEditIssues?.(issues);\n }\n return Object.freeze({\n status,\n changes: Object.freeze(changes),\n issues: Object.freeze(issues),\n });\n }\n\n function rangeEdits(origin: CellPosition, matrix: readonly (readonly string[])[]): CellEdit[] {\n const { rows, columns } = getSnapshot();\n const edits: CellEdit[] = [];\n matrix.forEach((line, rowOffset) => {\n const row = rows[origin.row + rowOffset];\n if (!row) {\n return;\n }\n line.forEach((input, columnOffset) => {\n const column = columns[origin.column + columnOffset];\n if (column) {\n edits.push({ rowKey: row.key, column: column.id, input });\n }\n });\n });\n return edits;\n }\n\n function replay(changes: readonly CellChange<TRow>[], direction: \"undo\" | \"redo\"): void {\n applyChanges(\n changes.map((change) => ({\n rowKey: change.rowKey,\n column: change.column,\n value: direction === \"undo\" ? change.previous : change.value,\n })),\n false,\n );\n }\n\n const table: DataTable<TRow> = {\n getSnapshot,\n getState: () => state,\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n\n setState(patch) {\n const next = mergeState(state, patch);\n if (next !== state) {\n state = next;\n notify();\n }\n },\n setData(next) {\n if (next === data) {\n return;\n }\n data = next;\n undoStack.clear();\n notify();\n },\n setColumns(next) {\n if (next === definitions) {\n return;\n }\n definitions = next;\n notify();\n },\n setRowCount(next) {\n if (next === rowCount) {\n return;\n }\n rowCount = next;\n notify();\n },\n\n toggleSort(columnId, { multi = false } = {}) {\n const current = state.sorting.find((rule) => rule.column === columnId)?.direction;\n const next = current === undefined ? \"asc\" : current === \"asc\" ? \"desc\" : undefined;\n setSort(columnId, next, multi);\n },\n sort(columnId, direction, { multi = false } = {}) {\n setSort(columnId, direction, multi);\n },\n clearSorting() {\n commit({ sorting: [] });\n },\n search(text) {\n if (text === state.search) {\n return;\n }\n commit({ search: text, pagination: firstPage() });\n },\n filter(columnId, value) {\n const filters: Record<string, unknown> = { ...state.filters };\n const empty =\n value === undefined ||\n value === null ||\n value === \"\" ||\n (Array.isArray(value) && value.length === 0);\n if (empty ? !(columnId in filters) : Object.is(filters[columnId], value)) {\n return;\n }\n if (empty) {\n delete filters[columnId];\n } else {\n filters[columnId] = value;\n }\n commit({ filters, pagination: firstPage() });\n },\n clearFilters() {\n if (Object.keys(state.filters).length > 0) {\n commit({ filters: {}, pagination: firstPage() });\n }\n },\n\n goToPage(page) {\n const { pageCount, page: currentPage } = getSnapshot();\n const next = clampPage(page, pageCount);\n if (next !== currentPage || next !== state.pagination.page) {\n commit({ pagination: { page: next, pageSize: state.pagination.pageSize } });\n }\n },\n nextPage() {\n table.goToPage(getSnapshot().page + 1);\n },\n previousPage() {\n table.goToPage(getSnapshot().page - 1);\n },\n setPageSize(pageSize) {\n if (!Number.isInteger(pageSize) || pageSize < 1 || pageSize === state.pagination.pageSize) {\n return;\n }\n const { pageStart } = getSnapshot();\n const page = pageStart === 0 ? 1 : Math.floor((pageStart - 1) / pageSize) + 1;\n commit({ pagination: { page, pageSize } });\n },\n\n select(keys) {\n applySelection([...state.selection, ...keys]);\n },\n deselect(keys) {\n const removed = new Set(keys);\n applySelection(state.selection.filter((key) => !removed.has(key)));\n },\n toggleRow(key, selected) {\n const isSelected = state.selection.includes(key);\n const next = selected ?? !isSelected;\n if (next === isSelected) {\n return;\n }\n if (next) {\n table.select([key]);\n } else {\n table.deselect([key]);\n }\n },\n toggleAll(scope = selectScope) {\n if (selectionMode !== \"multiple\") {\n return;\n }\n const current = getSnapshot();\n const rows = scope === \"page\" || manual ? current.rows : current.processedRows;\n const keys = rows.map((row) => row.key);\n const allSelected = keys.length > 0 && keys.every((key) => current.isSelected(key));\n if (allSelected) {\n table.deselect(keys);\n } else {\n table.select(keys);\n }\n },\n clearSelection() {\n applySelection([]);\n },\n getSelectedRows() {\n const current = getSnapshot();\n return state.selection.flatMap((key) => {\n const row = current.getRow(key);\n return row ? [row] : [];\n });\n },\n\n toggleColumn(columnId, visible) {\n if (!getSnapshot().getColumn(columnId)) {\n return;\n }\n const hidden = state.hiddenColumns.includes(columnId);\n const show = visible ?? hidden;\n if (show === !hidden) {\n return;\n }\n commit({\n hiddenColumns: show\n ? state.hiddenColumns.filter((id) => id !== columnId)\n : [...state.hiddenColumns, columnId],\n });\n },\n moveColumn(columnId, toIndex) {\n const order = getSnapshot().allColumns.map((column) => column.id);\n const from = order.indexOf(columnId);\n if (from === -1) {\n return;\n }\n const target = Math.min(Math.max(0, Math.trunc(toIndex)), order.length - 1);\n if (target === from) {\n return;\n }\n order.splice(from, 1);\n order.splice(target, 0, columnId);\n commit({ columnOrder: order });\n },\n\n edit(edits) {\n return applyChanges(Array.isArray(edits) ? edits : [edits as CellEdit], true);\n },\n undo() {\n const changes = undoStack.undo();\n if (!changes) {\n return false;\n }\n replay(changes, \"undo\");\n return true;\n },\n redo() {\n const changes = undoStack.redo();\n if (!changes) {\n return false;\n }\n replay(changes, \"redo\");\n return true;\n },\n copy(range) {\n const { rows, columns } = getSnapshot();\n const matrix: string[][] = [];\n rows.forEach((row, rowIndex) => {\n const line: string[] = [];\n columns.forEach((column, columnIndex) => {\n if (rangeContains(range, { row: rowIndex, column: columnIndex })) {\n line.push(row.getDisplay(column.id));\n }\n });\n if (line.length > 0) {\n matrix.push(line);\n }\n });\n return toDelimited(matrix);\n },\n paste(origin, text) {\n return applyChanges(rangeEdits(origin, parseDelimited(text)), true);\n },\n clear(range) {\n const matrix = Array.from({ length: range.bottom - range.top + 1 }, () =>\n Array.from({ length: range.right - range.left + 1 }, () => \"\"),\n );\n const current = getSnapshot();\n const edits = rangeEdits({ row: range.top, column: range.left }, matrix).filter((edit) => {\n const row = current.getRow(edit.rowKey);\n return (\n row !== undefined && current.getColumn(edit.column)?.isEditable(row.original) === true\n );\n });\n return applyChanges(edits, true);\n },\n exportRows({ format = \"csv\", columns: ids, pageOnly = false, headers = true } = {}) {\n const current = getSnapshot();\n const columns = ids\n ? ids.flatMap((id) => {\n const column = current.getColumn(id);\n return column ? [column] : [];\n })\n : current.columns;\n const rows = pageOnly ? current.rows : current.processedRows;\n const matrix = rows.map((row) => columns.map((column) => row.getDisplay(column.id)));\n if (headers) {\n matrix.unshift(columns.map((column) => column.header));\n }\n return toDelimited(matrix, format === \"csv\" ? \",\" : \"\\t\");\n },\n\n reset() {\n commit(initialState);\n },\n destroy() {\n listeners.clear();\n },\n };\n return table;\n}\n"],"mappings":";;;;;AAIA,SAAgB,SAAS,IAAoB;CAM3C,MAAM,WALQ,GACX,QAAQ,uBAAuB,OAAO,CAAC,CACvC,MAAM,WAAW,CAAC,CAClB,QAAQ,SAAS,KAAK,SAAS,CAAC,CAAC,CACjC,KAAK,SAAS,KAAK,YAAY,CACb,CAAC,CAAC,KAAK,GAAG;CAC/B,OAAO,SAAS,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,SAAS,MAAM,CAAC;AAC5D;;;;AC+BA,SAASA,WAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU;AAChD;;AAGA,SAAgB,QAAQ,QAAiB,MAAuB;CAC9D,IAAI,UAAmB;CACvB,KAAK,MAAM,WAAW,KAAK,MAAM,GAAG,GAAG;EACrC,IAAI,CAACA,WAAS,OAAO,GACnB;EAEF,UAAU,QAAQ;CACpB;CACA,OAAO;AACT;;;;;AAMA,SAAgB,QAAW,QAAW,MAAc,OAAmB;CACrE,MAAM,CAAC,MAAM,GAAG,QAAQ,KAAK,MAAM,GAAG;CACtC,MAAM,OAAgCA,WAAS,MAAM,IAAI,EAAE,GAAG,OAAO,IAAI,CAAC;CAC1E,IAAI,SAAS,QACX,OAAO;CAET,KAAK,QAAQ,KAAK,WAAW,IAAI,QAAQ,QAAQ,KAAK,OAAO,KAAK,KAAK,GAAG,GAAG,KAAK;CAClF,OAAO;AACT;;;;;ACaA,SAAgB,cACd,SAC4B;CAC5B,OAAO,OAAO,OAAO,CAAC,GAAG,OAAO,CAAC;AACnC;AAmCA,MAAM,WAAW,IAAI,KAAK,SAAS,QAAW;CAAE,SAAS;CAAM,aAAa;AAAO,CAAC;AAEpF,SAAS,QAAQ,OAAyB;CACxC,OAAO,UAAU,QAAQ,UAAU,UAAa,UAAU;AAC5D;;AAGA,SAAgB,cAAc,MAAe,OAAwB;CACnE,MAAM,YAAY,QAAQ,IAAI;CAC9B,MAAM,aAAa,QAAQ,KAAK;CAChC,IAAI,aAAa,YACf,OAAO,cAAc,aAAa,IAAI,YAAY,IAAI;CAExD,IAAI,OAAO,SAAS,YAAY,OAAO,UAAU,UAC/C,OAAO,OAAO;CAEhB,IAAI,OAAO,SAAS,YAAY,OAAO,UAAU,UAC/C,OAAO,OAAO,QAAQ,KAAK,OAAO,QAAQ,IAAI;CAEhD,IAAI,gBAAgB,QAAQ,iBAAiB,MAC3C,OAAO,KAAK,QAAQ,IAAI,MAAM,QAAQ;CAExC,IAAI,OAAO,SAAS,aAAa,OAAO,UAAU,WAChD,OAAO,OAAO,IAAI,IAAI,OAAO,KAAK;CAEpC,OAAO,SAAS,QAAQ,YAAY,IAAI,GAAG,YAAY,KAAK,CAAC;AAC/D;;;;;;AAOA,SAAgB,YAAY,OAAwB;CAClD,IAAI,UAAU,QAAQ,UAAU,QAC9B,OAAO;CAET,IAAI,iBAAiB,MACnB,OAAO,OAAO,MAAM,MAAM,QAAQ,CAAC,IAAI,KAAK,MAAM,YAAY;CAEhE,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,MAAM,IAAI,WAAW,CAAC,CAAC,KAAK,IAAI;CAEzC,IAAI,OAAO,UAAU,UACnB,OAAO,KAAK,UAAU,KAAK;CAE7B,QAAQ,OAAO,OAAf;EACE,KAAK,UACH,OAAO;EACT,KAAK;EACL,KAAK;EACL,KAAK,WACH,OAAO,OAAO,KAAK;EACrB,KAAK,UACH,OAAO,MAAM,SAAS;EACxB,SACE,OAAO;CACX;AACF;AAEA,SAAS,aAAa,OAA6C;CACjE,IAAI,iBAAiB,MAAM;EACzB,MAAM,OAAO,MAAM,QAAQ;EAC3B,OAAO,OAAO,MAAM,IAAI,IAAI,SAAY;CAC1C;CACA,IAAI,OAAO,UAAU,UACnB,OAAO,OAAO,MAAM,KAAK,IAAI,SAAY;CAE3C,OAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;;;;;;AAOA,SAAS,QAAQ,OAAgB,OAA6C;CAC5E,IAAI,QAAQ,KAAK,GACf;CAEF,IAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAAU;EAC1D,MAAM,SAAS,OAAO,MAAM,KAAK,CAAC;EAClC,OAAO,MAAM,KAAK,MAAM,MAAM,OAAO,MAAM,MAAM,IAAI,SAAY;CACnE;CACA,IAAI,OAAO,UAAU,YAAY,iBAAiB,MAChD,OAAO,aAAa,IAAI,KAAK,KAAK,CAAC;CAErC,IAAI,iBAAiB,QAAQ,OAAO,UAAU,UAE5C,OAAO,OAAO,MAAM,MAAM,QAAQ,CAAC,IAAI,SAAY,MAAM,YAAY,CAAC,CAAC,MAAM,GAAG,MAAM,MAAM;CAE9F,OAAO,aAAa,KAAK;AAC3B;AAEA,SAAS,cAAc,OAAsC;CAC3D,OACE,OAAO,UAAU,YACjB,UAAU,QACV,CAAC,MAAM,QAAQ,KAAK,KACpB,EAAE,iBAAiB,UAClB,SAAS,SAAS,SAAS;AAEhC;;;;;;;;;;;AAYA,SAAgB,cAAc,OAAgB,aAAsB,SAA0B;CAC5F,IAAI,QAAQ,WAAW,KAAM,MAAM,QAAQ,WAAW,KAAK,YAAY,WAAW,GAChF,OAAO;CAET,IAAI,MAAM,QAAQ,WAAW,GAC3B,OAAO,YAAY,MAAM,SAAS,OAAO,GAAG,MAAM,KAAK,KAAK,cAAc,MAAM,KAAK,MAAM,CAAC;CAE9F,IAAI,cAAc,WAAW,GAAG;EAC9B,MAAM,MAAM,QAAQ,YAAY,KAAK,KAAK;EAC1C,MAAM,MAAM,QAAQ,YAAY,KAAK,KAAK;EAC1C,IAAI,QAAQ,UAAa,QAAQ,QAC/B,OAAO;EAET,MAAM,aAAa,aAAa,KAAK;EACrC,IAAI,eAAe,QACjB,OAAO;EAET,QAAQ,QAAQ,UAAa,cAAc,SAAS,QAAQ,UAAa,cAAc;CACzF;CACA,IAAI,OAAO,gBAAgB,UACzB,OAAO,QAAQ,YAAY,CAAC,CAAC,SAAS,YAAY,YAAY,CAAC;CAEjE,OAAO,OAAO,GAAG,OAAO,WAAW;AACrC;AAEA,MAAM,6BAAa,IAAI,IAAI;CAAC;CAAQ;CAAK;CAAO;CAAK;AAAI,CAAC;AAC1D,MAAM,8BAAc,IAAI,IAAI;CAAC;CAAS;CAAK;CAAM;CAAK;AAAK,CAAC;;AAG5D,SAAgB,OAAO,OAAwC;CAC7D,IAAI,UAAU,QAAQ,UAAU,QAC9B;CAEF,IAAI,OAAO,UAAU,UACnB,OAAO;CAET,IAAI,OAAO,UAAU,WACnB,OAAO;CAET,OAAO,iBAAiB,OAAO,SAAS;AAC1C;;AAGA,SAAgB,QAAQ,OAAe,MAA+B;CACpE,MAAM,OAAO,MAAM,KAAK;CACxB,IAAI,SAAS,QACX,OAAO;EAAE,IAAI;EAAM,OAAO;CAAM;CAElC,IAAI,SAAS,IACX,OAAO;EAAE,IAAI;EAAM,OAAO;CAAK;CAEjC,IAAI,SAAS,UAAU;EACrB,MAAM,QAAQ,OAAO,IAAI;EACzB,OAAO,OAAO,SAAS,KAAK,IACxB;GAAE,IAAI;GAAM;EAAM,IAClB;GAAE,IAAI;GAAO,SAAS,IAAI,MAAM;EAAmB;CACzD;CACA,IAAI,SAAS,WAAW;EACtB,MAAM,OAAO,KAAK,YAAY;EAC9B,IAAI,WAAW,IAAI,IAAI,GACrB,OAAO;GAAE,IAAI;GAAM,OAAO;EAAK;EAEjC,IAAI,YAAY,IAAI,IAAI,GACtB,OAAO;GAAE,IAAI;GAAM,OAAO;EAAM;EAElC,OAAO;GAAE,IAAI;GAAO,SAAS,IAAI,MAAM;EAA4B;CACrE;CACA,MAAM,QAAQ,IAAI,KAAK,IAAI;CAC3B,OAAO,OAAO,MAAM,MAAM,QAAQ,CAAC,IAC/B;EAAE,IAAI;EAAO,SAAS,IAAI,MAAM;CAAiB,IACjD;EAAE,IAAI;EAAM;CAAM;AACxB;;AAGA,SAAgB,cAAoB,YAAgD;CAElF,MAAM,MAAM;CACZ,MAAM,EAAE,aAAa;CACrB,MAAM,WAAmC,cAAc,QAAQ,QAAQ,KAAK,IAAI,EAAE;CAClF,MAAM,SAAS,IAAI,YAAY,UAAmB,YAAY,KAAK;CACnE,MAAM,UAAU,IAAI,WAAW;CAC/B,MAAM,eAAe,IAAI;CACzB,MAAM,cAAc,IAAI;CACxB,MAAM,WAAW,IAAI,YAAY;CACjC,MAAM,iBAAiB,IAAI;CAC3B,MAAM,WAAW,aAAa,UAAa,mBAAmB;CAE9D,OAAO,OAAO,OAAO;EACnB,IAAI,IAAI;EACR,QAAQ,IAAI,UAAU,SAAS,IAAI,EAAE;EACrC,OAAO,IAAI,SAAS;EACpB,OAAO,IAAI;EACX,UAAU,IAAI;EACd,UAAU,IAAI,YAAY;EAC1B,YAAY,IAAI,cAAc;EAC9B,iBAAiB,IAAI,UAAU;EAC/B,MAAM,OAAO,OAAO,EAAE,GAAG,IAAI,KAAK,CAAC;EACnC;EACA;EACA,SAAS,OAAgB,QAAsB,OAAO,OAAgB,GAAG;EACzE,UAAU,MAAe,UAA2B,QAAQ,MAAe,KAAc;EACzF,QAAQ,OAAgB,aAAsB,KAAoB;GAChE,OAAO,eACH,aAAa,OAAgB,aAAa,GAAG,IAC7C,cAAc,OAAO,aAAa,OAAO,OAAgB,GAAG,CAAC;EACnE;EACA,WAAW,KAAoB;GAC7B,IAAI,CAAC,UACH,OAAO;GAET,OAAO,OAAO,aAAa,aAAa,SAAS,GAAG,IAAI;EAC1D;EACA,MAAM,OAAe,KAAW,QAA+B;GAC7D,IAAI,aACF,IAAI;IACF,OAAO;KAAE,IAAI;KAAM,OAAO,YAAY,OAAO,GAAG;IAAE;GACpD,SAAS,OAAO;IACd,OAAO;KAAE,IAAI;KAAO,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;IAAE;GACtF;GAEF,OAAO,QAAQ,OAAO,IAAI,QAAQ,OAAO,SAAS,GAAG,CAAC,KAAK,OAAO,MAAM,KAAK,MAAM;EACrF;EACA,SAAS,KAAW,OAAkC;GACpD,IAAI,gBACF,OAAO,eAAe,KAAK,KAAK;GAElC,OAAO,aAAa,SAAY,QAAQ,KAAK,IAAI,IAAI,KAAK,IAAI;EAChE;CACF,CAAC;AACH;;;;;;;;;;ACvWA,SAAS,MAAM,OAAe,WAA2B;CACvD,OAAO,MAAM,SAAS,SAAS,KAC7B,MAAM,SAAS,IAAG,KAClB,MAAM,SAAS,IAAI,KACnB,MAAM,SAAS,IAAI,IACjB,IAAI,MAAM,WAAW,MAAK,MAAI,EAAE,KAChC;AACN;;AAGA,SAAgB,YAAY,QAAwC,YAAY,KAAc;CAC5F,OAAO,OACJ,KAAK,SAAS,KAAK,KAAK,UAAU,MAAM,OAAO,SAAS,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAC3E,KAAK,IAAI;AACd;;;;;AAMA,SAAgB,eAAe,MAAc,YAAY,KAAkB;CACzE,MAAM,OAAmB,CAAC;CAC1B,IAAI,MAAgB,CAAC;CACrB,IAAI,QAAQ;CACZ,IAAI,SAAS;CACb,IAAI,QAAQ;CAEZ,MAAM,iBAAuB;EAC3B,IAAI,KAAK,KAAK;EACd,QAAQ;CACV;CACA,MAAM,eAAqB;EACzB,SAAS;EACT,KAAK,KAAK,GAAG;EACb,MAAM,CAAC;CACT;CAEA,OAAO,QAAQ,KAAK,QAAQ;EAC1B,MAAM,OAAO,KAAK,OAAO,KAAK;EAC9B,IAAI,QAAQ;GACV,IAAI,SAAS,MAAK;IAChB,IAAI,KAAK,OAAO,QAAQ,CAAC,MAAM,MAAK;KAClC,SAAS;KACT,SAAS;IACX,OACE,SAAS;GAEb,OACE,SAAS;EAEb,OAAO,IAAI,SAAS,QAAO,UAAU,IACnC,SAAS;OACJ,IAAI,SAAS,WAClB,SAAS;OACJ,IAAI,SAAS,QAAQ,SAAS,MAAM;GACzC,IAAI,SAAS,QAAQ,KAAK,OAAO,QAAQ,CAAC,MAAM,MAC9C,SAAS;GAEX,OAAO;EACT,OACE,SAAS;EAEX,SAAS;CACX;CAEA,IAAI,UAAU,MAAM,IAAI,SAAS,GAC/B,OAAO;CAET,OAAO;AACT;;;;ACpCA,SAAS,MAAM,OAAe,KAAqB;CACjD,OAAO,KAAK,IAAI,KAAK,IAAI,GAAG,KAAK,GAAG,KAAK,IAAI,GAAG,MAAM,CAAC,CAAC;AAC1D;AAEA,SAAgB,cAAc,UAAwB,QAAkC;CACtF,OAAO;EAAE,KAAK,MAAM,SAAS,KAAK,OAAO,IAAI;EAAG,QAAQ,MAAM,SAAS,QAAQ,OAAO,OAAO;CAAE;AACjG;;AAGA,SAAgB,WAAW,UAAuC;CAChE,OAAO;EAAE,QAAQ;EAAU,OAAO;CAAS;AAC7C;;AAGA,SAAgB,cACd,WACA,WACA,QACA,UAAuB,CAAC,GACT;CACf,MAAM,EAAE,KAAK,WAAW,UAAU;CAClC,MAAM,MAAM,QAAQ,WAAW;CAC/B,MAAM,OAAqB,cACzB;EACE,KACE,cAAc,OACV,MACE,IACA,MAAM,IACR,cAAc,SACZ,MACE,OAAO,OAAO,IACd,MAAM,IACR;EACR,QACE,cAAc,SACV,MACE,IACA,SAAS,IACX,cAAc,UACZ,MACE,OAAO,UAAU,IACjB,SAAS,IACX;CACV,GACA,MACF;CACA,OAAO,QAAQ,WAAW,OACtB;EAAE,QAAQ,UAAU;EAAQ,OAAO;CAAK,IACxC;EAAE,QAAQ;EAAM,OAAO;CAAK;AAClC;;AAGA,SAAgB,eAAe,WAAqC;CAClE,OAAO;EACL,KAAK,KAAK,IAAI,UAAU,OAAO,KAAK,UAAU,MAAM,GAAG;EACvD,MAAM,KAAK,IAAI,UAAU,OAAO,QAAQ,UAAU,MAAM,MAAM;EAC9D,QAAQ,KAAK,IAAI,UAAU,OAAO,KAAK,UAAU,MAAM,GAAG;EAC1D,OAAO,KAAK,IAAI,UAAU,OAAO,QAAQ,UAAU,MAAM,MAAM;CACjE;AACF;AAEA,SAAgB,cAAc,OAAkB,UAAiC;CAC/E,OACE,SAAS,OAAO,MAAM,OACtB,SAAS,OAAO,MAAM,UACtB,SAAS,UAAU,MAAM,QACzB,SAAS,UAAU,MAAM;AAE7B;;AAGA,SAAgB,YAAY,OAAuB;CACjD,IAAI,QAAQ;CACZ,IAAI,OAAO,QAAQ;CACnB,OAAO,OAAO,GAAG;EACf,MAAM,aAAa,OAAO,KAAK;EAC/B,QAAQ,OAAO,aAAa,KAAK,SAAS,IAAI;EAC9C,OAAO,KAAK,OAAO,OAAO,KAAK,EAAE;CACnC;CACA,OAAO;AACT;;AAGA,SAAgB,KAAK,UAAgC;CACnD,OAAO,GAAG,YAAY,SAAS,MAAM,IAAI,SAAS,MAAM;AAC1D;;AAGA,SAAgB,OAAO,WAA6C;CAClE,MAAM,QAAQ,wBAAwB,KAAK,UAAU,KAAK,CAAC,CAAC,YAAY,CAAC;CACzE,IAAI,CAAC,QAAQ,MAAM,CAAC,MAAM,IACxB;CAEF,IAAI,SAAS;CACb,KAAK,MAAM,QAAQ,MAAM,IACvB,SAAS,SAAS,MAAM,KAAK,WAAW,CAAC,IAAI;CAE/C,OAAO;EAAE,KAAK,OAAO,MAAM,EAAE,IAAI;EAAG,QAAQ,SAAS;CAAE;AACzD;AAqBA,MAAM,SAAkD;CACtD,SAAS;CACT,WAAW;CACX,WAAW;CACX,YAAY;AACd;;;;;;;AAQA,SAAgB,YAAY,OAAyC;CACnE,MAAM,MAAM,MAAM,YAAY,QAAQ,MAAM,YAAY;CACxD,MAAM,QAAQ,MAAM,aAAa;CACjC,MAAM,YAAY,OAAO,MAAM;CAC/B,IAAI,WACF,OAAO;EAAE,MAAM;EAAQ;EAAW,SAAS;GAAE,QAAQ;GAAO,QAAQ;EAAI;CAAE;CAE5E,QAAQ,MAAM,KAAd;EACE,KAAK,OACH,OAAO;GAAE,MAAM;GAAQ,WAAW,QAAQ,SAAS;GAAS,SAAS,CAAC;EAAE;EAC1E,KAAK;EACL,KAAK,OACH,OAAO;GACL,MAAM;GACN,WAAW,MAAM,QAAQ,SAAS,SAAS;GAC3C,SAAS;IAAE,QAAQ;IAAO,QAAQ;GAAK;EACzC;EACF,KAAK;EACL,KAAK,MACH,OAAO,EAAE,MAAM,OAAO;EACxB,KAAK;EACL,KAAK,aACH,OAAO,EAAE,MAAM,QAAQ;EACzB,KAAK,UACH,OAAO,EAAE,MAAM,SAAS;CAG5B;CACA,IAAI,KAAK;EACP,MAAM,MAAM,MAAM,IAAI,YAAY;EAClC,IAAI,QAAQ,KACV,OAAO,EAAE,MAAM,YAAY;EAE7B,IAAI,QAAQ,KACV,OAAO,QAAQ,EAAE,MAAM,OAAO,IAAI,EAAE,MAAM,OAAO;EAEnD,IAAI,QAAQ,KACV,OAAO,EAAE,MAAM,OAAO;EAExB;CACF;CACA,IAAI,MAAM,IAAI,WAAW,KAAK,MAAM,WAAW,MAC7C,OAAO;EAAE,MAAM;EAAQ,SAAS,MAAM;CAAI;AAG9C;;;;AC3MA,SAAgB,gBAAwB,QAAQ,KAAwB;CACtE,MAAM,OAAiB,CAAC;CACxB,MAAM,SAAmB,CAAC;CAC1B,OAAO;EACL,IAAI,UAAmB;GACrB,OAAO,KAAK,SAAS;EACvB;EACA,IAAI,UAAmB;GACrB,OAAO,OAAO,SAAS;EACzB;EACA,OAAO,OAAqB;GAC1B,KAAK,KAAK,KAAK;GACf,IAAI,KAAK,SAAS,OAChB,KAAK,MAAM;GAEb,OAAO,SAAS;EAClB;EACA,OAA2B;GACzB,MAAM,QAAQ,KAAK,IAAI;GACvB,IAAI,UAAU,QACZ,OAAO,KAAK,KAAK;GAEnB,OAAO;EACT;EACA,OAA2B;GACzB,MAAM,QAAQ,OAAO,IAAI;GACzB,IAAI,UAAU,QACZ,KAAK,KAAK,KAAK;GAEjB,OAAO;EACT;EACA,QAAc;GACZ,KAAK,SAAS;GACd,OAAO,SAAS;EAClB;CACF;AACF;;;;ACjDA,SAAS,cAAc,OAAkD;CACvE,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GACpE,OAAO;CAET,MAAM,YAAqB,OAAO,eAAe,KAAK;CACtD,OAAO,cAAc,OAAO,aAAa,cAAc;AACzD;AAEA,SAAS,QAAQ,OAAgB,QAAgB,OAAe,MAAyB;CACvF,IAAI,CAAC,cAAc,KAAK,GACtB;CAEF,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,GAAG;EAChD,MAAM,OAAO,WAAW,KAAK,MAAM,GAAG,OAAO,GAAG;EAChD,IAAI,cAAc,KAAK,KAAK,QAAQ,GAClC,QAAQ,OAAO,MAAM,QAAQ,GAAG,IAAI;OAEpC,KAAK,IAAI,IAAI;CAEjB;AACF;;;;;AAMA,SAAgB,aAAmB,MAAuB,SAAS,IAAgC;CACjG,MAAM,wBAAQ,IAAI,IAAY;CAC9B,KAAK,MAAM,OAAO,KAAK,MAAM,GAAG,MAAM,GACpC,QAAQ,KAAK,IAAI,GAAG,KAAK;CAE3B,OAAO,OAAO,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,KAAK,QAAQ,EAAE,GAAG,EAAqB,CAAC;AAC1E;;;;;;;;;ACxBA,SAAS,YAAY,QAAmC;CACtD,OAAO,OACJ,YAAY,CAAC,CACb,MAAM,MAAM,CAAC,CACb,QAAQ,SAAS,KAAK,SAAS,CAAC;AACrC;;;;;AAMA,SAAgB,WACd,MACA,SACA,QACA,SAC2B;CAC3B,MAAM,QAAQ,YAAY,MAAM;CAChC,MAAM,OAAO,IAAI,IAAI,QAAQ,KAAK,WAAW,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC;CACjE,MAAM,gBAAgB,OAAO,QAAQ,OAAO,CAAC,CAAC,SAAS,CAAC,IAAI,WAAW;EACrE,MAAM,SAAS,KAAK,IAAI,EAAE;EAC1B,OAAO,UAAU,UAAU,SAAY,CAAC;GAAE;GAAQ;EAAM,CAAC,IAAI,CAAC;CAChE,CAAC;CACD,MAAM,aAAa,QAAQ,QAAQ,WAAW,OAAO,UAAU;CAE/D,IAAI,MAAM,WAAW,KAAK,cAAc,WAAW,GACjD,OAAO;CAGT,OAAO,KAAK,QAAQ,QAAQ;EAC1B,KAAK,MAAM,EAAE,QAAQ,WAAW,eAC9B,IAAI,CAAC,OAAO,QAAQ,IAAI,SAAS,OAAO,EAAE,GAAG,OAAO,IAAI,QAAQ,GAC9D,OAAO;EAGX,IAAI,MAAM,WAAW,GACnB,OAAO;EAET,MAAM,WAAW,WAAW,KAAK,WAAW,IAAI,WAAW,OAAO,EAAE,CAAC,CAAC,YAAY,CAAC;EACnF,OAAO,MAAM,OAAO,SAAS,SAAS,MAAM,SAAS,KAAK,SAAS,IAAI,CAAC,CAAC;CAC3E,CAAC;AACH;;AAGA,SAAgB,SACd,MACA,SACA,SAC2B;CAC3B,MAAM,OAAO,IAAI,IAAI,QAAQ,KAAK,WAAW,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC;CACjE,MAAM,QAAQ,QAAQ,SAAS,SAAS;EACtC,MAAM,SAAS,KAAK,IAAI,KAAK,MAAM;EACnC,OAAO,SAAS,CAAC;GAAE;GAAQ,MAAM,KAAK,cAAc,SAAS,KAAK;EAAE,CAAC,IAAI,CAAC;CAC5E,CAAC;CACD,IAAI,MAAM,WAAW,GACnB,OAAO;CAET,OAAO,KAAK,UAAU,MAAM,UAAU;EACpC,KAAK,MAAM,EAAE,QAAQ,UAAU,OAAO;GACpC,MAAM,YAAY,KAAK,SAAS,OAAO,EAAE;GACzC,MAAM,aAAa,MAAM,SAAS,OAAO,EAAE;GAC3C,MAAM,YAAY,cAAc,QAAQ,cAAc,UAAa,cAAc;GAGjF,IAAI,eAFe,eAAe,QAAQ,eAAe,UAAa,eAAe,KAGnF,OAAO,YAAY,IAAI;GAEzB,MAAM,QAAQ,OAAO,QAAQ,WAAW,UAAU,IAAI;GACtD,IAAI,UAAU,GACZ,OAAO;EAEX;EACA,OAAO;CACT,CAAC;AACH;;AAGA,SAAgB,WAAW,UAAkB,UAA0B;CACrE,OAAO,KAAK,IAAI,GAAG,KAAK,KAAK,WAAW,QAAQ,CAAC;AACnD;;AAGA,SAAgB,UAAU,MAAc,WAA2B;CACjE,OAAO,KAAK,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,KAAK,CAAC,GAAG,SAAS;AAC/D;;AAGA,SAAgB,aACd,MACA,YAC2B;CAC3B,MAAM,SAAS,WAAW,OAAO,KAAK,WAAW;CACjD,OAAO,KAAK,MAAM,OAAO,QAAQ,WAAW,QAAQ;AACtD;;;;;AAWA,SAAgB,gBACd,MACA,WACA,WAAW,GACU;CACrB,MAAM,wBAAQ,IAAI,IAAY,CAAC,GAAG,SAAS,CAAC;CAC5C,KAAK,IAAI,SAAS,CAAC,UAAU,UAAU,UAAU,UAAU,GAAG;EAC5D,MAAM,YAAY,OAAO;EACzB,IAAI,aAAa,KAAK,aAAa,WACjC,MAAM,IAAI,SAAS;CAEvB;CACA,MAAM,SAAS,CAAC,GAAG,KAAK,CAAC,CAAC,UAAU,MAAM,UAAU,OAAO,KAAK;CAChE,MAAM,QAAoB,CAAC;CAC3B,IAAI,WAAW;CACf,KAAK,MAAM,SAAS,QAAQ;EAC1B,IAAI,QAAQ,aAAa,GACvB,MAAM,KAAK;GAAE,MAAM;GAAQ,MAAM,QAAQ;GAAG,SAAS,QAAQ,MAAM;EAAK,CAAC;OACpE,IAAI,QAAQ,WAAW,GAC5B,MAAM,KAAK;GAAE,MAAM;GAAO,KAAK,OAAO,SAAS,GAAG;EAAQ,CAAC;EAE7D,MAAM,KAAK;GAAE,MAAM;GAAQ,MAAM;GAAO,SAAS,UAAU;EAAK,CAAC;EACjE,WAAW;CACb;CACA,OAAO;AACT;;;;AClGA,MAAa,oBAAoB;AAEjC,SAAgB,mBAAmB,QAAyB,CAAC,GAAe;CAC1E,OAAO,YAAY;EACjB,SAAS,MAAM,WAAW,CAAC;EAC3B,QAAQ,MAAM,UAAU;EACxB,SAAS,MAAM,WAAW,CAAC;EAC3B,YAAY,MAAM,cAAc;GAAE,MAAM;GAAG;EAA4B;EACvE,WAAW,MAAM,aAAa,CAAC;EAC/B,eAAe,MAAM,iBAAiB,CAAC;EACvC,aAAa,MAAM,eAAe,CAAC;CACrC,CAAC;AACH;AAEA,SAAgB,WAAW,OAAmB,OAAoC;CAChF,IAAI,UAAU;CACd,MAAM,OAAgC,EAAE,GAAG,MAAM;CACjD,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,GAAG;EAChD,IAAI,UAAU,UAAa,OAAO,GAAG,KAAK,MAAM,KAAK,GACnD;EAEF,IACE,QAAQ,gBACR,eAAe,KAAK,MAAyB,KAAwB,GAErE;EAEF,KAAK,OAAO;EACZ,UAAU;CACZ;CACA,OAAO,UAAU,YAAY,IAA6B,IAAI;AAChE;AAEA,SAAS,eAAe,MAAuB,OAAiC;CAC9E,OAAO,KAAK,SAAS,MAAM,QAAQ,KAAK,aAAa,MAAM;AAC7D;AAEA,SAAS,YAAY,OAA+B;CAClD,OAAO,OAAO,OAAO;EACnB,SAAS,OAAO,OAAO,MAAM,QAAQ,KAAK,SAAS,OAAO,OAAO,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC;EAC9E,QAAQ,MAAM;EACd,SAAS,OAAO,OAAO,EAAE,GAAG,MAAM,QAAQ,CAAC;EAC3C,YAAY,OAAO,OAAO,EAAE,GAAG,MAAM,WAAW,CAAC;EACjD,WAAW,OAAO,OAAO,CAAC,GAAG,MAAM,SAAS,CAAC;EAC7C,eAAe,OAAO,OAAO,CAAC,GAAG,MAAM,aAAa,CAAC;EACrD,aAAa,OAAO,OAAO,CAAC,GAAG,MAAM,WAAW,CAAC;CACnD,CAAC;AACH;;;;AClEA,SAAgB,MACd,MACA,SACA,UAA0F,CAAC,GAC/E;CACZ,OAAO,OAAO,OAAO;EAAE;EAAM;EAAS,GAAG;CAAQ,CAAC;AACpD;;;;ACXA,SAAgB,UACd,UACA,KACA,OACA,SACgB;CAChB,MAAM,yBAAS,IAAI,IAAqB;CACxC,MAAM,2BAAW,IAAI,IAAoB;CAEzC,MAAM,YAAY,aAA8B;EAC9C,IAAI,OAAO,IAAI,QAAQ,GACrB,OAAO,OAAO,IAAI,QAAQ;EAE5B,MAAM,QAAQ,QAAQ,IAAI,QAAQ,CAAC,EAAE,SAAS,QAAQ;EACtD,OAAO,IAAI,UAAU,KAAK;EAC1B,OAAO;CACT;CAEA,OAAO,OAAO,OAAO;EACnB;EACA;EACA;EACA;EACA,WAAW,UAA0B;GACnC,MAAM,SAAS,SAAS,IAAI,QAAQ;GACpC,IAAI,WAAW,QACb,OAAO;GAET,MAAM,SAAS,QAAQ,IAAI,QAAQ;GACnC,MAAM,UAAU,SAAS,OAAO,OAAO,SAAS,QAAQ,GAAG,QAAQ,IAAI;GACvE,SAAS,IAAI,UAAU,OAAO;GAC9B,OAAO;EACT;CACF,CAAC;AACH;;;;ACoLA,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEA,SAAS,KACP,SAC6B;CAC7B,IAAI;CACJ,QAAQ,GAAG,SAAyB;EAClC,IACE,QACA,KAAK,KAAK,WAAW,KAAK,UAC1B,KAAK,KAAK,OAAO,GAAG,MAAM,OAAO,GAAG,GAAG,KAAK,EAAE,CAAC,GAE/C,OAAO,KAAK;EAEd,MAAM,SAAS,QAAQ,GAAG,IAAI;EAC9B,OAAO;GAAE;GAAM;EAAO;EACtB,OAAO;CACT;AACF;AAEA,SAAS,YAAY,MAAuC;CAC1D,OAAO,WAAW;AACpB;AAEA,SAAS,SAAS,UAAkB,OAAkC;CACpE,IAAI,aAAa,KAAK,UAAU,GAC9B,OAAO;CAET,OAAO,aAAa,QAAQ,QAAQ;AACtC;;AASA,SAAgB,YAAkB,SAA8C;CAC9E,MAAM,gBAAgB,QAAQ,iBAAiB;CAC/C,MAAM,cAAc,QAAQ,eAAe;CAC3C,MAAM,SAAS,QAAQ,UAAU;CACjC,MAAM,YAAY,gBAA6C,QAAQ,YAAY;CACnF,MAAM,4BAAY,IAAI,IAA6C;CAEnE,IAAI,OAAO,QAAQ;CACnB,IAAI,cAAc,QAAQ;CAC1B,IAAI,WAAW,QAAQ;CACvB,MAAM,eAAe,mBAAmB;EACtC,GAAG,QAAQ;EACX,eACE,QAAQ,cAAc,iBACtB,QAAQ,QAAQ,QAAQ,WAAW,OAAO,WAAW,IAAI,CAAC,CAAC,KAAK,WAAW,OAAO,EAAE;CACxF,CAAC;CACD,IAAI,QAAQ;CACZ,IAAI;CAEJ,MAAM,WAAW,KAAW,UAA0B;EACpD,MAAM,EAAE,WAAW;EACnB,IAAI,OAAO,WAAW,YACpB,OAAO,OAAO,KAAK,KAAK;EAG1B,MAAM,QAAQ,QAAQ,KADT,UAAU,IACQ;EAC/B,IAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAChD,OAAO;EAET,OAAO,WAAW,UAAa,CAAC,SAAS,GAAG,IAAI,QAAQ,OAAO,KAAK;CACtE;CAEA,MAAM,iBAAiB,MAAM,SAAqC;EAChE,MAAM,UAAU,KAAK,KAAK,eAAe,cAAc,UAAU,CAAC;EAClE,OAAO;GAAE;GAAS,MAAM,IAAI,IAAI,QAAQ,KAAK,WAAW,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC;EAAE;CAChF,CAAC;CAED,MAAM,YAAY,MACf,MAAuB,SAAoE;EAC1F,MAAM,wBAAQ,IAAI,IAA4B;EAC9C,MAAM,SAAuB,CAAC;EAiB9B,OAAO;GAAE,MAhBO,KAAK,KAAK,UAAU,UAAU;IAC5C,IAAI,MAAM,QAAQ,UAAU,KAAK;IACjC,IAAI,MAAM,IAAI,GAAG,GAAG;KAClB,OAAO,KACL,MACE,qBACA,OAAO,MAAM,oBAAoB,OAAO,GAAG,EAAE,kBAAkB,OAAO,GAAG,EAAE,GAAG,MAAM,aACpF,EAAE,QAAQ,IAAI,CAChB,CACF;KACA,MAAM,GAAG,OAAO,GAAG,EAAE,GAAG;IAC1B;IACA,MAAM,MAAM,UAAU,UAAU,KAAK,OAAO,IAAI;IAChD,MAAM,IAAI,KAAK,GAAG;IAClB,OAAO;GACT,CACqB;GAAG;GAAO;EAAO;CACxC,CACF;CAEA,MAAM,eAAe,MAEjB,SACA,aACA,kBACG;EACH,MAAM,WAAW,IAAI,IAAI,YAAY,KAAK,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC,CAAC;EACpE,MAAM,UAAU,QACb,KAAK,QAAQ,WAAW;GAAE;GAAQ;EAAM,EAAE,CAAC,CAC3C,UAAU,MAAM,UAAU;GAGzB,QAFqB,SAAS,IAAI,KAAK,OAAO,EAAE,KAAK,YAAY,SAAS,KAAK,UACzD,SAAS,IAAI,MAAM,OAAO,EAAE,KAAK,YAAY,SAAS,MAAM;EAEpF,CAAC,CAAC,CACD,KAAK,EAAE,aAAa,MAAM;EAC7B,MAAM,SAAS,IAAI,IAAI,aAAa;EACpC,OAAO;GAAE,KAAK;GAAS,SAAS,QAAQ,QAAQ,WAAW,CAAC,OAAO,IAAI,OAAO,EAAE,CAAC;EAAE;CACrF,CACF;CAEA,MAAM,cAAc,KAAK,UAAgB;CACzC,MAAM,YAAY,KAAK,QAAc;CACrC,MAAM,cAAc,MAAM,cAAiC,IAAI,IAAI,SAAS,CAAC;CAE7E,SAAS,YAAY,MAA4D;EAC/E,MAAM,SAAuB,CAAC;EAC9B,MAAM,6BAAa,IAAI,IAAI;GACzB,GAAG,MAAM,QAAQ,KAAK,SAAS,KAAK,MAAM;GAC1C,GAAG,OAAO,KAAK,MAAM,OAAO;GAC5B,GAAG,MAAM;GACT,GAAG,MAAM;EACX,CAAC;EACD,KAAK,MAAM,MAAM,YACf,IAAI,CAAC,KAAK,IAAI,EAAE,GACd,OAAO,KACL,MAAM,kBAAkB,iCAAiC,GAAG,yBAAyB,EACnF,QAAQ,GACV,CAAC,CACH;EAGJ,MAAM,EAAE,aAAa,MAAM;EAC3B,IAAI,CAAC,OAAO,UAAU,QAAQ,KAAK,WAAW,GAC5C,OAAO,KACL,MACE,qBACA,aAAa,OAAO,QAAQ,EAAE,sCAAqD,UACrF,CACF;EAEF,OAAO;CACT;CAEA,SAAS,kBAAuC;EAC9C,MAAM,EAAE,SAAS,SAAS,eAAe,WAAW;EACpD,MAAM,UAAU,UAAU,MAAM,IAAI;EACpC,MAAM,UAAU,aAAa,SAAS,MAAM,aAAa,MAAM,aAAa;EAC5E,MAAM,SAAS,CAAC,GAAG,QAAQ,QAAQ,GAAG,YAAY,IAAI,CAAC;EACvD,MAAM,gBAAgB,MAAM,WAAW;EACvC,MAAM,WACJ,OAAO,UAAU,aAAa,KAAK,iBAAiB,IAAI;EAE1D,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI,QAAQ;GACV,gBAAgB,QAAQ;GACxB,OAAO,QAAQ;GACf,gBAAgB,YAAY,QAAQ,KAAK;GACzC,YAAY,WAAW,eAAe,QAAQ;GAC9C,OAAO,UAAU,MAAM,WAAW,MAAM,SAAS;EACnD,OAAO;GACL,MAAM,WAAW,YAAY,QAAQ,MAAM,SAAS,MAAM,QAAQ,MAAM,OAAO;GAC/E,gBAAgB,UAAU,UAAU,SAAS,MAAM,OAAO;GAC1D,gBAAgB,cAAc;GAC9B,YAAY,WAAW,eAAe,QAAQ;GAC9C,OAAO,UAAU,MAAM,WAAW,MAAM,SAAS;GACjD,OAAO,aAAa,eAAe;IAAE;IAAM;GAAS,CAAC;EACvD;EAEA,MAAM,WAAW,YAAY,MAAM,SAAS;EAC5C,MAAM,eAAe,KAAK,QAAQ,QAAQ,SAAS,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC;EACjE,MAAM,YAAY,gBAAgB,UAAU,SAAS,OAAO;EAC5D,MAAM,gBACJ,cAAc,OAAO,eAAe,UAAU,QAAQ,QAAQ,SAAS,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC;EACvF,MAAM,YAAY,KAAK,WAAW,IAAI,KAAK,OAAO,KAAK,WAAW;EAClE,MAAM,YAAY,IAAI,IACpB,MAAM,QAAQ,KAAK,MAAM,aAAa,CAAC,KAAK,QAAQ;GAAE,WAAW,KAAK;GAAW;EAAS,CAAC,CAAC,CAC9F;EAEA,OAAO,OAAO,OAAO;GACnB;GACA,SAAS,QAAQ;GACjB,YAAY,QAAQ;GACpB;GACA;GACA;GACA;GACA;GACA,UAAU;GACV,eAAe,SAAS,gBAAgB,QAAQ,KAAK;GACrD;GACA,SAAS,KAAK,WAAW,IAAI,IAAI,YAAY,KAAK,SAAS;GAC3D,WAAW,gBAAgB,MAAM,SAAS;GAC1C,iBAAiB,OAAO;GACxB,aAAa,OAAO;GACpB;GACA,eAAe,MAAM,UAAU;GAC/B,eAAe,SAAS,cAAc,KAAK,MAAM;GACjD,cAAc,SAAS,eAAe,UAAU,MAAM;GACtD,SAAS,UAAU;GACnB,SAAS,UAAU;GACnB,QAAQ,OAAO,OAAO,MAAM;GAC5B,aAAa,QAAyB,SAAS,IAAI,GAAG;GACtD,UAAU,aAA2C,UAAU,IAAI,QAAQ;GAC3E,YAAY,aAAoD,KAAK,IAAI,QAAQ;GACjF,SAAS,QAA4C,QAAQ,MAAM,IAAI,GAAG;EAC5E,CAAC;CACH;CAEA,SAAS,cAAmC;EAC1C,aAAa,gBAAgB;EAC7B,OAAO;CACT;CAEA,SAAS,SAAe;EACtB,WAAW;EACX,IAAI,UAAU,SAAS,GACrB;EAEF,MAAM,OAAO,YAAY;EACzB,KAAK,MAAM,YAAY,WACrB,SAAS,IAAI;CAEjB;;CAGA,SAAS,OAAO,OAA8B;EAC5C,MAAM,WAAW;EACjB,MAAM,OAAO,WAAW,OAAO,KAAK;EACpC,IAAI,SAAS,UACX;EAEF,QAAQ;EACR,QAAQ,gBAAgB,OAAO,QAAQ;EACvC,OAAO;CACT;CAEA,MAAM,mBAAyE;EAC7E,MAAM;EACN,UAAU,MAAM,WAAW;CAC7B;CAEA,SAAS,QAAQ,UAAkB,WAAsC,OAAsB;EAE7F,IAAI,CADW,YAAY,CAAC,CAAC,UAAU,QAC7B,CAAC,EAAE,UACX;EAEF,MAAM,SAAS,QAAQ,MAAM,QAAQ,QAAQ,SAAS,KAAK,WAAW,QAAQ,IAAI,CAAC;EACnF,MAAM,WAAW,MAAM,QAAQ,WAAW,SAAS,KAAK,WAAW,QAAQ;EAC3E,IAAI,UAAU;EACd,IAAI,WAAW;GACb,MAAM,OAAO;IAAE,QAAQ;IAAU;GAAU;GAC3C,UACE,SAAS,aAAa,KAClB,MAAM,QAAQ,KAAK,YAAa,QAAQ,WAAW,WAAW,OAAO,OAAQ,IAC7E,CAAC,GAAG,QAAQ,IAAI;EACxB;EACA,OAAO;GAAE;GAAS,YAAY,UAAU;EAAE,CAAC;CAC7C;CAEA,SAAS,eAAe,MAA+B;EACrD,IAAI,kBAAkB,QACpB;EAEF,MAAM,SAAS,CAAC,GAAG,IAAI,IAAI,IAAI,CAAC;EAChC,MAAM,YAAY,kBAAkB,WAAW,OAAO,MAAM,EAAE,IAAI;EAClE,MAAM,UAAU,MAAM;EACtB,IAAI,UAAU,WAAW,QAAQ,UAAU,UAAU,OAAO,KAAK,MAAM,QAAQ,QAAQ,EAAE,GACvF;EAEF,OAAO,EAAE,UAAU,CAAC;CACtB;CAEA,SAAS,aAAa,OAA4B,QAAmC;EACnF,MAAM,UAAU,YAAY;EAC5B,MAAM,UAAU,CAAC,GAAG,IAAI;EACxB,MAAM,SAAuB,CAAC;EAC9B,MAAM,UAA8B,CAAC;EAGrC,MAAM,0BAAU,IAAI,IAAqB;EACzC,MAAM,YAAY,aAA8B;GAC9C,IAAI,CAAC,QAAQ,IAAI,QAAQ,GAAG;IAC1B,MAAM,QAAQ,QAAQ,cAAc,MAAM,cAAc;KACtD,MAAM,QAAQ,UAAU,SAAS,QAAQ;KACzC,OAAO,UAAU,QAAQ,UAAU;IACrC,CAAC;IACD,QAAQ,IAAI,UAAU,OAAO,SAAS,QAAQ,CAAC;GACjD;GACA,OAAO,QAAQ,IAAI,QAAQ;EAC7B;EACA,KAAK,MAAM,QAAQ,OAAO;GACxB,MAAM,MAAM,QAAQ,OAAO,KAAK,MAAM;GACtC,MAAM,SAAS,QAAQ,UAAU,KAAK,MAAM;GAC5C,IAAI,CAAC,KAAK;IACR,OAAO,KACL,MAAM,eAAe,uBAAuB,OAAO,KAAK,MAAM,EAAE,KAAK;KACnE,QAAQ,KAAK;KACb,QAAQ,KAAK;IACf,CAAC,CACH;IACA;GACF;GACA,IAAI,CAAC,QAAQ;IACX,OAAO,KACL,MAAM,kBAAkB,yBAAyB,KAAK,OAAO,KAAK;KAChE,QAAQ,KAAK;KACb,QAAQ,KAAK;IACf,CAAC,CACH;IACA;GACF;GACA,MAAM,WAAW,QAAQ,IAAI;GAC7B,IAAI,UAAU,CAAC,OAAO,WAAW,QAAQ,GAAG;IAC1C,OAAO,KACL,MACE,kBACA,QAAQ,OAAO,GAAG,iBAAiB,OAAO,IAAI,GAAG,EAAE,kBACnD;KACE,QAAQ,IAAI;KACZ,QAAQ,OAAO;IACjB,CACF,CACF;IACA;GACF;GACA,IAAI;GACJ,IAAI,YAAY,IAAI,GAAG;IACrB,MAAM,SAAS,OAAO,MAAM,KAAK,OAAO,UAAU,SAAS,OAAO,EAAE,CAAC;IACrE,IAAI,CAAC,OAAO,IAAI;KACd,OAAO,KACL,MAAM,iBAAiB,OAAO,SAAS;MAAE,QAAQ,IAAI;MAAK,QAAQ,OAAO;KAAG,CAAC,CAC/E;KACA;IACF;IACA,QAAQ,OAAO;GACjB,OACE,QAAQ,KAAK;GAEf,MAAM,WAAW,OAAO,SAAS,QAAQ;GACzC,IAAI,OAAO,GAAG,UAAU,KAAK,GAC3B;GAEF,MAAM,UAAU,OAAO,SAAS,UAAU,KAAK;GAC/C,IAAI,YAAY,QAAW;IACzB,OAAO,KACL,MAAM,kBAAkB,QAAQ,OAAO,GAAG,wCAAwC;KAChF,QAAQ,IAAI;KACZ,QAAQ,OAAO;IACjB,CAAC,CACH;IACA;GACF;GACA,QAAQ,IAAI,SAAS;GACrB,QAAQ,KAAK;IAAE,QAAQ,IAAI;IAAK,QAAQ,OAAO;IAAI;IAAU;IAAO,KAAK;GAAQ,CAAC;EACpF;EAEA,IAAI;EACJ,IAAI,QAAQ,WAAW,GACrB,SAAS,OAAO,SAAS,IAAI,aAAa;OACrC;GACL,SAAS,OAAO,SAAS,IAAI,YAAY;GACzC,OAAO;GACP,IAAI,QACF,UAAU,OAAO,OAAO;GAE1B,QAAQ,eAAe,MAAM,OAAO;GACpC,OAAO;EACT;EACA,IAAI,OAAO,SAAS,GAClB,QAAQ,eAAe,MAAM;EAE/B,OAAO,OAAO,OAAO;GACnB;GACA,SAAS,OAAO,OAAO,OAAO;GAC9B,QAAQ,OAAO,OAAO,MAAM;EAC9B,CAAC;CACH;CAEA,SAAS,WAAW,QAAsB,QAAoD;EAC5F,MAAM,EAAE,MAAM,YAAY,YAAY;EACtC,MAAM,QAAoB,CAAC;EAC3B,OAAO,SAAS,MAAM,cAAc;GAClC,MAAM,MAAM,KAAK,OAAO,MAAM;GAC9B,IAAI,CAAC,KACH;GAEF,KAAK,SAAS,OAAO,iBAAiB;IACpC,MAAM,SAAS,QAAQ,OAAO,SAAS;IACvC,IAAI,QACF,MAAM,KAAK;KAAE,QAAQ,IAAI;KAAK,QAAQ,OAAO;KAAI;IAAM,CAAC;GAE5D,CAAC;EACH,CAAC;EACD,OAAO;CACT;CAEA,SAAS,OAAO,SAAsC,WAAkC;EACtF,aACE,QAAQ,KAAK,YAAY;GACvB,QAAQ,OAAO;GACf,QAAQ,OAAO;GACf,OAAO,cAAc,SAAS,OAAO,WAAW,OAAO;EACzD,EAAE,GACF,KACF;CACF;CAEA,MAAM,QAAyB;EAC7B;EACA,gBAAgB;EAChB,UAAU,UAAU;GAClB,UAAU,IAAI,QAAQ;GACtB,aAAa;IACX,UAAU,OAAO,QAAQ;GAC3B;EACF;EAEA,SAAS,OAAO;GACd,MAAM,OAAO,WAAW,OAAO,KAAK;GACpC,IAAI,SAAS,OAAO;IAClB,QAAQ;IACR,OAAO;GACT;EACF;EACA,QAAQ,MAAM;GACZ,IAAI,SAAS,MACX;GAEF,OAAO;GACP,UAAU,MAAM;GAChB,OAAO;EACT;EACA,WAAW,MAAM;GACf,IAAI,SAAS,aACX;GAEF,cAAc;GACd,OAAO;EACT;EACA,YAAY,MAAM;GAChB,IAAI,SAAS,UACX;GAEF,WAAW;GACX,OAAO;EACT;EAEA,WAAW,UAAU,EAAE,QAAQ,UAAU,CAAC,GAAG;GAC3C,MAAM,UAAU,MAAM,QAAQ,MAAM,SAAS,KAAK,WAAW,QAAQ,CAAC,EAAE;GAExE,QAAQ,UADK,YAAY,SAAY,QAAQ,YAAY,QAAQ,SAAS,QAClD,KAAK;EAC/B;EACA,KAAK,UAAU,WAAW,EAAE,QAAQ,UAAU,CAAC,GAAG;GAChD,QAAQ,UAAU,WAAW,KAAK;EACpC;EACA,eAAe;GACb,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC;EACxB;EACA,OAAO,MAAM;GACX,IAAI,SAAS,MAAM,QACjB;GAEF,OAAO;IAAE,QAAQ;IAAM,YAAY,UAAU;GAAE,CAAC;EAClD;EACA,OAAO,UAAU,OAAO;GACtB,MAAM,UAAmC,EAAE,GAAG,MAAM,QAAQ;GAC5D,MAAM,QACJ,UAAU,UACV,UAAU,QACV,UAAU,MACT,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW;GAC5C,IAAI,QAAQ,EAAE,YAAY,WAAW,OAAO,GAAG,QAAQ,WAAW,KAAK,GACrE;GAEF,IAAI,OACF,OAAO,QAAQ;QAEf,QAAQ,YAAY;GAEtB,OAAO;IAAE;IAAS,YAAY,UAAU;GAAE,CAAC;EAC7C;EACA,eAAe;GACb,IAAI,OAAO,KAAK,MAAM,OAAO,CAAC,CAAC,SAAS,GACtC,OAAO;IAAE,SAAS,CAAC;IAAG,YAAY,UAAU;GAAE,CAAC;EAEnD;EAEA,SAAS,MAAM;GACb,MAAM,EAAE,WAAW,MAAM,gBAAgB,YAAY;GACrD,MAAM,OAAO,UAAU,MAAM,SAAS;GACtC,IAAI,SAAS,eAAe,SAAS,MAAM,WAAW,MACpD,OAAO,EAAE,YAAY;IAAE,MAAM;IAAM,UAAU,MAAM,WAAW;GAAS,EAAE,CAAC;EAE9E;EACA,WAAW;GACT,MAAM,SAAS,YAAY,CAAC,CAAC,OAAO,CAAC;EACvC;EACA,eAAe;GACb,MAAM,SAAS,YAAY,CAAC,CAAC,OAAO,CAAC;EACvC;EACA,YAAY,UAAU;GACpB,IAAI,CAAC,OAAO,UAAU,QAAQ,KAAK,WAAW,KAAK,aAAa,MAAM,WAAW,UAC/E;GAEF,MAAM,EAAE,cAAc,YAAY;GAElC,OAAO,EAAE,YAAY;IAAE,MADV,cAAc,IAAI,IAAI,KAAK,OAAO,YAAY,KAAK,QAAQ,IAAI;IAC/C;GAAS,EAAE,CAAC;EAC3C;EAEA,OAAO,MAAM;GACX,eAAe,CAAC,GAAG,MAAM,WAAW,GAAG,IAAI,CAAC;EAC9C;EACA,SAAS,MAAM;GACb,MAAM,UAAU,IAAI,IAAI,IAAI;GAC5B,eAAe,MAAM,UAAU,QAAQ,QAAQ,CAAC,QAAQ,IAAI,GAAG,CAAC,CAAC;EACnE;EACA,UAAU,KAAK,UAAU;GACvB,MAAM,aAAa,MAAM,UAAU,SAAS,GAAG;GAC/C,MAAM,OAAO,YAAY,CAAC;GAC1B,IAAI,SAAS,YACX;GAEF,IAAI,MACF,MAAM,OAAO,CAAC,GAAG,CAAC;QAElB,MAAM,SAAS,CAAC,GAAG,CAAC;EAExB;EACA,UAAU,QAAQ,aAAa;GAC7B,IAAI,kBAAkB,YACpB;GAEF,MAAM,UAAU,YAAY;GAE5B,MAAM,QADO,UAAU,UAAU,SAAS,QAAQ,OAAO,QAAQ,cAChD,CAAC,KAAK,QAAQ,IAAI,GAAG;GAEtC,IADoB,KAAK,SAAS,KAAK,KAAK,OAAO,QAAQ,QAAQ,WAAW,GAAG,CAAC,GAEhF,MAAM,SAAS,IAAI;QAEnB,MAAM,OAAO,IAAI;EAErB;EACA,iBAAiB;GACf,eAAe,CAAC,CAAC;EACnB;EACA,kBAAkB;GAChB,MAAM,UAAU,YAAY;GAC5B,OAAO,MAAM,UAAU,SAAS,QAAQ;IACtC,MAAM,MAAM,QAAQ,OAAO,GAAG;IAC9B,OAAO,MAAM,CAAC,GAAG,IAAI,CAAC;GACxB,CAAC;EACH;EAEA,aAAa,UAAU,SAAS;GAC9B,IAAI,CAAC,YAAY,CAAC,CAAC,UAAU,QAAQ,GACnC;GAEF,MAAM,SAAS,MAAM,cAAc,SAAS,QAAQ;GACpD,MAAM,OAAO,WAAW;GACxB,IAAI,SAAS,CAAC,QACZ;GAEF,OAAO,EACL,eAAe,OACX,MAAM,cAAc,QAAQ,OAAO,OAAO,QAAQ,IAClD,CAAC,GAAG,MAAM,eAAe,QAAQ,EACvC,CAAC;EACH;EACA,WAAW,UAAU,SAAS;GAC5B,MAAM,QAAQ,YAAY,CAAC,CAAC,WAAW,KAAK,WAAW,OAAO,EAAE;GAChE,MAAM,OAAO,MAAM,QAAQ,QAAQ;GACnC,IAAI,SAAS,IACX;GAEF,MAAM,SAAS,KAAK,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,CAAC,GAAG,MAAM,SAAS,CAAC;GAC1E,IAAI,WAAW,MACb;GAEF,MAAM,OAAO,MAAM,CAAC;GACpB,MAAM,OAAO,QAAQ,GAAG,QAAQ;GAChC,OAAO,EAAE,aAAa,MAAM,CAAC;EAC/B;EAEA,KAAK,OAAO;GACV,OAAO,aAAa,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAiB,GAAG,IAAI;EAC9E;EACA,OAAO;GACL,MAAM,UAAU,UAAU,KAAK;GAC/B,IAAI,CAAC,SACH,OAAO;GAET,OAAO,SAAS,MAAM;GACtB,OAAO;EACT;EACA,OAAO;GACL,MAAM,UAAU,UAAU,KAAK;GAC/B,IAAI,CAAC,SACH,OAAO;GAET,OAAO,SAAS,MAAM;GACtB,OAAO;EACT;EACA,KAAK,OAAO;GACV,MAAM,EAAE,MAAM,YAAY,YAAY;GACtC,MAAM,SAAqB,CAAC;GAC5B,KAAK,SAAS,KAAK,aAAa;IAC9B,MAAM,OAAiB,CAAC;IACxB,QAAQ,SAAS,QAAQ,gBAAgB;KACvC,IAAI,cAAc,OAAO;MAAE,KAAK;MAAU,QAAQ;KAAY,CAAC,GAC7D,KAAK,KAAK,IAAI,WAAW,OAAO,EAAE,CAAC;IAEvC,CAAC;IACD,IAAI,KAAK,SAAS,GAChB,OAAO,KAAK,IAAI;GAEpB,CAAC;GACD,OAAO,YAAY,MAAM;EAC3B;EACA,MAAM,QAAQ,MAAM;GAClB,OAAO,aAAa,WAAW,QAAQ,eAAe,IAAI,CAAC,GAAG,IAAI;EACpE;EACA,MAAM,OAAO;GACX,MAAM,SAAS,MAAM,KAAK,EAAE,QAAQ,MAAM,SAAS,MAAM,MAAM,EAAE,SAC/D,MAAM,KAAK,EAAE,QAAQ,MAAM,QAAQ,MAAM,OAAO,EAAE,SAAS,EAAE,CAC/D;GACA,MAAM,UAAU,YAAY;GAO5B,OAAO,aANO,WAAW;IAAE,KAAK,MAAM;IAAK,QAAQ,MAAM;GAAK,GAAG,MAAM,CAAC,CAAC,QAAQ,SAAS;IACxF,MAAM,MAAM,QAAQ,OAAO,KAAK,MAAM;IACtC,OACE,QAAQ,UAAa,QAAQ,UAAU,KAAK,MAAM,CAAC,EAAE,WAAW,IAAI,QAAQ,MAAM;GAEtF,CACwB,GAAG,IAAI;EACjC;EACA,WAAW,EAAE,SAAS,OAAO,SAAS,KAAK,WAAW,OAAO,UAAU,SAAS,CAAC,GAAG;GAClF,MAAM,UAAU,YAAY;GAC5B,MAAM,UAAU,MACZ,IAAI,SAAS,OAAO;IAClB,MAAM,SAAS,QAAQ,UAAU,EAAE;IACnC,OAAO,SAAS,CAAC,MAAM,IAAI,CAAC;GAC9B,CAAC,IACD,QAAQ;GAEZ,MAAM,UADO,WAAW,QAAQ,OAAO,QAAQ,cAC5B,CAAC,KAAK,QAAQ,QAAQ,KAAK,WAAW,IAAI,WAAW,OAAO,EAAE,CAAC,CAAC;GACnF,IAAI,SACF,OAAO,QAAQ,QAAQ,KAAK,WAAW,OAAO,MAAM,CAAC;GAEvD,OAAO,YAAY,QAAQ,WAAW,QAAQ,MAAM,GAAI;EAC1D;EAEA,QAAQ;GACN,OAAO,YAAY;EACrB;EACA,UAAU;GACR,UAAU,MAAM;EAClB;CACF;CACA,OAAO;AACT"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["isRecord"],"sources":["../src/humanize.ts","../src/issues.ts","../src/path.ts","../src/column.ts","../src/delimited.ts","../src/grid.ts","../src/undo-stack.ts","../src/virtualizer.ts","../src/infer.ts","../src/pipeline.ts","../src/row.ts","../src/state.ts","../src/table.ts"],"sourcesContent":["/**\n * Turn a column id into a readable header: `\"name.first_name\"` becomes `\"Name first name\"` and\n * `\"createdAt\"` becomes `\"Created at\"`.\n */\nexport function humanize(id: string): string {\n const words = id\n .replace(/([a-z0-9])([A-Z])/gu, \"$1 $2\")\n .split(/[\\s._-]+/u)\n .filter((word) => word.length > 0)\n .map((word) => word.toLowerCase());\n const sentence = words.join(\" \");\n return sentence.charAt(0).toUpperCase() + sentence.slice(1);\n}\n","import type { RowKey } from \"./state\";\n\n/** Every problem the engine can report. The union grows in minor versions. */\nexport type TableIssueCode =\n | \"duplicate_row_key\"\n | \"unknown_column\"\n | \"invalid_page_size\"\n | \"unknown_row\"\n | \"read_only_cell\"\n | \"invalid_value\"\n | \"invalid_expanded\"\n | \"unsafe_path\"\n | \"paste_truncated\"\n | \"invalid_paste_limit\"\n | \"invalid_virtual_option\"\n | \"invalid_virtual_size\"\n | \"invalid_virtual_viewport\"\n | \"duplicate_virtual_key\";\n\n/**\n * A problem the engine recovered from. Invalid input is never dropped silently: the engine falls\n * back to something safe and reports what it did here.\n */\nexport interface TableIssue {\n readonly code: TableIssueCode;\n readonly message: string;\n readonly column?: string | undefined;\n readonly rowKey?: RowKey | undefined;\n}\n\nexport function issue(\n code: TableIssueCode,\n message: string,\n details: { readonly column?: string | undefined; readonly rowKey?: RowKey | undefined } = {},\n): TableIssue {\n return Object.freeze({ code, message, ...details });\n}\n","/**\n * Dotted property paths.\n *\n * A column addresses nested data with a path such as `\"address.city\"`. The types below give every\n * such path its value type, and the functions read and write through a path without mutating.\n */\n\nimport { issue, type TableIssue } from \"./issues\";\n\ntype Leaf =\n | string\n | number\n | boolean\n | bigint\n | symbol\n | null\n | undefined\n | Date\n | readonly unknown[]\n | ((...args: never[]) => unknown);\n\ntype Depth = [never, 0, 1, 2, 3];\n\n/** Every dotted path into `T`, four levels deep. Arrays, dates, and functions are leaves. */\nexport type DeepKeys<T, TDepth extends number = 4> = [TDepth] extends [never]\n ? never\n : T extends Leaf\n ? never\n : {\n [K in keyof T & string]:\n | K\n | (NonNullable<T[K]> extends Leaf\n ? never\n : `${K}.${DeepKeys<NonNullable<T[K]>, Depth[TDepth]>}`);\n }[keyof T & string];\n\n/** The value found at `TPath` in `T`. A nullable step makes the result possibly `undefined`. */\nexport type PathValue<T, TPath extends string> = TPath extends `${infer THead}.${infer TRest}`\n ? THead extends keyof T\n ? PathValue<NonNullable<T[THead]>, TRest> | (undefined extends T[THead] ? undefined : never)\n : undefined\n : TPath extends keyof T\n ? T[TPath]\n : undefined;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\n/** Whether every path segment can be read or written without addressing a prototype. */\nexport function isSafePath(path: string): boolean {\n return path\n .split(\".\")\n .every(\n (segment) => segment !== \"__proto__\" && segment !== \"constructor\" && segment !== \"prototype\",\n );\n}\n\n/** Read the value at a dotted path, or `undefined` when a step is missing. */\nexport function getPath(source: unknown, path: string): unknown {\n if (!isSafePath(path)) {\n return undefined;\n }\n let current: unknown = source;\n for (const segment of path.split(\".\")) {\n if (!isRecord(current)) {\n return undefined;\n }\n current = current[segment];\n }\n return current;\n}\n\n/**\n * Return a copy of `source` with `value` at `path`. Only the objects along the path are copied;\n * everything else is shared. Missing steps are created as plain objects. Unsafe paths return\n * `source` unchanged and report an `unsafe_path` issue through `onIssue`, when supplied.\n */\nexport function setPath<T>(\n source: T,\n path: string,\n value: unknown,\n onIssue?: (problem: TableIssue) => void,\n): T {\n if (!isSafePath(path)) {\n onIssue?.(\n issue(\"unsafe_path\", `The path \"${path}\" addresses a prototype and cannot be written.`, {\n column: path,\n }),\n );\n return source;\n }\n const [head, ...rest] = path.split(\".\");\n const base: Record<string, unknown> = isRecord(source) ? { ...source } : {};\n if (head === undefined) {\n return source;\n }\n base[head] =\n rest.length === 0\n ? value\n : setPath(Object.hasOwn(base, head) ? base[head] : undefined, rest.join(\".\"), value);\n return base as T;\n}\n","import { humanize } from \"./humanize\";\nimport { getPath, isSafePath, setPath, type DeepKeys, type PathValue } from \"./path\";\n\nexport type ColumnAlign = \"start\" | \"center\" | \"end\";\n\n/** How typed or pasted text becomes a value when a column has no `parse`. */\nexport type ColumnType = \"text\" | \"number\" | \"boolean\" | \"date\";\n\n/** A range filter value, inclusive at both ends. Either end may be left open. */\nexport interface RangeFilter {\n readonly min?: number | string | Date | undefined;\n readonly max?: number | string | Date | undefined;\n}\n\n/** Options shared by path columns and computed columns. */\nexport interface ColumnOptions<TRow, TValue> {\n /** Header text. Defaults to the id made readable: `\"createdAt\"` becomes `\"Created at\"`. */\n readonly header?: string | undefined;\n readonly align?: ColumnAlign | undefined;\n /** Width in pixels. */\n readonly width?: number | undefined;\n readonly minWidth?: number | undefined;\n /** Whether a user may sort by this column. Defaults to `true`. */\n readonly sortable?: boolean | undefined;\n /** Whether the free-text search looks at this column. Defaults to `true`. */\n readonly searchable?: boolean | undefined;\n /** Hidden until a user shows it. */\n readonly hidden?: boolean | undefined;\n /**\n * How text becomes a value. Defaults to the type of the cell's current value, or of another\n * row's value when the cell is empty.\n */\n readonly type?: ColumnType | undefined;\n /** Whether cells of this column accept edits. A function decides per row. */\n readonly editable?: boolean | ((row: TRow) => boolean) | undefined;\n /** Order two values; the engine flips the sign for descending sorts. */\n readonly compare?: ((left: TValue, right: TValue) => number) | undefined;\n /** Decide whether a row passes this column's filter value. */\n readonly filter?: ((value: TValue, filterValue: unknown, row: TRow) => boolean) | undefined;\n /** Turn a value into the text a cell shows, searches, copies, and exports. */\n readonly format?: ((value: TValue, row: TRow) => string) | undefined;\n /**\n * Turn typed or pasted text into a value. Throw to reject the input. Defaults to reading the\n * column's `type`.\n */\n readonly parse?: ((input: string, row: TRow) => TValue) | undefined;\n /** Free-form data for renderers. The engine never reads it. */\n readonly meta?: Readonly<Record<string, unknown>> | undefined;\n}\n\n/** A column that reads `row[id]`, following dots into nested objects. */\nexport interface PathColumnDef<TRow, TPath extends string> extends ColumnOptions<\n TRow,\n PathValue<TRow, TPath>\n> {\n readonly id: TPath;\n readonly accessor?: undefined;\n readonly setValue?: undefined;\n}\n\n/** A column whose value is computed from the row. It is editable only with `setValue`. */\nexport interface ComputedColumnDef<TRow, TValue = unknown> extends ColumnOptions<TRow, TValue> {\n readonly id: string;\n readonly accessor: (row: TRow) => TValue;\n /** Return a copy of `row` carrying `value`. Without it the column is read-only. */\n readonly setValue?: ((row: TRow, value: TValue) => TRow) | undefined;\n}\n\n/**\n * One column definition. A path column is discriminated by its literal id, so `format`,\n * `compare`, and `parse` receive the value type found at that path.\n */\nexport type ColumnDef<TRow> =\n | {\n [TPath in DeepKeys<TRow>]: PathColumnDef<TRow, TPath>;\n }[DeepKeys<TRow>]\n | ComputedColumnDef<TRow, any>;\n\n/**\n * A column definition for any row type, for props and containers that accept every table.\n */\nexport type AnyColumnDef = ColumnDef<any>;\n\n/** Declare columns for a row type with full inference, outside a table. */\nexport function defineColumns<TRow>(\n columns: readonly ColumnDef<TRow>[],\n): readonly ColumnDef<TRow>[] {\n return Object.freeze([...columns]);\n}\n\n/**\n * A column resolved against its defaults. Renderers read these; they never read definitions.\n */\nexport interface TableColumn<TRow> {\n readonly id: string;\n readonly header: string;\n readonly align: ColumnAlign;\n readonly width: number | undefined;\n readonly minWidth: number | undefined;\n readonly sortable: boolean;\n readonly searchable: boolean;\n readonly initiallyHidden: boolean;\n readonly meta: Readonly<Record<string, unknown>>;\n readonly definition: ColumnDef<TRow>;\n getValue(row: TRow): unknown;\n format(value: unknown, row: TRow): string;\n compare(left: unknown, right: unknown): number;\n matches(value: unknown, filterValue: unknown, row: TRow): boolean;\n isEditable(row: TRow): boolean;\n /**\n * Parse text into a value, or report why it could not be read. `sample` is a value from another\n * row, used to tell the column's type when this cell is empty.\n */\n parse(input: string, row: TRow, sample?: unknown): ParseResult;\n /** Return a copy of `row` carrying `value`, or `undefined` for a read-only column. */\n setValue(row: TRow, value: unknown): TRow | undefined;\n}\n\n/** The outcome of reading text into a cell value. */\nexport type ParseResult =\n | { readonly ok: true; readonly value: unknown }\n | { readonly ok: false; readonly message: string };\n\nconst collator = new Intl.Collator(undefined, { numeric: true, sensitivity: \"base\" });\n\nfunction isEmpty(value: unknown): boolean {\n return value === null || value === undefined || value === \"\";\n}\n\n/** Order any two values: empty last, then numbers, dates, booleans, and text naturally. */\nexport function compareValues(left: unknown, right: unknown): number {\n const leftEmpty = isEmpty(left);\n const rightEmpty = isEmpty(right);\n if (leftEmpty || rightEmpty) {\n return leftEmpty === rightEmpty ? 0 : leftEmpty ? 1 : -1;\n }\n if (typeof left === \"number\" && typeof right === \"number\") {\n return left - right;\n }\n if (typeof left === \"bigint\" && typeof right === \"bigint\") {\n return left < right ? -1 : left > right ? 1 : 0;\n }\n if (left instanceof Date && right instanceof Date) {\n return left.getTime() - right.getTime();\n }\n if (typeof left === \"boolean\" && typeof right === \"boolean\") {\n return Number(left) - Number(right);\n }\n return collator.compare(formatValue(left), formatValue(right));\n}\n\n/**\n * Text for a value: empty for `null` and `undefined`, ISO for dates, comma-joined for arrays, and\n * JSON for other objects. The result never depends on the runtime's locale, so server and client\n * render the same text.\n */\nexport function formatValue(value: unknown): string {\n if (value === null || value === undefined) {\n return \"\";\n }\n if (value instanceof Date) {\n return Number.isNaN(value.getTime()) ? \"\" : value.toISOString();\n }\n if (Array.isArray(value)) {\n return value.map(formatValue).join(\", \");\n }\n if (typeof value === \"object\") {\n return JSON.stringify(value);\n }\n switch (typeof value) {\n case \"string\":\n return value;\n case \"number\":\n case \"bigint\":\n case \"boolean\":\n return String(value);\n case \"symbol\":\n return value.toString();\n default:\n return \"\";\n }\n}\n\nfunction toComparable(value: unknown): number | string | undefined {\n if (value instanceof Date) {\n const time = value.getTime();\n return Number.isNaN(time) ? undefined : time;\n }\n if (typeof value === \"number\") {\n return Number.isNaN(value) ? undefined : value;\n }\n return typeof value === \"string\" ? value : undefined;\n}\n\n/**\n * Read a range bound in the kind of the value it is compared with, so a bound typed into a text\n * box (`\"10\"`, `\"2024-01-31\"`) compares with numbers as a number and with dates as a time. An\n * empty or unreadable bound leaves that end of the range open.\n */\nfunction toBound(bound: unknown, value: unknown): number | string | undefined {\n if (isEmpty(bound)) {\n return undefined;\n }\n if (typeof bound === \"string\" && typeof value === \"number\") {\n const number = Number(bound.trim());\n return bound.trim() === \"\" || Number.isNaN(number) ? undefined : number;\n }\n if (typeof bound === \"string\" && value instanceof Date) {\n return toComparable(new Date(bound));\n }\n if (bound instanceof Date && typeof value === \"string\") {\n // Compare text dates at their own precision: \"2024-01-31\" against the bound's day.\n return Number.isNaN(bound.getTime()) ? undefined : bound.toISOString().slice(0, value.length);\n }\n return toComparable(bound);\n}\n\nfunction isRangeFilter(value: unknown): value is RangeFilter {\n return (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n !(value instanceof Date) &&\n (\"min\" in value || \"max\" in value)\n );\n}\n\n/**\n * The default column filter:\n *\n * - an empty filter value (`undefined`, `null`, `\"\"`, `[]`) lets every row through;\n * - an array keeps rows whose value is one of its items;\n * - `{ min, max }` keeps values inside the inclusive range; a bound given as text is read as a\n * number or a date when the value is one, and an empty bound leaves that end open;\n * - text keeps rows whose shown text contains it, ignoring case;\n * - anything else keeps rows whose value is identical.\n */\nexport function matchesFilter(value: unknown, filterValue: unknown, display: string): boolean {\n if (isEmpty(filterValue) || (Array.isArray(filterValue) && filterValue.length === 0)) {\n return true;\n }\n if (Array.isArray(filterValue)) {\n return filterValue.some((item) => Object.is(item, value) || compareValues(item, value) === 0);\n }\n if (isRangeFilter(filterValue)) {\n const min = toBound(filterValue.min, value);\n const max = toBound(filterValue.max, value);\n if (min === undefined && max === undefined) {\n return true;\n }\n const comparable = toComparable(value);\n if (comparable === undefined) {\n return false;\n }\n return (min === undefined || comparable >= min) && (max === undefined || comparable <= max);\n }\n if (typeof filterValue === \"string\") {\n return display.toLowerCase().includes(filterValue.toLowerCase());\n }\n return Object.is(value, filterValue);\n}\n\nconst TRUE_WORDS = new Set([\"true\", \"1\", \"yes\", \"y\", \"on\"]);\nconst FALSE_WORDS = new Set([\"false\", \"0\", \"no\", \"n\", \"off\"]);\n\n/** The column type a value suggests, or `undefined` for an empty value. */\nexport function typeOf(value: unknown): ColumnType | undefined {\n if (value === null || value === undefined) {\n return undefined;\n }\n if (typeof value === \"number\") {\n return \"number\";\n }\n if (typeof value === \"boolean\") {\n return \"boolean\";\n }\n return value instanceof Date ? \"date\" : \"text\";\n}\n\n/** Read text as a column type. Empty text is `null` for every type but text. */\nexport function parseAs(input: string, type: ColumnType): ParseResult {\n const text = input.trim();\n if (type === \"text\") {\n return { ok: true, value: input };\n }\n if (text === \"\") {\n return { ok: true, value: null };\n }\n if (type === \"number\") {\n const value = Number(text);\n return Number.isFinite(value)\n ? { ok: true, value }\n : { ok: false, message: `\"${input}\" is not a number` };\n }\n if (type === \"boolean\") {\n const word = text.toLowerCase();\n if (TRUE_WORDS.has(word)) {\n return { ok: true, value: true };\n }\n if (FALSE_WORDS.has(word)) {\n return { ok: true, value: false };\n }\n return { ok: false, message: `\"${input}\" is not a yes or no value` };\n }\n const value = new Date(text);\n return Number.isNaN(value.getTime())\n ? { ok: false, message: `\"${input}\" is not a date` }\n : { ok: true, value };\n}\n\n/** Resolve a definition against its defaults. */\nexport function resolveColumn<TRow>(definition: ColumnDef<TRow>): TableColumn<TRow> {\n // Both branches of the union share these members; the value type is erased at runtime.\n const def = definition as ComputedColumnDef<TRow> | PathColumnDef<TRow, string>;\n const { accessor } = def;\n const safe = isSafePath(def.id);\n const getValue: (row: TRow) => unknown = safe\n ? (accessor ?? ((row) => getPath(row, def.id)))\n : () => undefined;\n const format = def.format ?? ((value: unknown) => formatValue(value));\n const compare = def.compare ?? compareValues;\n const customFilter = def.filter;\n const customParse = def.parse;\n const editable = def.editable ?? false;\n const customSetValue = def.setValue;\n const canWrite = safe && (accessor === undefined || customSetValue !== undefined);\n\n return Object.freeze({\n id: def.id,\n header: def.header ?? humanize(def.id),\n align: def.align ?? \"start\",\n width: def.width,\n minWidth: def.minWidth,\n sortable: def.sortable ?? true,\n searchable: def.searchable ?? true,\n initiallyHidden: def.hidden ?? false,\n meta: Object.freeze({ ...def.meta }),\n definition,\n getValue,\n format: (value: unknown, row: TRow): string => format(value as never, row),\n compare: (left: unknown, right: unknown): number => compare(left as never, right as never),\n matches(value: unknown, filterValue: unknown, row: TRow): boolean {\n return customFilter\n ? customFilter(value as never, filterValue, row)\n : matchesFilter(value, filterValue, format(value as never, row));\n },\n isEditable(row: TRow): boolean {\n if (!canWrite) {\n return false;\n }\n return typeof editable === \"function\" ? editable(row) : editable;\n },\n parse(input: string, row: TRow, sample?: unknown): ParseResult {\n if (customParse) {\n try {\n return { ok: true, value: customParse(input, row) };\n } catch (error) {\n return { ok: false, message: error instanceof Error ? error.message : String(error) };\n }\n }\n return parseAs(input, def.type ?? typeOf(getValue(row)) ?? typeOf(sample) ?? \"text\");\n },\n setValue(row: TRow, value: unknown): TRow | undefined {\n if (!safe) {\n return undefined;\n }\n if (customSetValue) {\n return customSetValue(row, value);\n }\n return accessor === undefined ? setPath(row, def.id, value) : undefined;\n },\n });\n}\n","/**\n * Delimited text: tab-separated for the clipboard, comma-separated for export.\n *\n * A field is quoted when it holds the delimiter, a quote, or a line break, and quotes inside it\n * are doubled. This is what spreadsheet applications write and read.\n */\n\nfunction quote(field: string, delimiter: string): string {\n return field.includes(delimiter) ||\n field.includes('\"') ||\n field.includes(\"\\n\") ||\n field.includes(\"\\r\")\n ? `\"${field.replaceAll('\"', '\"\"')}\"`\n : field;\n}\n\n/** Escape formula-like display text; a finite number formatted as a number stays numeric. */\nexport function escapeFormula(text: string, value?: unknown): string {\n const numeric =\n typeof value === \"number\" &&\n Number.isFinite(value) &&\n /^[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?$/u.test(text);\n return !numeric && /^[=+\\-@\\t\\r\\n=+-@]/u.test(text) ? \"'\" + text : text;\n}\n\nexport interface DelimitedLimits {\n readonly maxRows: number;\n readonly maxColumns: number;\n readonly maxCells: number;\n readonly maxLength: number;\n}\n\nexport interface DelimitedResult {\n readonly rows: string[][];\n readonly truncated: boolean;\n}\n\n/** Write a matrix of text as delimited lines joined with `\\n`. */\nexport function toDelimited(matrix: readonly (readonly string[])[], delimiter = \"\\t\"): string {\n return matrix\n .map((line) => line.map((field) => quote(field, delimiter)).join(delimiter))\n .join(\"\\n\");\n}\n\n/**\n * Read delimited text into a matrix. Accepts `\\n` and `\\r\\n`, quoted fields with doubled quotes\n * and embedded line breaks, and ignores one trailing line break.\n */\nexport function parseDelimited(text: string, delimiter = \"\\t\"): string[][] {\n return readDelimited(\n text,\n {\n maxRows: Infinity,\n maxColumns: Infinity,\n maxCells: Infinity,\n maxLength: Infinity,\n },\n delimiter,\n ).rows;\n}\n\n/** Read complete fields within a grid and work budget, without materializing discarded fields. */\nexport function readDelimited(\n text: string,\n limits: DelimitedLimits,\n delimiter = \"\\t\",\n): DelimitedResult {\n const rows: string[][] = [];\n if (limits.maxRows === 0 || limits.maxColumns === 0) {\n return { rows, truncated: text.length > 0 };\n }\n let row: string[] = [];\n let field = \"\";\n let quoted = false;\n let started = false;\n let index = 0;\n let column = 0;\n let cells = 0;\n let truncated = false;\n const end = Math.min(text.length, limits.maxLength);\n\n const endField = (): void => {\n if (column < limits.maxColumns) {\n row.push(field);\n } else {\n truncated = true;\n }\n column += 1;\n cells += 1;\n field = \"\";\n started = false;\n };\n const append = (char: string): void => {\n if (column < limits.maxColumns) {\n field += char;\n }\n };\n\n while (index < end) {\n const char = text.charAt(index);\n if (quoted) {\n if (char === '\"') {\n if (index + 1 < end && text.charAt(index + 1) === '\"') {\n append('\"');\n index += 1;\n } else {\n quoted = false;\n }\n } else {\n append(char);\n }\n } else if (char === '\"' && !started) {\n quoted = true;\n } else if (char === delimiter) {\n endField();\n index += 1;\n if (\n cells >= limits.maxCells ||\n (rows.length + 1 >= limits.maxRows && column >= limits.maxColumns)\n ) {\n rows.push(row);\n return { rows, truncated: true };\n }\n continue;\n } else if (char === \"\\n\" || char === \"\\r\") {\n if (char === \"\\r\" && index + 1 < end && text.charAt(index + 1) === \"\\n\") {\n index += 1;\n }\n endField();\n rows.push(row);\n row = [];\n column = 0;\n index += 1;\n if (cells >= limits.maxCells || rows.length >= limits.maxRows) {\n return { rows, truncated: truncated || index < text.length };\n }\n continue;\n } else {\n append(char);\n }\n started = true;\n index += 1;\n }\n\n if (end < text.length) {\n // A field cut short by the character budget must never become a different cell value.\n if (row.length > 0) {\n rows.push(row);\n }\n return { rows, truncated: true };\n }\n if (started || column > 0) {\n endField();\n rows.push(row);\n }\n return { rows, truncated };\n}\n","/**\n * Spreadsheet addressing and selection.\n *\n * A cell is addressed by its position in what is shown: the row index on the current page and the\n * column index among visible columns. A selection is an anchor, where it started, and a focus,\n * where it is now; the rectangle between them is the selected range.\n */\n\nexport interface CellPosition {\n readonly row: number;\n readonly column: number;\n}\n\nexport interface CellRange {\n readonly top: number;\n readonly left: number;\n readonly bottom: number;\n readonly right: number;\n}\n\nexport interface GridSelection {\n readonly anchor: CellPosition;\n readonly focus: CellPosition;\n}\n\n/** The size of the addressable grid. */\nexport interface GridBounds {\n readonly rows: number;\n readonly columns: number;\n}\n\nexport type GridDirection = \"up\" | \"down\" | \"left\" | \"right\";\n\nexport interface MoveOptions {\n /** Keep the anchor and move only the focus, growing or shrinking the range. */\n readonly extend?: boolean | undefined;\n /** Jump to the edge of the grid in that direction. */\n readonly toEdge?: boolean | undefined;\n}\n\nfunction clamp(value: number, max: number): number {\n return Math.min(Math.max(0, value), Math.max(0, max - 1));\n}\n\nexport function clampPosition(position: CellPosition, bounds: GridBounds): CellPosition {\n return { row: clamp(position.row, bounds.rows), column: clamp(position.column, bounds.columns) };\n}\n\n/** A selection of one cell. */\nexport function selectCell(position: CellPosition): GridSelection {\n return { anchor: position, focus: position };\n}\n\n/** Move the focus one step, or to the edge, staying inside the bounds. */\nexport function moveSelection(\n selection: GridSelection,\n direction: GridDirection,\n bounds: GridBounds,\n options: MoveOptions = {},\n): GridSelection {\n const { row, column } = selection.focus;\n const far = options.toEdge === true;\n const next: CellPosition = clampPosition(\n {\n row:\n direction === \"up\"\n ? far\n ? 0\n : row - 1\n : direction === \"down\"\n ? far\n ? bounds.rows - 1\n : row + 1\n : row,\n column:\n direction === \"left\"\n ? far\n ? 0\n : column - 1\n : direction === \"right\"\n ? far\n ? bounds.columns - 1\n : column + 1\n : column,\n },\n bounds,\n );\n return options.extend === true\n ? { anchor: selection.anchor, focus: next }\n : { anchor: next, focus: next };\n}\n\n/** The rectangle a selection covers. */\nexport function selectionRange(selection: GridSelection): CellRange {\n return {\n top: Math.min(selection.anchor.row, selection.focus.row),\n left: Math.min(selection.anchor.column, selection.focus.column),\n bottom: Math.max(selection.anchor.row, selection.focus.row),\n right: Math.max(selection.anchor.column, selection.focus.column),\n };\n}\n\nexport function rangeContains(range: CellRange, position: CellPosition): boolean {\n return (\n position.row >= range.top &&\n position.row <= range.bottom &&\n position.column >= range.left &&\n position.column <= range.right\n );\n}\n\n/** `0` is `\"A\"`, `25` is `\"Z\"`, `26` is `\"AA\"`. */\nexport function columnLabel(index: number): string {\n let label = \"\";\n let rest = index + 1;\n while (rest > 0) {\n const remainder = (rest - 1) % 26;\n label = String.fromCharCode(65 + remainder) + label;\n rest = Math.floor((rest - 1) / 26);\n }\n return label;\n}\n\n/** `{ row: 2, column: 1 }` is `\"B3\"`. */\nexport function toA1(position: CellPosition): string {\n return `${columnLabel(position.column)}${position.row + 1}`;\n}\n\n/** `\"B3\"` is `{ row: 2, column: 1 }`. Returns `undefined` for anything else. */\nexport function fromA1(reference: string): CellPosition | undefined {\n const match = /^([A-Z]+)([1-9]\\d*)$/u.exec(reference.trim().toUpperCase());\n if (!match?.[1] || !match[2]) {\n return undefined;\n }\n let column = 0;\n for (const char of match[1]) {\n column = column * 26 + (char.charCodeAt(0) - 64);\n }\n return { row: Number(match[2]) - 1, column: column - 1 };\n}\n\n/** The keys of a keyboard event that grid navigation reads. */\nexport interface GridKey {\n readonly key: string;\n readonly shiftKey?: boolean | undefined;\n readonly ctrlKey?: boolean | undefined;\n readonly metaKey?: boolean | undefined;\n readonly altKey?: boolean | undefined;\n}\n\n/** What a key press asks a grid to do while no cell is being edited. */\nexport type GridCommand =\n | { readonly type: \"move\"; readonly direction: GridDirection; readonly options: MoveOptions }\n | { readonly type: \"edit\"; readonly initial?: string | undefined }\n | { readonly type: \"clear\" }\n | { readonly type: \"selectAll\" }\n | { readonly type: \"undo\" }\n | { readonly type: \"redo\" }\n | { readonly type: \"cancel\" };\n\nconst ARROWS: Readonly<Record<string, GridDirection>> = {\n ArrowUp: \"up\",\n ArrowDown: \"down\",\n ArrowLeft: \"left\",\n ArrowRight: \"right\",\n};\n\n/**\n * Map a key press to a grid command, spreadsheet style: arrows move (Shift extends, Ctrl or Cmd\n * jumps to the edge), Tab moves across, Home and End reach the row's ends, Enter or F2 edit,\n * a printable character starts editing with that character, Delete and Backspace clear, Escape\n * collapses the selection, and Ctrl or Cmd with A, Z, Y select all, undo, and redo.\n */\nexport function gridCommand(event: GridKey): GridCommand | undefined {\n const mod = event.ctrlKey === true || event.metaKey === true;\n const shift = event.shiftKey === true;\n const direction = ARROWS[event.key];\n if (direction) {\n return { type: \"move\", direction, options: { extend: shift, toEdge: mod } };\n }\n switch (event.key) {\n case \"Tab\":\n return { type: \"move\", direction: shift ? \"left\" : \"right\", options: {} };\n case \"Home\":\n case \"End\":\n return {\n type: \"move\",\n direction: event.key === \"Home\" ? \"left\" : \"right\",\n options: { extend: shift, toEdge: true },\n };\n case \"Enter\":\n case \"F2\":\n return { type: \"edit\" };\n case \"Delete\":\n case \"Backspace\":\n return { type: \"clear\" };\n case \"Escape\":\n return { type: \"cancel\" };\n default:\n break;\n }\n if (mod) {\n const key = event.key.toLowerCase();\n if (key === \"a\") {\n return { type: \"selectAll\" };\n }\n if (key === \"z\") {\n return shift ? { type: \"redo\" } : { type: \"undo\" };\n }\n if (key === \"y\") {\n return { type: \"redo\" };\n }\n return undefined;\n }\n if (event.key.length === 1 && event.altKey !== true) {\n return { type: \"edit\", initial: event.key };\n }\n return undefined;\n}\n","/**\n * An undo stack of batches. Recording a batch clears whatever could be redone, and the stack\n * keeps at most `limit` batches, dropping the oldest.\n */\nexport interface UndoStack<TEntry> {\n readonly canUndo: boolean;\n readonly canRedo: boolean;\n record(entry: TEntry): void;\n /** Take the most recent batch to undo, if any. */\n undo(): TEntry | undefined;\n /** Take the most recently undone batch to redo, if any. */\n redo(): TEntry | undefined;\n clear(): void;\n}\n\nexport function createUndoStack<TEntry>(limit = 100): UndoStack<TEntry> {\n const past: TEntry[] = [];\n const future: TEntry[] = [];\n return {\n get canUndo(): boolean {\n return past.length > 0;\n },\n get canRedo(): boolean {\n return future.length > 0;\n },\n record(entry: TEntry): void {\n past.push(entry);\n if (past.length > limit) {\n past.shift();\n }\n future.length = 0;\n },\n undo(): TEntry | undefined {\n const entry = past.pop();\n if (entry !== undefined) {\n future.push(entry);\n }\n return entry;\n },\n redo(): TEntry | undefined {\n const entry = future.pop();\n if (entry !== undefined) {\n past.push(entry);\n }\n return entry;\n },\n clear(): void {\n past.length = 0;\n future.length = 0;\n },\n };\n}\n","import { issue, type TableIssue, type TableIssueCode } from \"./issues\";\nimport type { RowKey } from \"./state\";\n\nexport type VirtualAlign = \"start\" | \"center\" | \"end\" | \"auto\";\n\nexport interface VirtualizerOptions {\n readonly count: number;\n readonly estimateSize: number | ((index: number) => number);\n /** Extra items on each side. Defaults to 5. */\n readonly overscan?: number | undefined;\n /** Stable, unique identities preserve measurements across reorder and filtering. */\n readonly getKey?: ((index: number) => RowKey) | undefined;\n readonly onIssue?: ((problem: TableIssue) => void) | undefined;\n}\n\nexport interface VirtualItem {\n readonly index: number;\n readonly key: RowKey;\n readonly start: number;\n readonly size: number;\n}\n\nexport interface VirtualWindow {\n readonly items: readonly VirtualItem[];\n readonly totalSize: number;\n readonly paddingStart: number;\n readonly paddingEnd: number;\n /** Inclusive indices; an empty result uses 0 and -1. */\n readonly startIndex: number;\n readonly endIndex: number;\n /** Clamped viewport values, excluding overscan. */\n readonly offset: number;\n readonly viewportSize: number;\n readonly issues: readonly TableIssue[];\n}\n\nexport interface Virtualizer {\n setOptions(options: VirtualizerOptions): void;\n setViewport(offset: number, size: number): void;\n measure(key: RowKey, size: number): void;\n getWindow(): VirtualWindow;\n getOffsetForIndex(index: number, align?: VirtualAlign): number;\n subscribe(listener: (view: VirtualWindow) => void): () => void;\n}\n\nconst FALLBACK_SIZE = 40;\n\n/** Layout arithmetic for either axis. All viewport values and measurements come from the caller. */\nexport function createVirtualizer(initialOptions: VirtualizerOptions): Virtualizer {\n let options = initialOptions;\n let count = 0;\n let overscan = 5;\n let fixedSize: number | undefined;\n let keys: RowKey[] = [];\n let byKey = new Map<RowKey, number>();\n let sizes: number[] = [];\n // Retain only the prefix before the first changed item; extend it lazily on the next lookup.\n let prefix = [0];\n let offset = 0;\n let viewportSize = 0;\n let cached: VirtualWindow | undefined;\n const measured = new Map<RowKey, number>();\n const problems = new Map<TableIssueCode, TableIssue>();\n const listeners = new Set<(view: VirtualWindow) => void>();\n\n function recover(code: TableIssueCode, message: string): void {\n // One representative issue per code keeps diagnostics bounded even for many bad items.\n if (!problems.has(code)) {\n const problem = issue(code, message);\n problems.set(code, problem);\n options.onIssue?.(problem);\n cached = undefined;\n }\n }\n\n function validSize(value: number): number {\n if (Number.isFinite(value) && value > 0) return value;\n recover(\n \"invalid_virtual_size\",\n `Item size ${String(value)} is not positive and finite; 40 is used.`,\n );\n return FALLBACK_SIZE;\n }\n\n function configure(next: VirtualizerOptions): void {\n options = next;\n problems.clear();\n count = Number.isSafeInteger(next.count) && next.count >= 0 ? next.count : 0;\n if (count !== next.count) {\n recover(\n \"invalid_virtual_option\",\n \"Virtual item count must be a non-negative safe integer; 0 is used.\",\n );\n }\n const requestedOverscan = next.overscan ?? 5;\n overscan =\n Number.isSafeInteger(requestedOverscan) && requestedOverscan >= 0 ? requestedOverscan : 5;\n if (overscan !== requestedOverscan) {\n recover(\"invalid_virtual_option\", \"Overscan must be a non-negative safe integer; 5 is used.\");\n }\n const estimate =\n typeof next.estimateSize === \"number\" ? validSize(next.estimateSize) : undefined;\n const nextKeys: RowKey[] = [];\n const nextSizes: number[] = [];\n const nextByKey = new Map<RowKey, number>();\n let firstChanged = count;\n let uniform = estimate !== undefined;\n for (let index = 0; index < count; index += 1) {\n let key = next.getKey ? next.getKey(index) : index;\n if (!(typeof key === \"string\" || (typeof key === \"number\" && Number.isFinite(key)))) {\n recover(\"invalid_virtual_option\", `Item ${index} has an invalid key; its index is used.`);\n key = index;\n }\n if (nextByKey.has(key)) {\n recover(\n \"duplicate_virtual_key\",\n `Item ${index} repeats a key; a distinct fallback key is used.`,\n );\n key = JSON.stringify([\"virtual\", index]);\n while (nextByKey.has(key)) key += \":\";\n }\n const size =\n measured.get(key) ??\n estimate ??\n validSize((next.estimateSize as (index: number) => number)(index));\n uniform &&= size === estimate;\n if (keys[index] !== key || sizes[index] !== size)\n firstChanged = Math.min(firstChanged, index);\n nextKeys.push(key);\n nextSizes.push(size);\n nextByKey.set(key, index);\n }\n if (fixedSize !== undefined || uniform) prefix = [0];\n else prefix.length = Math.min(prefix.length, firstChanged + 1);\n keys = nextKeys;\n sizes = nextSizes;\n byKey = nextByKey;\n fixedSize = uniform ? estimate : undefined;\n cached = undefined;\n }\n\n function startOf(index: number): number {\n if (fixedSize !== undefined) return index * fixedSize;\n while (prefix.length <= index) {\n const at = prefix.length - 1;\n prefix.push(prefix[at]! + sizes[at]!);\n }\n return prefix[index]!;\n }\n\n function totalSize(): number {\n return startOf(count);\n }\n\n function indexAt(position: number): number {\n if (fixedSize !== undefined) return Math.min(count - 1, Math.floor(position / fixedSize));\n let low = 0;\n let high = count - 1;\n while (low < high) {\n const middle = Math.floor((low + high) / 2);\n if (startOf(middle + 1) <= position) low = middle + 1;\n else high = middle;\n }\n return low;\n }\n\n function getWindow(): VirtualWindow {\n if (cached) return cached;\n const total = totalSize();\n const clampedOffset = Math.min(offset, Math.max(0, total - viewportSize));\n let first = 0;\n let last = -1;\n if (count > 0 && viewportSize > 0) {\n first = Math.max(0, indexAt(clampedOffset) - overscan);\n const edge = Math.min(total, clampedOffset + viewportSize);\n let visibleEnd = indexAt(edge);\n if (startOf(visibleEnd) >= edge) visibleEnd -= 1;\n last = Math.min(count - 1, visibleEnd + overscan);\n }\n const items: VirtualItem[] = [];\n for (let index = first; index <= last; index += 1) {\n items.push(\n Object.freeze({ index, key: keys[index]!, start: startOf(index), size: sizes[index]! }),\n );\n }\n const paddingStart = items.length > 0 ? startOf(first) : 0;\n const paddingEnd = items.length > 0 ? Math.max(0, total - startOf(last + 1)) : total;\n cached = Object.freeze({\n items: Object.freeze(items),\n totalSize: total,\n paddingStart,\n paddingEnd,\n startIndex: first,\n endIndex: last,\n offset: clampedOffset,\n viewportSize,\n issues: Object.freeze([...problems.values()]),\n });\n return cached;\n }\n\n function notify(): void {\n cached = undefined;\n if (listeners.size > 0) {\n const view = getWindow();\n for (const listener of listeners) listener(view);\n }\n }\n\n configure(initialOptions);\n return {\n setOptions(next) {\n configure(next);\n notify();\n },\n setViewport(nextOffset, nextSize) {\n const issueCount = problems.size;\n const safeOffset = Number.isFinite(nextOffset) && nextOffset >= 0 ? nextOffset : 0;\n const safeSize = Number.isFinite(nextSize) && nextSize >= 0 ? nextSize : 0;\n if (safeOffset !== nextOffset || safeSize !== nextSize) {\n recover(\n \"invalid_virtual_viewport\",\n \"Viewport offset and size must be non-negative and finite; invalid values use 0.\",\n );\n }\n if (offset === safeOffset && viewportSize === safeSize && problems.size === issueCount)\n return;\n offset = safeOffset;\n viewportSize = safeSize;\n notify();\n },\n measure(key, size) {\n const index = byKey.get(key);\n if (index === undefined) return;\n if (!Number.isFinite(size) || size <= 0) {\n recover(\n \"invalid_virtual_size\",\n \"Measured size must be positive and finite; the previous size is retained.\",\n );\n notify();\n return;\n }\n measured.set(key, size);\n if (sizes[index] === size) return;\n if (fixedSize !== undefined) {\n fixedSize = undefined;\n prefix = [0];\n } else prefix.length = Math.min(prefix.length, index + 1);\n sizes[index] = size;\n notify();\n },\n getWindow,\n getOffsetForIndex(index, align = \"auto\") {\n if (count === 0) return 0;\n if (!Number.isFinite(index) || !Number.isInteger(index)) {\n recover(\n \"invalid_virtual_option\",\n \"Scroll index must be a finite integer; it is clamped to a valid item.\",\n );\n }\n const target = Math.min(\n count - 1,\n Math.max(0, Number.isFinite(index) ? Math.trunc(index) : 0),\n );\n const start = startOf(target);\n const end = start + sizes[target]!;\n const current = getWindow().offset;\n let result = start;\n if (align === \"center\") result = start - (viewportSize - sizes[target]!) / 2;\n else if (align === \"end\") result = end - viewportSize;\n else if (align === \"auto\") {\n result =\n start < current ? start : end > current + viewportSize ? end - viewportSize : current;\n }\n return Math.min(Math.max(0, totalSize() - viewportSize), Math.max(0, result));\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n","import type { ColumnDef } from \"./column\";\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return false;\n }\n const prototype: unknown = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction collect(value: unknown, prefix: string, depth: number, into: Set<string>): void {\n if (!isPlainObject(value)) {\n return;\n }\n for (const [key, child] of Object.entries(value)) {\n const path = prefix === \"\" ? key : `${prefix}.${key}`;\n if (isPlainObject(child) && depth < 4) {\n collect(child, path, depth + 1, into);\n } else {\n into.add(path);\n }\n }\n}\n\n/**\n * Columns for data that has none declared: one path column per leaf of the first `sample` rows,\n * nested objects flattened into dotted paths, in first-seen order.\n */\nexport function inferColumns<TRow>(rows: readonly TRow[], sample = 20): readonly ColumnDef<TRow>[] {\n const paths = new Set<string>();\n for (const row of rows.slice(0, sample)) {\n collect(row, \"\", 1, paths);\n }\n return Object.freeze([...paths].map((id) => ({ id }) as ColumnDef<TRow>));\n}\n","import type { TableColumn } from \"./column\";\nimport type { TableRow } from \"./row\";\nimport type { PaginationState, SortRule } from \"./state\";\n\n/**\n * The row pipeline: filter, then sort, then paginate. Each stage is a pure function, so a table\n * recomputes only the stages whose inputs changed, and a server can run the same stages.\n */\n\n/** Split free text into lowercase terms. */\nfunction searchTerms(search: string): readonly string[] {\n return search\n .toLowerCase()\n .split(/\\s+/u)\n .filter((term) => term.length > 0);\n}\n\n/**\n * Keep rows that pass every column filter and contain every search term in at least one\n * searchable column.\n */\nexport function filterRows<TRow>(\n rows: readonly TableRow<TRow>[],\n columns: readonly TableColumn<TRow>[],\n search: string,\n filters: Readonly<Record<string, unknown>>,\n): readonly TableRow<TRow>[] {\n const terms = searchTerms(search);\n const byId = new Map(columns.map((column) => [column.id, column]));\n const activeFilters = Object.entries(filters).flatMap(([id, value]) => {\n const column = byId.get(id);\n return column && value !== undefined ? [{ column, value }] : [];\n });\n const searchable = columns.filter((column) => column.searchable);\n\n if (terms.length === 0 && activeFilters.length === 0) {\n return rows;\n }\n\n return rows.filter((row) => {\n for (const { column, value } of activeFilters) {\n if (!column.matches(row.getValue(column.id), value, row.original)) {\n return false;\n }\n }\n if (terms.length === 0) {\n return true;\n }\n const haystack = searchable.map((column) => row.getDisplay(column.id).toLowerCase());\n return terms.every((term) => haystack.some((text) => text.includes(term)));\n });\n}\n\n/** Sort rows by each rule in turn. The sort is stable: ties keep their incoming order. */\nexport function sortRows<TRow>(\n rows: readonly TableRow<TRow>[],\n columns: readonly TableColumn<TRow>[],\n sorting: readonly SortRule[],\n): readonly TableRow<TRow>[] {\n const byId = new Map(columns.map((column) => [column.id, column]));\n const rules = sorting.flatMap((rule) => {\n const column = byId.get(rule.column);\n return column ? [{ column, sign: rule.direction === \"desc\" ? -1 : 1 }] : [];\n });\n if (rules.length === 0) {\n return rows;\n }\n return rows.toSorted((left, right) => {\n for (const { column, sign } of rules) {\n const leftValue = left.getValue(column.id);\n const rightValue = right.getValue(column.id);\n const leftEmpty = leftValue === null || leftValue === undefined || leftValue === \"\";\n const rightEmpty = rightValue === null || rightValue === undefined || rightValue === \"\";\n // Empty values stay last in both directions.\n if (leftEmpty !== rightEmpty) {\n return leftEmpty ? 1 : -1;\n }\n const order = column.compare(leftValue, rightValue) * sign;\n if (order !== 0) {\n return order;\n }\n }\n return 0;\n });\n}\n\n/** The number of pages for a row count. An empty table still has one page. */\nexport function countPages(rowCount: number, pageSize: number): number {\n return Math.max(1, Math.ceil(rowCount / pageSize));\n}\n\n/** Clamp a page into `1..pageCount`. */\nexport function clampPage(page: number, pageCount: number): number {\n return Math.min(Math.max(1, Math.trunc(page) || 1), pageCount);\n}\n\n/** The rows on one page. `pagination.page` must already be clamped. */\nexport function paginateRows<TRow>(\n rows: readonly TableRow<TRow>[],\n pagination: PaginationState,\n): readonly TableRow<TRow>[] {\n const start = (pagination.page - 1) * pagination.pageSize;\n return rows.slice(start, start + pagination.pageSize);\n}\n\n/** A page number, or a gap between page numbers. */\nexport type PageItem =\n | { readonly type: \"page\"; readonly page: number; readonly current: boolean }\n | { readonly type: \"gap\"; readonly key: string };\n\n/**\n * The page buttons to show: always the first and last page, `siblings` pages on each side of the\n * current one, and a gap wherever pages are skipped. A gap never hides a single page.\n */\nexport function paginationItems(\n page: number,\n pageCount: number,\n siblings = 1,\n): readonly PageItem[] {\n const pages = new Set<number>([1, pageCount]);\n for (let offset = -siblings; offset <= siblings; offset += 1) {\n const candidate = page + offset;\n if (candidate >= 1 && candidate <= pageCount) {\n pages.add(candidate);\n }\n }\n const sorted = [...pages].toSorted((left, right) => left - right);\n const items: PageItem[] = [];\n let previous = 0;\n for (const value of sorted) {\n if (value - previous === 2) {\n items.push({ type: \"page\", page: value - 1, current: value - 1 === page });\n } else if (value - previous > 2) {\n items.push({ type: \"gap\", key: `gap-${previous}-${value}` });\n }\n items.push({ type: \"page\", page: value, current: value === page });\n previous = value;\n }\n return items;\n}\n","import type { TableColumn } from \"./column\";\nimport type { RowKey } from \"./state\";\n\n/**\n * One row of data as the engine sees it: its key, its position in the source data, and cached\n * access to each column's value and text.\n */\nexport interface TableRow<TRow> {\n readonly key: RowKey;\n /** Position in the data the table was given. */\n readonly index: number;\n readonly original: TRow;\n readonly canExpand: boolean;\n readonly isExpanded: boolean;\n getValue(columnId: string): unknown;\n /** The formatted text of a cell, as shown, searched, copied, and exported. */\n getDisplay(columnId: string): string;\n}\n\nexport type RowItemKind = \"row\" | \"detail\";\n\n/** A renderer item; detail items do not count as data rows or grid coordinates. */\nexport interface TableRenderItem<TRow> {\n readonly kind: RowItemKind;\n readonly key: string;\n /** The parent data row, also for detail items. */\n readonly row: TableRow<TRow>;\n /** Position of the parent in snapshot.rows. */\n readonly rowIndex: number;\n}\n\n/** Disjoint namespaces and typed keys avoid collisions between 1, \"1\", and detail-like ids. */\nexport function getRowItemKey(key: RowKey, kind: RowItemKind = \"row\"): string {\n return JSON.stringify([kind, typeof key, key]);\n}\n\nexport function createRow<TRow>(\n original: TRow,\n key: RowKey,\n index: number,\n columns: ReadonlyMap<string, TableColumn<TRow>>,\n canExpand = false,\n): TableRow<TRow> {\n const values = new Map<string, unknown>();\n const displays = new Map<string, string>();\n\n const getValue = (columnId: string): unknown => {\n if (values.has(columnId)) {\n return values.get(columnId);\n }\n const value = columns.get(columnId)?.getValue(original);\n values.set(columnId, value);\n return value;\n };\n\n return Object.freeze({\n key,\n index,\n original,\n canExpand,\n isExpanded: false,\n getValue,\n getDisplay(columnId: string): string {\n const cached = displays.get(columnId);\n if (cached !== undefined) {\n return cached;\n }\n const column = columns.get(columnId);\n const display = column ? column.format(getValue(columnId), original) : \"\";\n displays.set(columnId, display);\n return display;\n },\n });\n}\n","import { issue, type TableIssue } from \"./issues\";\n\n/** A stable identity for a row, read from the row itself or produced by a function. */\nexport type RowKey = string | number;\nexport type ExpandedState = readonly RowKey[] | true;\n\nexport type SortDirection = \"asc\" | \"desc\";\n\n/** One level of a sort. Several rules sort by the first, then break ties with the next. */\nexport interface SortRule {\n readonly column: string;\n readonly direction: SortDirection;\n}\n\n/** Pages are counted from 1. */\nexport interface PaginationState {\n readonly page: number;\n readonly pageSize: number;\n}\n\n/**\n * Everything a user can change about a table, as plain serializable data.\n *\n * Being plain data, the state can be stored, restored, sent to a server that sorts and pages, or\n * written to the URL with a library such as QueryWeave.\n */\nexport interface TableState {\n readonly sorting: readonly SortRule[];\n /** Free text matched against every searchable column. */\n readonly search: string;\n /** Filter value per column id, interpreted by that column's `filter`. */\n readonly filters: Readonly<Record<string, unknown>>;\n readonly pagination: PaginationState;\n readonly selection: readonly RowKey[];\n /** Expanded keys, or true for every expandable row. */\n readonly expanded: ExpandedState;\n readonly hiddenColumns: readonly string[];\n /** Column ids in display order. Columns missing from the list keep their definition order. */\n readonly columnOrder: readonly string[];\n}\n\n/** A partial state, as accepted by `setState` and `initialState`. */\nexport type TableStatePatch = {\n readonly [K in keyof TableState]?: TableState[K] | undefined;\n};\n\nexport const DEFAULT_PAGE_SIZE = 10;\n\nexport function createInitialState(\n patch: TableStatePatch = {},\n onIssue?: (problem: TableIssue) => void,\n): TableState {\n return freezeState({\n sorting: patch.sorting ?? [],\n search: patch.search ?? \"\",\n filters: patch.filters ?? {},\n pagination: patch.pagination ?? { page: 1, pageSize: DEFAULT_PAGE_SIZE },\n selection: patch.selection ?? [],\n expanded: normalizeExpanded(patch.expanded === undefined ? [] : patch.expanded, onIssue),\n hiddenColumns: patch.hiddenColumns ?? [],\n columnOrder: patch.columnOrder ?? [],\n });\n}\n\nexport function mergeState(\n state: TableState,\n patch: TableStatePatch,\n onIssue?: (problem: TableIssue) => void,\n): TableState {\n let changed = false;\n const next: Record<string, unknown> = { ...state };\n for (const [key, input] of Object.entries(patch)) {\n const value =\n key === \"expanded\" && input !== undefined ? normalizeExpanded(input, onIssue) : input;\n if (value === undefined || Object.is(next[key], value)) {\n continue;\n }\n if (\n key === \"pagination\" &&\n samePagination(next[key] as PaginationState, value as PaginationState)\n ) {\n continue;\n }\n if (key === \"expanded\" && sameExpanded(state.expanded, value as ExpandedState)) continue;\n next[key] = value;\n changed = true;\n }\n return changed ? freezeState(next as unknown as TableState, state) : state;\n}\n\nfunction normalizeExpanded(value: unknown, onIssue?: (problem: TableIssue) => void): ExpandedState {\n if (value === true) return true;\n if (\n Array.isArray(value) &&\n value.every(\n (key: unknown) =>\n typeof key === \"string\" || (typeof key === \"number\" && Number.isFinite(key)),\n )\n ) {\n return [...new Set(value as RowKey[])];\n }\n onIssue?.(\n issue(\n \"invalid_expanded\",\n \"Expanded state must be true or an array of string/finite number keys; an empty array is used.\",\n ),\n );\n return [];\n}\n\nfunction sameExpanded(left: ExpandedState, right: ExpandedState): boolean {\n return (\n left === right ||\n (left !== true &&\n right !== true &&\n left.length === right.length &&\n left.every((key, index) => key === right[index]))\n );\n}\n\nfunction samePagination(left: PaginationState, right: PaginationState): boolean {\n return left.page === right.page && left.pageSize === right.pageSize;\n}\n\nfunction freezeState(state: TableState, previous?: TableState): TableState {\n return Object.freeze({\n sorting:\n state.sorting === previous?.sorting\n ? previous.sorting\n : Object.freeze(state.sorting.map((rule) => Object.freeze({ ...rule }))),\n search: state.search,\n filters:\n state.filters === previous?.filters ? previous.filters : Object.freeze({ ...state.filters }),\n pagination:\n state.pagination === previous?.pagination\n ? previous.pagination\n : Object.freeze({ ...state.pagination }),\n selection:\n state.selection === previous?.selection\n ? previous.selection\n : Object.freeze([...state.selection]),\n expanded:\n state.expanded === previous?.expanded\n ? previous.expanded\n : state.expanded === true\n ? true\n : Object.freeze([...state.expanded]),\n hiddenColumns:\n state.hiddenColumns === previous?.hiddenColumns\n ? previous.hiddenColumns\n : Object.freeze([...state.hiddenColumns]),\n columnOrder:\n state.columnOrder === previous?.columnOrder\n ? previous.columnOrder\n : Object.freeze([...state.columnOrder]),\n });\n}\n","import { resolveColumn, type ColumnDef, type TableColumn } from \"./column\";\nimport { escapeFormula, readDelimited, toDelimited } from \"./delimited\";\nimport { rangeContains, type CellPosition, type CellRange } from \"./grid\";\nimport { issue, type TableIssue } from \"./issues\";\nimport type { DeepKeys } from \"./path\";\nimport { getPath, isSafePath } from \"./path\";\nimport {\n clampPage,\n countPages,\n filterRows,\n paginateRows,\n sortRows,\n type PageItem,\n paginationItems,\n} from \"./pipeline\";\nimport { createRow, getRowItemKey, type TableRow, type TableRenderItem } from \"./row\";\nimport {\n DEFAULT_PAGE_SIZE,\n createInitialState,\n mergeState,\n type RowKey,\n type ExpandedState,\n type SortDirection,\n type TableState,\n type TableStatePatch,\n} from \"./state\";\nimport { createUndoStack } from \"./undo-stack\";\n\nexport type SelectionMode = \"none\" | \"single\" | \"multiple\";\nexport type ExpandMode = \"single\" | \"multiple\";\n\n/** Which rows \"select all\" covers: the current page, or every row that passes the filters. */\nexport type SelectScope = \"page\" | \"all\";\n\nexport interface PasteLimit {\n /** Maximum fields examined per paste, including clipped columns. Defaults to 100,000. */\n readonly maxCells?: number | undefined;\n /** Maximum UTF-16 code units examined per paste. Defaults to 5,000,000. */\n readonly maxLength?: number | undefined;\n}\n\nexport interface TableOptions<TRow> {\n readonly data: readonly TRow[];\n readonly columns: readonly ColumnDef<TRow>[];\n /**\n * How to identify a row: a path into it, or a function. Defaults to `id` when rows have one and\n * to the row's position otherwise.\n */\n readonly rowKey?: DeepKeys<TRow> | ((row: TRow, index: number) => RowKey) | undefined;\n readonly initialState?: TableStatePatch | undefined;\n /** Present all processed rows rather than a page. Defaults to true. */\n readonly paginate?: boolean | undefined;\n readonly getRowCanExpand?: ((row: TRow) => boolean) | undefined;\n readonly expandMode?: ExpandMode | undefined;\n /** Defaults to `\"multiple\"`. */\n readonly selectionMode?: SelectionMode | undefined;\n /** Defaults to `\"all\"`. */\n readonly selectScope?: SelectScope | undefined;\n /**\n * The data is one page that a server has already searched, filtered, sorted, and paginated\n * with the current state. The table only presents it; `rowCount` gives the total.\n */\n readonly manual?: boolean | undefined;\n /** The total number of rows across all pages, for `manual` tables. */\n readonly rowCount?: number | undefined;\n /** Called after every state change a table operation makes, not after `setState`. */\n readonly onStateChange?: ((state: TableState, previous: TableState) => void) | undefined;\n /** Called with the new data after an edit, a paste, an undo, or a redo. */\n readonly onDataChange?:\n | ((data: readonly TRow[], changes: readonly CellChange<TRow>[]) => void)\n | undefined;\n /** Called with the reasons whenever an edit, a paste, or a clear refuses some cells. */\n readonly onEditIssues?: ((issues: readonly TableIssue[]) => void) | undefined;\n /** The most edit batches `undo` can reach. Defaults to 100. */\n readonly historyLimit?: number | undefined;\n /** Bound clipboard parsing. Only complete cells inside the visible grid are applied. */\n readonly pasteLimit?: PasteLimit | undefined;\n}\n\nexport type SelectionCoverage = \"none\" | \"some\" | \"all\";\n\nexport interface SortInfo {\n readonly direction: SortDirection;\n /** 0 for the first rule, 1 for the next, and so on. */\n readonly priority: number;\n}\n\n/**\n * Everything a renderer needs, computed from the data, the columns, and the state. A snapshot is\n * frozen and replaced on each change, so comparing snapshots by identity detects a change.\n */\nexport interface TableSnapshot<TRow> {\n readonly state: TableState;\n /** Visible columns in display order. */\n readonly columns: readonly TableColumn<TRow>[];\n /** Every column in display order, hidden ones included. */\n readonly allColumns: readonly TableColumn<TRow>[];\n /** Rows on the current page, or all processed rows when pagination is disabled. */\n readonly rows: readonly TableRow<TRow>[];\n /** Data rows followed by their open details; details do not affect pagination or grid positions. */\n readonly renderItems: readonly TableRenderItem<TRow>[];\n readonly paginate: boolean;\n /** Rows on every page, filtered and sorted. For `manual` tables this is the current page. */\n readonly processedRows: readonly TableRow<TRow>[];\n /** The current page, clamped into range. */\n readonly page: number;\n readonly pageSize: number;\n readonly pageCount: number;\n /** Rows that pass the search and filters. */\n readonly rowCount: number;\n /** Rows before searching and filtering. */\n readonly totalRowCount: number;\n /** The 1-based position of the first row on this page, or 0 when there are no rows. */\n readonly pageStart: number;\n /** The 1-based position of the last row on this page, or 0 when there are no rows. */\n readonly pageEnd: number;\n readonly pageItems: readonly PageItem[];\n readonly canPreviousPage: boolean;\n readonly canNextPage: boolean;\n readonly selectionMode: SelectionMode;\n readonly selectedCount: number;\n /** How much of the current page is selected. */\n readonly pageSelection: SelectionCoverage;\n /** How much of the select-all scope is selected. */\n readonly allSelection: SelectionCoverage;\n readonly canUndo: boolean;\n readonly canRedo: boolean;\n readonly issues: readonly TableIssue[];\n isSelected(key: RowKey): boolean;\n getSort(columnId: string): SortInfo | undefined;\n getColumn(columnId: string): TableColumn<TRow> | undefined;\n getRow(key: RowKey): TableRow<TRow> | undefined;\n}\n\n/** An edit given as a value of the column's type. */\nexport interface CellValueEdit {\n readonly rowKey: RowKey;\n readonly column: string;\n readonly value: unknown;\n}\n\n/** An edit given as text, read by the column's `parse`, as typed or pasted. */\nexport interface CellInputEdit {\n readonly rowKey: RowKey;\n readonly column: string;\n readonly input: string;\n}\n\nexport type CellEdit = CellValueEdit | CellInputEdit;\n\nexport interface CellChange<TRow> {\n readonly rowKey: RowKey;\n readonly column: string;\n readonly previous: unknown;\n readonly value: unknown;\n /** The row after the change. */\n readonly row: TRow;\n}\n\nexport type EditStatus = \"applied\" | \"partial\" | \"rejected\" | \"unchanged\";\n\n/**\n * The outcome of a batch of edits. `partial` means some edits applied and others were refused;\n * each refusal is in `issues`.\n */\nexport interface EditResult<TRow> {\n readonly status: EditStatus;\n readonly changes: readonly CellChange<TRow>[];\n readonly issues: readonly TableIssue[];\n}\n\nexport interface CopyOptions {\n /** Prefix formula-like text with an apostrophe. Defaults to false for clipboard copies. */\n readonly escapeFormulas?: boolean | undefined;\n}\n\nexport interface ExportOptions extends CopyOptions {\n /** Prefix formula-like text with an apostrophe. Defaults to true for exports. */\n readonly escapeFormulas?: boolean | undefined;\n /** Defaults to `\"csv\"`. */\n readonly format?: \"csv\" | \"tsv\" | undefined;\n /** Column ids to export. Defaults to the visible columns. */\n readonly columns?: readonly string[] | undefined;\n /** Export only the current page. Defaults to every filtered row. */\n readonly pageOnly?: boolean | undefined;\n /** Defaults to `true`. */\n readonly headers?: boolean | undefined;\n}\n\n/**\n * A data table: data, columns, and state, with named operations to change them. It knows nothing\n * about rendering; a framework binding subscribes to it and draws each snapshot.\n */\nexport interface DataTable<TRow> {\n getSnapshot(): TableSnapshot<TRow>;\n getState(): TableState;\n /** Called after every change with the new snapshot. Returns the unsubscribe function. */\n subscribe(listener: (snapshot: TableSnapshot<TRow>) => void): () => void;\n\n /** Replace part of the state from outside, without calling `onStateChange`. */\n setState(patch: TableStatePatch): void;\n /** Replace the data. The undo stack is cleared unless the data is the table's own. */\n setData(data: readonly TRow[]): void;\n setColumns(columns: readonly ColumnDef<TRow>[]): void;\n /** Update the total row count of a `manual` table. */\n setRowCount(rowCount: number): void;\n\n /** Cycle a column through ascending, descending, and unsorted. */\n toggleSort(columnId: string, options?: { readonly multi?: boolean | undefined }): void;\n /** Sort by one column, or clear it with `undefined`. */\n sort(\n columnId: string,\n direction: SortDirection | undefined,\n options?: { readonly multi?: boolean | undefined },\n ): void;\n clearSorting(): void;\n search(text: string): void;\n /** Set a column's filter value; an empty value removes the filter. */\n filter(columnId: string, value: unknown): void;\n clearFilters(): void;\n\n goToPage(page: number): void;\n nextPage(): void;\n previousPage(): void;\n /** Change the page size, keeping the first row of the current page in view. */\n setPageSize(pageSize: number): void;\n\n select(keys: readonly RowKey[]): void;\n deselect(keys: readonly RowKey[]): void;\n toggleRow(key: RowKey, selected?: boolean): void;\n /** Select every row in the scope, or clear them when all are already selected. */\n toggleAll(scope?: SelectScope): void;\n clearSelection(): void;\n /** The selected rows that are present in the data. */\n getSelectedRows(): readonly TableRow<TRow>[];\n\n toggleExpanded(key: RowKey, expanded?: boolean): void;\n expandAll(): void;\n collapseAll(): void;\n\n toggleColumn(columnId: string, visible?: boolean): void;\n moveColumn(columnId: string, toIndex: number): void;\n\n edit(edits: CellEdit | readonly CellEdit[]): EditResult<TRow>;\n undo(): boolean;\n redo(): boolean;\n /** The text of a range of shown cells, tab-separated like a spreadsheet clipboard. */\n copy(range: CellRange, options?: CopyOptions): string;\n /** Paste tab-separated text with its top-left cell at `origin`, clipped to the grid. */\n paste(origin: CellPosition, text: string): EditResult<TRow>;\n /** Empty every editable cell in a range. */\n clear(range: CellRange): EditResult<TRow>;\n exportRows(options?: ExportOptions): string;\n\n /** Return to the initial state. */\n reset(): void;\n /** Drop every listener. */\n destroy(): void;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction memo<TDeps extends readonly unknown[], TResult>(\n compute: (...deps: TDeps) => TResult,\n): (...deps: TDeps) => TResult {\n let last: { readonly deps: TDeps; readonly result: TResult } | undefined;\n return (...deps: TDeps): TResult => {\n if (\n last &&\n last.deps.length === deps.length &&\n last.deps.every((d, i) => Object.is(d, deps[i]))\n ) {\n return last.result;\n }\n const result = compute(...deps);\n last = { deps, result };\n return result;\n };\n}\n\nfunction isInputEdit(edit: CellEdit): edit is CellInputEdit {\n return \"input\" in edit;\n}\n\nfunction coverage(selected: number, total: number): SelectionCoverage {\n if (selected === 0 || total === 0) {\n return \"none\";\n }\n return selected === total ? \"all\" : \"some\";\n}\n\ninterface IndexedRows<TRow> {\n readonly rows: readonly TableRow<TRow>[];\n readonly byKey: ReadonlyMap<RowKey, TableRow<TRow>>;\n readonly issues: readonly TableIssue[];\n}\n\nfunction pasteLimit(\n value: number | undefined,\n fallback: number,\n name: string,\n issues: TableIssue[],\n): number {\n if (value === undefined) {\n return fallback;\n }\n if (Number.isSafeInteger(value) && value > 0) {\n return value;\n }\n issues.push(\n issue(\n \"invalid_paste_limit\",\n `Paste ${name} ${String(value)} is not a positive safe integer; ${fallback} is used.`,\n ),\n );\n return fallback;\n}\n\n/** Create a data table. */\nexport function createTable<TRow>(options: TableOptions<TRow>): DataTable<TRow> {\n const paginate = options.paginate ?? true;\n const expandMode = options.expandMode ?? \"multiple\";\n const selectionMode = options.selectionMode ?? \"multiple\";\n const selectScope = options.selectScope ?? \"all\";\n const manual = options.manual ?? false;\n const undoStack = createUndoStack<readonly CellChange<TRow>[]>(options.historyLimit);\n const listeners = new Set<(snapshot: TableSnapshot<TRow>) => void>();\n const optionIssues: TableIssue[] = [];\n const maxPasteCells = pasteLimit(options.pasteLimit?.maxCells, 100_000, \"maxCells\", optionIssues);\n const maxPasteLength = pasteLimit(\n options.pasteLimit?.maxLength,\n 5_000_000,\n \"maxLength\",\n optionIssues,\n );\n\n let data = options.data;\n let definitions = options.columns;\n let rowCount = options.rowCount;\n let expandedIssue: TableIssue | undefined;\n let initialState = createInitialState(\n {\n ...options.initialState,\n hiddenColumns:\n options.initialState?.hiddenColumns ??\n options.columns.filter((column) => column.hidden === true).map((column) => column.id),\n },\n (problem) => {\n expandedIssue = problem;\n },\n );\n let state = initialState;\n let snapshot: TableSnapshot<TRow> | undefined;\n\n const readKey = (row: TRow, index: number): RowKey => {\n const { rowKey } = options;\n if (typeof rowKey === \"function\") {\n return rowKey(row, index);\n }\n const path = rowKey ?? \"id\";\n const value = getPath(row, path);\n if (typeof value === \"string\" || typeof value === \"number\") {\n return value;\n }\n return rowKey === undefined || !isRecord(row) ? index : String(value);\n };\n\n const resolveColumns = memo((defs: readonly ColumnDef<TRow>[]) => {\n const issues: TableIssue[] = [];\n const columns = defs.flatMap((definition) => {\n if (!isSafePath(definition.id)) {\n issues.push(\n issue(\n \"unsafe_path\",\n `The column \"${definition.id}\" addresses a prototype and is ignored.`,\n { column: definition.id },\n ),\n );\n return [];\n }\n return [resolveColumn(definition)];\n });\n return { columns, byId: new Map(columns.map((column) => [column.id, column])), issues };\n });\n\n const indexRows = memo(\n (rows: readonly TRow[], byId: ReadonlyMap<string, TableColumn<TRow>>): IndexedRows<TRow> => {\n const byKey = new Map<RowKey, TableRow<TRow>>();\n const issues: TableIssue[] = [];\n const indexed = rows.map((original, index) => {\n let key = readKey(original, index);\n if (byKey.has(key)) {\n issues.push(\n issue(\n \"duplicate_row_key\",\n `Row ${index} repeats the key \"${String(key)}\"; it is keyed \"${String(key)}#${index}\" instead.`,\n { rowKey: key },\n ),\n );\n key = `${String(key)}#${index}`;\n }\n const row = createRow(\n original,\n key,\n index,\n byId,\n options.getRowCanExpand?.(original) ?? false,\n );\n byKey.set(key, row);\n return row;\n });\n return { rows: indexed, byKey, issues };\n },\n );\n\n const orderColumns = memo(\n (\n columns: readonly TableColumn<TRow>[],\n columnOrder: readonly string[],\n hiddenColumns: readonly string[],\n ) => {\n const position = new Map(columnOrder.map((id, index) => [id, index]));\n const ordered = columns\n .map((column, index) => ({ column, index }))\n .toSorted((left, right) => {\n const leftPosition = position.get(left.column.id) ?? columnOrder.length + left.index;\n const rightPosition = position.get(right.column.id) ?? columnOrder.length + right.index;\n return leftPosition - rightPosition;\n })\n .map(({ column }) => column);\n const hidden = new Set(hiddenColumns);\n return { all: ordered, visible: ordered.filter((column) => !hidden.has(column.id)) };\n },\n );\n\n const filterStage = memo(filterRows<TRow>);\n const sortStage = memo(sortRows<TRow>);\n const selectedSet = memo((selection: readonly RowKey[]) => new Set(selection));\n const expansionStage = memo((indexed: IndexedRows<TRow>, expanded: ExpandedState) => {\n const keys = expanded === true ? undefined : new Set(expanded);\n const rows = indexed.rows.map((row) =>\n row.canExpand && (expanded === true || keys?.has(row.key))\n ? Object.freeze({ ...row, isExpanded: true })\n : row,\n );\n return { rows, byKey: new Map(rows.map((row) => [row.key, row])) };\n });\n const expandedOrder = memo(\n (rows: readonly TableRow<TRow>[], byKey: ReadonlyMap<RowKey, TableRow<TRow>>) =>\n rows.map((row) => byKey.get(row.key)!),\n );\n\n function stateIssues(byId: ReadonlyMap<string, TableColumn<TRow>>): TableIssue[] {\n const issues: TableIssue[] = [];\n if (expandedIssue) issues.push(expandedIssue);\n const referenced = new Set([\n ...state.sorting.map((rule) => rule.column),\n ...Object.keys(state.filters),\n ...state.hiddenColumns,\n ...state.columnOrder,\n ]);\n for (const id of referenced) {\n if (!byId.has(id)) {\n issues.push(\n issue(\"unknown_column\", `The state refers to a column \"${id}\" that is not defined.`, {\n column: id,\n }),\n );\n }\n }\n const { pageSize } = state.pagination;\n if (paginate && (!Number.isInteger(pageSize) || pageSize < 1)) {\n issues.push(\n issue(\n \"invalid_page_size\",\n `Page size ${String(pageSize)} is not a positive whole number; ${DEFAULT_PAGE_SIZE} is used.`,\n ),\n );\n }\n return issues;\n }\n\n function computeSnapshot(): TableSnapshot<TRow> {\n const { columns, byId, issues: columnIssues } = resolveColumns(definitions);\n const indexed = indexRows(data, byId);\n const expanded = expansionStage(indexed, state.expanded);\n const ordered = orderColumns(columns, state.columnOrder, state.hiddenColumns);\n const issues = [...optionIssues, ...columnIssues, ...indexed.issues, ...stateIssues(byId)];\n const requestedSize = state.pagination.pageSize;\n let pageSize =\n Number.isInteger(requestedSize) && requestedSize >= 1 ? requestedSize : DEFAULT_PAGE_SIZE;\n\n let processedRows: readonly TableRow<TRow>[];\n let rows: readonly TableRow<TRow>[];\n let filteredCount: number;\n let page: number;\n let pageCount: number;\n if (manual) {\n processedRows = expanded.rows;\n rows = expanded.rows;\n filteredCount = rowCount ?? indexed.rows.length;\n pageCount = countPages(filteredCount, pageSize);\n page = clampPage(state.pagination.page, pageCount);\n } else {\n const filtered = filterStage(indexed.rows, columns, state.search, state.filters);\n processedRows = expandedOrder(sortStage(filtered, columns, state.sorting), expanded.byKey);\n filteredCount = processedRows.length;\n pageCount = countPages(filteredCount, pageSize);\n page = clampPage(state.pagination.page, pageCount);\n rows = paginateRows(processedRows, { page, pageSize });\n }\n\n if (!paginate) {\n rows = processedRows;\n page = 1;\n pageCount = 1;\n pageSize = Math.max(1, rows.length);\n }\n\n const selected = selectedSet(state.selection);\n const pageSelected = rows.filter((row) => selected.has(row.key)).length;\n const scopeRows = selectScope === \"page\" || manual ? rows : processedRows;\n const scopeSelected =\n scopeRows === rows ? pageSelected : scopeRows.filter((row) => selected.has(row.key)).length;\n const pageStart = rows.length === 0 ? 0 : (page - 1) * pageSize + 1;\n const sortIndex = new Map(\n state.sorting.map((rule, priority) => [rule.column, { direction: rule.direction, priority }]),\n );\n\n return Object.freeze({\n state,\n columns: ordered.visible,\n allColumns: ordered.all,\n rows,\n renderItems: Object.freeze(\n rows.flatMap((row, rowIndex): TableRenderItem<TRow>[] => {\n const item = Object.freeze({\n kind: \"row\" as const,\n key: getRowItemKey(row.key),\n row,\n rowIndex,\n });\n return row.isExpanded\n ? [\n item,\n Object.freeze({\n kind: \"detail\" as const,\n key: getRowItemKey(row.key, \"detail\"),\n row,\n rowIndex,\n }),\n ]\n : [item];\n }),\n ),\n paginate,\n processedRows,\n page,\n pageSize,\n pageCount,\n rowCount: filteredCount,\n totalRowCount: manual ? filteredCount : indexed.rows.length,\n pageStart,\n pageEnd: rows.length === 0 ? 0 : pageStart + rows.length - 1,\n pageItems: paginationItems(page, pageCount),\n canPreviousPage: page > 1,\n canNextPage: page < pageCount,\n selectionMode,\n selectedCount: state.selection.length,\n pageSelection: coverage(pageSelected, rows.length),\n allSelection: coverage(scopeSelected, scopeRows.length),\n canUndo: undoStack.canUndo,\n canRedo: undoStack.canRedo,\n issues: Object.freeze(issues),\n isSelected: (key: RowKey): boolean => selected.has(key),\n getSort: (columnId: string): SortInfo | undefined => sortIndex.get(columnId),\n getColumn: (columnId: string): TableColumn<TRow> | undefined => byId.get(columnId),\n getRow: (key: RowKey): TableRow<TRow> | undefined => expanded.byKey.get(key),\n });\n }\n\n function getSnapshot(): TableSnapshot<TRow> {\n snapshot ??= computeSnapshot();\n return snapshot;\n }\n\n function notify(): void {\n snapshot = undefined;\n if (listeners.size === 0) {\n return;\n }\n const next = getSnapshot();\n for (const listener of listeners) {\n listener(next);\n }\n }\n\n /** Apply a change made by a table operation. */\n function commit(patch: TableStatePatch): void {\n const previous = state;\n const previousIssue = expandedIssue;\n const next = mergePatch(patch);\n if (next === previous && previousIssue === expandedIssue) {\n return;\n }\n state = next;\n if (next !== previous) options.onStateChange?.(state, previous);\n notify();\n }\n\n function canonicalExpanded(\n expanded: ExpandedState,\n candidate: TableState = state,\n ): ExpandedState {\n if (expandMode === \"multiple\") return expanded;\n if (expanded !== true) return expanded.slice(-1);\n const { columns, byId } = resolveColumns(definitions);\n const indexed = indexRows(data, byId);\n const processed = manual\n ? indexed.rows\n : sortStage(\n filterStage(indexed.rows, columns, candidate.search, candidate.filters),\n columns,\n candidate.sorting,\n );\n const first = processed.find((row) => row.canExpand);\n return first ? [first.key] : [];\n }\n\n function mergePatch(patch: TableStatePatch): TableState {\n if (patch.expanded !== undefined) expandedIssue = undefined;\n const next = mergeState(state, patch, (problem) => {\n expandedIssue = problem;\n });\n return expandMode === \"single\" && patch.expanded !== undefined\n ? mergeState(state, { ...patch, expanded: canonicalExpanded(next.expanded, next) })\n : next;\n }\n\n const firstPage = (): { readonly page: number; readonly pageSize: number } => ({\n page: 1,\n pageSize: state.pagination.pageSize,\n });\n\n function setSort(columnId: string, direction: SortDirection | undefined, multi: boolean): void {\n const column = getSnapshot().getColumn(columnId);\n if (!column?.sortable) {\n return;\n }\n const others = multi ? state.sorting.filter((rule) => rule.column !== columnId) : [];\n const existing = state.sorting.findIndex((rule) => rule.column === columnId);\n let sorting = others;\n if (direction) {\n const rule = { column: columnId, direction };\n sorting =\n multi && existing !== -1\n ? state.sorting.map((current) => (current.column === columnId ? rule : current))\n : [...others, rule];\n }\n commit({ sorting, pagination: firstPage() });\n }\n\n function applySelection(next: readonly RowKey[]): void {\n if (selectionMode === \"none\") {\n return;\n }\n const unique = [...new Set(next)];\n const selection = selectionMode === \"single\" ? unique.slice(-1) : unique;\n const current = state.selection;\n if (selection.length === current.length && selection.every((key, i) => key === current[i])) {\n return;\n }\n commit({ selection });\n }\n\n function applyChanges(\n edits: readonly CellEdit[],\n record: boolean,\n recoveredIssues: readonly TableIssue[] = [],\n ): EditResult<TRow> {\n const current = getSnapshot();\n const working = [...data];\n const issues: TableIssue[] = [...recoveredIssues];\n const changes: CellChange<TRow>[] = [];\n // A value from another row tells a column's type when the edited cell is empty. It is looked\n // up once per column, not once per edit, so pasting a large range stays linear.\n const samples = new Map<string, unknown>();\n const sampleOf = (columnId: string): unknown => {\n if (!samples.has(columnId)) {\n const other = current.processedRows.find((candidate) => {\n const value = candidate.getValue(columnId);\n return value !== null && value !== undefined;\n });\n samples.set(columnId, other?.getValue(columnId));\n }\n return samples.get(columnId);\n };\n for (const edit of edits) {\n const row = current.getRow(edit.rowKey);\n const column = current.getColumn(edit.column);\n if (!row) {\n issues.push(\n issue(\"unknown_row\", `No row has the key \"${String(edit.rowKey)}\".`, {\n rowKey: edit.rowKey,\n column: edit.column,\n }),\n );\n continue;\n }\n if (!isSafePath(edit.column)) {\n issues.push(\n issue(\n \"unsafe_path\",\n `The path \"${edit.column}\" addresses a prototype and cannot be written.`,\n { rowKey: edit.rowKey, column: edit.column },\n ),\n );\n continue;\n }\n if (!column) {\n issues.push(\n issue(\"unknown_column\", `No column has the id \"${edit.column}\".`, {\n rowKey: edit.rowKey,\n column: edit.column,\n }),\n );\n continue;\n }\n const original = working[row.index] as TRow;\n if (record && !column.isEditable(original)) {\n issues.push(\n issue(\n \"read_only_cell\",\n `The \"${column.id}\" cell of row \"${String(row.key)}\" is read-only.`,\n {\n rowKey: row.key,\n column: column.id,\n },\n ),\n );\n continue;\n }\n let value: unknown;\n if (isInputEdit(edit)) {\n const parsed = column.parse(edit.input, original, sampleOf(column.id));\n if (!parsed.ok) {\n issues.push(\n issue(\"invalid_value\", parsed.message, { rowKey: row.key, column: column.id }),\n );\n continue;\n }\n value = parsed.value;\n } else {\n value = edit.value;\n }\n const previous = column.getValue(original);\n if (Object.is(previous, value)) {\n continue;\n }\n const updated = column.setValue(original, value);\n if (updated === undefined) {\n issues.push(\n issue(\"read_only_cell\", `The \"${column.id}\" column has no way to write a value.`, {\n rowKey: row.key,\n column: column.id,\n }),\n );\n continue;\n }\n working[row.index] = updated;\n changes.push({ rowKey: row.key, column: column.id, previous, value, row: updated });\n }\n\n let status: EditStatus;\n if (changes.length === 0) {\n status = issues.length > 0 ? \"rejected\" : \"unchanged\";\n } else {\n status = issues.length > 0 ? \"partial\" : \"applied\";\n data = working;\n if (record) {\n undoStack.record(changes);\n }\n options.onDataChange?.(data, changes);\n notify();\n }\n if (issues.length > 0) {\n options.onEditIssues?.(issues);\n }\n return Object.freeze({\n status,\n changes: Object.freeze(changes),\n issues: Object.freeze(issues),\n });\n }\n\n function rangeEdits(origin: CellPosition, matrix: readonly (readonly string[])[]): CellEdit[] {\n const { rows, columns } = getSnapshot();\n const edits: CellEdit[] = [];\n matrix.forEach((line, rowOffset) => {\n const row = rows[origin.row + rowOffset];\n if (!row) {\n return;\n }\n line.forEach((input, columnOffset) => {\n const column = columns[origin.column + columnOffset];\n if (column) {\n edits.push({ rowKey: row.key, column: column.id, input });\n }\n });\n });\n return edits;\n }\n\n function replay(changes: readonly CellChange<TRow>[], direction: \"undo\" | \"redo\"): void {\n applyChanges(\n changes.map((change) => ({\n rowKey: change.rowKey,\n column: change.column,\n value: direction === \"undo\" ? change.previous : change.value,\n })),\n false,\n );\n }\n\n if (expandMode === \"single\") {\n initialState = mergeState(initialState, { expanded: canonicalExpanded(initialState.expanded) });\n state = initialState;\n snapshot = undefined;\n }\n\n const table: DataTable<TRow> = {\n getSnapshot,\n getState: () => state,\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n\n setState(patch) {\n const previousIssue = expandedIssue;\n const next = mergePatch(patch);\n if (next !== state || previousIssue !== expandedIssue) {\n state = next;\n notify();\n }\n },\n setData(next) {\n if (next === data) {\n return;\n }\n data = next;\n undoStack.clear();\n notify();\n },\n setColumns(next) {\n if (next === definitions) {\n return;\n }\n definitions = next;\n notify();\n },\n setRowCount(next) {\n if (next === rowCount) {\n return;\n }\n rowCount = next;\n notify();\n },\n\n toggleSort(columnId, { multi = false } = {}) {\n const current = state.sorting.find((rule) => rule.column === columnId)?.direction;\n const next = current === undefined ? \"asc\" : current === \"asc\" ? \"desc\" : undefined;\n setSort(columnId, next, multi);\n },\n sort(columnId, direction, { multi = false } = {}) {\n setSort(columnId, direction, multi);\n },\n clearSorting() {\n commit({ sorting: [] });\n },\n search(text) {\n if (text === state.search) {\n return;\n }\n commit({ search: text, pagination: firstPage() });\n },\n filter(columnId, value) {\n const filters: Record<string, unknown> = { ...state.filters };\n const empty =\n value === undefined ||\n value === null ||\n value === \"\" ||\n (Array.isArray(value) && value.length === 0);\n if (empty ? !(columnId in filters) : Object.is(filters[columnId], value)) {\n return;\n }\n if (empty) {\n delete filters[columnId];\n } else {\n filters[columnId] = value;\n }\n commit({ filters, pagination: firstPage() });\n },\n clearFilters() {\n if (Object.keys(state.filters).length > 0) {\n commit({ filters: {}, pagination: firstPage() });\n }\n },\n\n goToPage(page) {\n if (!paginate) return;\n const { pageCount, page: currentPage } = getSnapshot();\n const next = clampPage(page, pageCount);\n if (next !== currentPage || next !== state.pagination.page) {\n commit({ pagination: { page: next, pageSize: state.pagination.pageSize } });\n }\n },\n nextPage() {\n table.goToPage(getSnapshot().page + 1);\n },\n previousPage() {\n table.goToPage(getSnapshot().page - 1);\n },\n setPageSize(pageSize) {\n if (!paginate) return;\n if (!Number.isInteger(pageSize) || pageSize < 1 || pageSize === state.pagination.pageSize) {\n return;\n }\n const { pageStart } = getSnapshot();\n const page = pageStart === 0 ? 1 : Math.floor((pageStart - 1) / pageSize) + 1;\n commit({ pagination: { page, pageSize } });\n },\n\n select(keys) {\n applySelection([...state.selection, ...keys]);\n },\n deselect(keys) {\n const removed = new Set(keys);\n applySelection(state.selection.filter((key) => !removed.has(key)));\n },\n toggleRow(key, selected) {\n const isSelected = state.selection.includes(key);\n const next = selected ?? !isSelected;\n if (next === isSelected) {\n return;\n }\n if (next) {\n table.select([key]);\n } else {\n table.deselect([key]);\n }\n },\n toggleAll(scope = selectScope) {\n if (selectionMode !== \"multiple\") {\n return;\n }\n const current = getSnapshot();\n const rows = scope === \"page\" || manual ? current.rows : current.processedRows;\n const keys = rows.map((row) => row.key);\n const allSelected = keys.length > 0 && keys.every((key) => current.isSelected(key));\n if (allSelected) {\n table.deselect(keys);\n } else {\n table.select(keys);\n }\n },\n clearSelection() {\n applySelection([]);\n },\n getSelectedRows() {\n const current = getSnapshot();\n return state.selection.flatMap((key) => {\n const row = current.getRow(key);\n return row ? [row] : [];\n });\n },\n\n toggleExpanded(key, expanded) {\n const row = getSnapshot().getRow(key);\n if (!row?.canExpand) return;\n const open = expanded ?? !row.isExpanded;\n if (open === row.isExpanded) return;\n if (expandMode === \"single\") {\n commit({ expanded: open ? [key] : [] });\n } else if (state.expanded === true) {\n const { byId } = resolveColumns(definitions);\n commit({\n expanded: indexRows(data, byId)\n .rows.filter((candidate) => candidate.canExpand && candidate.key !== key)\n .map((candidate) => candidate.key),\n });\n } else {\n commit({\n expanded: open\n ? [...state.expanded, key]\n : state.expanded.filter((candidate) => candidate !== key),\n });\n }\n },\n expandAll() {\n commit({ expanded: true });\n },\n collapseAll() {\n commit({ expanded: [] });\n },\n\n toggleColumn(columnId, visible) {\n if (!getSnapshot().getColumn(columnId)) {\n return;\n }\n const hidden = state.hiddenColumns.includes(columnId);\n const show = visible ?? hidden;\n if (show === !hidden) {\n return;\n }\n commit({\n hiddenColumns: show\n ? state.hiddenColumns.filter((id) => id !== columnId)\n : [...state.hiddenColumns, columnId],\n });\n },\n moveColumn(columnId, toIndex) {\n const order = getSnapshot().allColumns.map((column) => column.id);\n const from = order.indexOf(columnId);\n if (from === -1) {\n return;\n }\n const target = Math.min(Math.max(0, Math.trunc(toIndex)), order.length - 1);\n if (target === from) {\n return;\n }\n order.splice(from, 1);\n order.splice(target, 0, columnId);\n commit({ columnOrder: order });\n },\n\n edit(edits) {\n return applyChanges(Array.isArray(edits) ? edits : [edits as CellEdit], true);\n },\n undo() {\n const changes = undoStack.undo();\n if (!changes) {\n return false;\n }\n replay(changes, \"undo\");\n return true;\n },\n redo() {\n const changes = undoStack.redo();\n if (!changes) {\n return false;\n }\n replay(changes, \"redo\");\n return true;\n },\n copy(range, { escapeFormulas = false } = {}) {\n const { rows, columns } = getSnapshot();\n const matrix: string[][] = [];\n rows.forEach((row, rowIndex) => {\n const line: string[] = [];\n columns.forEach((column, columnIndex) => {\n if (rangeContains(range, { row: rowIndex, column: columnIndex })) {\n const display = row.getDisplay(column.id);\n line.push(escapeFormulas ? escapeFormula(display, row.getValue(column.id)) : display);\n }\n });\n if (line.length > 0) {\n matrix.push(line);\n }\n });\n return toDelimited(matrix);\n },\n paste(origin, text) {\n if (\n !Number.isInteger(origin.row) ||\n !Number.isInteger(origin.column) ||\n origin.row < 0 ||\n origin.column < 0\n ) {\n return applyChanges([], true, [\n issue(\n \"invalid_value\",\n \"The paste origin must use non-negative whole row and column indices.\",\n ),\n ]);\n }\n const { rows, columns } = getSnapshot();\n const parsed = readDelimited(text, {\n maxRows: Math.max(0, rows.length - origin.row),\n maxColumns: Math.max(0, columns.length - origin.column),\n maxCells: maxPasteCells,\n maxLength: maxPasteLength,\n });\n const issues = parsed.truncated\n ? [\n issue(\n \"paste_truncated\",\n \"The paste exceeds the visible grid or parsing limits; only complete cells within those limits are applied.\",\n ),\n ]\n : [];\n return applyChanges(rangeEdits(origin, parsed.rows), true, issues);\n },\n clear(range) {\n const matrix = Array.from({ length: range.bottom - range.top + 1 }, () =>\n Array.from({ length: range.right - range.left + 1 }, () => \"\"),\n );\n const current = getSnapshot();\n const edits = rangeEdits({ row: range.top, column: range.left }, matrix).filter((edit) => {\n const row = current.getRow(edit.rowKey);\n return (\n row !== undefined && current.getColumn(edit.column)?.isEditable(row.original) === true\n );\n });\n return applyChanges(edits, true);\n },\n exportRows({\n format = \"csv\",\n columns: ids,\n pageOnly = false,\n headers = true,\n escapeFormulas = true,\n } = {}) {\n const current = getSnapshot();\n const columns = ids\n ? ids.flatMap((id) => {\n const column = current.getColumn(id);\n return column ? [column] : [];\n })\n : current.columns;\n const rows = pageOnly ? current.rows : current.processedRows;\n const matrix = rows.map((row) =>\n columns.map((column) => {\n const display = row.getDisplay(column.id);\n return escapeFormulas ? escapeFormula(display, row.getValue(column.id)) : display;\n }),\n );\n if (headers) {\n matrix.unshift(\n columns.map((column) => (escapeFormulas ? escapeFormula(column.header) : column.header)),\n );\n }\n return toDelimited(matrix, format === \"csv\" ? \",\" : \"\\t\");\n },\n\n reset() {\n commit(initialState);\n },\n destroy() {\n listeners.clear();\n },\n };\n return table;\n}\n"],"mappings":"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"}
|